forked from achamaikin/CCSModuleSW30Web
e8b3ed90cd
Replace outdated files with the latest working tree from fork/CCSModuleSW30Web to align source and generated artifacts. Co-authored-by: Cursor <cursoragent@cursor.com>
134 lines
9.8 KiB
Markdown
134 lines
9.8 KiB
Markdown
# Журнал изменений (сессия чата): `fork/CCSModuleSW30Web`
|
||
|
||
Документ фиксирует доработки проекта **CCSModuleSW30Web** в ветке/каталоге форка
|
||
`/Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web`, обсуждавшиеся и вносившиеся в рамках описанной сессии (UART, ADC/DMA, CP, отладка IRQ, оптимизация `-Ofast` для кода из прерываний).
|
||
|
||
---
|
||
|
||
## 1. UART и протокол
|
||
|
||
### 1.1. UART3 (Everest / `serial.c`)
|
||
|
||
- Таймаут «нет связи с хостом»:** `EVEREST_TIMEOUT_MS` = **5000** мс.
|
||
- Жёсткий реинициал при отсутствии RX:** `UART3_REINIT_TIMEOUT_MS` = **1500** мс (с защитой от слишком частых реинициалов через `uart3_last_reinit_tick`).
|
||
- Расширено логирование путей сброса/ошибок приёма и ошибок HAL для диагностики «таймаут без остановки UART3».
|
||
- Колбэки и вспомогательные функции, вызываемые из контекста прерывания, помечены **`ISR_FAST`** (см. раздел 6):
|
||
`CCS_RxEventCallback`, `HAL_UART_ErrorCallback`, `uart3_log_hal_error`, `uart3_arm_rx_or_log`, цепочка разбора пакета (`process_received_packet`, `crc16_ibm`, `expected_payload_len`, `apply_command`).
|
||
|
||
### 1.2. UART2 / `serial_control.c`
|
||
|
||
- Отдельная логика **`SC_UART2_Watchdog()`**, вызывается из **`SC_Task()`** (не из IRQ).
|
||
- Константы:
|
||
- **`SC_UART2_REINIT_TIMEOUT_MS`** = **500** мс — порог для жёсткого реинициала при отсутствии пакетов;
|
||
- **`SC_UART2_PACKET_TIMEOUT_MS`** = **5000** мс — таймаут коммуникации.
|
||
- Сценарий **новый пакет при `BUSY_TX`**: при необходимости **`Abort_IT`**, сброс направления RS-485, затем повторная инициализация UART и приём `ReceiveToIdle_IT` (защита от обрыва TX из-за агрессивного watchdog).
|
||
- Отдельная ветка **жёсткого реинициала при `BUSY_TX`** с логом `USART2 BUSY_TX: hard reinit` (отслеживание `sc_uart2_last_busy_tx_reinit_packet_tick`).
|
||
- HAL-колбэки **`HAL_UARTEx_RxEventCallback`**, **`HAL_UART_TxCpltCallback`** помечены **`ISR_FAST`**.
|
||
|
||
### 1.3. `SC_SendPacket` и стек CRC/кодирования
|
||
|
||
- Для единообразной оптимизации пути «IRQ → ответ» на функции **`calculate_crc32`**, **`encode_packet`**, **`parse_packet`**, **`process_received_packet`** и публичную **`SC_SendPacket`** добавлен **`ISR_FAST`**.
|
||
- В **`Core/Inc/serial_control.h`**: подключение **`isr_opt.h`**, прототип **`ISR_FAST void SC_SendPacket(...)`** (согласованность с определением в `.c`).
|
||
|
||
**Замечание:** `SC_SendPacket` вызывается и из основного потока; для GCC вся функция компилируется с `-Ofast`. При необходимости строгого разделения можно вынести отдельную версию «только из IRQ».
|
||
|
||
---
|
||
|
||
## 2. Отладочные линии DBG в `stm32f1xx_it.c`
|
||
|
||
На время входа/выхода из выбранных обработчиков прерываний поднимается/опускается соответствующий GPIO — удобно для осциллографа (длительность IRQ).
|
||
|
||
| Линия | Обработчик |
|
||
|--------|------------|
|
||
| **DBG1** | `UART5_IRQHandler` |
|
||
| **DBG2** | `USART2_IRQHandler` |
|
||
| **DBG3** | `USART3_IRQHandler` |
|
||
| **DBG4** | `DMA1_Channel1_IRQHandler`, `ADC1_2_IRQHandler`, `TIM3_IRQHandler` |
|
||
| **DBG5** | `CAN1_RX0_IRQHandler`, `CAN2_TX_IRQHandler`, `CAN2_RX1_IRQHandler` |
|
||
| — | `USART1_IRQHandler` — без обёртки DBG (по согласованию) |
|
||
|
||
В **`DMA1_Channel1_IRQHandler`** вызывается **`HAL_DMA_IRQHandler(&hdma_adc1)`** для цепочки ADC+DMA.
|
||
|
||
Для всего файла **`stm32f1xx_it.c`** под GCC добавлено:
|
||
|
||
```c
|
||
#pragma GCC optimize("Ofast")
|
||
```
|
||
|
||
(в блоке `USER CODE BEGIN Includes`).
|
||
|
||
---
|
||
|
||
## 3. ADC: DMA, глобальные данные, колбэк
|
||
|
||
- Файлы **`adc.c` / `adc.h`**: структура **`ADC_ScanData_t`**, глобально **`volatile ADC_ScanData_t adc_data`** с полями сырых каналов (`in3_raw`, `cp_raw`, `ntc1_raw`, `ntc2_raw`, `temp_sensor_raw`, `vrefint_raw` и т.д. по фактическому объявлению в заголовке).
|
||
- **`HAL_ADC_ConvCpltCallback`**: копирование из буфера DMA в **`adc_data`**, помечен **`ISR_FAST`**.
|
||
- Публичная **`ADC_ScanStart()`** — запуск сканирования (после калибровки вызывается из инициализации платы).
|
||
- **`board.c`**: после **`HAL_ADCEx_Calibration_Start`** вызывается **`ADC_ScanStart()`**; **`CONN_ReadTemp`** читает **`adc_data.ntc1_raw` / `ntc2_raw`** вместо блокирующего опроса ADC.
|
||
|
||
**Диагностика (из обсуждения):** если не вызываются **`HAL_ADC_ConvCpltCallback`** / **`HAL_DMA_IRQHandler`**, проверять: срабатывание триггера ADC (например, **TIM3 TRGO**), работу TIM3, порядок инициализации DMA/NVIC, срабатывание **`DMA1_Channel1_IRQHandler`**.
|
||
|
||
---
|
||
|
||
## 4. CP (`cp.c` / `cp.h`)
|
||
|
||
- Измерение опоры на **`adc_data.cp_raw`** (и при необходимости **`vrefint_raw`** по текущей реализации в коде).
|
||
- Логика классификации/порогов приведена к варианту, согласованному с основным **CCSModuleSW30Web** (не форк).
|
||
- Сэмпл по таймеру: уход от тяжёлой работы в IRQ OC — использование **`HAL_TIM_OC_Start`** без прерывания по сравнению, обновление напряжения в **`CP_GetVoltage()`** / основном цикле (**`CP_Loop`** опирается на **`CP_GetState()`** и т.п. по фактическому коду).
|
||
|
||
---
|
||
|
||
## 5. Отладочный UART (`debug.c`)
|
||
|
||
При **`#ifndef USE_WEB_INTERFACE`** (или эквивалентной ветке сборки в файле): колбэк **`HAL_UARTEx_RxEventCallback`** и **`debug_rx_interrupt`** помечены **`ISR_FAST`**.
|
||
|
||
---
|
||
|
||
## 6. Оптимизация `-Ofast` для кода из прерываний
|
||
|
||
### 6.1. Макрос `ISR_FAST`
|
||
|
||
Файл **`Core/Inc/isr_opt.h`**:
|
||
|
||
- **GCC:** `#define ISR_FAST __attribute__((optimize("Ofast")))`
|
||
- **Иное:** пустой макрос.
|
||
|
||
### 6.2. Где используется (по состоянию репозитория)
|
||
|
||
| Файл | Элементы с `ISR_FAST` / pragma |
|
||
|------|--------------------------------|
|
||
| `stm32f1xx_it.c` | `#pragma GCC optimize("Ofast")` на весь файл (GCC) |
|
||
| `adc.c` | `HAL_ADC_ConvCpltCallback` |
|
||
| `serial.c` | `CCS_RxEventCallback`, `HAL_UART_ErrorCallback`, `uart3_log_hal_error`, `uart3_arm_rx_or_log`, `process_received_packet`, `crc16_ibm`, `expected_payload_len`, `apply_command` |
|
||
| `serial_control.c` | `HAL_UARTEx_RxEventCallback`, `HAL_UART_TxCpltCallback`, `calculate_crc32`, `encode_packet`, `parse_packet`, `process_received_packet`, `SC_SendPacket` |
|
||
| `serial_control.h` | прототип `SC_SendPacket` + `#include "isr_opt.h"` |
|
||
| `psu_control.c` | `HAL_CAN_RxFifo1MsgPendingCallback` |
|
||
| `debug.c` | см. раздел 5 |
|
||
|
||
---
|
||
|
||
## 7. Ограничения и переносимость
|
||
|
||
- **`ISR_FAST`** и pragma в **`stm32f1xx_it.c`** рассчитаны на **GCC** (STM32CubeIDE по умолчанию). Для **IAR / ARM Compiler 6** потребуется отдельная стратегия (прагмы/ключи проекта).
|
||
- **`-Ofast`** допускает агрессивные преобразования с плавающей точкой и перестановки, влияющие на строго воспроизводимую арифметику; для критичных вычислений вне IRQ при необходимости ограничивайте область оптимизации.
|
||
|
||
---
|
||
|
||
## 8. Затронутые пути (краткий список)
|
||
|
||
- `Core/Inc/isr_opt.h` — новый/центральный заголовок оптимизации IRQ.
|
||
- `Core/Inc/serial_control.h` — `isr_opt.h`, `ISR_FAST` у `SC_SendPacket`.
|
||
- `Core/Src/stm32f1xx_it.c` — DBG, DMA ADC, pragma `Ofast`.
|
||
- `Core/Src/adc.c`, `Core/Inc/adc.h` — DMA, `adc_data`, `ADC_ScanStart`, колбэк.
|
||
- `Core/Src/board.c` — калибровка, старт скана, температура из `adc_data`.
|
||
- `Core/Src/cp.c`, `Core/Inc/cp.h` — CP и ADC.
|
||
- `Core/Src/serial.c` — UART3, таймауты, логи, `ISR_FAST`.
|
||
- `Core/Src/serial_control.c` — UART2, watchdog, `ISR_FAST`.
|
||
- `Core/Src/psu_control.c` — CAN RX callback.
|
||
- `Core/Src/debug.c` — отладочный UART под условием сборки.
|
||
- `Core/Src/dma.c`, `gpio.c`, `main.h` — по необходимости для DMA1 Ch1 и DBG-пинов.
|
||
|
||
---
|
||
|
||
*Документ сгенерирован для фиксации контекста сессии; при дальнейших правках кода имеет смысл обновлять соответствующие разделы вручную.*
|