Перейти к содержанию
    

Вызов функций из bootloader

В приложении необходимо переписывать таблицы констант расположенные в FLASH. Для этого требуется вызывать подпрограмму расположенную в boot-секторе. Но не всё так просто как кажется! Boot-sector полностью занял bootloader и при загрузке или обновлении приложения через бут, этот кусочек кода bootloader ом отбрасывается, тк секция защищена от записи сама в себя. И получается невозможным реализовать запись приложения во FLASH тк отсутствует нужная подпрограмма.

 

Остаётся попробовать пользоваться функциями записи самого bootloader. Попробовал, не работает.

Как делал:

 

1. Смотрю адрес нужной функции в IAR map файле:

flash_page_write CODE 0001F72E

 

2. Создаю в основной программе указатель:

void (*flash_page_write)(unsigned short) = (void (*)(unsigned short))0x1F72E;

При этом IAR выдаёт предупреждение. Warning[Pe1053]: conversion from integer to smaller pointer

 

3. Записываю в кристалл boot, затем с его помощью загружаю и запускаю приложение.

4. Пытаюсь записать страницу памяти.

 

Затем всё зависает. Вероятно не происходит возврата из вызванной функции.

Посмотреть отладчиком что происходит не получается.

 

Вопрос такой. Если boot-сектор залочен от чтения и записи, выполняются ли из него вызовы из приложения?

Что делаю не так?

Изменено пользователем sevstels

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос такой. Если boot-сектор залочен от чтения и записи, выполняются ли из него вызовы из приложения?

Что делаю не так?

 

Memory programming / Lock bits

1 1 1 No restrictions for SPM or (E)LPM accessing the Boot
Loader section.
2 1 0 SPM is not allowed to write to the Boot Loader section.
3 0 0
SPM is not allowed to write to the Boot Loader section,
and (E)LPM executing from the Application section is not
allowed to read from the Boot Loader section. If interrupt
vectors are placed in the Application section, interrupts
are disabled while executing from the Boot Loader section.
4 0 1
(E)LPM executing from the Application section is not
allowed to read from the Boot Loader section. If interrupt
vectors are placed in the Application section, interrupts
are disabled while executing from the Boot Loader section.
Memory Lock Bits Protection Type

 

Можно предложить обходной путь - выделяется область памяти в ОЗУ под команду загрузчику. Туда пишется команда, ее аргументы и crc, затем процессор перезагружается (скажем по вотчдогу). Загрузчик при старте проверяет, есть ли в этой области команда и выполняет ее

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

>> выделяется область памяти в ОЗУ под команду загрузчику

Перезагружаться нельзя, тк будет разорвана связь с PC и процесс обновления "упадёт". А сам же фирменный Atmel CAN bootloader к сожалению крив до безобразия, тк писать страницы выше 64к он не способен ввиду того, что ему забыли прикрутить long адресацию. Через CAN протокол поддерживается передача только 2х байтного адреса и попытка это исправить вызывает переполнение boot section и загручик не влазит в память. Как ни крути - а переписать FLASH константы самим бутом - не получится. Только из приложения.

Изменено пользователем sevstels

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

>> выделяется область памяти в ОЗУ под команду загрузчику

Перезагружаться нельзя, тк будет разорвана связь с PC и процесс обновления "упадёт". А сам же фирменный Atmel CAN bootloader к сожалению крив до безобразия, тк писать страницы выше 64к он не способен ввиду того, что ему забыли прикрутить long адресацию. Как ни крути - а переписать FLASH константы самим бутом - не получится. Только из приложения.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробовал снять все биты защиты.

Результат аналогичен - зависает.

 

Смущает предупреждение компилятора: Warning[Pe1053]: conversion from integer to smaller pointer

Похоже указатель void 2х байтный, а надо 3х байтный те __farflash.

Но IAR указатель __farflash отказывается принять... как правильно написать не соображу.

 

Изменено пользователем sevstels

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2. Создаю в основной программе указатель:

void (*flash_page_write)(unsigned short) = (void (*)(unsigned short))0x1F72E;

 

Проверьте адресацию в map-файле. Вполне вероятно, что она байтовая и тогда Вы вызываете функцию по случайному адресу вместо (0x1F72E>>1);

 

 

Но IAR указатель __farflash отказывается принять... как правильно написать не соображу.

__far

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

__far не принимается (размер памяти программ 128к, AT90CAN128)

Error[Pa043]: the keyword "__far" is not available with the current settings

 

Вот такой вариант собирается но не работает:

void (__nearfunc *flash_page_write)(unsigned short) = ( void (__nearfunc *)(unsigned short))0x1F72E;

Трудность всё та-же: Warning[Pe1053]: conversion from integer to smaller pointer

Посмотрел вызов в дизассемблере отладчика. Он 2х байтный, всместо 0x1F72E адрес 0xF72E;

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрел вызов в дизассемблере отладчика. Он 2х байтный, всместо 0x1F72E адрес 0xF72E;

 

Так может надо записать в указатель 0x1F72E / 2 ? Давно не имел дела с потрохами avr, уже не помню точно...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вам нужно такой оператор.

void (*flash_page_write)(unsigned short) = (void (*)(unsigned short))0xFB97; // (0x1F72E>>1);

 

Флеш адресуется пословно, но в мепе указан побайтовый, который в 2-раза больший.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

>> в мепе указан побайтовый

Таки Бинго, работает!

 

void (*flash_wr_block)(unsigned char*, long, unsigned short) =

(void (*)(unsigned char*, long, unsigned short))(0x1F004>>1);

 

Позвал из bootloader более высокоуровневую: flash_wr_block(pMem, fl_address, 256);

 

Нормально пишет по всему CODE area;

aiwa спасибо Вам за подсказку.

Изменено пользователем sevstels

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Любая подпрограмма из закрытой области BOOT вызывается без проблем, так и наоборот из обрасти BOOT можно выполнить любую операцию (если она не завязана на прерывания и перенастройку периферии). Векторы прерываний надо переключать, после перехода из BOOT -> MAIN и наоборот.

Это ведь для нас код как бы скрыт, для проца данные всегда в читабельном виде. Просто встроенный в процессор загрузчик в зависимости от состояния локбитов выдает нам одно либо другое.

 

Немного из моей практики.

К примеру есть у Вас протокол, по которому Вы обновляете ПО, это будет UART, CAN, или свой какой-то 1-wire, о котором никто никогда и не догадается.

Для обновления прошивки не обязательно дергать ресетами, зажимать кнопки, итд.

В MAIN пишем обработчик "секретной" посылки, (он же обязан быть и в секции BOOT)!

Перешли в бут и работаем с бутом.

Аналогично схожей командой и вышли от туда.

 

Кстати, сам не пользуюсь загрузчиками от ATMEL, пишу свои.

Стояла задача работать с областями Flash, EEprom, External i2c.

Лень было каждую 24схх в программаторе писать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как будет выглядеть вызов функции с параметрами?

void MyFunc(unsigned int MyPar)

{

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...