Выполнение кода во встроенных системах

Можно ли передать системное свойство Java для каждого задания? Если так, можно параметризовать как это:

java -Dmy_var=somevalue my.job.Classname

И затем в Вашем log4j.properties:

log4j.appender.A.File=${my_var}/A.log

Вы могли заполнить системное свойство Java со значением от среды хоста (например), которая однозначно определит экземпляр задания.

9
задан inquisitive 2 September 2009 в 10:46
поделиться

6 ответов

Как архитектор микропроцессоров, я имел возможность работать с программным обеспечением на очень низком уровне. По сути, низкоуровневое встроенное ПО сильно отличается от общего программирования ПК только на уровне аппаратного обеспечения.

Низкоуровневое встроенное программное обеспечение можно разбить на следующее:

  1. Вектор сброса - обычно это записывается сборка. Это самое первое, что запускается при запуске, и его можно рассматривать как программный код. Обычно он выполняет простые функции, такие как установка процессора в заранее определенное устойчивое состояние путем настройки регистров и т. Д. Затем он перейдет к коду запуска. Самый простой вектор сброса просто переходит непосредственно к коду запуска.
  2. Код запуска - это первый запускаемый программно-зависимый код. Его задача состоит в том, чтобы настроить программную среду так, чтобы код C мог работать поверх. Например, код C предполагает, что существует область памяти, определенная как стек и куча. Обычно это программные конструкции, а не оборудование. Следовательно, этот фрагмент кода запуска будет определять указатели стека, указатели кучи и тому подобное. Обычно это группируется под « c-runtime ». Для кода C ++ также вызываются конструкторы. В конце подпрограммы он выполнит main () . править: Здесь выполняются переменные, которые необходимо инициализировать, а также определенные части памяти, которые необходимо очистить. По сути, все, что нужно для перевода вещей в «известное состояние».
  3. Код приложения - это ваше собственное приложение C, начиная с функции main () . Как видите, многие вещи на самом деле скрыты и происходят еще до того, как будет вызвана ваша первая основная функция. Этот код обычно может быть написан как аппаратно-независимый, если имеется хороший уровень аппаратной абстракции . Код приложения определенно будет использовать множество библиотечных функций. Эти библиотеки обычно статически связаны во встроенных системах.
  4. Библиотеки - это ваши стандартные библиотеки C, которые предоставляют примитивные функции C. Существуют также библиотеки для конкретных процессоров, которые реализуют такие вещи, как программная поддержка операций с плавающей запятой. Также могут быть аппаратно-зависимые библиотеки для доступа к устройствам ввода-вывода, например, для stdin / stdout. Пара общих библиотек C - это Newlib и uClibc .
  5. Прерывание / Исключение обработчик - это процедуры, которые выполняются в случайное время во время нормального выполнения кода в результате изменений в состоянии оборудования или процессора. Эти подпрограммы также обычно пишутся на ассемблере, так как они должны работать с минимальными затратами на программное обеспечение для обслуживания вызываемого оборудования.

Надеюсь, это будет хорошим началом. Не стесняйтесь оставлять комментарии, если у вас есть другие вопросы.

39
ответ дан 4 December 2019 в 06:00
поделиться

Как правило, вы работаете на гораздо более низком уровне, чем компьютеры общего назначения.

Каждый ЦП будет иметь определенное поведение при включении питания, например, очистка всех регистров и установка счетчика программ на 0xf000 (здесь все не является конкретным, как и ваш вопрос).

Уловка состоит в том, чтобы убедиться, что ваш код находится в нужном месте.

Процесс компиляции обычно аналогичен компьютерам общего назначения, поскольку вы переводите C в машинный код (объектные файлы). Оттуда вам нужно связать этот код с:

  • кодом запуска вашей системы, часто на ассемблере.
  • любыми библиотеками времени выполнения (включая необходимые биты C RTL).

Обычно код запуска системы просто инициализирует оборудование и настраивает среду для работы вашего кода C. Библиотеки времени выполнения во встроенных системах часто делают большие объемные вещи (например, поддержку с плавающей запятой или printf) необязательными, чтобы уменьшить раздувание кода.

Компоновщик во встроенных системах также обычно намного проще, выводя код с фиксированным местоположением, а не перемещаемые двоичные файлы. Вы используете его, чтобы убедиться, что код запуска находится (например) на 0xf000.

Во встроенных системах вы обычно хотите, чтобы исполняемый код был там с самого начала, чтобы вы могли записать его в EPROM (или EEPROM, или Flash или другое устройство, которое сохраняет содержимое при выключении питания).

Конечно, имейте в виду, что мой последний набег был с процессорами 8051 и 68302. Возможно, что «встроенные» системы в настоящее время представляют собой полноценные Linux-системы со всеми видами замечательного оборудования, и в этом случае не будет реальной разницы между универсальным и встроенным.

Но я сомневаюсь в этом. Там' все еще существует потребность в оборудовании с очень низкими техническими характеристиками, которое требует специальных операционных систем и / или кода приложений.

SPJ Embedded Technologies имеет загружаемую оценку их среды разработки 8051, которая выглядит как вы хотите. Вы можете создавать программы размером до 2K, но кажется, что они проходят через весь процесс (компилирование, связывание, создание файлов HEX или BIN для выгрузки на целевое оборудование, даже симулятор, который дает доступ к материалам на кристалле и внешним устройствам) ).

Продукт без оценки стоит 200 евро, но, если все, что вам нужно, это немного поиграться, я бы просто загрузил оценку - кроме ограничения 2K, это полный продукт.

SPJ Embedded Technologies имеет загружаемую оценку их среды разработки 8051, которая выглядит именно так, как вам нужно. Вы можете создавать программы размером до 2 КБ, но, похоже, они проходят через весь процесс (компилирование, связывание, создание файлов HEX или BIN для выгрузки на целевое оборудование, даже симулятор, который дает доступ к материалам на кристалле и внешним устройствам) ).

Продукт без оценки стоит 200 евро, но, если все, что вам нужно, это немного поиграться, я просто скачаю тестовую версию - кроме ограничения 2K, это полный продукт.

SPJ Embedded Technologies имеет загружаемую оценку их среды разработки 8051, которая выглядит именно так, как вам нужно. Вы можете создавать программы размером до 2K, но кажется, что они проходят через весь процесс (компилирование, связывание, создание файлов HEX или BIN для выгрузки на целевое оборудование, даже симулятор, который дает доступ к материалам на кристалле и внешним устройствам) ).

Продукт без оценки стоит 200 евро, но, если все, что вам нужно, это немного поиграться, я бы просто загрузил оценку - кроме ограничения 2K, это полный продукт.

5
ответ дан 4 December 2019 в 06:00
поделиться

У меня сложилось впечатление, что вас больше всего интересует то, что sybreon называет «шагом 2». Там может происходить многое, и это сильно зависит от платформы. Обычно с этим справляется некоторая комбинация загрузчика, пакета поддержки платы, среды выполнения C (CRT) и, если она у вас есть, ОС.

Обычно после вектора сброса запускается какой-то загрузчик. от вспышки. Этот загрузчик может просто настроить оборудование и перейти в CRT вашего приложения, также во флэш-памяти. В этом случае CRT, вероятно, очистит .bss, скопирует .data в RAM и т. Д. В других системах загрузчик может загружать приложение из закодированного файла, такого как ELF, а CRT просто настраивает другие материал времени выполнения (куча и т. д.). Все это происходит до того, как CRT вызовет функцию main () приложения.

Если ваше приложение статически связано, Директивы компоновщика будут указывать адреса, по которым инициализируются .data / .bss и стек. Эти значения либо связаны с CRT, либо закодированы в ELF. В динамически связанной среде загрузкой приложения обычно занимается ОС, которая перенаправляет ELF для работы в той памяти, которую назначает ОС.

Кроме того, некоторые целевые объекты запускают приложения из флэш-памяти, а другие копируют исполняемый файл .text из флэш-памяти в оперативную память. (Обычно это компромисс между скоростью и занимаемой площадью, поскольку для большинства целей оперативная память быстрее / шире, чем флеш-память.)

но другие скопируют исполняемый файл .text из флэш-памяти в ОЗУ. (Обычно это компромисс между скоростью и занимаемой площадью, поскольку для большинства целей оперативная память быстрее / шире, чем флэш-память.)

но другие скопируют исполняемый файл .text из флэш-памяти в ОЗУ. (Обычно это компромисс между скоростью и занимаемой площадью, поскольку для большинства целей оперативная память быстрее / шире, чем флэш-память.)

3
ответ дан 4 December 2019 в 06:00
поделиться

У меня есть опыт работы с микроконтроллерами AVR, но я думаю, что это будет почти одинаково для всех из них:

Компиляция выполняется по тем же принципам, что и с обычным кодом C. Он компилируется в объектные файлы, они связаны друг с другом, но вместо вывода какого-то сложного формата, такого как ELF или PE, вывод просто помещается по фиксированному адресу в памяти uC без каких-либо заголовков.

Код запуска (если компилятор генерирует любой) добавляется так же, как код запуска для "обычных" компьютеров - некоторый код добавляется перед вашим кодом main () (и, возможно, после него тоже).

Еще одно отличие заключается в связывании - все должен быть связан статически, потому что микроконтроллеры не имеют ОС для обработки динамического связывания.

1
ответ дан 4 December 2019 в 06:00
поделиться

Вы можете ознакомиться с очень подробным учебником GNU ARM от Джима Линча.

1
ответ дан 4 December 2019 в 06:00
поделиться

Хорошо, я попробую ...

Прежде всего, архитектуры. Фон Нейман против Гарварда. Гарвардская архитектура имеет отдельную память для кода и данных. Фон Нейман - нет. Гарвард используется во многих микроконтроллерах, и это то, с чем я знаком.

Итак, начиная с вашей базовой гарвардской архитектуры, у вас есть программная память. Когда микроконтроллер впервые запускается, он выполняет инструкции в нулевой ячейке памяти. Обычно это команда JUMP to address, с которой начинается основной код.

Теперь, когда я говорю «инструкции», я имею в виду коды операций. Коды операций - это инструкции, закодированные в двоичные данные - обычно 8 или 16 бит. В некоторых архитектурах каждый код операции жестко запрограммирован для обозначения определенных вещей, в других каждый бит может быть значимым (например, бит 1 означает проверку переноса, бит 2 означает проверку нулевого флага и т. Д.). Итак, есть коды операций, а затем параметры для кодов операций. Инструкция JUMP - это код операции и 8-, 16- или 32-битный адрес памяти, на который код «перескакивает». Т.е. управление передается инструкциям по этому адресу. Это достигается путем манипулирования специальным регистром, который содержит адрес следующей инструкции, которая должна быть выполнена. Таким образом, чтобы перейти к ячейке памяти 0x0050, он заменит содержимое этого регистра на 0x0050. В следующем тактовом цикле процессор прочитает регистр, найдет адрес памяти и выполнит там инструкцию.

Выполнение инструкций вызывает изменения в состоянии машины. Существует общий регистр состояния, в котором записывается информация о том, что сделала последняя команда (т. Е. Если это добавление, то если требуется выполнение, для этого есть бит и т. Д.). Существует ' регистр аккумулятора, в который помещается результат выполнения инструкции. Параметры для инструкций могут находиться либо в одном из нескольких регистров общего назначения, либо в аккумуляторе, либо в адресах памяти (данные ИЛИ программа). Различные коды операций могут выполняться с данными только в определенных местах. Например, вы можете добавить данные из двух регистров общего назначения и отобразить результат в аккумуляторе, но вы не можете взять данные из двух ячеек памяти данных и отобразить результат в другом месте памяти данных. Вам нужно будет переместить нужные данные в регистры общего назначения, произвести сложение, а затем переместить результат в нужное место памяти. Вот почему сборка считается сложной. Регистров состояния столько, сколько рассчитана архитектура. Более сложные архитектуры могут иметь больше возможностей для более сложных команд. Более простые - нет.

Существует также область памяти, известная как стек. Для некоторых микроконтроллеров (например, 8051) это просто область памяти. В других он может иметь особую защиту. Существует регистр, называемый указателем стека, который записывает, в каком месте памяти находится «верх» стека. Когда вы «вставляете» что-то в стек из аккумулятора, тогда «верхний» адрес памяти увеличивается, а данные из аккумулятора помещаются в прежний адрес. При извлечении или извлечении данных из стека выполняется обратное, и указатели стека уменьшаются, а данные из стека помещаются в аккумулятор.

Теперь я также как бы застеклил над тем, как «выполняются» инструкции. Хорошо, это когда вы переходите к цифровой логике - типа VHDL. Мультиплексоры, декодеры, таблицы истинности и все такое. Это настоящая мелочь дизайна - вроде как. Поэтому, если вы хотите «переместить» содержимое ячейки памяти в аккумулятор, вам нужно выяснить логику адресации, очистить регистр аккумулятора, И его данными в ячейке памяти и т. Д. вы выполнили отдельные части (например, адресацию, полусумматор и т. д.) на VHDL или в любой другой цифровой логике, у вас может быть представление о том, что требуется.

Как это относится к C? Что ж, компилятор возьмет инструкции C и превратит их в серию кодов операций, которые выполняют запрошенные операции. Все это в основном шестнадцатеричные данные - единицы и нули, которые помещаются в какой-то момент в памяти программы. Это делается с помощью директив компилятора / компоновщика, которые сообщают, какая область памяти используется для какого кода. Он записывается во флеш-память на чипе, а затем, когда чип перезагружается, он переходит в ячейку памяти кода 0x0000 и переходит к начальному адресу кода в программной памяти, а затем начинает вставлять коды операций.

2
ответ дан 4 December 2019 в 06:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: