Библиотека LUFA (раннее название MyUSB) версия 101122
|
Общее требование многих приложений - возможность перейти по запросу к запрограммированному в чип бутлоадеру из кода пользовательского firmware (например, без каких-либо физических манипуляций с аппаратурой для пользователя). Это может понадобиться по причине отсутствия в устройстве какого-либо физического ввода от пользователя, или просто для оптимизирования процесса обновления firmware со стороны хоста PC.
Следующий фрагмент кода C может использоваться для входа в бутлоадер по запросу приложения пользователя. Путем использования сторожевого таймера (watchdog) для физического сброса контроллера, обеспечивается полный сброс всей аппаратуры чипа в её состояние по умолчанию, перед тем как запустится бутлоадер. Это очень важно; поскольку бутлоадеры пишутся так, чтобы занимать как можно меньше места в памяти, то они обычно предполагают состояние регистров по умолчанию после холодного сброса (hard-reset) чипа.
#include <avr/wdt.h> #include <avr/io.h> #include <util/delay.h> #include <LUFA/Common/Common.h> #include <LUFA/Drivers/USB/USB.h> uint32_t Boot_Key ATTR_NO_INIT; #define MAGIC_BOOT_KEY 0xDC42ACCA #define BOOTLOADER_START_ADDRESS (FLASH_SIZE_BYTES - BOOTLOADER_SEC_SIZE_BYTES) void Bootloader_Jump_Check(void) ATTR_INIT_SECTION(3); void Bootloader_Jump_Check(void) { // Если источник сброса был загрузчик, и состояние ключа корректное, очищаем ключ и делаем прыжок в бутлоадер if ((MCUSR & (1 << WDRF)) && (Boot_Key == MAGIC_BOOT_KEY)) { Boot_Key = 0; ((void (*)(void))BOOTLOADER_START_ADDRESS)(); } } void Jump_To_Bootloader(void) { // Если USB используется, сделаем отключение от шины USB_ShutDown(); // Запрет всех прерываний cli(); // Ждем две секунды, чтобы отключение от USB было зарегистрировано хостом for (uint8_t i = 0; i < 128; i++) _delay_ms(16); // Установка ключа бутлоадера в магическое значение и запускаем принудительную перезагрузку Boot_Key = MAGIC_BOOT_KEY; wdt_enable(WDTO_250MS); for (;;); }
Примечание: магический ключ для бутлоадера может иметь произвольное значение. Токены FLASH_SIZE_BYTES и BOOTLOADER_SEC_SIZE_BYTES должны быть заменены общим размером flash на чипе AVR в байтах, и выделенным размером секции бутлоадера на целевом чипе AVR.