forked from achamaikin/CCSModuleSW30Web
261 lines
14 KiB
Markdown
261 lines
14 KiB
Markdown
# Рекомендации по добавлению 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
|
||
- Управление реле
|
||
- Команды через последовательный порт
|
||
- Ограничения мощности
|
||
|