Добавить защищённое обновление приложения через RS и CAN с сохранением загрузчика, проверкой CRC, восстановлением передачи и защитой EEPROM. Подключить общий процесс сборки C2000 и автоматический счётчик версии для согласованных RAM, Flash, CAN и паспортов бинарных образов. Уточнить запуск ЦАП, обработку измерений и параметров нагрузки, начальную индикацию и документацию регистров GAS. Дополнить модели аппаратуры и изолировать заголовки CAN в тестах. Проверка: 26 тестов выпуска, 4 теста восстановления CAN и восемь программных моделей CAN, Flash, EEPROM, ЦАП, параметров и TESTLAMP.
70 lines
14 KiB
C
70 lines
14 KiB
C
/* Проверяет реальные Default_params/Load_params и защиту живого слова команд от сохранённого START в EEPROM. */
|
|
#include <assert.h> /* Делает нарушение сохранности команд, атомарности или состояния IRQ ошибкой теста. */
|
|
#include <stdio.h> /* Печатает результат самостоятельной регрессии загрузки параметров. */
|
|
#include <string.h> /* Копирует модель EEPROM и обнуляет регистры между независимыми сценариями. */
|
|
#define interrupt /* Убирает аппаратный атрибут ISR при подключении настоящих типов и констант датчиков на ПК. */
|
|
#include "../../Source/Internal/Include/filter_bat2.h" /* Предоставляет настоящий тип FILTERBAT, необходимый объявлениям measure.h. */
|
|
#include "../../Source/Internal/Include/measure.h" /* Подключает настоящие ERROR, частоты и объявления глобальных измерительных данных. */
|
|
typedef union { int all; struct { unsigned int reserved:4, bit4:1; } bit; } WORDE; /* Сохраняет адресацию слова R127 и бита калибровки4 в модели GCC. */
|
|
#include "../../Source/Internal/Include/package.h" /* Использует настоящие адреса R127, калибровок, тайм-аута и лимита пусков профиля167. */
|
|
#include "../../Source/Internal/Include/caliber.h" /* Даёт Default_params реальные заводские таблицы167 для всех режимов платы. */
|
|
#define ANSWER_LEN 128U /* Повторяет длину технологической карты без аппаратных зависимостей message.h. */
|
|
#define BALSAM167_EEPROM_PARAMS_START_WORD 0x3F7EU /* Адрес не влияет на управление: модель проверяет чтение полного блока параметров без запрета IRQ. */
|
|
int modbus[129], READY, Desk, Mode, Kalibro, Owen, Kurrent, TermoSW; /* Предоставляет рабочим функциям регистры и признаки режима платы. */
|
|
unsigned int param[129], Caliber_time; /* Предоставляет считанный EEPROM-блок и таймер калибровки из рабочего интерфейса. */
|
|
int sens_type[24]; /* Позволяет заводской инициализации обращаться к таблице типов SHKF без изменения рабочего алгоритма. */
|
|
static unsigned int irq_mask, saved_count, concurrent_command; /* Хранит исходную маску IRQ, число записей EEPROM и команду, принятую во время чтения. */
|
|
static unsigned int image[129]; /* Моделирует отдельную сохранённую EEPROM, чтобы загрузка не читала текущие команды обратно из RAM. */
|
|
static unsigned int __disable_interrupts(void) { unsigned int old = irq_mask; irq_mask = 1; return old; } /* Проверяет вложенное сохранение маски при применении RAM-настроек. */
|
|
static void __restore_interrupts(unsigned int old) { irq_mask = old; } /* Возвращает переданную вызывающим кодом маску, включая заранее запрещённые IRQ. */
|
|
static void Seeprom_read(unsigned long address, unsigned int *data, unsigned int bytes) /* Моделирует только длительное чтение EEPROM, не подменяя Default/Load. */
|
|
{ /* Начинает передачу проверенного набора параметров в рабочий буфер param. */
|
|
assert(!irq_mask && address == BALSAM167_EEPROM_PARAMS_START_WORD && bytes == 258U); /* EEPROM-драйвер нуждается в прерываниях; 129 слов занимают258 байт C28x. */
|
|
memcpy(data, image, sizeof(image)); /* Считывает в том числе сохранённый START, чтобы проверить его исключение из применения параметров. */
|
|
if (concurrent_command) Commands = concurrent_command; /* Имитирует принятие нового START/RESET по CAN во время длительного чтения EEPROM. */
|
|
} /* Заканчивает чтение при исходно разрешённых прерываниях. */
|
|
static unsigned int get_crc16(const unsigned int *data, unsigned int words) { assert(data == param && words == ANSWER_LEN); return 0x1234U; } /* Выбирает валидную ветку по контрольному слову image без повторения алгоритма загрузки. */
|
|
void Save_params(void) { assert(!irq_mask); saved_count++; } /* Проверяет, что восстановление заводских настроек не удерживает IRQ во время записи EEPROM. */
|
|
void Init_sensors_more(void) { assert(!irq_mask); } /* Проверяет освобождение короткой RAM-секции перед расчётом измерительных коэффициентов. */
|
|
#include "production_parameters.inc" /* Подключает неизменённые reset_parameter_commands, Default_params и Load_params из текущего рабочего message.c. */
|
|
static void setup(unsigned int live, unsigned int stored, unsigned int crc) /* Готовит независимую плату нагрузки и EEPROM с намеренно отличающимся словом команд. */
|
|
{ /* Сбрасывает модель, сохраняя реальное расположение регистров профиля167. */
|
|
memset(modbus, 0, sizeof(modbus)); memset(image, 0, sizeof(image)); /* Удаляет состояние предыдущего сценария только в тестовой модели. */
|
|
READY = 1; Desk = dsk_LOAD; Mode = adr_LOA1; Kalibro = Kurrent = 1; Owen = TermoSW = 0; /* Выбирает готовую плату нагрузки с заводской калибровкой167. */
|
|
Commands = live; image[127] = stored; image[126] = Mode; image[ANSWER_LEN] = crc; /* Разделяет текущую команду интерфейса и потенциально опасный сохранённый START. */
|
|
image[0x52] = 2000; image[0x7D] = 7; irq_mask = saved_count = concurrent_command = 0; /* Задаёт допустимые новые защиты и независимые счётчики модели. */
|
|
} /* Завершает подготовку до вызова настоящего рабочего кода. */
|
|
int main(void) /* Проверяет режимы RUN/STOP/RESET/FAULT через сохранение уровней, на которых работает неизменённый автомат DAC167. */
|
|
{ /* Начинает все комбинации текущих и сохранённых команд. */
|
|
unsigned int live, stored; /* Перебирает четыре сочетания START/RESET независимо от содержимого EEPROM. */
|
|
for (live = 0; live <= 0xC0U; live += 0x40U) { /* Проверяет ожидание, RESET, START и совместное удержание двух управляющих битов. */
|
|
for (stored = 0; stored <= 0xC0U; stored += 0x40U) { /* Не допускает ни отмены текущего START, ни появления START из EEPROM. */
|
|
setup(live | 0x0305U, stored, 0x1234U); Load_params(); /* Загружает корректный блок с дополнительными одноразовыми служебными командами. */
|
|
assert((unsigned int)Commands == live && LOAD_MAX_ATTEMPTS == 7 && LOAD_CAN_TIMEOUT == 2000 && !irq_mask && !saved_count); /* Сохраняет только живые START/RESET и действительно применяет новые настройки защиты. */
|
|
setup(live | 0x0305U, stored, 0); Load_params(); /* Проверяет ту же гарантию при неверной CRC и автоматическом восстановлении заводских параметров. */
|
|
assert((unsigned int)Commands == live && saved_count == 1 && LOAD_MAX_ATTEMPTS == 5 && LOAD_CAN_TIMEOUT == 2000 && !irq_mask); /* Сохранение исправленного блока EEPROM не очищает управляющие уровни нагрузки. */
|
|
} /* Завершает все варианты сохранённых команд для текущего живого уровня. */
|
|
setup(live | 0x0305U, 0, 0x1234U); Default_params(); /* Проверяет прямую команду Default без предварительного чтения EEPROM. */
|
|
assert((unsigned int)Commands == live && !irq_mask && LOAD_MAX_ATTEMPTS == 5); /* Заводской сброс сохраняет RUN/STOP-семантику, удаляя одноразовые служебные флаги. */
|
|
} /* Завершает проверку всех четырёх живых сочетаний START/RESET. */
|
|
setup(0, 0x80U, 0x1234U); concurrent_command = 0xC0U; Load_params(); /* Передаёт новый RESET/START во время чтения вместо снимка, снятого до EEPROM. */
|
|
assert(Commands == 0xC0U && !irq_mask); /* Не теряет последнюю принятую по интерфейсу команду при завершении Load. */
|
|
setup(0xC0U, 0x80U, 0x1234U); READY = 0; Load_params(); /* На холодном старте имитирует и мусор RAM, и сохранённый START EEPROM. */
|
|
assert(!Commands && !irq_mask); /* До READY ни один источник сохранённого состояния не разрешает автоматический пуск. */
|
|
setup(0xC0U, 0, 0x1234U); READY = 0; Default_params(); /* Проверяет ту же стартовую очистку в заводской ветке без EEPROM. */
|
|
assert(!Commands && !irq_mask); /* Начальные START/RESET обязательно очищены до разрешения рабочего такта платы. */
|
|
setup(0xC0U, 0x80U, 0x1234U); Desk = dsk_COMM; Kalibro = Kurrent = 0; Load_params(); /* У остальных плат сохраняет прежнее поведение очистки всех команд после загрузки. */
|
|
assert(!Commands && !irq_mask); /* Не переносит специальную семантику УМП на несвязанные типы плат. */
|
|
setup(0x2C0U, 0, 0x1234U); irq_mask = 1; reset_parameter_commands(); /* Проверяет вызов helper из уже защищённого блока применения параметров. */
|
|
assert(Commands == 0xC0U && irq_mask == 1); /* Вложенный helper сохраняет внешнюю маску IRQ и не выдаёт EINT без разрешения вызывающего кода. */
|
|
setup(0, 0, 0x1234U); Desk = dsk_EPLT; READY = 0; image[0] = 3950; image[1] = (unsigned int)-2310; image[2] = 0x3FU; image[3] = 0xFFFFU; image[0x62] = 6; /* Воспроизводит сохранённые 395.0 и -231, маски ламп и допустимую яркость при холодном старте задатчика. */
|
|
Load_params(); /* Применяет настоящий EEPROM-загрузчик до первого рабочего обмена с задатчиком. */
|
|
assert(!modbus[0] && !modbus[1] && !modbus[2] && !modbus[3] && Bright[0] == 6 && !irq_mask); /* Показания и лампы остаются нулевыми, но сохраняемая яркость действительно загружается из EEPROM. */
|
|
modbus[0] = 1234; modbus[1] = -567; modbus[2] = 1; modbus[3] = 2; READY = 1; Load_params(); /* Имитирует повторную загрузку настроек после получения новых показаний и масок по связи. */
|
|
assert(modbus[0] == 1234 && modbus[1] == -567 && modbus[2] == 1 && modbus[3] == 2 && Bright[0] == 6); /* Сохранённый снимок не перезаписывает актуальную индикацию работающего задатчика. */
|
|
setup(0, 0, 0x1234U); image[0] = 3950; image[1] = 2310; Load_params(); /* Проверяет прежнюю загрузку R0/R1 у платы нагрузки, где карта имеет другой смысл. */
|
|
assert(modbus[0] == 3950 && modbus[1] == 2310); /* Ограничивает исключение четырёх регистров только типом dsk_EPLT. */
|
|
puts("PASS: production parameters preserve live START/RESET and reject stored setpoint display values"); /* Подтверждает защиту команд нагрузки и текущей индикации задатчика на настоящем Load_params. */
|
|
return 0; /* Возвращает успех только после всех сценариев сохранности команд и состояния IRQ. */
|
|
} /* Завершает регрессию без обращения к аппаратной плате. */
|