Как демонстрационный загрузчик USB-DFU STM32 проверяет, загружен ли код пользователя?
Демонстрационный загрузчик USB-DFU STM32 HAL имеет следующий код:
/* Test if user code is programmed starting from address 0x0800C000 */
if (((*(__IO uint32_t *) USBD_DFU_APP_DEFAULT_ADD) & 0x2FFC0000) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t *) (USBD_DFU_APP_DEFAULT_ADD + 4);
JumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t *) USBD_DFU_APP_DEFAULT_ADD);
JumpToApplication();
}
Как это предикат
((*(__IO uint32_t *) USBD_DFU_APP_DEFAULT_ADD) & 0x2FFC0000) == 0x20000000
определить, загружен ли код пользователя на MPU STM32H7A3?
Что это за волшебная маска 0x2FFC0000 ?
2 ответа
Это очень простой и очень плохой способ. Он просто проверяет, равно ли по адресу USBD_DFU_APP_DEFAULT_ADD (где должно быть начальное значение указателя стека) значение AND-et с маской какому-либо значению.
Я лично всегда добавляю CRC32 в конце приложения, чтобы проверить, есть ли приложение и действительно ли оно.
... определить, загружен ли код пользователя на MPU STM32H7A3?
Не имеет ничего общего с MPU
Этот пример кода распространяется с CubeMX
STM32Cube_FW_H7_V1.9.0
Пакет изначально проверяет, находится ли начальный адрес приложения (верх стека) в адресном пространстве ОЗУ - между 0x20000000 и 0x2003FFFF (256 КБ).
Для MPU STM32H7A3ZI (например, Nucleo-H7A3ZI-Q) это неверно, потому что «обычная» RAM (не DTCRAM) начинается с адреса 0x24000000 и имеет размер 1024 КБ. Я думаю, что правильная проверка для этого MPU должна быть:
if((stackAddr & 0x24F00000) == 0x24000000) ...