Добавить неизменяемое окно firmware-info v1 0x1200 из 12 слов для FC03 и служебного CAN, запретить запись. Сохранить текущую технологическую карту и логгер v4 с записью 12 слов. Подключить общий генератор версии 1.0.0 для Balsam-166-PM35, prebuild CCS и локальный выпуск BIN с manifest и SHA-256. Проверять соответствие встроенных слов манифесту до публикации; старый OUT без паспорта отклонять. Проверка: реальные обработчики RS/CAN и CRC под GCC O3, прежний тест логгера, анализатор установленного SetGUI, полная сборка TI C2000 22.6.0.LTS. BIN 30248 байт при границе параметров 32508 байт. Аппаратная проверка требует установки нового образа и перезапуска платы.
57 lines
10 KiB
C
57 lines
10 KiB
C
#include <stdint.h> /* Задаёт независимые от host ABI размеры слов паспорта. */
|
|
#include <stdio.h> /* Сообщает точную строку нарушенной регрессии. */
|
|
#include <string.h> /* Сбрасывает только модель RS-запроса между сценариями. */
|
|
#include "crc16.h" /* Использует настоящую CRC прошивки вместо имитации проверки ответа. */
|
|
#include "firmware_info.h" /* Подключает действительный адаптер границ 0x1200..0x120B. */
|
|
#include "../src/firmware_info_static.c" /* Проверяет тот же общий упаковщик, который компилируется в message.c. */
|
|
#define CHECK(value) do { if (!(value)) { printf("FAIL line %d: %s\n", __LINE__, #value); return 1; } } while (0) /* Сохраняет проверки при оптимизации O3. */
|
|
#define CMD_MODBUS_3 3U /* Код чтения holding-регистров остаётся прежним. */
|
|
#define CMD_MODBUS_6 6U /* Код одиночной записи используется для проверки защиты паспорта. */
|
|
#define CNTRL_ADDR 1U /* Тестирует конкретный корректный адрес узла без изменения производственной адресации. */
|
|
#define ANSWER_LEN 128 /* Повторяет размер прежней технологической карты. */
|
|
#define true 1 /* Повторяет 16-битное представление флага готовности ответа C28x. */
|
|
#define LOBYTE(value) ((value) & 255U) /* Сохраняет порядок младшего октета CRC в RS-ответе. */
|
|
#define HIBYTE(value) (((value) >> 8) & 255U) /* Сохраняет старший октет контрольной суммы Modbus. */
|
|
typedef struct { unsigned int RS_Header[400], buffer[400], flag_TIMEOUT_to_Send; } RS_DATA; /* Даёт настоящим обработчикам только используемые поля UART-окружения. */
|
|
static unsigned int sent, irq_mask, irq_calls, reads, writes, command, command_events; /* Наблюдает длину кадра, защиту IRQ и возможное повреждение старого backend. */
|
|
static int modbus[ANSWER_LEN + 1]; /* Проверяет чтение технологических регистров прежним маршрутом. */
|
|
static struct { unsigned int all; } Modbus[ANSWER_LEN + 1]; /* Поддерживает прежний интерфейс записи в таблицу параметров. */
|
|
static unsigned int __disable_interrupts(void) { unsigned int previous = irq_mask; irq_mask = 1U; ++irq_calls; return previous; } /* Выявляет лишнюю блокировку IRQ при чтении неизменяемого паспорта. */
|
|
static void __restore_interrupts(unsigned int previous) { irq_mask = previous; } /* Проверяет сохранение исходной маски для снимков логгера. */
|
|
static void RS_Send(RS_DATA *rs, unsigned int *data, unsigned long length) { (void)rs; (void)data; sent = (unsigned int)length; } /* Перехватывает готовый кадр без реального UART. */
|
|
unsigned int ump_log_read(unsigned int address) { ++reads; return address == 0x1000U ? 0x554DU : address; } /* Делает обращения к старому логгеру видимыми и узнаваемыми. */
|
|
int ump_log_write(unsigned int address, unsigned int value) { (void)address; (void)value; ++writes; return 1; } /* Любая ошибочная запись паспорта в backend станет видна тесту. */
|
|
static void UMP_commands_write(unsigned int value) { command = value; } /* Сохраняет наблюдение штатной команды регистра 127. */
|
|
static void ump_log_rs(void) { ++command_events; } /* Проверяет сохранение прежней регистрации команды RS. */
|
|
#include "ump_can_protocol.h" /* Тестирует реальный адаптер CAN 166, сохранивший двенадцатисловный логгер v4. */
|
|
/* PRODUCTION_MODBUS */
|
|
static void request(RS_DATA *rs, unsigned int address, unsigned int count) /* Формирует уже проверенный транспортом заголовок для настоящих обработчиков. */
|
|
{ /* Здесь не подменяется алгоритм чтения или упаковки ответа. */
|
|
memset(rs, 0, sizeof(*rs)); sent = 0; /* Не переносит данные предыдущего ответа в новый запрос. */
|
|
rs->RS_Header[2] = address >> 8; rs->RS_Header[3] = address & 255U; /* Упаковывает исходный адрес старшим октетом вперёд. */
|
|
rs->RS_Header[4] = count >> 8; rs->RS_Header[5] = count & 255U; /* Упаковывает число слов либо значение одиночной записи. */
|
|
} /* Приём полного CRC-запроса остаётся вне этой локальной проверки обработчиков. */
|
|
int main(void) /* Проверяет перенос паспорта и сохранность старых границ протокола. */
|
|
{ /* Эталон задан независимо от макроса общего C-инициализатора. */
|
|
const unsigned int expected[12] = {1, 1, 0, 0, 2026, 0x0A10, 0x0834, 22, 0x3132, 0x3334, 0x6162, 0x6364}; /* Формат v1, версия 1.0.0, UTC 2026-10-16 08:52:22, Build ID 1234abcd. */
|
|
RS_DATA rs; unsigned int words[UMP_CAN_MAX_WORDS], error, i, before; /* Использует те же ёмкости ответа, что действующий служебный CAN. */
|
|
request(&rs, 0x1200U, 12U); ReceiveCommandModbus3(&rs); CHECK(sent == 29U && rs.buffer[1] == 3U && rs.buffer[2] == 24U); /* Полный паспорт отвечает стандартным FC03 без хвостовых нулей. */
|
|
for (i = 0; i < 12U; ++i) CHECK(((rs.buffer[3 + i * 2] << 8) | rs.buffer[4 + i * 2]) == expected[i]); /* Проверяет все поля, порядок символов и октетов независимо от производственной упаковки. */
|
|
CHECK(get_crc_16(0xFFFFU, rs.buffer, sent) == 0U && reads == 0U && irq_calls == 0U); /* Паспорт защищён настоящей CRC и не обращается к логгеру или маске IRQ. */
|
|
request(&rs, 0x120BU, 1U); ReceiveCommandModbus3(&rs); CHECK(sent == 7U && rs.buffer[3] == 0x63U && rs.buffer[4] == 0x64U); /* Последнее слово поддерживает частичное чтение в пределах контракта 167. */
|
|
request(&rs, 0x120BU, 2U); ReceiveCommandModbus3(&rs); CHECK(sent == 5U && rs.buffer[1] == 0x83U && rs.buffer[2] == 2U); /* Пересечение верхней границы не раскрывает соседнюю память. */
|
|
request(&rs, 0x11FFU, 2U); ReceiveCommandModbus3(&rs); CHECK(rs.buffer[2] == 2U); /* Запрос из несуществующего регистра перед паспортом не считается допустимым. */
|
|
request(&rs, 0x1200U, 0U); ReceiveCommandModbus3(&rs); CHECK(rs.buffer[2] == 2U); /* Пустое чтение не принимает произвольный контекст за паспорт. */
|
|
request(&rs, 0xFFFFU, 12U); ReceiveCommandModbus3(&rs); CHECK(rs.buffer[2] == 2U); /* Проверка диапазона выдерживает переполнение 16-битного адреса. */
|
|
request(&rs, 0x1200U, 99U); ReceiveCommandModbus6(&rs); CHECK(sent == 5U && rs.buffer[1] == 0x86U && rs.buffer[2] == 2U && writes == 0U); /* Запись паспорта явно отвергается, не попадая в сохранённые параметры или логгер. */
|
|
CHECK(ump_can_prepare(3U, 0x1200U, 12U, words, &error) == 12U && error == 0U); /* Служебный CAN читает тот же паспорт без переноса остального драйвера 167. */
|
|
for (i = 0; i < 12U; ++i) CHECK(words[i] == expected[i]); /* Исключает расхождение паспорта между RS и CAN. */
|
|
ump_can_prepare(3U, 0x120BU, 2U, words, &error); CHECK(error == 2U); ump_can_prepare(6U, 0x1200U, 0U, words, &error); CHECK(error == 2U && writes == 0U); /* CAN также запрещает выход за паспорт и запись в него. */
|
|
modbus[5] = 0x1234; request(&rs, 5U, 1U); ReceiveCommandModbus3(&rs); CHECK(sent == 10U && rs.buffer[3] == 0x12U && rs.buffer[4] == 0x34U); /* Исторический ответ технологического регистра и его хвост сохранены. */
|
|
request(&rs, 0x1000U, 16U); ReceiveCommandModbus3(&rs); CHECK(sent == 37U && rs.buffer[3] == 0x55U && rs.buffer[4] == 0x4DU && reads == 16U && irq_calls == 1U && irq_mask == 0U); /* Снимок статуса логгера сохраняет прежний маршрут и защиту IRQ. */
|
|
before = reads; CHECK(ump_can_prepare(3U, UMP_LOG_DATA, 12U, words, &error) == 12U && error == 0U && reads == before + 12U && UMP_LOG_WORDS == 12U); /* Текущая запись v4 остаётся двенадцатисловной и не заменяется реализацией 167. */
|
|
request(&rs, 127U, 0x55U); ReceiveCommandModbus6(&rs); CHECK(command == 0x55U && command_events == 1U && sent == 10U); /* Штатная команда управления проходит прежний обработчик без изменения её смысла. */
|
|
puts("PASS: firmware-info RS/CAN, all 12 words, CRC, bounds, read-only, legacy registers and logger v4"); /* Подтверждает проверенный перенос без заявления об испытании аппаратной платы. */
|
|
return 0; /* Завершает все поведенческие сценарии реального кода обработчиков. */
|
|
} /* Остальные аппаратные алгоритмы не участвуют в тесте и не изменяются доработкой. */
|