#define F28335_CAN_FLASH_UPDATE 1 /* Включает настоящий выбор памяти и Flash callbacks аппаратного CAN-порта в host-модели. */ #include "transfer_model.c" /* Использует существующие реальные ядро, EEPROM-журнал, CAN mailbox и экспорт кадров клиента. */ #include "f28335_flash_app.c" /* Проверяет фактически записанный FAB1 тем же кодом, что постоянный загрузчик. */ static uint16_t flash_memory[0x40000]; /* Моделирует все 256 Кслов внутренней Flash F28335, включая защищённый сектор A. */ static unsigned int flash_fault, flash_erases, flash_programs; /* Вводит аппаратные отказы erase, данных и завершающего FAB1. */ static bool erase_model(void *user) /* Моделирует только аппаратную операцию TI Flash_Erase. */ { /* Постоянный boot обязан пережить любой результат обновления. */ uint32_t i; (void)user; ++flash_erases; /* Фиксирует первый фактический erase, отделяя его от подготовки staging EEPROM. */ for (i = 0UL; i < 0x38000UL; ++i) flash_memory[i] = 0xFFFFU; /* Маска FE стирает B–H до адреса 0x338000 и не касается A. */ return flash_fault != 1U; /* Отказ erase оставляет приложение недействительным и boot доступным. */ } /* Эта подмена не меняет алгоритм проверки и порядка программирования. */ static bool program_model(void *user, uint32_t address, uint16_t *data, unsigned int words) /* Моделирует физическую запись и readback одной порции. */ { /* Отдельно контролирует адреса каждого production-вызова. */ unsigned int i, count = words; (void)user; ++flash_programs; /* Подсчитывает операции, включая попытку публикации FAB1. */ if (address < F28335_FLASH_APP_START || address >= F28335_FLASH_APP_STOP || words > F28335_FLASH_APP_STOP - address) return false; /* Даже ошибочный writer не обращается за пределы модели. */ if (flash_fault == 2U || (flash_fault == 3U && address == F28335_FLASH_APP_START)) count /= 2U; /* Обрыв питания оставляет половину данных либо половину FAB1. */ for (i = 0U; i < count; ++i) flash_memory[address - F28335_FLASH_APP_START + i] = data[i]; /* Сохраняет частичный физический результат до сообщения об ошибке. */ return count == words; /* Неполная запись не должна подтверждать COMMIT. */ } /* Успешная порция полностью совпадает с переданным RAM-буфером. */ static uint16_t read_model(void *user, uint32_t address) /* Даёт production-валидатору фактические слова модели Flash. */ { /* CPU-адреса преобразуются в индексы только внутри host-аппаратуры. */ (void)user; assert(address >= F28335_FLASH_APP_START && address < F28335_FLASH_APP_STOP); /* Проверяет границы каждого итогового чтения FAB1/CRC. */ return flash_memory[address - F28335_FLASH_APP_START]; /* Возвращает записанное значение, а не ожидаемое слово staging. */ } /* CRC физической памяти считается production-кодом. */ bool F28335Boot_FlashProgram(f28335_flash_update_t *s) /* Подменяет только обвязку официального TI API, сохраняя настоящий Flash writer. */ { /* Вся структурная проверка, повторная CRC и порядок FAB1 остаются неизменёнными. */ f28335_flash_ops_t ops = { erase_model, program_model, read_model, 0 }; /* Передаёт операции модели через публичный аппаратный контракт. */ return f28335_flash_update_program(s, &ops); /* Ошибка модели проходит через обычный статус CAN COMMIT. */ } /* Python управляет лишь входными кадрами и аппаратными отказами. */ __declspec(dllexport) void model_flash_reset(unsigned int fault) /* Начинает независимый сценарий без физических интерфейсов. */ { /* Заполняет boot контрольным значением перед проверкой его сохранности. */ uint32_t i; model_reset(); flash_fault = fault; flash_erases = flash_programs = 0U; /* Сбрасывает CAN/EEPROM штатной моделью и выбирает точку отказа. */ for (i = 0UL; i < 0x40000UL; ++i) flash_memory[i] = 0x5A5AU; /* Контрольное заполнение выявляет стирание любого слова сектора A. */ } /* Последующее обновление должно изменить только область приложения. */ __declspec(dllexport) unsigned int model_flash_valid(void) /* Проверяет возможность запуска после успеха либо смоделированного обрыва. */ { /* Использует единый валидатор постоянного boot. */ uint32_t entry; return f28335_flash_app_validate(read_model, 0, &entry); /* Частично записанный файл не должен получить разрешение запуска. */ } /* Никакая модельная переменная успеха не заменяет реальную CRC. */ __declspec(dllexport) unsigned int model_flash_intact(void) /* Подтверждает сохранность boot и защищённой области EEPROM. */ { /* Проверяет каждый адрес сектора A после любой попытки обновления. */ uint32_t i; for (i = 0x38000UL; i < 0x40000UL; ++i) if (flash_memory[i] != 0x5A5AU) return 0U; /* Весь сектор A, включая аппаратный вход и CSM, остаётся исходным. */ return model_parameters_intact(); /* Дополнительно проверяет резерв и все параметры M95M02. */ } /* Сохранность загрузчика проверяется независимо от результата COMMIT. */ __declspec(dllexport) unsigned int model_flash_erase_count(void) { return flash_erases; } /* Позволяет доказать отсутствие erase при ошибке CRC, адреса или назначения. */ __declspec(dllexport) void model_flash_corrupt(void) { memory[(flash_staging ? F28335_AB_SLOT_B : F28335_AB_SLOT_A) + 30UL] ^= 1U; } /* Повреждает EEPROM между VERIFY и COMMIT для проверки повторной CRC до erase. */ __declspec(dllexport) unsigned int model_flash_check(const pcan_boot_byte_t *data, unsigned int length) /* Проверяет недоверенные SCI8 непосредственно MCU-валидатором, минуя локальный отказ клиента. */ { /* Разрушительные callbacks Flash в этой проверке вообще не вызываются. */ unsigned int i; pcan_boot_manifest_t manifest; f28335_boot_io_t io = { F28335Boot_Read, F28335Boot_Write, 0 }; /* Источник остаётся настоящим интерфейсом staging EEPROM. */ if (length > F28335_AB_SLOT_BYTES) return 0U; /* Не позволяет самой модели выйти за физическую ёмкость слота. */ for (i = 0U; i < length; ++i) memory[F28335_AB_SLOT_A + i] = (unsigned char)data[i]; /* Подменяет только ранее принятые байты физической EEPROM. */ memset(&manifest, 0, sizeof(manifest)); manifest.image_size = length; manifest.image_crc32 = pcan_boot_crc32_update(0UL, data, length); /* Транспортная CRC намеренно правильная даже для структурно запрещённой таблицы. */ return f28335_flash_update_validate(&flash_update, &io, F28335_AB_SLOT_A, &manifest); /* Отказ должен возникать на адресах, структуре или FAB1, а не на CRC CAN. */ } /* Такой повреждённый файл не получает разрешение erase даже от произвольного внешнего клиента. */