Обновить логгер УМП и исправить запуск UART и EEPROM

Перейти на компактные 12-словные записи v4 и сохранять 10 процентов банка после отключения. Добавить трёхсекундное ожидание роста ЗПТ и настраиваемый лимит пусков. Явно инициализировать состояние UART и гарантировать публикацию параметров EEPROM перед запуском Timer2. Сохранить воспроизводимые сборки, регрессионные проверки, документацию и обновлённые результаты сборки; исключить временные артефакты.
This commit is contained in:
2026-10-12 12:25:41 +03:00
parent f741741cf8
commit 1e911e5250
38 changed files with 2089 additions and 1485 deletions
+25 -16
View File
@@ -59,7 +59,7 @@ int modbus[ANSWER_LEN+1];
/* Объявляет param — данные param. */
unsigned int param[ANSWER_LEN+1];
/* Заполняет регистры заводскими значениями; тайм-аут CAN нагрузки по умолчанию равен 600 мс. */
/* Заполняет регистры заводскими значениями; для LOAD задаёт тайм-аут свежести CAN 2000 мс. Значение 600 мс применяется отдельно при восстановлении недопустимого параметра. */
void Default_params()
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
{
@@ -248,6 +248,8 @@ void Default_params()
/* Записывает DAC_go значением 6; начальный ток нагрузки в мА, технологический регистр 0x50. */
DAC_go = 6; // начало зарада
LOAD_CAN_TIMEOUT = 2000; /* ms without fresh ZPT: freeze ramp. */ /* Записывает LOAD_CAN_TIMEOUT значением 2000; сохраняемый тайм-аут свежести напряжения CAN в миллисекундах, регистр 0x52. */
/* Устанавливает прежний заводской лимит пяти пусков, включая первый START; настройка хранится в сохраняемом регистре 0x7D. */
LOAD_MAX_ATTEMPTS = LOAD_DEFAULT_MAX_ATTEMPTS;
/* Записывает DAC_stop значением 16; конечный ток нагрузки в мА, технологический регистр 0x51. */
DAC_stop= 16; // конец зарада
@@ -295,7 +297,7 @@ void Load_params()
else
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
{
/* Вызывает Default_params. Заполняет регистры заводскими значениями; тайм-аут CAN нагрузки по умолчанию равен 600 мс. */
/* Восстанавливает заводские параметры после неверного CRC или несоответствия режима платы; LOAD_CAN_TIMEOUT получает 2000 мс. */
Default_params();
/* Записывает Commands значением 0; слово команд, технологический регистр 127. */
Commands=0;
@@ -373,7 +375,7 @@ static void modbus_exception(RS_DATA *rs_arr, unsigned int function, unsigned in
}
/* UART parser has already validated CRC and accepted the device address. */
/* Выбирает GAS либо существующее адресное пространство УМП и снимает согласованный ответ под краткой блокировкой IRQ. */
/* Маршрутизирует расширенные адреса: RAM УМП/GAS захватывается под краткой блокировкой IRQ, а чтение EEPROM выполняется с разрешёнными IRQ, поскольку SPI продвигается из Timer2. */
static int receive_ump(RS_DATA *rs_arr)
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
{
@@ -381,7 +383,7 @@ static int receive_ump(RS_DATA *rs_arr)
unsigned int address, value, saved, length, count, error;
/* Main-loop only; encoded into the UART buffer before the next request.
* Keep the 124-word snapshot off the shared interrupt stack. */
/* Объявляет words — слова. */
/* Статический буфер хранит до 124 слов снимка вне общего стека прерываний; главный цикл сериализует его до обработки следующего запроса. */
static uint16_t words[UMP_MAX_WORDS];
/* Записывает address значением (rs_arr->RS_Header[2] << 8) | rs_arr->RS_Header[3]; адрес. */
address = (rs_arr->RS_Header[2] << 8) | rs_arr->RS_Header[3];
@@ -503,17 +505,18 @@ void ReceiveCommandModbus3(RS_DATA *rs_arr)
/* Записывает rs_arr->buffer[2] значением Length_MB*2; rs arr буфер. */
rs_arr->buffer[2] = Length_MB*2;
/* Защищаем целостность одного снимка/блока; передача UART идёт уже
* с разрешёнными прерываниями и не задерживает измерение/управление. */
/* Цикл for (i=0;i<Length_MB;i++); задаёт начальное значение, условие продолжения и шаг перебора. */
/* Штатные регистры копируются последовательно без блокировки IRQ вокруг всего блока.
* Измерительные ISR могут обновить соседние слова между чтениями; этот путь не гарантирует
* единый момент захвата всех значений. RAM-расширения захватываются отдельно в receive_ump. */
/* Формирует payload из запрошенного числа 16-битных слов; для каждого слова в ответе нужны два байта. */
for (i=0;i<Length_MB;i++)
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
{
/* Записывает value значением modbus[Address_MB+i]; данные value. */
/* Читает очередное слово один раз, чтобы старший и младший байты ответа относились к одному считанному значению. */
value = modbus[Address_MB+i];
/* Записывает rs_arr->buffer[3+i*2] значением (value >> 8) & 0xFF; rs arr буфер. */
/* Помещает старший байт слова после трёхбайтного заголовка; данные регистра передаются старшим байтом вперёд. */
rs_arr->buffer[3+i*2] = (value >> 8) & 0xFF;
/* Записывает rs_arr->buffer[3+i*2+1] значением value & 0xFF; rs arr буфер. */
/* Помещает младший байт непосредственно за старшим, сохраняя исходный 16-битный рисунок регистра. */
rs_arr->buffer[3+i*2+1] = value & 0xFF;
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
@@ -528,13 +531,13 @@ void ReceiveCommandModbus3(RS_DATA *rs_arr)
/* Записывает rs_arr->buffer[Length_MB*2+4] значением HIBYTE(crc); rs arr буфер. */
rs_arr->buffer[Length_MB*2+4] = HIBYTE(crc);
/* Записывает rs_arr->buffer[Length_MB*2+5] значением 0; rs arr буфер. */
/* Первый исторический нулевой байт после CRC; входит в увеличенную длину штатного ответа. */
rs_arr->buffer[Length_MB*2+5] = 0;
/* Записывает rs_arr->buffer[Length_MB*2+6] значением 0; rs arr буфер. */
/* Второй исторический нулевой байт после CRC; сохраняет прежний формат низких технологических адресов. */
rs_arr->buffer[Length_MB*2+6] = 0;
/* Записывает rs_arr->buffer[Length_MB*2+7] значением 0; rs arr буфер. */
/* Третий исторический нулевой байт после CRC; это последний элемент передаваемого буфера при длине 2*N+8. */
rs_arr->buffer[Length_MB*2+7] = 0;
/* Записывает rs_arr->buffer[Length_MB*2+8] значением 0; rs arr буфер. */
/* Дополнительный ноль находится за длиной, переданной в RS_Send; в текущий ответ это слово не отправляется. */
rs_arr->buffer[Length_MB*2+8] = 0;
/* Записывает rs_arr->flag_TIMEOUT_to_Send значением true; rs arr флаг TIMEOUT to Send. */
@@ -577,12 +580,18 @@ void ReceiveCommandModbus6(RS_DATA *rs_arr)
/* Записывает Data_MB значением (rs_arr->RS_Header[4] << 8) | rs_arr->RS_Header[5]; данные MB. */
Data_MB = (rs_arr->RS_Header[4] << 8) | rs_arr->RS_Header[5];
/* Проверяет if (Desk == dsk_LOAD и (Address_MB == 0x7CU или Address_MB == 0x7DU)); последующий оператор выполняется только при истинном условии. */
if (Desk == dsk_LOAD && (Address_MB == 0x7CU || Address_MB == 0x7DU)) {
/* На плате LOAD запрещает запись только состояния защиты 0x7C; регистр лимита 0x7D принимает настройку. */
if (Desk == dsk_LOAD && Address_MB == 0x7CU) {
/* Вызывает modbus_exception. Формирует ответ Modbus с установленным старшим битом функции и кодом исключения. */
modbus_exception(rs_arr, CMD_MODBUS_6, 2); return;
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
/* Ноль в лимите 0x7D недопустим: первый пуск должен входить в разрешённые 1..65535 попыток. */
if (Desk == dsk_LOAD && Address_MB == 0x7DU && Data_MB == 0U) {
/* Возвращает код Modbus 3 для недопустимого значения, сохраняя прежний лимит и состояние автомата. */
modbus_exception(rs_arr, CMD_MODBUS_6, 3); return;
/* Завершает проверку ненулевого лимита перед общей записью технологического слова. */
}
/* Проверяет if (Desk == dsk_LOAD и Address_MB == 0x52U и; последующий оператор выполняется только при истинном условии. */
if (Desk == dsk_LOAD && Address_MB == 0x52U &&
/* Продолжает список аргументов, полей или выражение (Data_MB == 0U || Data_MB > 60000U)) {; порядок элементов сохраняется. */