/* Проверка gas167 на модели ПК. Русские пояснения сохранены в UTF-8. */ /* Подключает : настройки и интерфейс assert. */ #include /* Подключает : настройки и интерфейс stdbool. */ #include /* Подключает : настройки и интерфейс stdint. */ #include /* Подключает : настройки и интерфейс stdio. */ #include /* Подключает : настройки и интерфейс string. */ #include /* Подключает "gas167.h": дополнительная карта GAS 167/v1 только для новой EEPROM M95M02. */ #include "gas167.h" /* Подключает "ump_protocol.h": настройки и интерфейс ump_protocol. */ #include "ump_protocol.h" /* Подключает "ump_tms28335.h": настройки и интерфейс ump_tms28335. */ #include "ump_tms28335.h" /* Подключает "include/balsam167_eeprom_block.h": настройки и интерфейс balsam167_eeprom_block. */ #include "include/balsam167_eeprom_block.h" /* Задаёт ANSWER_LEN = 128U; данные ANSWER_LEN. */ #define ANSWER_LEN 128U /* Задаёт MAX_SEND_LENGTH = 400U; MAX SEND длина. */ #define MAX_SEND_LENGTH 400U /* Задаёт CNTRL_ADDR = 16U; данные CNTRL_ADDR. */ #define CNTRL_ADDR 16U /* Задаёт CMD_MODBUS_3 = 3U; данные CMD_MODBUS_3. */ #define CMD_MODBUS_3 3U /* Задаёт CMD_MODBUS_6 = 6U; данные CMD_MODBUS_6. */ #define CMD_MODBUS_6 6U /* Задаёт dsk_LOAD = 6; код платы нагрузки. */ #define dsk_LOAD 6 /* Задаёт LOBYTE = ((v) & 255U); данные LOBYTE. */ #define LOBYTE(v) ((v) & 255U) /* Задаёт HIBYTE = (((v) >> 8) & 255U); данные HIBYTE. */ #define HIBYTE(v) (((v) >> 8) & 255U) /* Задаёт UMP_CAN_MAX_WORDS = UMP_MAX_WORDS; UMP CAN MAX слова. */ #define UMP_CAN_MAX_WORDS UMP_MAX_WORDS /* Задаёт ump_can_prepare = ump_tms28335_prepare; ump CAN prepare. */ #define ump_can_prepare ump_tms28335_prepare /* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */ typedef struct { int all; } WORDE; /* Задаёт Modbus = ((WORDE *)modbus); данные Modbus. */ #define Modbus ((WORDE *)modbus) /* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */ typedef struct { /* Объявляет RS_Header — данные RS_Header; buffer — буфер. */ uint16_t RS_Header[8], buffer[MAX_SEND_LENGTH]; /* Продолжает список аргументов, полей или выражение unsigned flag_TIMEOUT_to_Send;; порядок элементов сохраняется. */ unsigned flag_TIMEOUT_to_Send; /* Продолжает список аргументов, полей или выражение } RS_DATA;; порядок элементов сохраняется. */ } RS_DATA; /* Объявляет modbus — массив технологических регистров; слово int на C28x занимает 16 бит; Desk — аппаратно определённый тип платы; dsk_LOAD — код платы нагрузки. Начальное значение задаётся справа от знака равенства. */ int modbus[129], Desk = dsk_LOAD; /* Продолжает список аргументов, полей или выражение static unsigned captures, spi_reads, sent, irq_depth, legacy_reads;; порядок элементов сохраняется. */ static unsigned captures, spi_reads, sent, irq_depth, legacy_reads; /* Начинает функцию __disable_interrupts; назначение модуля — проверка gas167 на модели ПК. */ static unsigned __disable_interrupts(void) { /* Записывает saved значением irq_depth; данные saved. */ unsigned saved = irq_depth; /* Изменяет счётчик в выражении ++irq_depth; на один для следующего шага. */ ++irq_depth; /* Завершает __disable_interrupts и возвращает saved. */ return saved; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Начинает функцию __restore_interrupts; назначение модуля — проверка gas167 на модели ПК. */ static void __restore_interrupts(unsigned saved) { irq_depth = saved; } /* Регистрирует изменение слова команд после записи по последовательному интерфейсу. */ void ump_log_rs(void) { ++captures; } /* Проверяет область чтения регистратора и возвращает слова состояния либо архивной записи. */ unsigned int ump_log_read(unsigned int address) { ++legacy_reads; return address; } /* Применяет допустимые команды управления регистратором, сохраняя ограничения адресов. */ int ump_log_write(unsigned int address, unsigned int value) { return 1; } /* Начинает функцию get_crc_16; назначение модуля — проверка gas167 на модели ПК. */ static unsigned get_crc_16(unsigned seed, const uint16_t *data, unsigned size) { /* Вызывает assert с аргументами (seed == 0xFFFFU) в текущей последовательности операций. */ assert(seed == 0xFFFFU); /* Завершает get_crc_16 и возвращает ump_crc(data, size). */ return ump_crc(data, size); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Передаёт массив слов через SCI в выбранном режиме упаковки. */ static void RS_Send(RS_DATA *rs, uint16_t *data, unsigned size) { /* Вызывает assert с аргументами (irq_depth == 0) в текущей последовательности операций. */ assert(irq_depth == 0); /* Записывает sent значением size; данные sent. */ sent = size; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Читает EEPROM порциями; адрес задаётся словами C28x, размер переводится в число передаваемых слов. */ static void Seeprom_read(unsigned long word, uint16_t *data, unsigned bytes) { /* Продолжает список аргументов, полей или выражение unsigned i;; порядок элементов сохраняется. */ unsigned i; assert(irq_depth == 0); /* The Timer2 SPI driver must retain interrupts. */ /* Вызывает assert с аргументами (irq_depth == 0) в текущей последовательности операций. */ /* Изменяет счётчик в выражении ++spi_reads; на один для следующего шага. */ ++spi_reads; /* Цикл for (i = 0; i < bytes/2; ++i) data[i] = (uint16_t)(0xBEEFU+i);; задаёт начальное значение, условие продолжения и шаг перебора. */ for (i = 0; i < bytes/2; ++i) data[i] = (uint16_t)(0xBEEFU+i); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */ static unsigned Load_protection_prepare(unsigned fn, unsigned a, unsigned n, /* Объявляет out — данные out. Хранит указатель на данные. */ uint16_t *out, unsigned *error) { /* Записывает out[0] значением (uint16_t)a; out[1] = (uint16_t)n; *error = 0; данные out. */ out[0] = (uint16_t)a; out[1] = (uint16_t)n; *error = 0; /* Завершает Load_protection_prepare и возвращает 2. */ return 2; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Описывает структуру mock_reg; порядок полей определяет расположение данных. */ struct mock_reg { uint32_t all; }; /* Продолжает список аргументов, полей или выражение static struct {; порядок элементов сохраняется. */ static struct { /* Описывает структуру mock_reg CANTA, CANAA, CANTRR, CANTRS;; порядок полей определяет расположение данных. */ struct mock_reg CANTA, CANAA, CANTRR, CANTRS; /* Продолжает список аргументов, полей или выражение } ECanaRegs;; порядок элементов сохраняется. */ } ECanaRegs; /* Продолжает список аргументов, полей или выражение static struct {; порядок элементов сохраняется. */ static struct { /* Описывает структуру ; порядок полей определяет расположение данных. */ struct { struct mock_reg MDH, MDL; } MBOX2; /* Продолжает список аргументов, полей или выражение } ECanaMboxes;; порядок элементов сохраняется. */ } ECanaMboxes; /* Продолжает список аргументов, полей или выражение static struct { unsigned long InterruptCount; } CpuTimer1;; порядок элементов сохраняется. */ static struct { unsigned long InterruptCount; } CpuTimer1; /* Подключает "production_routes.inc": настройки и интерфейс production_routes. */ #include "production_routes.inc" /* Начинает функцию request; назначение модуля — проверка gas167 на модели ПК. */ static void request(RS_DATA *rs, unsigned fn, unsigned a, unsigned n) { /* Продолжает список аргументов, полей или выражение unsigned crc;; порядок элементов сохраняется. */ unsigned crc; /* Вызывает memset с аргументами (rs, 0, sizeof(*rs)) в текущей последовательности операций. */ memset(rs, 0, sizeof(*rs)); /* Записывает rs->RS_Header[0] значением CNTRL_ADDR; rs->RS_Header[1] = fn; данные rs->RS_Header. */ rs->RS_Header[0] = CNTRL_ADDR; rs->RS_Header[1] = fn; /* Записывает rs->RS_Header[2] значением a >> 8; rs->RS_Header[3] = a & 255U; данные rs->RS_Header. */ rs->RS_Header[2] = a >> 8; rs->RS_Header[3] = a & 255U; /* Записывает rs->RS_Header[4] значением n >> 8; rs->RS_Header[5] = n & 255U; данные rs->RS_Header. */ rs->RS_Header[4] = n >> 8; rs->RS_Header[5] = n & 255U; /* Записывает crc значением ump_crc(rs->RS_Header, 6); данные crc. */ crc = ump_crc(rs->RS_Header, 6); /* Записывает rs->RS_Header[6] значением crc & 255U; rs->RS_Header[7] = crc >> 8; данные rs->RS_Header. */ rs->RS_Header[6] = crc & 255U; rs->RS_Header[7] = crc >> 8; /* Записывает sent значением 0; данные sent. */ sent = 0; /* Проверяет if (fn == 3) ReceiveCommandModbus3(rs); последующий оператор выполняется только при истинном условии. */ if (fn == 3) ReceiveCommandModbus3(rs); /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ else ReceiveCommandModbus6(rs); /* Вызывает assert с аргументами (irq_depth == 0 && rs->flag_TIMEOUT_to_Send) в текущей последовательности операций. */ assert(irq_depth == 0 && rs->flag_TIMEOUT_to_Send); /* Вызывает assert с аргументами (ump_crc(rs->buffer, rs->buffer[1] & 128U ? 5 : в текущей последовательности операций. */ assert(ump_crc(rs->buffer, rs->buffer[1] & 128U ? 5 : /* Продолжает список аргументов, полей или выражение (fn == 6 ? 8 : 5+rs->buffer[2])) == 0);; порядок элементов сохраняется. */ (fn == 6 ? 8 : 5+rs->buffer[2])) == 0); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Начинает функцию can_request; назначение модуля — проверка gas167 на модели ПК. */ static void can_request(unsigned fn, unsigned a, unsigned n) { /* Вызывает memset с аргументами (&ECanaRegs, 0, sizeof(ECanaRegs)) в текущей последовательности операций. */ memset(&ECanaRegs, 0, sizeof(ECanaRegs)); /* Вызывает memset с аргументами (&ECanaMboxes, 0, sizeof(ECanaMboxes)) в текущей последовательности операций. */ memset(&ECanaMboxes, 0, sizeof(ECanaMboxes)); /* Записывает ump_can_waiting значением 0; ump_can_length = 0; ump_can_index = 0; ump CAN waiting. */ ump_can_waiting = 0; ump_can_length = 0; ump_can_index = 0; /* Записывает ump_can_pending значением 1; ump_can_tag = 0x0100U | fn; флаг ожидающего запроса служебного CAN между ISR и главным циклом. */ ump_can_pending = 1; ump_can_tag = 0x0100U | fn; /* Записывает ump_can_address значением a; ump_can_value = n; ump CAN адрес. */ ump_can_address = a; ump_can_value = n; /* Вызывает UMP_CAN_service. В главном цикле готовит замороженный ответ служебного CAN и отправляет его двухсловными фрагментами. */ UMP_CAN_service(); /* Вызывает assert с аргументами (irq_depth == 0 && !ump_can_pending) в текущей последовательности операций. */ assert(irq_depth == 0 && !ump_can_pending); /* Вызывает assert с аргументами (ECanaRegs.CANTRS.all == 4U) в текущей последовательности операций. */ assert(ECanaRegs.CANTRS.all == 4U); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Точка входа: настраивает периферию, загружает параметры и обслуживает команды в главном цикле. */ int main(void) { /* Объявляет rs — данные rs. */ RS_DATA rs; /* Продолжает список аргументов, полей или выражение unsigned i;; порядок элементов сохраняется. */ unsigned i; /* Цикл for (i = 0; i < 129; ++i) modbus[i] = (int)i;; задаёт начальное значение, условие продолжения и шаг перебора. */ for (i = 0; i < 129; ++i) modbus[i] = (int)i; /* Записывает modbus[128] значением 0xD00D; массив технологических регистров; слово int на C28x занимает 16 бит. */ modbus[128] = 0xD00D; /* Exercise the real native handlers in both builds. */ /* Вызывает request с аргументами (&rs, 6, 1, 0xFEDC) в текущей последовательности операций. */ request(&rs, 6, 1, 0xFEDC); /* Вызывает assert с аргументами (modbus[1] == 0xFEDC && sent == 10) в текущей последовательности операций. */ assert(modbus[1] == 0xFEDC && sent == 10); /* Вызывает request с аргументами (&rs, 3, 0, 2) в текущей последовательности операций. */ request(&rs, 3, 0, 2); /* Вызывает assert с аргументами (rs.buffer[2] == 4 && rs.buffer[5] == 0xFE && rs.buffer[6] == 0xDC) в текущей последовательности операций. */ assert(rs.buffer[2] == 4 && rs.buffer[5] == 0xFE && rs.buffer[6] == 0xDC); /* Вызывает request с аргументами (&rs, 6, 0x52, 0) в текущей последовательности операций. */ request(&rs, 6, 0x52, 0); /* Вызывает assert с аргументами (rs.buffer[1] == 0x86 && rs.buffer[2] == 3 && modbus[0x52] == 0x52) в текущей последовательности операций. */ assert(rs.buffer[1] == 0x86 && rs.buffer[2] == 3 && modbus[0x52] == 0x52); /* Вызывает request с аргументами (&rs, 6, 0x7C, 9) в текущей последовательности операций. */ request(&rs, 6, 0x7C, 9); /* Вызывает assert с аргументами (rs.buffer[2] == 2 && modbus[0x7C] == 0x7C) в текущей последовательности операций. */ assert(rs.buffer[2] == 2 && modbus[0x7C] == 0x7C); /* Запись лимита через штатный FC06 возвращает обычное подтверждение для продолжения обмена GUI. */ request(&rs, 6, 0x7D, 5); /* Проверяет подтверждение записи пяти попыток в технологическом регистре. */ assert(sent == 10 && rs.buffer[1] == 6 && modbus[0x7D] == 5); /* Чтение обратно возвращает заданный лимит независимо от текущего счётчика START. */ request(&rs, 3, 0x7D, 1); /* Проверяет значение 5 как 16-битное слово с нулевым старшим байтом. */ assert(rs.buffer[3] == 0 && rs.buffer[4] == 5); /* Нулевая настройка отклоняется без изменения предыдущего лимита. */ request(&rs, 6, 0x7D, 0); /* Код 3 обозначает недопустимое значение; прежний лимит остаётся в RAM. */ assert(sent == 5 && rs.buffer[1] == 0x86 && rs.buffer[2] == 3 && modbus[0x7D] == 5); /* Верхняя граница проходит проверку без ограничения знаковым представлением int C28x. */ request(&rs, 6, 0x7D, 65535U); /* Проверяет 16-битный рисунок максимального значения в записанном регистре. */ assert(sent == 10 && (uint16_t)modbus[0x7D] == 65535U); /* Каждый штатный CAN-слот принимает ненулевую настройку и игнорирует ноль. */ for (unsigned slot = 0; slot < 3; slot++) { /* Сдвигает начало кадра так, чтобы выбранный маской слот адресовал 0x7D. */ native_can_slots(0x7DU - slot, 0x8000U >> slot, 7, 7, 7); /* Проверяет принятие лимита без изменения защищённого статуса 0x7C. */ assert(modbus[0x7D] == 7 && modbus[0x7C] == 0x7C); /* Ноль в том же слоте не заменяет принятую настройку семи пусков. */ native_can_slots(0x7DU - slot, 0x8000U >> slot, 0, 0, 0); /* Проверяет сохранение прежнего лимита после недопустимого CAN-значения. */ assert(modbus[0x7D] == 7); /* Проверяет 65535 во всех позициях штатного кадра CAN. */ native_can_slots(0x7DU - slot, 0x8000U >> slot, 65535U, 65535U, 65535U); /* Сохраняется весь 16-битный рисунок максимального числа пусков. */ assert((uint16_t)modbus[0x7D] == 65535U); /* Завершает проверку каждого штатного CAN-слота. */ } /* Existing UMP and protection routing must still work. */ /* Вызывает request с аргументами (&rs, 3, 0x1000, 2) в текущей последовательности операций. */ request(&rs, 3, 0x1000, 2); /* Вызывает assert с аргументами (rs.buffer[1] == 3 && rs.buffer[3] == 0x10 && legacy_reads == 2) в текущей последовательности операций. */ assert(rs.buffer[1] == 3 && rs.buffer[3] == 0x10 && legacy_reads == 2); /* Вызывает request с аргументами (&rs, 3, 0x1300, 2) в текущей последовательности операций. */ request(&rs, 3, 0x1300, 2); /* Вызывает assert с аргументами (rs.buffer[1] == 3 && rs.buffer[3] == 0x13) в текущей последовательности операций. */ assert(rs.buffer[1] == 3 && rs.buffer[3] == 0x13); /* Условие компиляции EEPROM_M95M02: выбранный блок включается в текущий вариант прошивки. */ #if EEPROM_M95M02 /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Объявляет out — данные out. */ uint16_t out[124]; /* Продолжает список аргументов, полей или выражение unsigned error, count;; порядок элементов сохраняется. */ unsigned error, count; /* Цикл for (i = 0; i < 65536U; ++i); задаёт начальное значение, условие продолжения и шаг перебора. */ for (i = 0; i < 65536U; ++i) /* Вызывает assert с аргументами (gas167_contains((uint16_t)i) == в текущей последовательности операций. */ assert(gas167_contains((uint16_t)i) == /* Продолжает список аргументов, полей или выражение ((i >= 0x5000U && i <= 0x507FU) || (i >= 0x5F00U && i <= 0x5F07U)));; порядок элементов сохраняется. */ ((i >= 0x5000U && i <= 0x507FU) || (i >= 0x5F00U && i <= 0x5F07U))); /* Вызывает assert с аргументами (gas167_prepare(3, 0x5000, 124, 0, out, &error) == 124 && !error) в текущей последовательности операций. */ assert(gas167_prepare(3, 0x5000, 124, 0, out, &error) == 124 && !error); /* Вызывает assert с аргументами (out[1] == 0xFEDC && out[123] == 123) в текущей последовательности операций. */ assert(out[1] == 0xFEDC && out[123] == 123); /* Записывает count значением gas167_prepare(3, 0x507F, 2, 0, out, &error); число. */ count = gas167_prepare(3, 0x507F, 2, 0, out, &error); /* Вызывает assert с аргументами (count == 2 && error == 2 && modbus[128] == 0xD00D) в текущей последовательности операций. */ assert(count == 2 && error == 2 && modbus[128] == 0xD00D); /* Вызывает assert с аргументами (gas167_prepare(3, 0x5000, 0, 0, out, &error) == 2 && error == 3) в текущей последовательности операций. */ assert(gas167_prepare(3, 0x5000, 0, 0, out, &error) == 2 && error == 3); /* Вызывает assert с аргументами (gas167_prepare(3, 0x5000, 125, 0, out, &error) == 2 && error == 3) в текущей последовательности операций. */ assert(gas167_prepare(3, 0x5000, 125, 0, out, &error) == 2 && error == 3); /* Вызывает assert с аргументами (gas167_prepare(3, 0x5000, 1, 1, out, &error) == 2 && error == 3) в текущей последовательности операций. */ assert(gas167_prepare(3, 0x5000, 1, 1, out, &error) == 2 && error == 3); /* Вызывает assert с аргументами (gas167_prepare(3, 0xFFFF, 2, 0, out, &error) == 2 && error == 2) в текущей последовательности операций. */ assert(gas167_prepare(3, 0xFFFF, 2, 0, out, &error) == 2 && error == 2); /* Вызывает assert с аргументами (gas167_prepare(16, 0x5000, 1, 0, out, &error) == 2 && error == 1) в текущей последовательности операций. */ assert(gas167_prepare(16, 0x5000, 1, 0, out, &error) == 2 && error == 1); /* Вызывает assert с аргументами (gas167_prepare(6, 0x5080, 7, 0, out, &error) == 2 && error == 2) в текущей последовательности операций. */ assert(gas167_prepare(6, 0x5080, 7, 0, out, &error) == 2 && error == 2); /* Вызывает assert с аргументами (gas167_prepare(6, 0x5052, 60001, 0, out, &error) == 2 && error == 3) в текущей последовательности операций. */ assert(gas167_prepare(6, 0x5052, 60001, 0, out, &error) == 2 && error == 3); /* Вызывает assert с аргументами (gas167_prepare(6, 0x5052, 60000, 0, out, &error) == 2 && !error) в текущей последовательности операций. */ assert(gas167_prepare(6, 0x5052, 60000, 0, out, &error) == 2 && !error); /* Вызывает assert с аргументами (modbus[0x52] == 60000) в текущей последовательности операций. */ assert(modbus[0x52] == 60000); /* Вызывает assert с аргументами (gas167_prepare(3, 0x5000, 1, 0, 0, &error) == 0) в текущей последовательности операций. */ assert(gas167_prepare(3, 0x5000, 1, 0, 0, &error) == 0); /* Вызывает assert с аргументами (gas167_prepare(6, 0x5000, 1, 0, out, 0) == 0 && modbus[0] == 0) в текущей последовательности операций. */ assert(gas167_prepare(6, 0x5000, 1, 0, out, 0) == 0 && modbus[0] == 0); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Вызывает request с аргументами (&rs, 3, 0x5000, 2) в текущей последовательности операций. */ request(&rs, 3, 0x5000, 2); /* Вызывает assert с аргументами (sent == 9 && rs.buffer[5] == 0xFE && rs.buffer[6] == 0xDC) в текущей последовательности операций. */ assert(sent == 9 && rs.buffer[5] == 0xFE && rs.buffer[6] == 0xDC); /* Вызывает request с аргументами (&rs, 3, 0x5000, 124) в текущей последовательности операций. */ request(&rs, 3, 0x5000, 124); /* Вызывает assert с аргументами (sent == 253 && rs.buffer[2] == 248) в текущей последовательности операций. */ assert(sent == 253 && rs.buffer[2] == 248); /* Вызывает request с аргументами (&rs, 3, 0x5F00, 8) в текущей последовательности операций. */ request(&rs, 3, 0x5F00, 8); /* Вызывает assert с аргументами (sent == 21 && rs.buffer[3] == 0x47 && rs.buffer[4] == 0x41) в текущей последовательности операций. */ assert(sent == 21 && rs.buffer[3] == 0x47 && rs.buffer[4] == 0x41); /* Вызывает assert с аргументами (rs.buffer[5] == 0x53 && rs.buffer[6] == 0x31) в текущей последовательности операций. */ assert(rs.buffer[5] == 0x53 && rs.buffer[6] == 0x31); /* Вызывает assert с аргументами (rs.buffer[10] == 167 && rs.buffer[18] == 1) в текущей последовательности операций. */ assert(rs.buffer[10] == 167 && rs.buffer[18] == 1); /* Вызывает request с аргументами (&rs, 6, 0x5F00, 0) в текущей последовательности операций. */ request(&rs, 6, 0x5F00, 0); /* Вызывает assert с аргументами (sent == 5 && rs.buffer[2] == 2) в текущей последовательности операций. */ assert(sent == 5 && rs.buffer[2] == 2); /* Вызывает request с аргументами (&rs, 3, 0x5F07, 2) в текущей последовательности операций. */ request(&rs, 3, 0x5F07, 2); /* Вызывает assert с аргументами (rs.buffer[2] == 2) в текущей последовательности операций. */ assert(rs.buffer[2] == 2); /* Вызывает request с аргументами (&rs, 6, 0x5052, 0) в текущей последовательности операций. */ request(&rs, 6, 0x5052, 0); /* Вызывает assert с аргументами (rs.buffer[2] == 3 && modbus[0x52] == 60000) в текущей последовательности операций. */ assert(rs.buffer[2] == 3 && modbus[0x52] == 60000); /* Вызывает request с аргументами (&rs, 6, 0x507D, 9) в текущей последовательности операций. */ request(&rs, 6, 0x507D, 9); /* GAS-псевдоним возвращает подтверждение записи девяти попыток с исходным адресом запроса. */ assert(sent == 8 && rs.buffer[1] == 6 && modbus[0x7D] == 9); /* Ноль отклоняется и через GAS, не перезаписывая принятый лимит. */ request(&rs, 6, 0x507D, 0); /* Код 3 отличает недопустимое значение от недоступного адреса; лимит остаётся равным девяти. */ assert(sent == 5 && rs.buffer[2] == 3 && modbus[0x7D] == 9); /* Вызывает request с аргументами (&rs, 6, 0x507F, 0x80) в текущей последовательности операций. */ request(&rs, 6, 0x507F, 0x80); /* Вызывает assert с аргументами (sent == 8 && rs.buffer[2] == 0x50 && rs.buffer[3] == 0x7F) в текущей последовательности операций. */ assert(sent == 8 && rs.buffer[2] == 0x50 && rs.buffer[3] == 0x7F); /* Вызывает assert с аргументами (captures == 1 && modbus[127] == 0x80) в текущей последовательности операций. */ assert(captures == 1 && modbus[127] == 0x80); /* Вызывает can_request с аргументами (6, 0x5001, 0xFEDC) в текущей последовательности операций. */ can_request(6, 0x5001, 0xFEDC); /* Вызывает assert с аргументами (modbus[1] == 0xFEDC && ECanaMboxes.MBOX2.MDL.all == 0x5001FEDCUL) в текущей последовательности операций. */ assert(modbus[1] == 0xFEDC && ECanaMboxes.MBOX2.MDL.all == 0x5001FEDCUL); /* Вызывает assert с аргументами (ECanaMboxes.MBOX2.MDH.all == 0x1F000100UL) в текущей последовательности операций. */ assert(ECanaMboxes.MBOX2.MDH.all == 0x1F000100UL); /* Вызывает can_request с аргументами (3, 0x5001, 2) в текущей последовательности операций. */ can_request(3, 0x5001, 2); /* Вызывает assert с аргументами (ECanaMboxes.MBOX2.MDL.all == 0xFEDC0002UL) в текущей последовательности операций. */ assert(ECanaMboxes.MBOX2.MDL.all == 0xFEDC0002UL); /* Вызывает can_request с аргументами (3, 0x5000, 124) в текущей последовательности операций. */ can_request(3, 0x5000, 124); /* Вызывает assert с аргументами (ump_can_length == 124 && ump_can_index == 2) в текущей последовательности операций. */ assert(ump_can_length == 124 && ump_can_index == 2); modbus[2] = 777; /* All fragments must retain the original snapshot. */ /* Записывает modbus[2] значением 777; массив технологических регистров; слово int на C28x занимает 16 бит. */ /* Цикл for (i = 1; i < 62; ++i) ; задаёт начальное значение, условие продолжения и шаг перебора. */ for (i = 1; i < 62; ++i) { /* Записывает ECanaRegs.CANTA.all значением 4; представление регистра целым словом без разбиения на битовые поля. */ ECanaRegs.CANTA.all = 4; /* Вызывает UMP_CAN_service. В главном цикле готовит замороженный ответ служебного CAN и отправляет его двухсловными фрагментами. */ UMP_CAN_service(); /* Вызывает assert с аргументами (ump_can_index == 2*(i+1)) в текущей последовательности операций. */ assert(ump_can_index == 2*(i+1)); /* Проверяет if (i == 1) assert(ECanaMboxes.MBOX2.MDL.all == 0x00020003UL); последующий оператор выполняется только при истинном условии. */ if (i == 1) assert(ECanaMboxes.MBOX2.MDL.all == 0x00020003UL); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Записывает modbus[2] значением 2; массив технологических регистров; слово int на C28x занимает 16 бит. */ modbus[2] = 2; /* Вызывает can_request с аргументами (3, 0x5000, 3) в текущей последовательности операций. */ can_request(3, 0x5000, 3); /* Вызывает assert с аргументами (ECanaMboxes.MBOX2.MDH.all == 0x1F000103UL) в текущей последовательности операций. */ assert(ECanaMboxes.MBOX2.MDH.all == 0x1F000103UL); /* Вызывает can_request с аргументами (6, 0x507C, 9) в текущей последовательности операций. */ can_request(6, 0x507C, 9); /* Вызывает assert с аргументами ((ECanaMboxes.MBOX2.MDH.all & 255U) == 2 && modbus[0x7C] == 0x7C) в текущей последовательности операций. */ assert((ECanaMboxes.MBOX2.MDH.all & 255U) == 2 && modbus[0x7C] == 0x7C); /* Служебный CAN использует тот же GAS-псевдоним для изменения лимита попыток. */ can_request(6, 0x507D, 7); /* Проверяет успешный ответ с исходным GAS-адресом и новый лимит семи пусков. */ assert((ECanaMboxes.MBOX2.MDH.all & 255U) == 0 && ECanaMboxes.MBOX2.MDL.all == 0x507D0007UL && modbus[0x7D] == 7); /* Недопустимый ноль отклоняется по служебному CAN без изменения последней настройки. */ can_request(6, 0x507D, 0); /* Проверяет код Modbus 3 и отсутствие изменения настроенного лимита. */ assert((ECanaMboxes.MBOX2.MDH.all & 255U) == 3 && modbus[0x7D] == 7); /* Вызывает can_request с аргументами (6, 0x507F, 0x40) в текущей последовательности операций. */ can_request(6, 0x507F, 0x40); /* Вызывает assert с аргументами (captures == 2 && modbus[127] == 0x40) в текущей последовательности операций. */ assert(captures == 2 && modbus[127] == 0x40); /* Вызывает can_request с аргументами (6, 0x5F00, 9) в текущей последовательности операций. */ can_request(6, 0x5F00, 9); /* Вызывает assert с аргументами ((ECanaMboxes.MBOX2.MDH.all & 255U) == 2) в текущей последовательности операций. */ assert((ECanaMboxes.MBOX2.MDH.all & 255U) == 2); /* Вызывает request с аргументами (&rs, 3, 0x8000, 0x8001) в текущей последовательности операций. */ request(&rs, 3, 0x8000, 0x8001); /* Выбирает альтернативный блок текущего условия компиляции. */ #else /* Вызывает request с аргументами (&rs, 3, 0x5000, 2) в текущей последовательности операций. */ request(&rs, 3, 0x5000, 2); /* Вызывает assert с аргументами (sent == 5 && rs.buffer[2] == 2) в текущей последовательности операций. */ assert(sent == 5 && rs.buffer[2] == 2); /* Вызывает request с аргументами (&rs, 6, 0x5001, 9) в текущей последовательности операций. */ request(&rs, 6, 0x5001, 9); /* Вызывает assert с аргументами (rs.buffer[2] == 2 && modbus[1] == 0xFEDC) в текущей последовательности операций. */ assert(rs.buffer[2] == 2 && modbus[1] == 0xFEDC); /* Вызывает request с аргументами (&rs, 3, 0x5000, 124) в текущей последовательности операций. */ request(&rs, 3, 0x5000, 124); /* Вызывает assert с аргументами (sent == 5 && rs.buffer[2] == 2) в текущей последовательности операций. */ assert(sent == 5 && rs.buffer[2] == 2); /* Вызывает request с аргументами (&rs, 3, 0x5F00, 8) в текущей последовательности операций. */ request(&rs, 3, 0x5F00, 8); /* Вызывает assert с аргументами (rs.buffer[2] == 2) в текущей последовательности операций. */ assert(rs.buffer[2] == 2); /* Вызывает can_request с аргументами (6, 0x5001, 9) в текущей последовательности операций. */ can_request(6, 0x5001, 9); /* Вызывает assert с аргументами ((ECanaMboxes.MBOX2.MDH.all & 255U) == 2 && modbus[1] == 0xFEDC) в текущей последовательности операций. */ assert((ECanaMboxes.MBOX2.MDH.all & 255U) == 2 && modbus[1] == 0xFEDC); /* Вызывает assert с аргументами (captures == 0) в текущей последовательности операций. */ assert(captures == 0); /* Вызывает request с аргументами (&rs, 3, 0x8000, 1) в текущей последовательности операций. */ request(&rs, 3, 0x8000, 1); /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Вызывает assert с аргументами (spi_reads == 1 && rs.buffer[3] == 0xBE && rs.buffer[4] == 0xEF) в текущей последовательности операций. */ assert(spi_reads == 1 && rs.buffer[3] == 0xBE && rs.buffer[4] == 0xEF); /* Вызывает assert с аргументами (modbus[128] == 0xD00D) в текущей последовательности операций. */ assert(modbus[128] == 0xD00D); /* Вызывает printf с аргументами ("PASS GAS167 profile %d: production RTU/CAN routes, guards, CRC and legacy services\n", EEPROM_M95M02) в текущей последовательности операций. */ printf("PASS GAS167 profile %d: production RTU/CAN routes, guards, CRC and legacy services\n", EEPROM_M95M02); /* Завершает main и возвращает 0. */ return 0; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ }