/* Проверяет удержание TESTLAMP и выбор пакетов при уже включённых рабочих лампах. */ #include /* Выводит конкретные нарушенные условия и итог сценария. */ #include /* Обнуляет регистровое пространство перед началом проверки. */ #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; /* Возвращает результат всех поведенческих требований. */ } /* Завершает хостовую проверку. */