Files
Balsam_167/tests/gas167/gas167_test.c
Andrey 1e911e5250 Обновить логгер УМП и исправить запуск UART и EEPROM
Перейти на компактные 12-словные записи v4 и сохранять 10 процентов банка после отключения. Добавить трёхсекундное ожидание роста ЗПТ и настраиваемый лимит пусков. Явно инициализировать состояние UART и гарантировать публикацию параметров EEPROM перед запуском Timer2. Сохранить воспроизводимые сборки, регрессионные проверки, документацию и обновлённые результаты сборки; исключить временные артефакты.
2026-10-12 12:25:41 +03:00

431 lines
41 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Проверка gas167 на модели ПК. Русские пояснения сохранены в UTF-8. */
/* Подключает <assert.h>: настройки и интерфейс assert. */
#include <assert.h>
/* Подключает <stdbool.h>: настройки и интерфейс stdbool. */
#include <stdbool.h>
/* Подключает <stdint.h>: настройки и интерфейс stdint. */
#include <stdint.h>
/* Подключает <stdio.h>: настройки и интерфейс stdio. */
#include <stdio.h>
/* Подключает <string.h>: настройки и интерфейс string. */
#include <string.h>
/* Подключает "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;
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}