Обеспечь единый процесс обновления для STM32F103/F407/G474 и TMS320F2812/F28335: discovery, служебные ответы, BUSY, тайм-аут сессии и подтверждение приложения. Добавь самостоятельные проекты CCS, аппаратные хранилища и Python-клиент. Совместимость: структуры конфигурации и порта расширены, поэтому потребители должны пересобраться и обнулить новые поля. Для C28x callbacks используют pcan_boot_byte_t; периодический pcan_boot_poll обслуживает discovery и настроенный тайм-аут.
27 lines
5.0 KiB
C
27 lines
5.0 KiB
C
#include "f28335_flash_app.h" /* Использует ту же границу сектора A и формат описания, что сборщик и RS-программатор. */
|
||
bool f28335_flash_app_validate(f28335_flash_read_word_t read_word, void *user, uint32_t *entry) /* Не обращается к EEPROM и подходит для постоянного загрузчика и проверки staging RAM. */
|
||
{ /* Никакие адреса из непроверенного заголовка не используются для чтения до проверки границ. */
|
||
uint16_t header[F28335_FLASH_APP_HEADER_WORDS], word, octet, bit, i; /* Малый локальный буфер хранит 16 слов описания FAB1. */
|
||
uint32_t address, start, end, expected, crc = 0xFFFFFFFFUL, target, inverse; /* CRC32 IEEE начинается со всех единиц и инвертируется после последнего октета. */
|
||
if (!read_word || !entry) return false; /* Отсутствующий источник или выходной указатель не должен вызывать обращение к памяти. */
|
||
for (i = 0; i < F28335_FLASH_APP_HEADER_WORDS; ++i) header[i] = read_word(user, F28335_FLASH_APP_START + i); /* Читает только фиксированное описание в секторе H. */
|
||
if (header[0] != 0x4146U || header[1] != 0x3142U || header[2] != 1U || header[3] != F28335_FLASH_APP_HEADER_WORDS || header[14] != 0x5AA5U || header[15] != 0xA55AU) return false; /* Физические октеты ASCII FAB1, версия 1, размер и два маркера отличают завершённый образ от стёртого либо старого Flash. */
|
||
target = (uint32_t)header[4] | ((uint32_t)header[5] << 16); /* Точка входа хранится младшим 16-битным словом вперёд внутри описания. */
|
||
start = (uint32_t)header[6] | ((uint32_t)header[7] << 16); /* Нижняя граница защищённого CRC диапазона должна начинаться сразу после описания. */
|
||
end = (uint32_t)header[8] | ((uint32_t)header[9] << 16); /* Верхняя граница является исключённым адресом слова, а не длиной в байтах. */
|
||
expected = (uint32_t)header[10] | ((uint32_t)header[11] << 16); /* Сохранённая CRC32 рассчитана по физическим октетам всех слов диапазона. */
|
||
inverse = (uint32_t)header[12] | ((uint32_t)header[13] << 16); /* Инверсия адреса выявляет частичную публикацию управляющих полей. */
|
||
if (start != F28335_FLASH_APP_DATA || end <= start || end > F28335_FLASH_APP_STOP || target < start || target >= end || inverse != ~target) return false; /* Запрещает RAM, сектор загрузчика, пустой код и случайные адреса из повреждённого описания. */
|
||
for (address = start; address < end; ++address) { /* Проверяет также стёртые промежутки между LOAD-секциями, чтобы JTAG и RS давали одинаковое содержимое. */
|
||
word = read_word(user, address); /* Получает одно 16-битное слово из Flash либо из модели staging SCI8. */
|
||
for (i = 0; i < 2U; ++i) { /* Каждый адрес C28x содержит два физических октета: сначала младший, затем старший. */
|
||
octet = (word >> (8U * i)) & 255U; /* Маска отделяет октет независимо от 16-битного char TI. */
|
||
crc ^= octet; /* Добавляет очередной октет в отражённое состояние CRC32 IEEE. */
|
||
for (bit = 0; bit < 8U; ++bit) crc = (crc & 1UL) ? ((crc >> 1) ^ 0xEDB88320UL) : (crc >> 1); /* 0xEDB88320 — отражённый полином IEEE 802.3, совпадающий с zlib.crc32. */
|
||
} /* Завершает обработку обоих октетов текущего слова. */
|
||
} /* Завершает чтение только внутри области приложения ниже сектора A. */
|
||
if ((crc ^ 0xFFFFFFFFUL) != expected) return false; /* Повреждённое или частично записанное приложение остаётся недоступным для запуска. */
|
||
*entry = target; /* Публикует точку старта только после подтверждения всех адресов и данных. */
|
||
return true; /* Разрешает загрузчику запустить именно проверенную Flash-программу. */
|
||
} /* Ошибка никогда не меняет EEPROM, Flash или сохранённый выходной адрес. */
|