/* Проверка load_control на модели ПК. Русские пояснения сохранены в UTF-8. */ /* Подключает : настройки и интерфейс stdio. */ #include /* Подключает : настройки и интерфейс string. */ #include /* Подключает "../../Source/Internal/DAC.c": выход ЦАП и автомат защиты нагрузки с проверкой напряжения и свежести CAN. */ #include "../../Source/Internal/DAC.c" /* Объявляет READY — данные READY; Desk — аппаратно определённый тип платы; Mode — рабочий адрес или режим платы, выбранный перемычками. Начальное значение задаётся справа от знака равенства. */ int READY = 1, Desk = 6, Mode = 5; /* Объявляет modbus — массив технологических регистров; слово int на C28x занимает 16 бит. */ int modbus[128]; /* Объявляет test_start — данные test_start; test_stop — данные test_stop; test_permission — данные test_permission; test_tick — данные test_tick. */ unsigned int test_start, test_stop, test_permission, test_tick; /* Объявляет test_starts — данные test_starts; test_last_stop_tick — данные test_last_stop_tick; test_last_start_tick — данные test_last_start_tick; test_init_dac — test init ЦАП. */ unsigned int test_starts, test_last_stop_tick, test_last_start_tick, test_init_dac; /* Объявляет test_bad_order — данные test_bad_order. */ int test_bad_order; /* Объявляет ump_dac_ramp — ump ЦАП ramp; ump_dac_duration — ump ЦАП duration; ump_dac_go10 — ump ЦАП go 10; ump_dac_stop10 — ump ЦАП stop 10; ump_dac_position — ump ЦАП position. */ unsigned int ump_dac_ramp, ump_dac_duration, ump_dac_go10, ump_dac_stop10, ump_dac_position; /* Задаёт CHECK = do { if (!(x)) { printf("FAIL line %d: %s\n", __LINE__, #x); return 1; } } while (0); данные CHECK. */ #define CHECK(x) do { if (!(x)) { printf("FAIL line %d: %s\n", __LINE__, #x); return 1; } } while (0) /* Начинает функцию setup; назначение модуля — проверка load_control на модели ПК. */ static void setup(int mode) { /* Записывает Mode значением mode; READY = 1; рабочий адрес или режим платы, выбранный перемычками. */ memset(modbus, 0, sizeof(modbus)); Mode = mode; READY = 1; /* Записывает test_start значением test_stop = test_permission = test_tick = test_starts = 0; данные test_start. */ test_start = test_stop = test_permission = test_tick = test_starts = 0; /* Записывает test_bad_order значением test_init_dac = 0; данные test_bad_order. */ test_bad_order = test_init_dac = 0; /* Записывает WAKEpowse значением 0; данные WAKEpowse. */ Load_control_init(); Setup_DAC_time(); WAKEpowse = 0; /* Записывает DAC_go значением 4; DAC_stop = 16; DAC_min() = 100; DAC_max() = 3000; начальный ток нагрузки в мА, технологический регистр 0x50. */ DAC_go = 4; DAC_stop = 16; DAC_min() = 100; DAC_max() = 3000; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Начинает функцию tick; назначение модуля — проверка load_control на модели ПК. */ static void tick(unsigned int n, int exchange, unsigned int volts) { /* Повторяет или ожидает, пока выполняется while (n--). */ while (n--) { /* Проверяет if (exchange) Load_voltage_can(0x8000U | (Mode == 5 ? 305U : 8U), volts, 0, 0); последующий оператор выполняется только при истинном условии. */ if (exchange) Load_voltage_can(0x8000U | (Mode == 5 ? 305U : 8U), volts, 0, 0); /* Изменяет счётчик в выражении test_tick++; Load_runner(); на один для следующего шага. */ test_tick++; Load_runner(); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Точка входа: настраивает периферию, загружает параметры и обслуживает команды в главном цикле. */ int main(void) { /* Объявляет out — данные out; error — ошибка; count — число; ramp — данные ramp; code — данные code. */ unsigned int out[8], error, count, ramp, code, stopped_at; /* Вызывает setup с аргументами (5) в текущей последовательности операций. */ setup(5); /* Boot ISR before parameters: no divide-by-zero and no GPIO start. */ /* Записывает Commands значением 0x80; tick(10, 1, 0); CHECK(!test_starts); слово команд, технологический регистр 127. */ Load_control_init(); Commands = 0x80; tick(10, 1, 0); CHECK(!test_starts); /* Записывает WAKEpowse значением 0; данные WAKEpowse. */ Setup_DAC_time(); WAKEpowse = 0; /* Вызывает tick с аргументами (10, 0, 0); CHECK(test_starts == 1 && test_permission) в текущей последовательности операций. */ tick(10, 0, 0); CHECK(test_starts == 1 && test_permission); /* Вызывает CHECK с аргументами (LOAD_CAN_TIMEOUT == 600) в текущей последовательности операций. */ CHECK(LOAD_CAN_TIMEOUT == 600); /* Wrong ZPT and masked slots never confirm freshness. */ /* Записывает Commands значением 0x80; слово команд, технологический регистр 127. */ setup(5); Commands = 0x80; /* Вызывает Load_voltage_can. Принимает напряжение выбранной нагрузки из достоверных слов CAN и сбрасывает возраст только нужного измерения. */ Load_voltage_can(0x8000U | 8U, 200, 0, 0); /* Вызывает Load_voltage_can. Принимает напряжение выбранной нагрузки из достоверных слов CAN и сбрасывает возраст только нужного измерения. */ Load_voltage_can(305U, 200, 0, 0); tick(10, 0, 0); /* Вызывает CHECK с аргументами (!test_starts && (LOAD_STATUS & 2)) в текущей последовательности операций. */ CHECK(!test_starts && (LOAD_STATUS & 2)); /* Вызывает Load_voltage_can. Принимает напряжение выбранной нагрузки из достоверных слов CAN и сбрасывает возраст только нужного измерения. */ Load_voltage_can(0x2000U | 303U, 0, 0, 30); /* Вызывает tick с аргументами (1, 0, 0); CHECK(test_starts == 1) в текущей последовательности операций. */ tick(1, 0, 0); CHECK(test_starts == 1); /* Freeze current and code at timeout; unrelated exchange cannot unfreeze. */ /* Вызывает tick с аргументами (1000, 1, 30); tick(600, 0, 0) в текущей последовательности операций. */ tick(1000, 1, 30); tick(600, 0, 0); /* Записывает ramp значением ump_dac_ramp; code = modbus[123]; данные ramp. */ ramp = ump_dac_ramp; code = modbus[123]; /* Вызывает tick с аргументами (2000, 0, 0); CHECK(ump_dac_ramp == ramp && (unsigned int)modbus[123] == code) в текущей последовательности операций. */ tick(2000, 0, 0); CHECK(ump_dac_ramp == ramp && (unsigned int)modbus[123] == code); /* Вызывает CHECK с аргументами (test_permission && !test_stop && (LOAD_STATUS & 2)) в текущей последовательности операций. */ CHECK(test_permission && !test_stop && (LOAD_STATUS & 2)); /* Вызывает Load_voltage_can. Принимает напряжение выбранной нагрузки из достоверных слов CAN и сбрасывает возраст только нужного измерения. */ Load_voltage_can(0x8000U | 8U, 200, 0, 0); tick(10, 0, 0); /* Вызывает CHECK с аргументами (ump_dac_ramp == ramp) в текущей последовательности операций. */ CHECK(ump_dac_ramp == ramp); /* Вызывает tick с аргументами (10, 1, 30); CHECK(ump_dac_ramp > ramp) в текущей последовательности операций. */ tick(10, 1, 30); CHECK(ump_dac_ramp > ramp); /* Exactly 30 V permits growth; 29 V fails strictly above 6 mA. */ /* Записывает Commands значением 0x80; tick(10, 1, 30); слово команд, технологический регистр 127. */ setup(6); Commands = 0x80; tick(10, 1, 30); /* Записывает load_count_ramp значением time_dac / 6; tick(5, 1, 30); load число ramp. */ load_count_ramp = time_dac / 6; tick(5, 1, 30); /* Вызывает CHECK с аргументами (load_state == LOAD_RUN && modbus[0x1C] >= 60) в текущей последовательности операций. */ CHECK(load_state == LOAD_RUN && modbus[0x1C] >= 60); /* Вызывает tick с аргументами (5, 1, 29); CHECK(load_state == LOAD_RELOAD && test_stop && !test_permission) в текущей последовательности операций. */ tick(5, 1, 29); CHECK(load_state == LOAD_RELOAD && test_stop && !test_permission); /* Вызывает CHECK с аргументами (!test_start && ump_dac_ramp == 0 && modbus[0x1C] == 40) в текущей последовательности операций. */ CHECK(!test_start && ump_dac_ramp == 0 && modbus[0x1C] == 40); /* Записывает stopped_at значением test_last_stop_tick; данные stopped_at. */ CHECK(modbus[123] == DAC_min()); stopped_at = test_last_stop_tick; /* Вызывает tick с аргументами (999, 1, 0); CHECK(test_starts == 1 && test_stop) в текущей последовательности операций. */ tick(999, 1, 0); CHECK(test_starts == 1 && test_stop); /* Вызывает tick с аргументами (1, 1, 0); CHECK(test_starts == 2 && test_last_start_tick-stopped_at == 1000) в текущей последовательности операций. */ tick(1, 1, 0); CHECK(test_starts == 2 && test_last_start_tick-stopped_at == 1000); /* Вызывает CHECK с аргументами (!test_stop && test_permission && !test_bad_order) в текущей последовательности операций. */ CHECK(!test_stop && test_permission && !test_bad_order); /* Five total attempts, then a persistent fault; no sixth start. */ /* Повторяет или ожидает, пока выполняется while (load_state != LOAD_FAULT). */ while (load_state != LOAD_FAULT) { /* Записывает load_count_ramp значением time_dac / 6; tick(5, 1, 0); load число ramp. */ load_count_ramp = time_dac / 6; tick(5, 1, 0); /* Проверяет if (load_state == LOAD_RELOAD) tick(1000, 1, 0); последующий оператор выполняется только при истинном условии. */ if (load_state == LOAD_RELOAD) tick(1000, 1, 0); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Вызывает CHECK с аргументами (test_starts == 5 && LOAD_ATTEMPTS == 5 && (LOAD_STATUS & 1)) в текущей последовательности операций. */ CHECK(test_starts == 5 && LOAD_ATTEMPTS == 5 && (LOAD_STATUS & 1)); /* Вызывает tick с аргументами (3000, 1, 200); CHECK(test_starts == 5 && test_stop && !test_permission) в текущей последовательности операций. */ tick(3000, 1, 200); CHECK(test_starts == 5 && test_stop && !test_permission); /* Записывает Commands значением 0xC0; tick(10, 1, 200); CHECK(load_state == LOAD_FAULT); слово команд, технологический регистр 127. */ Commands = 0xC0; tick(10, 1, 200); CHECK(load_state == LOAD_FAULT); /* Записывает Commands значением 0; tick(1000, 1, 200); CHECK(!(LOAD_STATUS & 1)); слово команд, технологический регистр 127. */ Commands = 0; tick(1000, 1, 200); CHECK(!(LOAD_STATUS & 1)); /* Записывает Commands значением 0x80; test_starts = 0; tick(10, 1, 200); CHECK(LOAD_ATTEMPTS == 1); слово команд, технологический регистр 127. */ Commands = 0x80; test_starts = 0; tick(10, 1, 200); CHECK(LOAD_ATTEMPTS == 1); /* Manual reset dominates START; releasing it alone cannot start again. */ /* Записывает Commands значением 0xC0; tick(1, 1, 200); CHECK(test_stop && !test_permission); слово команд, технологический регистр 127. */ Commands = 0xC0; tick(1, 1, 200); CHECK(test_stop && !test_permission); /* Записывает Commands значением 0x80; tick(1500, 1, 200); CHECK(test_starts == 1); слово команд, технологический регистр 127. */ Commands = 0x80; tick(1500, 1, 200); CHECK(test_starts == 1); /* Versioned simulation writes are bounded, read-only fields reject writes. */ /* Записывает count значением Load_protection_prepare(3, 0x1300, 8, out, &error); число. */ count = Load_protection_prepare(3, 0x1300, 8, out, &error); /* Вызывает CHECK с аргументами (count == 8 && !error && out[0] == 0x5550 && out[1] == 1) в текущей последовательности операций. */ CHECK(count == 8 && !error && out[0] == 0x5550 && out[1] == 1); /* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */ Load_protection_prepare(6, 0x1303, 0, out, &error); CHECK(error == 3); /* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */ Load_protection_prepare(6, 0x1304, 0, out, &error); CHECK(error == 2); /* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */ Load_protection_prepare(6, 0x1302, 4, out, &error); CHECK(error == 3); /* Записывает Commands значением 0x80; tick(10, 1, 200); слово команд, технологический регистр 127. */ setup(5); Commands = 0x80; tick(10, 1, 200); /* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */ Load_protection_prepare(6, 0x1303, 20, out, &error); CHECK(!error); /* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */ Load_protection_prepare(6, 0x1302, 1, out, &error); CHECK(!error); /* Вызывает tick с аргументами (30, 1, 200); CHECK(LOAD_STATUS & 2) в текущей последовательности операций. */ tick(30, 1, 200); CHECK(LOAD_STATUS & 2); /* Записывает ramp значением ump_dac_ramp; tick(100, 1, 200); CHECK(ump_dac_ramp == ramp); данные ramp. */ ramp = ump_dac_ramp; tick(100, 1, 200); CHECK(ump_dac_ramp == ramp); /* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */ Load_protection_prepare(6, 0x1302, 0, out, &error); /* Вызывает tick с аргументами (10, 1, 200); CHECK(!(LOAD_STATUS & 2) && ump_dac_ramp > ramp) в текущей последовательности операций. */ tick(10, 1, 200); CHECK(!(LOAD_STATUS & 2) && ump_dac_ramp > ramp); /* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */ Load_protection_prepare(6, 0x1302, 2, out, &error); /* Записывает load_count_ramp значением time_dac / 6; tick(5, 1, 200); CHECK(load_state == LOAD_RELOAD); load число ramp. */ load_count_ramp = time_dac / 6; tick(5, 1, 200); CHECK(load_state == LOAD_RELOAD); /* Calibration must not replace the forced 4 mA output during reload. */ /* Устанавливает биты Commands значением 0x200; DAC_cal() = 4095; tick(5, 1, 200); слово команд, технологический регистр 127. */ Commands |= 0x200; DAC_cal() = 4095; tick(5, 1, 200); /* Вызывает CHECK с аргументами (modbus[123] == DAC_min() && modbus[0x1C] == 40) в текущей последовательности операций. */ CHECK(modbus[123] == DAC_min() && modbus[0x1C] == 40); /* A calibration code preceding START must be replaced by 4 mA first. */ /* Записывает Commands значением 0x200; DAC_cal() = 4095; слово команд, технологический регистр 127. */ setup(5); Commands = 0x200; DAC_cal() = 4095; /* Вызывает tick с аргументами (10, 1, 200); CHECK(modbus[123] == 4095 && !load_zero_sent) в текущей последовательности операций. */ tick(10, 1, 200); CHECK(modbus[123] == 4095 && !load_zero_sent); /* Записывает Commands значением 0x280; tick(1, 1, 200); CHECK(!test_starts); слово команд, технологический регистр 127. */ Commands = 0x280; tick(1, 1, 200); CHECK(!test_starts); /* Вызывает tick с аргументами (4, 1, 200); CHECK(!test_starts && modbus[123] == DAC_min()) в текущей последовательности операций. */ tick(4, 1, 200); CHECK(!test_starts && modbus[123] == DAC_min()); /* Вызывает tick с аргументами (1, 1, 200); CHECK(test_starts == 1) в текущей последовательности операций. */ tick(1, 1, 200); CHECK(test_starts == 1); /* Timeout while STOP is held cannot initiate the pending retry. */ /* Записывает Commands значением 0x80; tick(10, 1, 0); слово команд, технологический регистр 127. */ setup(5); Commands = 0x80; tick(10, 1, 0); /* Записывает load_count_ramp значением time_dac / 6; tick(5, 1, 0); load число ramp. */ load_count_ramp = time_dac / 6; tick(5, 1, 0); /* Вызывает CHECK с аргументами (load_state == LOAD_RELOAD) в текущей последовательности операций. */ CHECK(load_state == LOAD_RELOAD); /* Вызывает tick с аргументами (1500, 0, 0); CHECK(test_starts == 1 && test_stop) в текущей последовательности операций. */ tick(1500, 0, 0); CHECK(test_starts == 1 && test_stop); /* Вызывает tick с аргументами (1, 1, 0); CHECK(test_starts == 2 && !test_stop) в текущей последовательности операций. */ tick(1, 1, 0); CHECK(test_starts == 2 && !test_stop); /* Вызывает Load_control_init. Сбрасывает все переменные автомата нагрузки до разрешения прерываний; COFF не обнуляет всю .ebss. */ Load_control_init(); CHECK(!load_simulation); /* Вызывает puts с аргументами ("PASS: production DAC control, timeout, CAN slots, STOP ordering, five attempts, simulation") в текущей последовательности операций. */ puts("PASS: production DAC control, timeout, CAN slots, STOP ordering, five attempts, simulation"); /* Завершает main и возвращает 0. */ return 0; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ }