Сохранить состояние TESTLAMP при кратких провалах входа и исключить повторный вход Timer1 во время передачи индикации. Явно сбрасывать служебный обмен CAN при запуске и выбирать соседнюю фазу по локальному индексу канала АЦП. Сохранить текущую последовательность DATA/CLK и проверочные варианты таймингов, добавить поведенческие тесты и обновить образ прошивки с картой памяти.
123 lines
18 KiB
C++
123 lines
18 KiB
C++
/* Проверяет удержание TESTLAMP и выбор пакетов при уже включённых рабочих лампах. */
|
||
#include <stdio.h> /* Выводит конкретные нарушенные условия и итог сценария. */
|
||
#include <string.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, CanPowse, CanGO; /* Хранит production-накопитель кнопки и таймер выдачи 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; /* Запоминает режим форматирования цифр и наличие числового пакета в текущем такте. */
|
||
#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) { /* Записывает также передачу цифр, чтобы обнаружить переход семисегментного индикатора в рабочий режим при провале кнопки. */
|
||
digit_word = dat; /* Сохраняет переданное production-функцией числовое значение. */
|
||
digit_dot = dot; /* Различает тест четырёх одинаковых цифр и обычное форматирование измерений. */
|
||
digit_sends++; /* Отмечает присутствие числового пакета в текущем такте. */
|
||
} /* Завершает фиксацию передачи на семисегментный индикатор. */
|
||
} /* Завершает заглушку аппаратной передачи. */
|
||
/* 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) /* Запускает на настоящих функциях сценарий рабочих ламп, теста с помехами и возврата в работу. */
|
||
{ /* Начинает общий поведенческий сценарий. */
|
||
int i, pwm_on = 0; /* Перебирает опросы и такты; считает включённые такты рабочего PWM за один полный период. */
|
||
memset(modbus, 0, sizeof(modbus)); /* Убирает старые команды и состояния перед сценарием. */
|
||
check(sizeof(WORDE) == sizeof(modbus[0]), "register layout"); /* Подтверждает корректность production-псевдонимов в хостовой модели. */
|
||
Desk = dsk_EPLT; /* Выбирает реальную ветвь чтения TESTLAMP пульта. */
|
||
modbus[2] = 1; /* Включает рабочую лампу до нажатия TESTLAMP, как в сообщении пользователя. */
|
||
Bright[0] = maximum_bright; /* Задаёт уже включённой лампе постоянную яркость для обнаружения случайных провалов. */
|
||
entry_mask = M_INT13 | (1U << 0) | (1U << 13); /* Разрешает Timer1, группу ADC и Timer2, проверяя также маскирование равного приоритета. */
|
||
tick(); /* Получает первый рабочий пакет ламп. */
|
||
check(lamp_word == 1, "normal lamp before test"); /* Подтверждает исходное постоянное свечение до нажатия. */
|
||
GpioDataRegs.GPADAT.bit.GPIO26 = 1; /* Нажимает физическую кнопку активным высоким уровнем. */
|
||
for (i = 0; i < 1001; i++) get_Buttons(); /* Проходит реальные 1000 накопительных опросов и следующий опрос фиксации порога. */
|
||
check(bTestLamp == 1, "test activation"); /* Требует включения теста после полной выдержки. */
|
||
for (i = 0; i < 600; i++) { /* Проверяет удержание более BLINK_TIME=500 тактов без подавления штатного медленного мигания. */
|
||
unsigned long expected_mask; /* Сохраняет фазу теста перед очередным возмущением кнопки. */
|
||
GpioDataRegs.GPADAT.bit.GPIO26 = 0; /* Вводит короткий провал входа на один опрос главного цикла. */
|
||
get_Buttons(); /* Выполняет настоящий накопительный фильтр и публикацию кнопки. */
|
||
check(bTestLamp == 1, "held test"); /* Проверяет сохранение TESTLAMP вместо мгновенного возврата рабочих масок. */
|
||
timer_pending = 1; /* Допускает новый аппаратный такт во время передачи для проверки запрета повторного входа. */
|
||
tick(); /* Формирует тестовый пакет при кратком провале физического входа. */
|
||
expected_mask = isMask; /* Получает ожидаемую медленную фазу из настоящей what_is. */
|
||
check(lamp_word == expected_mask, "test packet during input glitch"); /* Исключает рабочую маску уже горящих ламп из тестового потока. */
|
||
check(!digit_sends || (digit_word == isNumb && digit_dot == 4), "test digit packet during input glitch"); /* Требует сохранения тестового значения и формата цифр во время помехи кнопки. */
|
||
check(nested_entries == 0, "nested transmission"); /* Требует единственного владельца DATA/CLK на протяжении передачи. */
|
||
timer_pending = 0; /* Убирает смоделированное событие после завершения текущего такта. */
|
||
GpioDataRegs.GPADAT.bit.GPIO26 = 1; /* Возвращает уровень удерживаемой кнопки. */
|
||
get_Buttons(); /* Восстанавливает насыщенный накопитель без смены тестового режима. */
|
||
} /* Завершает серию коротких помех при удержании. */
|
||
check(isNumb == 1111 && isMask == 0xFFFFFFFFUL, "slow test sequence"); /* После 600 миллисекунд требует единственного штатного шага what_is с периодом 500 тактов, а не ускоренного строба. */
|
||
GpioDataRegs.GPADAT.bit.GPIO26 = 0; /* Отпускает физическую кнопку на длительное время. */
|
||
for (i = 0; i < 1001; i++) get_Buttons(); /* Даёт накопителю полностью разрядиться и зафиксировать отпускание. */
|
||
check(bTestLamp == 0, "test release"); /* Проверяет, что сохранение состояния не залипает в TESTLAMP. */
|
||
tick(); /* Возвращает передачу рабочей маски после отпускания. */
|
||
check(lamp_word == 1, "normal lamp after test"); /* Восстанавливает уже включённую до теста лампу. */
|
||
cTestLamp = 1; /* Включает независимую удалённую команду теста через production-регистр. */
|
||
tick(); /* Проверяет приоритет удалённого TESTLAMP при отпущенной физической кнопке. */
|
||
check(lamp_word == isMask, "remote test"); /* Требует тестовую маску для обоих источников команды. */
|
||
cTestLamp = 0; /* Завершает удалённый тест перед проверкой рабочего PWM. */
|
||
Bright[0] = 6; /* Устанавливает шесть включённых тактов из десяти в production-периоде яркости. */
|
||
for (i = 0; i < 10; i++) { /* Проверяет один полный период PWM после выхода из теста. */
|
||
tick(); /* Даёт настоящей функции вычислить текущую фазу яркости. */
|
||
check(lamp_word == 0 || lamp_word == 1, "normal PWM packet"); /* Исключает оставшиеся тестовые биты из рабочей маски. */
|
||
pwm_on += lamp_word == 1; /* Измеряет реальное число включённых тактов production-PWM. */
|
||
} /* Завершает период обычной яркости. */
|
||
check(pwm_on == 6, "normal PWM duty"); /* Подтверждает сохранение заданной яркости 6/10 после выхода из теста. */
|
||
printf("%s TESTLAMP: held input glitches, single ISR, normal lamps, release, remote command\n", failures ? "FAIL" : "PASS"); /* Выводит проверенные свойства без заявления о физическом испытании платы. */
|
||
return failures ? 1 : 0; /* Возвращает результат всех поведенческих требований. */
|
||
} /* Завершает хостовую проверку. */
|