Обновить логгер УМП и исправить запуск UART и EEPROM
Перейти на компактные 12-словные записи v4 и сохранять 10 процентов банка после отключения. Добавить трёхсекундное ожидание роста ЗПТ и настраиваемый лимит пусков. Явно инициализировать состояние UART и гарантировать публикацию параметров EEPROM перед запуском Timer2. Сохранить воспроизводимые сборки, регрессионные проверки, документацию и обновлённые результаты сборки; исключить временные артефакты.
This commit is contained in:
+25
-16
@@ -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)) {; порядок элементов сохраняется. */
|
||||
|
||||
Reference in New Issue
Block a user