AVR, как прыгнуть на bootloader из программы?

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Аватара пользователя
Coolish
Опытный кот
Сообщения: 785
Зарегистрирован: Сб фев 27, 2010 21:45:37
Откуда: Ростов-на-Дону
Контактная информация:

AVR, как прыгнуть на bootloader из программы?

Сообщение Coolish »

Здравствуйте.
В своих проектах на ATMEGA8,16,32 я использую bootloader avrprog_boot_v0_85. Он запускается по старту контроллера благодаря фьюзу BOOTRST.

Возник вопрос.

1) Каким образом можно корректно запустить загрузчик из основной программы, чтобы это не привело к переполнениям стека или ещё чего похуже?
2) Есть ли наиболее универсальный способ, какой-либо программный RESET, который перезапустит контроллер и запустит загрузчик, независимо от его размера и размера flash-памяти?

Цель - возможность запуска загрузчика при общении контроллера и компьютера без выполнения аппаратного сброса
Основная программа скомпилирована на CodeVision.
После выполнения загрузчика должна опять запуститься основная программа (естественно, с начала).
Сделать хотел грозу, а получил КоЗу
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение ARV »

про программно-аппаратный сброс уже было говорено не один раз: единственный способ настоящего сброса - это установить WDT и зациклиться, пока он не сработает. только после срабатывания WDT не забудьте его отключить, а то снова сработает через 15 мс.

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

Мой уютный бложик... заходите!
Аватара пользователя
alex2103
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт сен 18, 2007 16:41:16
Откуда: Украина, г. Запорожье
Контактная информация:

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение alex2103 »

Я просто по команде от ПК перехожу на адрес загрузчика...

А вот подскажите как можно использовать функции, которые лежать в области загрузчика, из основной программы?
Хочу сделать обновление прошивки по радиоканалу, протокол будет лежать в загрузчике...так почему же эти функции еще и в основной программе дублировать?
Как такое реализовать на CVAVR?
Shplv
Первый раз сказал Мяу!
Сообщения: 28
Зарегистрирован: Пт июн 04, 2010 19:24:26

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение Shplv »

alex2103 писал(а):А вот подскажите как можно использовать функции, которые лежать в области загрузчика, из основной программы?
Для этого нужно знать адреса функций. Если эти адреса известны, то вызываете функцию по этим адресам. Например, по адресу 1234h лежит функция, возвращающая char и имеющая один парамерт типа int

Код: Выделить всё

typedef char (* pFunc_t)(int);
pFunc_t Func= (pFunc_t)0x1234;

вызывается функция с параметром равным пяти так

Код: Выделить всё

char Ch;
Ch=Func(5);

или даже так

Код: Выделить всё

Ch=((pFunc_t)0x1234)(5);
Аватара пользователя
zebrox
Встал на лапы
Сообщения: 117
Зарегистрирован: Вс апр 12, 2009 22:40:37

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение zebrox »

а как узнать адрес функции?
в CVAVR и ICCAVR?
Shplv
Первый раз сказал Мяу!
Сообщения: 28
Зарегистрирован: Пт июн 04, 2010 19:24:26

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение Shplv »

zebrox писал(а):а как узнать адрес функции?
Самое простое - посмотреть в map-файле
Аватара пользователя
alex2103
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт сен 18, 2007 16:41:16
Откуда: Украина, г. Запорожье
Контактная информация:

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение alex2103 »

Все таки как узнать адреса функций в cvavr? Вроде бы все перерыл и нигде не нашел... :(

Смысла хранить 2 копии одних и тех же функций не вижу... Хотелось бы разобраться с этим вопросом.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение ARV »

разобраться с этим вопросом не сложно, если разобраться с тем, как CVAVR работает. лично я про это не знаю. а вот компиляторы традиционного вида, которые с нормальным компоновщиком и т.п. - с теми вполне легко.
во-первых, можно по map-файлу определить адреса функций и поступить, как было сказано ранее.
во-вторых, можно сделать таблицу входов в функции по принципу таблицы векторов - т.е. адрес ее начала и так уже известен, и содержимое так же известно.
в-третьих, можно поступить по принципу 21-го прерывания MS DOS (возможно, есть еще люди, кто в курсе, что это такое). а именно: в функции загрузчика проверять содержимое какого-то регистра или определенной ячейки ОЗУ, в котором будет номер конкретной функции вашего протокола. загрузчик, получив управление, проверяет содержимое этой ячейки и вызывает нужную функцию. ну а из обычной программы вы сначала записываете в эту ячейку номер функции, а потом делаете переход на загрузчик - адрес его начала вам известен. в этом методе есть плюс - не надо беспокоиться о расположении и адресах функций, но есть и минус - надо обеспечить а)гарантию отсутствия мусора в "переключательной" ячейке (например, при получении управления загрузчиком при подаче питания), и б) все "протокольные" функции должны иметь одинаковые параметры (лучше вообще их не иметь - только через глобальные переменные по абсолютным адресам работать) и одинаковый возвращаемый результат (так же лучше void).

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

