Добавить защищённое обновление приложения через RS и CAN с сохранением загрузчика, проверкой CRC, восстановлением передачи и защитой EEPROM. Подключить общий процесс сборки C2000 и автоматический счётчик версии для согласованных RAM, Flash, CAN и паспортов бинарных образов. Уточнить запуск ЦАП, обработку измерений и параметров нагрузки, начальную индикацию и документацию регистров GAS. Дополнить модели аппаратуры и изолировать заголовки CAN в тестах. Проверка: 26 тестов выпуска, 4 теста восстановления CAN и восемь программных моделей CAN, Flash, EEPROM, ЦАП, параметров и TESTLAMP.
125 lines
20 KiB
C++
125 lines
20 KiB
C++
/* Проверяет удержание TESTLAMP и выбор пакетов при уже включённых рабочих лампах. */
|
|
#include <stdio.h> /* Выводит конкретные нарушенные условия и итог сценария. */
|
|
#include <string.h> /* Обнуляет регистровое пространство перед началом проверки. */
|
|
#define ANSWER_LEN 128U /* Карта содержит 128 технологических регистров и дополнительное контрольное слово, как production message.h. */
|
|
#define interrupt /* Убирает аппаратный атрибут ISR при компиляции модели на ПК. */
|
|
typedef float FILTERBAT; /* Позволяет подключить production-заголовок с интерфейсами фильтров. */
|
|
#include "measure.h" /* Получает настоящие READY_FREQ, BLINK_TIME, CANPOWSE и maximum_bright. */
|
|
#include "package.h" /* Получает настоящие адреса TESTLAMP, яркости, ламп и типов плат. */
|
|
#include "DSP2833x_SWPrioritizedIsrLevels.h" /* Использует реальную вычисляемую маску приоритетов TI MINT13. */
|
|
typedef union { /* Моделирует слово Modbus размером хостового int, сохраняя номера битов production-псевдонимов. */
|
|
unsigned int all; /* Обеспечивает запись целого слова по тому же смещению массива. */
|
|
struct { /* Размещает шестнадцать технологических битов в младшей части слова. */
|
|
unsigned int bit0:1, bit1:1, bit2:1, bit3:1, bit4:1, bit5:1, bit6:1, bit7:1; /* Сохраняет позиции кнопок и команд 0..7. */
|
|
unsigned int bit8:1, bit9:1, bitA:1, bitB:1, bitC:1, bitD:1, bitE:1, bitF:1; /* Сохраняет позиции повторителей входов и старших команд 8..15. */
|
|
} bit; /* Предоставляет production-псевдонимам доступ к полям регистра. */
|
|
} WORDE; /* Завершает хостовое представление одного регистра Modbus. */
|
|
struct gpio_bits { /* Предоставляет входы всех ветвей настоящей get_Buttons, без моделирования электрических свойств. */
|
|
unsigned GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11; /* Представляет дискретные входы нескольких типов плат. */
|
|
unsigned GPIO20, GPIO21, GPIO22, GPIO23, GPIO24, GPIO25, GPIO26, GPIO27; /* Представляет перемычки и вход TESTLAMP GPIO26 пульта. */
|
|
unsigned GPIO48, GPIO49, GPIO50, GPIO51, GPIO52, GPIO53; /* Представляет входы банка B, читаемые get_Buttons. */
|
|
}; /* Завершает перечень моделируемых входов. */
|
|
struct gpio_reg { struct gpio_bits bit; }; /* Даёт регистрам GPADAT и GPBDAT production-форму обращения. */
|
|
static struct { struct gpio_reg GPADAT, GPBDAT; } GpioDataRegs; /* Хранит управляемые сценарием уровни входов. */
|
|
static struct { unsigned long all; } DigErr; /* Принимает диагностическую маску посторонней ветви SHKF. */
|
|
static struct { unsigned long InterruptCount; } CpuTimer1; /* Учитывает вызовы настоящего обработчика пульта. */
|
|
int modbus[129], Desk; /* Предоставляет технологические регистры и выбирает ветвь пульта. */
|
|
unsigned int INcount0; /* Сохраняет 16-битный тип накопителя кнопок из 167, соответствующий указателю er_anal. */
|
|
unsigned int CanPowse, CanGO; /* Хранит счётчик тактов выдачи CAN и признак готовности очередной передачи. */
|
|
unsigned long isMask, Lonely; /* Хранит тестовую маску и возраст последней связи. */
|
|
int isNumb, quaLamp = 6; /* Сохраняет тестовые цифры и число ламп из pulto.c. */
|
|
static unsigned int IER, mask_at_eint, entry_mask, failures, sends, nested_entries, timer_pending; /* Отслеживает разрешения прерываний, пакетные вызовы и возможность вложенного Timer1. */
|
|
static unsigned long lamp_word; /* Запоминает последний пакет шести сигнальных ламп канала 2. */
|
|
static long digit_word; /* Сохраняет последнее значение одного из двух семисегментных индикаторов в текущем такте. */
|
|
static int digit_dot, digit_sends; /* Запоминает режим форматирования цифр и наличие числового пакета в текущем такте. */
|
|
static long display_words[2]; /* Запоминает оба аппаратных канала отдельно, чтобы проверить начальные нули, свежие показания и тайм-аут связи. */
|
|
static int startup_irq_disabled; /* Отмечает запрет прерываний при выполнении настоящего начального участка main. */
|
|
#define DINT (startup_irq_disabled = 1) /* Моделирует ранний запрет IRQ до очистки карты и конфигурации Timer1. */
|
|
#define M_INT13 0x1000U /* Повторяет бит 12 INT13 из DSP2833x_Device.h для модели регистра IER. */
|
|
#define EALLOW ((void)0) /* Не моделирует защиту аппаратных регистров, поскольку она не влияет на рассматриваемые ветви. */
|
|
#define EDIS ((void)0) /* Завершает заглушку защищённой записи. */
|
|
#define EINT (mask_at_eint = IER) /* Снимает реально применённую маску в момент разрешения вложенных прерываний. */
|
|
#define ServiceDog() ((void)0) /* Исключает аппаратный сторожевой таймер из проверки индикации. */
|
|
#define toggle_ONLINE() ((void)0) /* Не моделирует электрический сигнал готовности ПЛИС. */
|
|
#define toggle_RES_OUT_1() ((void)0) /* Исключает резервный GPIO из логики выбора TESTLAMP. */
|
|
#define toggle_RES_OUT_2() ((void)0) /* Исключает второй резервный GPIO из пакетной проверки. */
|
|
void cpu_timer1_isr_PULT(void); /* Позволяет заглушке передачи смоделировать повторное аппаратное событие Timer1. */
|
|
static void kanal_Send(int adr, long dat, int dot) /* Записывает передаваемые данные, не подменяя проверяемый выбор режима. */
|
|
{ /* Начинает обработку одного production-вызова передачи. */
|
|
sends++; /* Позволяет обнаружить дополнительные вызовы передачи при повторном входе в ISR. */
|
|
if (timer_pending && (IER & M_INT13)) { /* Моделирует новый такт Timer1 во время незаконченной передачи, только когда собственное прерывание ошибочно разрешено. */
|
|
timer_pending = 0; /* Ограничивает искусственное событие одним вложенным вызовом. */
|
|
nested_entries++; /* Регистрирует перемешивание обработки двух тактов. */
|
|
cpu_timer1_isr_PULT(); /* Запускает настоящую production-функцию повторно при неверной маске. */
|
|
} /* Завершает моделирование потенциального повторного входа. */
|
|
if (adr == 2) lamp_word = (unsigned long)dat; /* Сохраняет именно канал сигнальных ламп, обновляемый в каждом такте. */
|
|
if (adr < 2) { /* Записывает также передачу цифр, чтобы обнаружить переход семисегментного индикатора в рабочий режим при провале кнопки. */
|
|
display_words[adr] = dat; /* Сохраняет фактическое число каждого индикатора без повторения production-логики выбора режима. */
|
|
digit_word = dat; /* Сохраняет переданное production-функцией числовое значение. */
|
|
digit_dot = dot; /* Различает тест четырёх одинаковых цифр и обычное форматирование измерений. */
|
|
digit_sends++; /* Отмечает присутствие числового пакета в текущем такте. */
|
|
} /* Завершает фиксацию передачи на семисегментный индикатор. */
|
|
} /* Завершает заглушку аппаратной передачи. */
|
|
static unsigned int F28335CanBoot_WatchdogAllowed(void) { return 1U; } /* Ламповый тест моделирует уже подтверждённое приложение; политика trial/CONFIRM проверяется отдельными CAN Boot тестами. */
|
|
/* HANDLERS */
|
|
static void check(int condition, const char *name) /* Накапливает ошибки, позволяя проверить все последствия одного дефекта. */
|
|
{ /* Начинает регистрацию одного требования. */
|
|
if (!condition) { /* Выводит только нарушенные условия. */
|
|
printf("FAIL %s\n", name); /* Даёт мутационному тесту устойчивое имя обнаруженного дефекта. */
|
|
failures++; /* Делает код завершения ненулевым при любой регрессии. */
|
|
} /* Завершает обработку ошибки. */
|
|
} /* Завершает проверку одного требования. */
|
|
static void tick(void) /* Моделирует сохранение и восстановление IER на границе аппаратного ISR. */
|
|
{ /* Начинает один такт индикации. */
|
|
IER = entry_mask; /* Возвращает исходные разрешения источников перед новым обработчиком. */
|
|
sends = 0; /* Отделяет вызовы передачи текущего такта от предыдущих. */
|
|
digit_sends = 0; /* Не принимает пакет предыдущего такта за обновление цифр в текущем. */
|
|
cpu_timer1_isr_PULT(); /* Выполняет настоящий алгоритм выбора режима, PWM и пакетов. */
|
|
check(mask_at_eint == (entry_mask & MINT13 & ~M_INT13), "interrupt mask"); /* Проверяет отсутствие собственного Timer1 и запрет включения ранее выключенных источников. */
|
|
check(sends >= 1 && sends <= 2, "packet count"); /* Требует штатный объём одного такта: пакет ламп и не более одного пакета очередного индикатора. */
|
|
} /* Завершает один такт индикации. */
|
|
int main(void) /* Проверяет двухсекундное удержание по Timer1 и защиту стробов DATA/CLOCK от повторного входа. */
|
|
{ /* Начинает независимые сценарии физической кнопки, удалённой команды и яркости. */
|
|
int i, pwm_on = 0; /* Считает такты удержания и включённые фазы десятишагового PWM. */
|
|
memset(modbus, 0xA5, sizeof(modbus)); startup_registers(); /* Заполняет все слова мусором, затем выполняет именно production-очистку из main до настройки периферии. */
|
|
for (i = 0; i <= ANSWER_LEN; i++) check(modbus[i] == 0, "startup register clear"); /* Проверяет оба числа, маски, команды и последнее слово, выявляя частичную очистку массива или ошибочный размер. */
|
|
check(startup_irq_disabled, "startup interrupts disabled"); /* Начальная очистка должна выполняться при запрещённых прерываниях. */
|
|
check(sizeof(WORDE) == sizeof(modbus[0]), "register layout"); /* Подтверждает совместимость битовых псевдонимов с массивом хостовой модели. */
|
|
Desk = dsk_EPLT; display_words[0] = 3950; display_words[1] = -2310; /* Начинает с произвольного состояния физических индикаторов, которое первые пакеты должны заменить нулями. */
|
|
entry_mask = M_INT13 | (1U << 0) | (1U << 13); /* Проверяет Timer1 вместе с ранее разрешёнными источниками разных приоритетов. */
|
|
for (i = 0; i < 3; i++) tick(); /* Три последовательных такта покрывают оба числовых канала и отдельный канал светодиодов. */
|
|
check(display_words[0] == 0 && display_words[1] == 0 && lamp_word == 0, "startup zero display"); /* Начальная индикация обнуляется сразу, без ожидания тайм-аута отсутствующей связи. */
|
|
modbus[2] = 1; Bright[0] = maximum_bright; /* Включает рабочую лампу перед существующими проверками местного и удалённого TESTLAMP. */
|
|
tick(); check(lamp_word == 1, "normal lamp before test"); /* Проверяет рабочую индикацию до начала удержания. */
|
|
GpioDataRegs.GPADAT.bit.GPIO26 = 1; /* Нажатие TESTLAMP представлено высоким уровнем входа платы. */
|
|
for (i = 0; i < 4000; i++) get_Buttons(); /* Частый main не должен ускорять выдержку, которую теперь считает только Timer1. */
|
|
check(!bTestLamp, "polling independent"); /* Доказывает независимость порога от числа опросов главного цикла. */
|
|
for (i = 0; i < 2 * READY_FREQ - 1; i++) { tick(); check(!bTestLamp, "short test"); } /* Даже 1999 тактов при 1000 Гц ещё не разрешают местный тест. */
|
|
tick(); check(bTestLamp, "test activation"); /* Двухтысячный такт включает тест точно после двух секунд удержания. */
|
|
for (i = 0; i < 600; i++) { /* Проверяет непрерывный тест дольше периода BLINK_TIME=500 без потери защиты стробов. */
|
|
timer_pending = 1; tick(); /* Имитирует новый такт во время передачи, когда прежний ISR ещё не завершился. */
|
|
check(bTestLamp && lamp_word == isMask, "held test"); /* Требует передачу тестовой фазы вместо исходной рабочей маски. */
|
|
check(!digit_sends || (digit_word == isNumb && digit_dot == 4), "test digit packet"); /* Проверяет тестовый формат числового индикатора. */
|
|
check(nested_entries == 0, "nested transmission"); timer_pending = 0; /* Единственный владелец DATA/CLOCK исключает перемешивание пакетов. */
|
|
} /* Завершает длительное удержание физической кнопки. */
|
|
GpioDataRegs.GPADAT.bit.GPIO26 = 0; tick(); /* Отпускание сбрасывает местный тест в следующем такте Timer1. */
|
|
check(!bTestLamp && lamp_word == 1, "release"); /* Возвращает заранее включённую рабочую лампу без дополнительной задержки. */
|
|
for (i = 0; i < 3; i++) { /* Отдельные короткие нажатия суммарно превышают две секунды, но не должны включать тест. */
|
|
int held; GpioDataRegs.GPADAT.bit.GPIO26 = 1; /* Начинает очередное независимое нажатие. */
|
|
for (held = 0; held < READY_FREQ; held++) tick(); /* Удерживает вход одну секунду, то есть меньше порога. */
|
|
check(!bTestLamp, "separate presses"); /* Не позволяет сложить длительности разных нажатий. */
|
|
GpioDataRegs.GPADAT.bit.GPIO26 = 0; tick(); /* Сбрасывает накопленную выдержку отпусканием. */
|
|
} /* Завершает сценарий повторных коротких нажатий. */
|
|
cTestLamp = 1; tick(); check(lamp_word == isMask, "remote test"); /* Команда Modbus сохраняет немедленный независимый запуск теста. */
|
|
cTestLamp = 0; Bright[0] = 6; /* Возвращает рабочий режим с яркостью шесть тактов из десяти. */
|
|
for (i = 0; i < 10; i++) { tick(); check(lamp_word <= 1, "normal PWM packet"); pwm_on += lamp_word == 1; } /* Измеряет полный период реального алгоритма яркости после теста. */
|
|
check(pwm_on == 6, "normal PWM duty"); /* Подтверждает сохранение настроенной скважности рабочего сигнала. */
|
|
Lonely = 0; modbus[0] = 1234; modbus[1] = -567; /* Имитирует получение новых чисел по связи после начальной нулевой индикации. */
|
|
for (i = 0; i < 3; i++) tick(); /* Даёт каждому числовому каналу один штатный пакет обновления. */
|
|
check(display_words[0] == 1234 && display_words[1] == -567, "fresh display values"); /* Исправление старта не скрывает реальные показания, полученные во время работы. */
|
|
for (i = 0; i < 20 * READY_FREQ + 3; i++) tick(); /* Пропускает существующие двадцать секунд без связи и полный цикл пакетов после порога. */
|
|
check(display_words[0] == 0 && display_words[1] == 0 && lamp_word == 0, "display timeout"); /* Подтверждает прежнее обнуление обоих индикаторов и ламп при потере обмена. */
|
|
printf("%s TESTLAMP: 2-second hold, main independent, single ISR, release, remote command, PWM\n", failures ? "FAIL" : "PASS"); /* Указывает проверенные программные свойства без заявления об аппаратном испытании. */
|
|
return failures ? 1 : 0; /* Любое нарушенное условие завершает процесс проверки с ошибкой. */
|
|
} /* Завершает проверку кнопки и защищённой передачи индикации. */
|