На свое удивление, получил работающую связку booter + приложение, скомпилированное для работы со смещением по адресу. Всё рабтает. Причем главное приложение работает под управлением операционки и весь код защищен контрольной суммой CRC32, которая тоже сходится. Сейчас получилось так: booter загружается при старте, проверяет EEPROM. Берет оттуда адрес и загружается с него, смещая при этом таблицу векторов прерывания. Функция для перехода в приложение выглядит проще чем я думал.
void go_to_app(uint32_t addr) { void (*app)(void); // create an Reset_Handler of app uint32_t *p = (uint32_t *)addr; // get a pointer to app __disable_irq(); SCB->VTOR = addr; // set offset the vector table __set_MSP(*p++); // set main stack pointer to app Reset_Handler app = (void (*)(void))(*p); // app now is entry point app(); // jump in }
Теперь предстоит следующее: расширить функционал основного приложения, что бы оно могло принять новую прошивку, проверить её, положить в нужный адрес во флеш-память, заменить значение смещения в EEPROM и перезагрузиться. Пока думаю так: прошивку передавать частями, по страницам, прикрывая их контрольной суммой, для надежности. Всю прошивку шифровать на ключе и подписывать. Таким образом можно будет передать зашифрованную прошивку кому угодно и обновлять устройство совершенно безопасно.