Две разные программы во Flash - PullRequest
0 голосов
/ 12 ноября 2010

Можно ли запускать 2 разные программы на Си (т.е. две основные ()), сохраненные во Flash (микроконтроллере), по одной за раз?

У меня есть код загрузчика, который является отдельной программой инаходится в отдельном защищенном разделе ПЗУ.Тогда у меня есть моя прикладная программа, которая находится в отдельном разделе ROM.Хотя пребывание в памяти не является проблемой, но как компоновщик это интерпретирует?Как я могу переключаться между 2 программами.Это возможно?

Например: Как только я закончу с загрузчиком, я могу перейти к функции приложения, но как компоновщик узнает эту функцию?

Просто добавлю, я использую серии Freescale HCS08 иIDE - это Codewarrior.

Далее приведена последовательность шагов: Я загружаю код загрузчика в ПЗУ.Затем этот код загрузчика требуется для загрузки кода моего приложения.И тогда мой код приложения должен вступить во владение.

Код загрузчика: область прикладной программы ПЗУ Запустить прикладную программу

Код приложения: проверить, следует ли запускать код загрузчика или само приложение.

Ответы [ 2 ]

1 голос
/ 12 ноября 2010

Main - это просто функция. Вы можете переименовать его и написать другой основной, который вызывает любой из них.

Если вы не хотите переименовывать main в исходном коде, вы можете изменить его имя с помощью define или ключа компилятора:

cc -Dmain=main1 ...

(для первой программы) и

cc -Dmain=main2 ...

(для второго). Основной селектор:

int main(void) {
    if(x) return main1();
    else return main2();
}

Затем свяжите все вместе и загрузите на свой контроллер.

Но есть проблема с ISR: вы не можете назначить две подпрограммы одному вектору irq. Если векторы жестко закодированы в каком-либо месте флэш-памяти (как в большинстве 8-битных контроллеров), вы не можете переключать ISR. Вам нужно написать оболочку ISR, узнающую, какая программа запущена, и вызывающую соответствующий ISR.

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

UPD2 О, теперь я действительно понимаю. Если вы хотите связать и загрузить их отдельно, вы должны иметь дело с картами компоновщика. В этом случае одинаковые имена символов (например, многие из основных) не проблема. В карте компоновщика вы должны определить известную точку входа [установить ее в абсолютный адрес], с которой начинается любой код приложения. Код запуска (обычно это код сборки) должен быть связан с этого адреса. От селектора вы должны решить и перейти непосредственно к определенному месту. (Делайте это только для загрузчика, если ваше приложение также является селектором).

Точка входа, предоставляемая компоновщиком, может быть доступна программой как внешняя функция:

int app2_start(void);

{
   .... /* condition check */
   app2_start(); /* this symbol defined in linker map, not in any source */
}

Но это не адрес его main (), потому что C RTL действительно выполняет много инициализаций (стек, инициализированные переменные, куча, IO и т. Д.), Прежде чем main () может запуститься.

Есть более распространенный способ, с помощью которого загрузчик решает, должен ли он запускаться сам или приложение, потому что, если код приложения не работает, boodloader может стать недоступным.

0 голосов
/ 12 ноября 2010

То, как я это сделал, - воткнуть точку входа в заголовок приложения. Затем заставьте загрузчик вытащить эту точку входа и перейти к ней с соответствующей инструкцией по сборке. Вам может понадобиться скрипт компоновщика, чтобы получить саму точку входа из приложения. GNU ld использует ENTRY .

...