Возможность обновления прошивки на серийно выпускаемых изделиях или на единичных изделиях, используемых заказчиком, невозможно переоценить.
Это не только дает возможность впоследствии устранить ошибки и расширить функционал, но и позволяет разработчику с легким сердцем выпустить на рынок «еще сырой» продукт, если того потребует руководство.
Поэтому важность наличия загрузчика во вновь разрабатываемых устройствах в большинстве случаев не подлежит сомнению.
В этой статье речь пойдет о разработке загрузчика через интерфейс USB на микроконтроллере Atmel. ЗРК Д21 с ядром Cortex M0+.
И конкретно на SAMD21J18A .
Микроконтроллеры SAM D20/21 не имеют заранее записанного загрузчика, поэтому его придется реализовать программно.
Вы можете найти его на сайте Atmel. Замечания по применению , как это сделать, используя стандартные интерфейсы (UART, I2C, SPI, USB).
Ниже под катом описание процесса создания загрузчика USB.
Постановка задачи
- Необходимо разработать максимально простой, с точки зрения конечного пользователя, способ обновления прошивки устройства.
Для этого вам нужно будет скопировать файл с новой прошивкой на обычную флешку, вставить флешку в устройство и нажать кнопку сброса (или сбросить питание).
После этого запускается загрузчик, проверяет наличие файла с прошивкой на флэшке и загружает содержимое этого файла как приложение
- В целях «защиты от дурака» мы используем заранее известное специальное имя для файла прошивки, чтобы предотвратить случайное совпадение названий с другими файлами на флэшке.
Более того, если «злоумышленник» самостоятельно создаст сторонний файл с именем, совпадающим с ожидаемым, устройство попытается использовать его в качестве прошивки.
Конечно, в этом случае функциональность устройства будет нарушена, но ее можно будет восстановить позже, подсунув флешку с правильной прошивкой.
- В качестве USB-интерфейса используется USB-оборудование микроконтроллера устройства.
- Устройство не имеет постоянного подключения к Интернету для самостоятельной загрузки новых прошивок.
- Мы считаем, что подключить ПК к устройству и обновить прошивку с помощью сторонней утилиты сложнее для конечного пользователя.
Немного теории и подготовки
Память
Адресное пространство в памяти микроконтроллеров серии SAMD20/21 устроено просто:Энергонезависимая память организована рядами, каждая строка содержит 4 страницы.
Размер 1 страницы 64 байта.
Энергонезависимая память стирается построчно и записывается постранично.
Это важно помнить.
Нижние (нижние) строки в основном адресном пространстве энергонезависимой памяти могут использоваться для загрузчика (настраивается с помощью фьюзов BOOTPROT), а верхние строки — для эмуляции EEPROM. Раздел Bootloader защищен битами блокировки и фьюзами BOOTPROT, соответствующими этому адресному пространству.
Фьюзы BOOTPROT одновременно определяют размер раздела загрузчика и защищают выделенную область памяти от чтения.
EEPROM может быть записан несмотря на защиту соответствующей области памяти.
Что необходимо для организации загрузчика?
- Работа с памятью контроллера – за это отвечает контроллер энергонезависимой памяти (NVM);
- Работа с USB – за это отвечает USB-контроллер;
- Работа с файловой системой под силу FATFS.
- И по мелочи: работа с портами ввода-вывода, тактирование.
С.
Ф.
(Программная платформа Atmel)
Тонкости USB
Согласно стандарту USB, для реализации шины требуется очень точная синхронизация.Мы будем использовать внешний кристалл с частотой 32 кГц в качестве эталона для DFLL (цифровая автоподстройка частоты).
Выход DFLL будет использоваться для синхронизации модуля USB и всего контроллера.
Для работы USB-модуля нужно настроить DFLL так, чтобы на выходе было ровно 48 МГц.
Для стабильности и точности выходной частоты DFFL его необходимо настроить в режиме замкнутого контура.
Собираем проект воедино
Используя Мастер ASF Подключаем все необходимые нам модули, перечисленные выше.
USB-хост
Добавлять USB-хост-сервис в режиме запоминающее устройство .
После добавления драйвера в проект появляется несколько заголовочных и исполняемых файлов.
Нас интересуют 2 из них:
- conf_usb_host.h — настраивает USB и настраивает обработчики прерываний (Callback),
- conf_access.h – настраивает абстрактный слой для работы с памятью.
Для этого щелкните правой кнопкой мыши по проекту и выберите Свойства -> Набор инструментов -> Компилятор ARM/GNU C -> Символы .USB_MASS_STORAGE_ENABLE=true ACCESS_MEM_TO_RAM_ENABLED=true
Закомментируйте строку "#define Lun_usb_unload - NULL" В Определения USB LUN в файле conf_access.h для предотвращения ошибок компиляции.
Для мониторинга подключенных устройств по шине USB введен обработчик прерываний на основе событий (обратный вызов).
Начало кадра .
Это прерывание происходит только после отправки каждого SOF, а поскольку SOF отправляется раз в 1 мс, когда устройство подключено к шине, это событие можно использовать как таймер.
Записываем обработчик прерывания в файл conf_usb_host.h .
Для этого добавим прототип функции main_usb_sof_event() в начале файла conf_usb_host.h в конце концов #includes. void main_usb_sof_event(void);
Также добавляем в этот файл строку: # define UHC_SOF_EVENT() main_usb_sof_event()
Теперь вам нужно глобально определить переменную-счетчик в файле.
main.c , мы будем увеличивать его каждый раз, когда вызываем соответствующий обработчик: volatile static uint16_t main_usb_sof_counter = 0;
Добавьте фактический обработчик прерывания (обратный вызов): void main_usb_sof_event(void)
{
main_usb_sof_counter++;
}
Файловая система
Добавлять Служба файловой системы FAT FS (с помощью мастера ASF).Разверните модуль и выберите режим драйвера RTC. Calendar_polled .
Для полноценного функционирования модуля файловой системы добавьте в начале main.c : #include "string.h"
#define MAX_DRIVE _VOLUMES
#define FIRMWARE_FILE "firmware.bin"
const char firmware_filename[] = {FIRMWARE_FILE};
/* FATFS variables */
static FATFS fs;
static FILE file_object;
Имя файла (#define FIRMWARE_FILE «firmware.bin») должно совпадать с именем файла прошивки на подключенной флешке.
Работа с энергонезависимой памятью
Добавьте NVM-Энергонезависимую память (драйвер).
Кроме того, определяем необходимые константы и переменные в файле main.c: #define APP_START_ADDRESS (NVMCTRL_ROW_SIZE * 200)
uint8_t page_buffer[NVMCTRL_PAGE_SIZE];
Также необходимо настроить контроллер энергонезависимой памяти.
Для этого добавьте структуру конфигурации (глобально), прочтите настройки по умолчанию, измените необходимые и установите (отформатируйте в отдельной функции): struct nvm_config nvm_cfg;
void nvm_init(void)
{
Теги: #samd20 #Atmel #bootloader #usb #cortex #cortex-m0 #cortex-m0 #atmel Arm #Программирование микроконтроллера
-
Как Легко Проверить, Изменяет Ли Ваш Супруг
19 Oct, 24 -
Перекресток. Главы 11 И 12
19 Oct, 24 -
Налет, Что Это Такое И Откуда Он Берется?
19 Oct, 24