# Рекомендации по добавлению 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
   - Управление реле
   - Команды через последовательный порт
   - Ограничения мощности

