Библиотека 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.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines