# Рекомендации по добавлению log_printf в проект ## Обзор Этот документ содержит рекомендации по добавлению логирования ошибок и информационных сообщений в проект зарядной станции GB/T. ## 1. Инициализация и конфигурация (main.c, can.c, adc.c, usart.c, tim.c, rtc.c) ### 1.1 main.c **Место:** Функция `Error_Handler()` ```c 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` - логировать параметры зарядки: ```c log_printf(LOG_INFO, "Charging started: V=%dV, I=%dA\n", volt/10, curr/10); ``` - При остановке зарядки - логировать причину: ```c 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мс): ```c 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; } ``` - При восстановлении связи: ```c if(psu_online[psu_n] == 0) { log_printf(LOG_INFO, "PSU%d communication restored\n", psu_n); } ``` ### 3.2 Ошибки отправки команд **Место:** Функция `PSU_SendCmd()` - При исчерпании попыток отправки: ```c 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()` - При ограничении мощности: ```c 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: ```c 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. Приоритетные места для добавления логирования 1. **Критично:** - Error_Handler() - добавить логирование перед зависанием - Ошибки инициализации периферии (CAN, ADC, UART, RTC) - Ошибки связи с PSU - Ошибки контактора 2. **Важно:** - Изменения состояний зарядки - Параметры начала зарядки - Причины остановки зарядки - Ошибки протокола GB/T 3. **Полезно:** - Изменения состояния CC - Управление реле - Команды через последовательный порт - Ограничения мощности