Обновить логгер УМП и исправить запуск 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
+46 -2
View File
@@ -206,6 +206,38 @@ int main(void) {
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);
@@ -291,8 +323,12 @@ int main(void) {
assert(rs.buffer[2] == 3 && modbus[0x52] == 60000);
/* Вызывает request с аргументами (&rs, 6, 0x507D, 9) в текущей последовательности операций. */
request(&rs, 6, 0x507D, 9);
/* Вызывает assert с аргументами (rs.buffer[2] == 2 && modbus[0x7D] == 0x7D) в текущей последовательности операций. */
assert(rs.buffer[2] == 2 && modbus[0x7D] == 0x7D);
/* 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) в текущей последовательности операций. */
@@ -336,6 +372,14 @@ int main(void) {
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) в текущей последовательности операций. */
+15
View File
@@ -63,6 +63,21 @@ routes = can_globals + "\n" + "".join(function(message, name) for name in
("modbus_exception", "receive_ump", "ReceiveCommandModbus3", "ReceiveCommandModbus6"))
# Задаёт routes + по выражению справа; значение используется последующими операциями.
routes += function(ecan, "UMP_CAN_service")
# Берёт три записи штатного CAN из рабочего обработчика, чтобы проверки не копировали его условия.
slots_start = ecan.index("\tfor (slot = 0; slot < 3; slot++, adr++, mask <<= 1)")
# Завершает фрагмент перед журналированием; оно не влияет на доступность технологических регистров.
slots_end = ecan.index("/* Фиксируем применённую команду", slots_start)
# Обёртка задаёт только поля кадра; проверки доступа остаются извлечённым рабочим кодом.
routes += """/* Проверяет рабочие записи CAN без аппаратных mailbox и обработки остальных событий ISR. */
static void native_can_slots(unsigned int adr, unsigned int mask, int a, int b, int c) {
/* Индекс выбирает одно из трёх слов; маска достоверности передана вызывающим тестом в аргументе mask. */
unsigned int slot;
/* Передаёт исходные слова рабочим условиям записи регистра. */
int Data[3] = {a, b, c};
"""
# Добавляет неизменённый фрагмент Handlai и закрывает обёртку с пояснением назначения блока.
routes += ecan[slots_start:slots_end] + "/* Завершает записи трёх слов штатного CAN-кадра. */\n}\n"
# Открывает управляемый ресурс tempfile.TemporaryDirectory(prefix="gas167-test-") as tmp с автоматическим освобождением.
with tempfile.TemporaryDirectory(prefix="gas167-test-") as tmp:
# Задаёт directory по выражению справа; значение используется последующими операциями.