Мой уютный бложик... заходите!
Аватара пользователя
alex2103
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт сен 18, 2007 16:41:16
Откуда: Украина, г. Запорожье
Контактная информация:

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение alex2103 »

в map-файле есть только переменные...функций нет.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение ARV »

alex2103 писал(а):в map-файле есть только переменные...функций нет.

я вам писал:
а вот компиляторы традиционного вида, которые с нормальным компоновщиком и т.п. - с теми вполне легко.
раз CVAVR не делает нормальный map-файл, этот вариант не подойдет - а остальные два вполне :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение Jack_A »

Все-таки мое предпочтение ассемблера языкам высокого уровня при работе с микроконтроллерами нашло вот такое яркое подтверждение : элементарнейший вопрос об адресации, который у "АСМ-щика" даже вообще не возникает, вызывает такую дискуссию, и пока не решен. Совет - посмотрите в Студии полученный код - я даже предлагать не буду : для этого же надо знать коды команд МК, а не высоко парящие PRINTF IF ELSE.
Я с CVAVR не работал, потому не знаю, как он справляется с бутлодырем, потому что тот должен ведь размещаться не где попало, а в определенной области флеши.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение ARV »

Jack_A писал(а):элементарнейший вопрос об адресации, который у "АСМ-щика" даже вообще не возникает, вызывает такую дискуссию, и пока не решен. Совет - посмотрите в Студии полученный код - я даже предлагать не буду
если асм-щик занимается тем, что глядя в дизассемблированный код определяет адреса для переходов, - грош ему цена в базарный день. это не метод. я многократно встречал асм-щиков, которые и таблицу векторов делают через пень-колоду...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
asteroid7
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 18, 2009 21:12:49

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение asteroid7 »

alex2103 писал(а):Все таки как узнать адреса функций в cvavr? Вроде бы все перерыл и нигде не нашел... :(
...

Имя функции - и есть её адрес.
Для чего этот адрес нужен? Что делать с ним дальше хотите?

Пример:

Код: Выделить всё

void fun( void )
{
    //...
}

void main( void )
{
    //указатель на функцию
    void( * fun_pointer )( void ) = fun;
    //так к функции можно обратиться через указатель
    fun_pointer();
   
    //а это адрес функции до 64 кБ
    unsigned int fun_adr = ( unsigned int )fun * 2;
    //и чё с ним делать???
    ...
}
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение ARV »

asteroid7 писал(а):Имя функции - и есть её адрес.
Для чего этот адрес нужен? Что делать с ним дальше хотите?
вы не внимательно прочли тему: внутри своей программы адреса всех функций известны, как вы справедливо изволили заметить, но bootloader - это отдельно разработанная программа, прошитая по фиксированному адресу, и основная об этой программе не знает ничего, кроме адреса начала boot-секции. в этом и есть проблема: дать одной программе сведения о функциях другой, чтобы они стали взаимодействоать.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Murav
Опытный кот
Сообщения: 877
Зарегистрирован: Чт фев 18, 2010 13:51:56

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение Murav »

asteroid7 писал(а):Имя функции - и есть её адрес.

Только внутри одной программы. А бутлоадер с основной прошивкой хоть и записываются в один контроллер, но компилятся отдельно.
asteroid7 писал(а):Для чего этот адрес нужен? Что делать с ним дальше хотите?

Вызвать функцию по этому адресу.

Вообще самый правильный способ - в прошивке бутлоадера по фиксированному адресу(например последних 64 байтах) создаётся структура в которой указывается сигнатура, чтобы знать что структура никуда не делась, и указатели на функции. Если интерфейс планируется менять между версиями, то можно использовать пару ID-указатель и искать по ID, а не по смещению, чтобы была совместимость новых прошивок со старыми бутлоадерами.

То есть в общем для бутлоадера и основной программы h-файле задаётся структура:

Код: Выделить всё

typedef int *func1_t(int param1);
typedef void *func2_t();
#define BOOTLOADERFUCTADDR 0x1FC0
#define BOOTLOADERFUCTSIGN 0x12345678
typedef struct {
unsigned long sign;
func1_t func1;
func2_t func2;
} BootloaderFunctionsStruct;

В бутлоадере задаётся сама структура:

Код: Выделить всё

int func1(int param1)
{
}
void func2()
{
}

__attribute__((__progmem__)) __attribute__((section (".functbl")) BootloaderFunctionsStruct bootfuncs = { //с атрибутами возможно ошибся - нужно смотреть документацию и эксперементировать
BOOTLOADERFUCTSIGN,
func1,
func2
}

А в настройках задаём новую секцию .functbl, начинающуюся с адреса 0x1FC0.
И в основной программе просто задаём переменную, которая ссылается на этот адрес:

Код: Выделить всё

BootloaderFunctionsStruct *bootfuncs = (BootloaderFunctionsStruct *)BOOTLOADERFUCTADDR;

void somefunc()
{
****
if (bootfuncs->sign!=BOOTLOADERFUCTSIGN) сообщаем об ошибке и выходим;
a = bootfuncs->func1(123);
}

Этот код я привёл для WinAVR, но на других компиляторах это тоже будет работать. Только атрибуты структуры в бутлоадере придётся указывать другие.
Последний раз редактировалось Murav Ср июл 21, 2010 22:41:01, всего редактировалось 1 раз.
Murav
Опытный кот
Сообщения: 877
Зарегистрирован: Чт фев 18, 2010 13:51:56

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение Murav »

Вообще задавать адреса на основе данных map-файла нежелательно - при любой перекомпиляции они сползут и их придётся задавать заново.
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение Jack_A »

ARV писал(а):если асм-щик занимается тем, что глядя в дизассемблированный код определяет адреса для переходов, - грош ему цена в базарный день. это не метод. я многократно встречал асм-щиков, которые и таблицу векторов делают через пень-колоду...

Ну, если он умеет только это - то может быть. А криво сделать таблицу векторов - это надо очень постараться, скопипастить из даташита кусок кода - это могут даже лошади.
Впрочем, во времена моей AVR-ной молодости изредка случалось :-) Но уж asm-щик никогда не заявит : эдрес функции - это ее имя. Ну нет в загружаемом модуле такого понятия вообще - имя. Оно накрылось во время компиляции, и выходной файл имеет понятные процессору вещи - адреса и коды команд.

Кстати для Murav: если пис`ать на АСМе, то никто никуда не слезает : есть такая директива .org - и код будет стоять в нужном месте, как вкопанный.
Murav
Опытный кот
Сообщения: 877
Зарегистрирован: Чт фев 18, 2010 13:51:56

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение Murav »

Jack_A писал(а):Кстати для Murav: если пис`ать на АСМе, то никто никуда не слезает : есть такая директива .org - и код будет стоять в нужном месте, как вкопанный.

Здесь предлагалось найти адрес функции в map-файле, а не задавать его .org . Вариант с .org для функций аналогичен варианту с таблицей адресов, только таблица адресов удобнее: адрес у неё один(а не по одному для функции), размер маленький, так что её можно запихнуть в конец памяти, где она мешатся не будет, не будет возникать дырок между экспортируемыми функциями и т.д.
Аватара пользователя
asteroid7
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 18, 2009 21:12:49

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение asteroid7 »

ARV писал(а):вы не внимательно прочли тему:
Перечитал. Увы, так и не нашёл, про раздельную компиляцию, что это линковщику/сборщику нужен неизвестный внешний/extern адрес функции.

ARV писал(а):... но bootloader - это отдельно разработанная программа, прошитая по фиксированному адресу, ...
Murav писал(а):...
А бутлоадер с основной прошивкой хоть и записываются в один контроллер, но компилятся отдельно. ...
Не обязательно. Можно одним целым компилить. Что бутлоадеру необходимо то в отдельную boot-секцию.


И всё равно, проблема мне не понятна. Даже, если раздельно компилить, то что мешает сделать точку входа совпадающую с адресом начала boot-секции?
Для перехода удобнее использовать fuse бит - стартовать с boot-секции при ресете.
Как ни крути, при любом решении адрес "бутлоадера" указывается и известен явно, даже при клонировании векторов прерываний.

Или я опять чего то не догоняю ) или здесь имеет место быть попытка компиляции без функции main()...
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: AVR, как прыгнуть на bootloader из программы?

Сообщение ARV »

asteroid7 писал(а): Даже, если раздельно компилить, то что мешает сделать точку входа совпадающую с адресом начала boot-секции?
я об этом и говорил :)

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

Мой уютный бложик... заходите!
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»