14 KiB
Рекомендации по добавлению log_printf в проект
Обзор
Этот документ содержит рекомендации по добавлению логирования ошибок и информационных сообщений в проект зарядной станции GB/T.
1. Инициализация и конфигурация (main.c, can.c, adc.c, usart.c, tim.c, rtc.c)
1.1 main.c
Место: Функция Error_Handler()
void Error_Handler(void) {
log_printf(LOG_CRIT, "System error occurred, entering infinite loop\n");
__disable_irq();
while (1) { }
}
Место: Функция SystemClock_Config()
- После
HAL_RCC_OscConfig()- добавить логирование успешной инициализации осцилляторов - После
HAL_RCC_ClockConfig()- добавить логирование успешной конфигурации тактирования - После
HAL_RCCEx_PeriphCLKConfig()- добавить логирование успешной конфигурации периферийных часов
Место: Функция main()
- После успешной инициализации каждого периферийного устройства (CAN, ADC, UART, RTC, TIM)
- При установке конфигурации:
log_printf(LOG_INFO, "Config loaded: location=%.3s, charger=%lu\n", config.location, config.chargerNumber);
1.2 can.c
Место: Функции MX_CAN1_Init() и MX_CAN2_Init()
- После проверки
HAL_CAN_Init()- логировать ошибку инициализации CAN - Добавить логирование успешной инициализации:
log_printf(LOG_INFO, "CAN%d initialized\n", can_num);
Место: Функция PSU_CAN_FilterInit() в psu_control.c
- После проверки
HAL_CAN_ConfigFilter()- логировать ошибку конфигурации фильтра
1.3 adc.c
Место: Функция MX_ADC1_Init()
- После проверки
HAL_ADC_Init()- логировать ошибку инициализации ADC - После проверки
HAL_ADC_ConfigChannel()- логировать ошибку конфигурации канала - Добавить логирование успешной инициализации:
log_printf(LOG_INFO, "ADC1 initialized\n");
1.4 usart.c
Место: Функция MX_USART2_UART_Init()
- После проверки
HAL_UART_Init()- логировать ошибку инициализации UART - Добавить логирование успешной инициализации:
log_printf(LOG_INFO, "USART2 initialized, baudrate=%d\n", 115200);
1.5 tim.c
Место: Функции инициализации таймеров
- После каждой проверки
HAL_TIM_*_Init()- логировать ошибки инициализации таймеров
1.6 rtc.c / soft_rtc.c
Место: Функции работы с RTC
- После проверки
HAL_RTC_Init()- логировать ошибку инициализации RTC - В функции
set_Time()- логировать установку времени:log_printf(LOG_INFO, "Time set: %lu\n", unix_time);
2. Управление зарядкой (charger_gbt.c)
2.1 Ошибки протокола GB/T
Место: Уже есть логирование таймаутов (BHM, BRM, BCP, BRO, BSD), но можно добавить:
- При получении неожиданных PGN:
log_printf(LOG_WARN, "Unexpected PGN received: 0x%X\n", PGN); - При ошибке отправки пакета:
log_printf(LOG_WARN, "Failed to send GBT packet, state=%d\n", GBT_State);
2.2 Состояния зарядки
Место: Функция GBT_ChargerTask()
- При переходе в состояние
GBT_S10_CHARGING- логировать параметры зарядки:log_printf(LOG_INFO, "Charging started: V=%dV, I=%dA\n", volt/10, curr/10); - При остановке зарядки - логировать причину:
log_printf(LOG_INFO, "Charging stopped, cause: 0x%X\n", GBT_StopCauseCode);
2.3 Ошибки изоляции
Место: Состояние GBT_S4_ISOTEST
- При обнаружении ошибки изоляции:
log_printf(LOG_ERR, "Isolation test failed\n");
2.4 Перегрев коннектора
Место: Уже есть логирование в состоянии GBT_S10_CHARGING, но можно улучшить:
- Добавить логирование при восстановлении нормальной температуры
3. Управление PSU (psu_control.c)
3.1 Ошибки CAN связи с PSU
Место: Функция PSU_Loop()
- При потере связи с PSU (таймаут > 500мс):
if((HAL_GetTick() - can_lastpacket[psu_n]) > 500) { if(psu_online[psu_n] == 1) { log_printf(LOG_WARN, "PSU%d communication lost\n", psu_n); } psu_online[psu_n] = 0; } - При восстановлении связи:
if(psu_online[psu_n] == 0) { log_printf(LOG_INFO, "PSU%d communication restored\n", psu_n); }
3.2 Ошибки отправки команд
Место: Функция PSU_SendCmd()
- При исчерпании попыток отправки:
if(retry_counter == 0) { log_printf(LOG_ERR, "PSU_SendCmd failed: source=0x%02X, dest=0x%02X, cmd=0x%02X\n", source, destination, cmd); }
3.3 Ограничения мощности
Место: Функция PSU_Loop()
- При ограничении мощности:
if ((CONN.WantedCurrent/10) * CONN.MeasuredVoltage > power_limit) { log_printf(LOG_INFO, "Power limited: %dW -> %dW\n", (CONN.WantedCurrent/10) * CONN.MeasuredVoltage, power_limit * 10); }
3.4 Переключение HV режима
Место: Функция PSU_Loop()
- При переключении в HV режим:
log_printf(LOG_INFO, "PSU HV mode enabled (V>490V)\n"); - При выходе из HV режима:
log_printf(LOG_INFO, "PSU HV mode disabled\n");
4. Управление коннектором (connector.c)
4.1 Изменение состояния CC
Место: Функция CONN_CC_ReadStateFiltered()
- При изменении состояния CC:
if (CC_STATE_FILTERED != prev_state) { log_printf(LOG_INFO, "CC state changed: %d -> %d (voltage=%.2fV)\n", prev_state, CC_STATE_FILTERED, CONN_CC_GetAdc()); }
4.2 Ошибки ADC
Место: Функция CONN_CC_GetAdc()
- При ошибке чтения ADC:
log_printf(LOG_ERR, "CC ADC read error\n"); - При неожиданных значениях напряжения:
log_printf(LOG_WARN, "CC voltage out of range: %.2fV\n", volt);
5. Управление замком (lock.c)
5.1 Уже есть логирование ошибок замка, но можно добавить:
Место: Функция GBT_ManageLockMotor()
- При успешном выполнении действия:
log_printf(LOG_INFO, "Lock %s successful\n", state ? "locked" : "unlocked"); - При начале попытки:
log_printf(LOG_DEBUG, "Lock action: %s, attempt %d\n", state ? "lock" : "unlock", GBT_LockState.retry_count + 1);
6. Последовательная связь (serial_control.c)
6.1 Ошибки протокола
Место: Функция process_received_packet()
- При неверном CRC:
log_printf(LOG_WARN, "Serial packet CRC error\n"); - При неверном формате пакета:
log_printf(LOG_WARN, "Serial packet format error, len=%d\n", packet_len);
6.2 Таймауты передачи
Место: Функция SerialControl_Task()
- При таймауте передачи:
log_printf(LOG_WARN, "UART TX timeout, aborting\n");
6.3 Ошибки команд
Место: Функция process_received_command() в serial_handler.c
- При неизвестной команде:
log_printf(LOG_WARN, "Unknown command: 0x%02X\n", cmd.command); - При неверной длине аргументов:
log_printf(LOG_WARN, "Command 0x%02X: invalid argument length: %d\n", cmd.command, cmd.argument_length);
6.4 Успешные команды
Место: Функция command_handler() в serial_handler.c
- При установке конфигурации:
log_printf(LOG_INFO, "Config updated: location=%.3s, charger=%lu\n", config.location, config.chargerNumber); - При изменении лимита мощности:
log_printf(LOG_INFO, "Power limit set: %dW\n", power_limit * 1000); - При изменении разрешения зарядки:
log_printf(LOG_INFO, "Charge permit: %s\n", CONN.connControl ? "allowed" : "not allowed"); - При включении тестового режима PSU:
log_printf(LOG_INFO, "PSU test mode: V=%dV, I=%dA\n", PSU_TestMode.voltage, PSU_TestMode.current);
7. J1939 протокол (j1939.c)
7.1 Ошибки приема
Место: Функция HAL_CAN_RxFifo0MsgPendingCallback()
- При ошибке получения сообщения:
log_printf(LOG_WARN, "J1939 RX error\n"); - При неверном PGN:
log_printf(LOG_WARN, "J1939 invalid PGN: 0x%X\n", PGN);
7.2 Ошибки отправки
Место: Функция J_SendPacket()
- При ошибке отправки:
log_printf(LOG_WARN, "J1939 TX error: PGN=0x%X\n", PGN);
7.3 Ошибки протокола передачи данных
Место: Обработка длинных пакетов
- При ошибке последовательности пакетов:
log_printf(LOG_WARN, "J1939 packet sequence error: expected %d, got %d\n", expected, received); - При таймауте передачи:
log_printf(LOG_WARN, "J1939 transmission timeout: PGN=0x%X\n", j_rx.PGN);
7.4 Реинициализация CAN
Место: Функция GBT_CAN_ReInit()
- При успешной реинициализации:
log_printf(LOG_INFO, "CAN1 reinitialized\n"); - При ошибке:
log_printf(LOG_ERR, "CAN1 reinit failed\n");
8. Управление реле (CONT_Loop в psu_control.c)
8.1 Ошибки контактора
Место: Уже есть логирование ошибки контактора, но можно добавить:
- При восстановлении нормальной работы:
log_printf(LOG_INFO, "Contactor feedback OK\n");
8.2 Управление реле
Место: Функция CONT_Loop()
- При включении/выключении реле AC:
log_printf(LOG_DEBUG, "Relay AC: %s\n", state ? "ON" : "OFF"); - При включении/выключении реле DC:
log_printf(LOG_DEBUG, "Relay DC: %s\n", state ? "ON" : "OFF");
9. Измерение энергии (meter.c)
9.1 Сброс счетчика
Место: Функция METER_CalculateEnergy()
- При сбросе смещения энергии:
log_printf(LOG_INFO, "Energy meter reset, offset=%lu Wh\n", METER.EnergyOffset);
9.2 Ошибки расчета
Место: Функция METER_CalculateEnergy()
- При переполнении счетчика:
log_printf(LOG_WARN, "Energy meter overflow detected\n");
10. Общие рекомендации
10.1 Уровни логирования
LOG_EMERG/LOG_CRIT- критические ошибки, требующие немедленного внимания (Error_Handler)LOG_ERR- ошибки, влияющие на функциональность (таймауты протокола, ошибки связи)LOG_WARN- предупреждения (потеря связи, неверные данные)LOG_INFO- информационные сообщения (изменение состояний, успешные операции)LOG_DEBUG- отладочная информация (детали работы алгоритмов)
10.2 Формат сообщений
Рекомендуемый формат: "[Module] Action: details\n"
Примеры:
log_printf(LOG_INFO, "[PSU] Communication restored: PSU%d\n", psu_n);log_printf(LOG_ERR, "[GBT] Protocol error: BHM timeout\n");log_printf(LOG_WARN, "[CAN] TX failed: retries exhausted\n");
10.3 Частота логирования
- Избегать логирования в циклах с высокой частотой (например, каждые 10мс)
- Использовать флаги для логирования изменений состояния (как
ED_TraceWarning) - Логировать только при изменении состояния или при ошибках
10.4 Производительность
log_printfиспользует буфер, но все равно стоит избегать избыточного логирования- Для отладочной информации использовать
LOG_DEBUG, который можно отключить в релизной версии
11. Приоритетные места для добавления логирования
-
Критично:
- Error_Handler() - добавить логирование перед зависанием
- Ошибки инициализации периферии (CAN, ADC, UART, RTC)
- Ошибки связи с PSU
- Ошибки контактора
-
Важно:
- Изменения состояний зарядки
- Параметры начала зарядки
- Причины остановки зарядки
- Ошибки протокола GB/T
-
Полезно:
- Изменения состояния CC
- Управление реле
- Команды через последовательный порт
- Ограничения мощности