Перейти на компактные 12-словные записи v4 и сохранять 10 процентов банка после отключения. Добавить трёхсекундное ожидание роста ЗПТ и настраиваемый лимит пусков. Явно инициализировать состояние UART и гарантировать публикацию параметров EEPROM перед запуском Timer2. Сохранить воспроизводимые сборки, регрессионные проверки, документацию и обновлённые результаты сборки; исключить временные артефакты.
431 lines
41 KiB
C
431 lines
41 KiB
C
/* Проверка 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;
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
}
|