Часть 11: Создаем свой загрузчик (Bootloader) для Arduino

Каждый раз, когда вы нажимаете «Загрузить» в Arduino IDE, на плату записывается новый скетч поверх старого. Этим занимается загрузчик (bootloader) — программа, которая живет в отдельной области Flash-памяти (первые 512 байт или 2 КБ).

Хак: Напишем свой загрузчик, который:

  • Загружает прошивку через Bluetooth или по радиоканалу (без USB).
  • Проверяет цифровую подпись перед записью.
  • Хранит две версии прошивки (резервная, если новая не загрузилась).

Пример кода загрузчика (на AVR C):

#include <avr/io.h>
#include <avr/boot.h>
#include <avr/interrupt.h>
#include <util/delay.h>

// Адрес начала пользовательской прошивки (0x0000 для загрузчика)
#define APP_START 0x3800  // 14 КБ (для ATmega328P)

// Флаг обновления (хранится в EEPROM)
#define UPDATE_FLAG_ADDR 0x00

// Функция записи страницы во Flash
void write_page(uint32_t page_addr, uint8_t *buffer) {
    uint16_t i;
    uint8_t sreg = SREG;
    cli();  // Отключаем прерывания
    
    boot_page_erase(page_addr);
    boot_spm_busy_wait();
    
    for (i = 0; i < SPM_PAGESIZE; i += 2) {
        uint16_t word = *((uint16_t*)(buffer + i));
        boot_page_fill(page_addr + i, word);
    }
    
    boot_page_write(page_addr);
    boot_spm_busy_wait();
    boot_rww_enable();  // Разрешаем выполнение кода из RWW-секции
    
    SREG = sreg;  // Восстанавливаем прерывания
}

int main(void) {
    // 1. Проверяем, есть ли команда на обновление (например, с UART)
    if (EEPROM_read(UPDATE_FLAG_ADDR) == 0xAA) {
        // Принимаем прошивку по UART
        uint8_t buffer[SPM_PAGESIZE];
        uint32_t addr = APP_START;
        
        // Ждем данные от компьютера/Bluetooth
        while (1) {
            // Получаем байты, заполняем буфер, записываем страницу
            // ...
        }
        
        // Стираем флаг обновления
        EEPROM_write(UPDATE_FLAG_ADDR, 0x00);
    }
    
    // 2. Переходим к основной прошивке
    void (*app_start)(void) = (void (*)(void))APP_START;
    app_start();
    
    while (1);
}

Как залить загрузчик: Используйте программатор AVR-ISP (например, USBasp) и команду:

avrdude -c usbasp -p m328p -U flash:w:bootloader.hex -U lock:w:0x0F:m

Результат: Вы можете обновлять Arduino через Bluetooth-модуль (HC-05) без подключения к компьютеру. Идеально для устройств, которые уже установлены в труднодоступных местах!

Вам также может понравиться

About the Author: ардуинчиков

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *