chore: remove obsolete documentation
删除不再使用的旧协议、硬件资料、测试文档和历史计划文件。
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 230 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 191 KiB |
File diff suppressed because it is too large
Load Diff
@@ -1,121 +0,0 @@
|
|||||||
# Source 状态机改造与角色切换维护计划
|
|
||||||
|
|
||||||
## 1. 改造目标
|
|
||||||
|
|
||||||
将电源(Source)控制整理为与负载(Sink)类似的独立状态机,但保留两者业务差异:
|
|
||||||
|
|
||||||
- 北向协议板只负责角色/CC 线选择、协议设置及周期读取协议板电压电流。
|
|
||||||
- 功率板角色、模式、电压、电流、继电器和启停全部由 `chrg_source.c` 管理。
|
|
||||||
- 所有 Source 南向寄存器命令统一使用 `chrg_sou_com_batch_submit()`,不再散落调用 `chrg_set_sou_reg()`。
|
|
||||||
- Source 不判断带载电流。协议板返回电压有效则进入 `RUNNING`;启动后持续无电压则回到 `WAIT`。
|
|
||||||
- 协议、协议电压或协议电流发生变化时,重新进入 `INIT`。
|
|
||||||
- Source/Sink 不停机切换时,必须先停止旧角色,确认完成后再初始化新角色。
|
|
||||||
|
|
||||||
## 2. 当前已完成的修改
|
|
||||||
|
|
||||||
当前工作区已完成第一阶段,尚未形成完整状态机:
|
|
||||||
|
|
||||||
1. `apps/chrg/applications/utils/chrg_source.c`
|
|
||||||
- 新增 `chrg_source_init_submit(rt_uint8_t idx, struct chrg_switch_t *pSW)`。
|
|
||||||
- 通过一个批次下发 `REG_ELOAD`、`REG_MODE`、`REG_VOLTAGE_OUT + 1`、`REG_CURRENT_OUT + 1` 和 `REG_WORK = WORK_STOP`。
|
|
||||||
2. `apps/chrg/applications/utils/chrg_source.h`
|
|
||||||
- 增加上述函数声明。
|
|
||||||
3. `apps/chrg/applications/thread/chrg_roll_nor.c`
|
|
||||||
- Source 协议设置流程进入 `IDX_GET_SOURCE_VC` 后提交南向初始化批次。
|
|
||||||
- 仅当批次提交成功时设置 `source.On_Flag = 1`。
|
|
||||||
|
|
||||||
注意:当前仍有旧 Source 路径在 `chrg_north.c`、`chrg_roll_nor.c` 和 `chrg_lcd.c` 中直接调用 `chrg_set_sou_reg()`。在完成后续步骤前,新旧逻辑会同时存在,不能作为最终版本发布。
|
|
||||||
|
|
||||||
## 3. 目标状态机
|
|
||||||
|
|
||||||
在 `chrg_source.h` 中增加明确的 Source 状态:
|
|
||||||
|
|
||||||
```c
|
|
||||||
typedef enum {
|
|
||||||
SOURCE_WORK_STOP = 0,
|
|
||||||
SOURCE_WORK_WAIT,
|
|
||||||
SOURCE_WORK_INIT,
|
|
||||||
SOURCE_WORK_START,
|
|
||||||
SOURCE_WORK_RUNNING,
|
|
||||||
SOURCE_WORK_STOPPING,
|
|
||||||
SOURCE_WORK_FAULT
|
|
||||||
} source_work_mode_t;
|
|
||||||
```
|
|
||||||
|
|
||||||
在 `chrg_src_t` 中增加每通道状态及参数快照:`work_mode`、`last_protocol`、`last_voltage`、`last_current`、`zero_volt_count`、`retry_count`。参数快照只能在对应命令确认完成后更新。
|
|
||||||
|
|
||||||
状态动作:
|
|
||||||
|
|
||||||
| 状态 | 动作 | 后续状态 |
|
|
||||||
|---|---|---|
|
|
||||||
| `INIT` | 批量设置 Source 角色、模式、电压、电流及继电器,保持停止 | `START` |
|
|
||||||
| `START` | 批量下发 `REG_WORK = WORK_START` | `WAIT` |
|
|
||||||
| `WAIT` | 北向周期读取协议板 VC | 有电压进入 `RUNNING` |
|
|
||||||
| `RUNNING` | 更新 VC;检测协议/电压/电流变化 | 变化进入 `INIT` |
|
|
||||||
| `STOPPING` | 批量停止输出、关闭功率板继电器 | `STOP` |
|
|
||||||
| `STOP` | 清理使能并断开北向继电器 | 保持 |
|
|
||||||
|
|
||||||
建议电压大于 `WORK_MIN_VOLT` 即视为有效。电压为零连续 3 次再由 `RUNNING` 回到 `WAIT`,避免单帧异常造成状态抖动。
|
|
||||||
|
|
||||||
## 4. COM 端改造
|
|
||||||
|
|
||||||
修改 `chrg_mb_write_sys()`:
|
|
||||||
|
|
||||||
- 当目标角色为 Source 且当前未工作时,只设置 `pSW->sub = IDX_SET_SOURCE_CC_SET`,由北向依次完成 CC 和协议设置;协议应答完成后才进入 `SOURCE_WORK_INIT`。
|
|
||||||
- 同角色下,比较协议、协议电压、协议电流。任一变化则进入 `SOURCE_WORK_INIT`;相同参数不得重复初始化。
|
|
||||||
- 不要在收到 `SYS_REG_ROLE_SWITCH` 时立即覆盖实际角色。应保存 `target_role`,在参数生效时启动切换流程。
|
|
||||||
- 切换期间返回 `MB_EX_SLAVE_BUSY`,或者只更新影子参数并等待本次切换完成。
|
|
||||||
|
|
||||||
角色切换顺序:
|
|
||||||
|
|
||||||
```text
|
|
||||||
Source -> Sink: Source STOPPING -> STOP -> 切换角色/继电器 -> Sink INIT
|
|
||||||
Sink -> Source: Sink STOP -> 切换角色/继电器 -> 北向 CC/协议 -> Source INIT
|
|
||||||
```
|
|
||||||
|
|
||||||
禁止 Source 和 Sink 的功率板继电器、工作命令在同一通道同时有效。
|
|
||||||
|
|
||||||
## 5. 北向流程改造
|
|
||||||
|
|
||||||
精简 `chrg_roll_nor_set()` 的 Source 分支,只保留:
|
|
||||||
|
|
||||||
1. `IDX_SET_SOURCE_CC_SET`:设置 CC 线,成功后进入 `IDX_SET_SOURCE_PD`。
|
|
||||||
2. `IDX_SET_SOURCE_PD`:设置协议,应答成功后设置 `SOURCE_WORK_INIT`。
|
|
||||||
3. `IDX_GET_SOURCE_VC`:读取协议板电压电流。
|
|
||||||
|
|
||||||
删除 Source 分支中的 `IDX_SET_SOURCE_ID`、`IDX_SET_SOURCE_CV`、`IDX_SER_SOURCE_VOLT`、`IDX_SER_SOURCE_CURR`、`IDX_SET_SOURCE_WORK` 南向设置动作。校准、控制台和 Sink 分支不在本次范围内。
|
|
||||||
|
|
||||||
`chrg_north.c` 只解析 Source VC:更新 `source.vc`、`Now_voltage`、`Now_current`,并根据电压推进 `WAIT/RUNNING`。移除 `chrg_source_standard_output()`、`chrg_source_fast_output()` 和旧的分步停机控制,避免解析函数直接下发南向命令。
|
|
||||||
|
|
||||||
## 6. 南向完成确认
|
|
||||||
|
|
||||||
`chrg_sou_com_batch_submit()` 返回成功仅表示入队成功,不表示功率板已经执行。需要为每通道增加批次完成序号或完成事件:
|
|
||||||
|
|
||||||
- `INIT` 批次全部应答匹配后才能进入 `START`。
|
|
||||||
- `START` 应答成功后才能进入 `WAIT`。
|
|
||||||
- `STOPPING` 批次完成后才能断开北向继电器和修改实际角色。
|
|
||||||
- CRC 错误、寄存器不匹配或超时不得推进状态;达到重试上限后进入 `FAULT`。
|
|
||||||
|
|
||||||
## 7. 推荐实施顺序
|
|
||||||
|
|
||||||
1. 增加 Source 状态枚举、参数快照及 `chrg_source_work()`。
|
|
||||||
2. 将 INIT、START、STOPPING 的南向动作全部迁移到 `chrg_source.c`。
|
|
||||||
3. 增加南向批次完成通知,再改为应答驱动状态转换。
|
|
||||||
4. 精简北向 Source 子状态,只保留 CC、协议和 VC。
|
|
||||||
5. 修改 COM 同角色参数差异及跨角色切换。
|
|
||||||
6. 清理 `chrg_lcd.c` 中重复的 Source 启停和角色寄存器写入。
|
|
||||||
7. 编译并在硬件验证后删除旧字段和旧函数。
|
|
||||||
|
|
||||||
## 8. 验证清单
|
|
||||||
|
|
||||||
- Keil 编译 `apps/chrg/chrg.uvprojx`,确认无未定义符号和头文件循环依赖。
|
|
||||||
- 单通道验证 Source 首次启动、停止、相同参数重复生效。
|
|
||||||
- 分别改变协议、协议电压和协议电流,确认只执行一次重新 INIT。
|
|
||||||
- 模拟协议板电压持续为零,确认进入 WAIT 且不会反复提交相同批次。
|
|
||||||
- 验证 Source -> Sink、Sink -> Source,示波器确认切换期间无输出重叠。
|
|
||||||
- 四通道同时运行并交叉切换,检查南向队列饥饿、响应错配、超时和缓存串通道。
|
|
||||||
- 回归 Sink 正常负载、动态测试、无电流重启及低压处理。
|
|
||||||
|
|
||||||
## 9. 接手注意事项
|
|
||||||
|
|
||||||
开始修改前先执行 `git status --short` 和 `git diff`。当前 `chrg_north.c` 还包含此前 Sink 连续确认次数改为 3 的修改及注释清理,不能在 Source 重构时回退。不要提交 Keil `build/`、`Obj/`、AXF、BIN 或 MAP 等生成文件。
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
# Source CC_CLOSE 协议切换修改说明
|
|
||||||
|
|
||||||
## 修改目标
|
|
||||||
|
|
||||||
修正 Source 北向协议板的命令顺序,避免在 CC 保持 Attached 时直接重配
|
|
||||||
`0xD0`。多通道同时切换时采用共享等待屏障,使保护时间并行发生,不按
|
|
||||||
通道串行累计。
|
|
||||||
|
|
||||||
## 本轮实施步骤
|
|
||||||
|
|
||||||
### 第一步:统一状态命名
|
|
||||||
|
|
||||||
断开 CC 的命令状态命名为 `IDX_SET_SOURCE_CC_CLOSE`,等待状态命名为
|
|
||||||
`IDX_WAIT_SOURCE_CC_CLOSE`。`CC_CLOSE` 固定发送 `0x17=0x03`,不覆盖
|
|
||||||
COM 保存的目标 `CC_Set`。
|
|
||||||
|
|
||||||
### 第二步:调整停止态启动顺序
|
|
||||||
|
|
||||||
Source 从停止状态启动以及 Sink 切换为 Source 时,不发送 `CC_CLOSE`,
|
|
||||||
直接按以下顺序执行:
|
|
||||||
|
|
||||||
```text
|
|
||||||
IDX_SET_SOURCE_PD
|
|
||||||
-> IDX_WAIT_SOURCE_PROTOCOL
|
|
||||||
-> IDX_SET_SOURCE_CC_SET
|
|
||||||
-> IDX_GET_SOURCE_VC
|
|
||||||
```
|
|
||||||
|
|
||||||
即先设置协议,收到 `0xD0` ACK 并完成保护等待后,再连接目标 CC。
|
|
||||||
|
|
||||||
### 第三步:识别必须断开 CC 的切换
|
|
||||||
|
|
||||||
COM 参数生效时,满足以下任一条件进入 `CC_CLOSE`:
|
|
||||||
|
|
||||||
- 新协议为 PD/PPS 或 PD3.1/AVS,并且协议或 CC 线与上次不同。
|
|
||||||
- 上次协议为 PD/PPS 或 PD3.1/AVS,本次切换为非 PD 协议。
|
|
||||||
|
|
||||||
其它协议配置变化从 `IDX_SET_SOURCE_PD` 开始。标准协议仅改变电压、电流
|
|
||||||
时直接更新功率板,不重复下发 `0xD0`。
|
|
||||||
|
|
||||||
### 第四步:执行 CC_CLOSE 命令链
|
|
||||||
|
|
||||||
COM先确定北向`sub`,协议或CC发生变化时进入
|
|
||||||
`SOURCE_WORK_PROTOCOL_SWITCH`,不在COM中调用发送函数。北向轮询线程
|
|
||||||
执行该Source工作状态,负责向南向功率板写入0V;标准协议还会在同一批
|
|
||||||
命令中依次写模式和电流。提交成功后清零`set_volt`并进入
|
|
||||||
`SOURCE_WORK_WAIT`,随后按已经选定的`sub`继续执行。
|
|
||||||
|
|
||||||
需要断开 CC 的通道按以下顺序执行:
|
|
||||||
|
|
||||||
```text
|
|
||||||
IDX_SET_SOURCE_CC_CLOSE 发送 0x17=0x03
|
|
||||||
-> IDX_WAIT_SOURCE_CC_CLOSE 等待共享保护时间
|
|
||||||
-> IDX_SET_SOURCE_PD 发送 0xD0
|
|
||||||
-> IDX_WAIT_SOURCE_PROTOCOL 等待协议 ACK 后保护时间
|
|
||||||
-> IDX_SET_SOURCE_CC_SET 发送 0x17=目标 CC
|
|
||||||
-> IDX_GET_SOURCE_VC 恢复 0x20 查询
|
|
||||||
```
|
|
||||||
|
|
||||||
每条设置命令仍需收到角色、命令、长度和 CRC 均正确的回码后才能推进
|
|
||||||
`sub`;错误回码继续沿用现有丢弃和有限重发逻辑。
|
|
||||||
|
|
||||||
### 第五步:多通道共享 CC_CLOSE 等待
|
|
||||||
|
|
||||||
使用 `pending_mask` 和 `acked_mask` 管理本轮参与切换的 Source 通道。
|
|
||||||
所有已登记通道都收到 `0x17` ACK 后,只启动一次 300 ms 保护等待。
|
|
||||||
一个通道和四个通道的保护等待本身均为 300 ms;四通道只额外产生必要的
|
|
||||||
命令收发时间,不会累计为四次 300 ms。
|
|
||||||
|
|
||||||
### 第六步:握手稳定确认(本轮不修改)
|
|
||||||
|
|
||||||
本轮不增加“连续两次 `0x20` 电压稳定后才进入 RUNNING”的新逻辑,继续
|
|
||||||
使用现有 `chrg_source_parse()` 电压误差和重试规则。
|
|
||||||
|
|
||||||
### 第七步:配置覆盖保护
|
|
||||||
|
|
||||||
继续使用 `config_version` 防止 COM 新配置被旧回码推进。停止、角色切换
|
|
||||||
或不再需要 `CC_CLOSE` 时,会把通道移出共享等待屏障,避免残留状态影响
|
|
||||||
下一次启动。
|
|
||||||
|
|
||||||
### 第八步:完整失败恢复(本轮不修改)
|
|
||||||
|
|
||||||
本轮不增加握手总超时、再次 detach、整套流程最多重试两轮以及故障上报。
|
|
||||||
单条北向命令仍使用现有的三次发送机制。完整恢复流程待单独验证后实施。
|
|
||||||
|
|
||||||
## 时间参数
|
|
||||||
|
|
||||||
| 参数 | 当前值 | 说明 |
|
|
||||||
|---|---:|---|
|
|
||||||
| `SOURCE_CC_CLOSE_WAIT_MS` | 300 ms | 从本轮最后一个有效 `CC_CLOSE` ACK 开始 |
|
|
||||||
| `SOURCE_PROTOCOL_WAIT_MS` | 100 ms | 每通道收到 `0xD0` ACK 后并行等待 |
|
|
||||||
| `NORTH_RESPONSE_TIMEOUT_MS` | 50 ms | 单次北向回码等待 |
|
|
||||||
| `NORTH_REQUEST_MAX_RETRIES` | 2 | 首次发送外最多重发两次 |
|
|
||||||
|
|
||||||
## 建议验证顺序
|
|
||||||
|
|
||||||
1. 单通道停止态启动 PD,确认发送顺序为 `D0 -> 17(目标CC) -> 20`。
|
|
||||||
2. 单通道 PD 改协议或 CC,确认顺序为 `17(03) -> 等待 -> D0 -> 17(目标CC) -> 20`。
|
|
||||||
3. 单通道 PD 切换 QC/FCP/标准,确认切换前先发送 `17(03)`。
|
|
||||||
4. 四通道连续生效,确认四路 `17(03)` 均回码后共享一次约 300 ms 等待。
|
|
||||||
5. 连续执行 20 至 30 轮协议切换,检查是否仍出现 Source 芯片 PD 状态异常。
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,65 +0,0 @@
|
|||||||
300W电源板Modbus RTU标准通讯协议指令
|
|
||||||
角色切换,默认是电子负载
|
|
||||||
1.读取当前角色信息
|
|
||||||
01 03 00 04 00 01 C5 CB
|
|
||||||
2.设置电源模式
|
|
||||||
01 06 00 04 00 01 09 CB
|
|
||||||
|
|
||||||
3.设置电子负载模式
|
|
||||||
01 06 00 04 00 02 49 CA
|
|
||||||
|
|
||||||
1.恒流恒压模式读取
|
|
||||||
01 03 00 1F 00 01 B5 CC
|
|
||||||
|
|
||||||
2.设置恒压模式
|
|
||||||
01 06 00 1F 00 01 79 CC
|
|
||||||
|
|
||||||
3.设置恒流模式
|
|
||||||
01 06 00 1F 00 02 39 CD
|
|
||||||
|
|
||||||
输入输出控制
|
|
||||||
启动: 01 06 00 1E 00 01 28 0C
|
|
||||||
停止: 01 06 00 1E 00 02 68 0D
|
|
||||||
故障复位:01 06 00 1E 00 03 A9 CD
|
|
||||||
|
|
||||||
先发送:01 06 00 29 00 00 58 02
|
|
||||||
//1V,最小被限制在3.0V,显示:3.287V;
|
|
||||||
01 06 00 2C 03 E8 A8 BC
|
|
||||||
//5V,实际显示:5.280-----------------标准电源
|
|
||||||
01 06 00 2A 13 88 A5 54
|
|
||||||
//6V,实际显示:6.280
|
|
||||||
电压指令,先发送: 电流指令:先发送:01 06 00 2B 00 00 F9 C2
|
|
||||||
01 06 00 2A 17 70 A6 16 :保护电流12A
|
|
||||||
//9V------------------------------------QC标准 //默认1A
|
|
||||||
01 06 00 2A 23 28 B1 2C //01 06 00 2C 03 E8 48 BD
|
|
||||||
//10V //2A
|
|
||||||
01 06 00 2A 27 10 B2 3E //01 06 00 2C 07 D0 4B AF
|
|
||||||
//11V //3A
|
|
||||||
01 06 00 2A 2E E0 B4 2A //01 06 00 2C 0B B8 4F 41
|
|
||||||
//12V-----------------------------------QC标准 //5A
|
|
||||||
01 06 00 2A 2E E0 B4 2A //01 06 00 2C 13 88 45 55
|
|
||||||
//15V //10A
|
|
||||||
01 06 00 2A 3A 98 BB 08 //01 06 00 2C 27 10 52 3F
|
|
||||||
//20V-----------------------------------PD标准 //11A
|
|
||||||
01 06 00 2A 4E 20 9C 7A //01 06 00 2C 2A F8 56 E1
|
|
||||||
//21V
|
|
||||||
01 06 00 2A 52 08 94 A4
|
|
||||||
//24V
|
|
||||||
01 06 00 2A 5D C0 90 C2
|
|
||||||
//28V
|
|
||||||
01 06 00 2A 6D 60 84 BA
|
|
||||||
//32V
|
|
||||||
01 06 00 2A 7D 00 89 52
|
|
||||||
//36V
|
|
||||||
01 06 00 2A 8C A0 CC BA
|
|
||||||
//42V
|
|
||||||
01 06 00 2A A4 10 D3 0E
|
|
||||||
//45V
|
|
||||||
01 06 00 2A AF C8 D4 64
|
|
||||||
//48V
|
|
||||||
01 06 00 2A BB 80 DB 52
|
|
||||||
//48.5V
|
|
||||||
01 06 00 2A BD 74 D9 75
|
|
||||||
|
|
||||||
电流:
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,108 +0,0 @@
|
|||||||
# apps/chrg 长期运行修复基线
|
|
||||||
|
|
||||||
## 记录信息
|
|
||||||
|
|
||||||
- 记录时间:2026-07-18 15:53:36 +08:00
|
|
||||||
- 当前分支:`feature`
|
|
||||||
- 当前 HEAD:`5ffc85077ee7c4ebd52178021d9ac99eed223cd6`
|
|
||||||
- 业务改动检查点:`c820aad feat: 完成项目多模块功能迭代与配置更新`
|
|
||||||
- 检查点说明:`c820aad` 包含当前 `apps/chrg` 多模块业务改动;后续 `5ffc850` 仅新增仓库 README 和死锁修复计划。当前 `apps/chrg` 相对 HEAD 无未提交差异。
|
|
||||||
- 保留的无关工作区文件:`docs/修改计划.md` 为未跟踪文件,本任务未修改、暂存或清理该文件。
|
|
||||||
|
|
||||||
## Git 工作区基线
|
|
||||||
|
|
||||||
执行命令:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
git status --short --branch
|
|
||||||
```
|
|
||||||
|
|
||||||
输出:
|
|
||||||
|
|
||||||
```text
|
|
||||||
## feature
|
|
||||||
?? "docs/\344\277\256\346\224\271\350\256\241\345\210\222.md"
|
|
||||||
```
|
|
||||||
|
|
||||||
执行命令:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
git diff --ignore-space-at-eol --stat -- apps/chrg
|
|
||||||
```
|
|
||||||
|
|
||||||
输出:无输出,表示 `apps/chrg` 相对当前 HEAD 没有未提交差异。
|
|
||||||
|
|
||||||
执行命令:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
git log -5 --oneline --decorate
|
|
||||||
```
|
|
||||||
|
|
||||||
输出:
|
|
||||||
|
|
||||||
```text
|
|
||||||
5ffc850 (HEAD -> feature) docs: 初始化HCDF MID 405充放电控制器固件仓库
|
|
||||||
c820aad feat: 完成项目多模块功能迭代与配置更新
|
|
||||||
250864c (origin/feature) debug north
|
|
||||||
3a413f5 (origin/master, origin/HEAD, master, agents/add-comments-to-sinkc) nor / sou roll
|
|
||||||
7e463e5 add more comments
|
|
||||||
```
|
|
||||||
|
|
||||||
## 修复前构建
|
|
||||||
|
|
||||||
执行命令:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
scons -C apps/chrg -j4
|
|
||||||
```
|
|
||||||
|
|
||||||
结果:**失败,构建环境缺失。**
|
|
||||||
|
|
||||||
```text
|
|
||||||
scons : 无法将“scons”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
|
|
||||||
CategoryInfo : ObjectNotFound: (scons:String) [], CommandNotFoundException
|
|
||||||
FullyQualifiedErrorId : CommandNotFoundException
|
|
||||||
```
|
|
||||||
|
|
||||||
环境复核结果:
|
|
||||||
|
|
||||||
- `scons`:无法取得,未安装或未加入 `PATH`。
|
|
||||||
- Python:系统 `PATH` 中无法取得;Codex 自带 Python 可运行,但未安装 `SCons` 模块。
|
|
||||||
- `arm-none-eabi-gcc`:无法取得,未安装或未加入 `PATH`。
|
|
||||||
- Keil UV4:常用路径 `C:\Keil_v5\UV4\UV4.exe` 及检查的常见安装目录中未找到。
|
|
||||||
- 既有输出:未找到可复用的 `chrg.elf`、`rtthread.bin` 或 `chrg.axf`。
|
|
||||||
- text/data/bss:无法取得,原因是构建未启动。
|
|
||||||
- 镜像大小:无法取得,原因是未生成镜像。
|
|
||||||
- 编译 warning:无法取得,原因是编译器未运行。
|
|
||||||
|
|
||||||
结论:Task 1 的修复前构建验收尚未通过。在具备 SCons 与 Arm GCC 或 Keil MDK 的构建机上补跑同一命令并补录产物尺寸、段大小和全部 warning 前,不应开始功能修改。
|
|
||||||
|
|
||||||
## 故障现场 Shell 快照
|
|
||||||
|
|
||||||
当前会话只有离线源码工作区,没有连接发生故障的 STM32F405 设备、串口或 USB Shell,因此不能执行板上命令。以下项目均显式记录为无法取得,避免将“未采集”误认为正常状态。
|
|
||||||
|
|
||||||
| 命令 | 结果 |
|
|
||||||
| --- | --- |
|
|
||||||
| `list_thread` | 无法取得:当前未连接目标板 Shell,线程状态和栈使用量未知。 |
|
|
||||||
| `list_mutex` | 无法取得:当前未连接目标板 Shell,mutex owner/suspend 未采集。 |
|
|
||||||
| `list_mailbox` | 无法取得:当前未连接目标板 Shell,邮箱 entry 数未采集。 |
|
|
||||||
| `list_event` | 无法取得:当前未连接目标板 Shell,事件状态未采集。 |
|
|
||||||
| `free` | 无法取得:当前未连接目标板 Shell,heap total/used/max-used 未采集。 |
|
|
||||||
| `list_device` | 无法取得:当前未连接目标板 Shell,设备状态未采集。 |
|
|
||||||
|
|
||||||
## 故障特征
|
|
||||||
|
|
||||||
- 首次异常运行时长:无法取得:未提供对应现场运行记录。
|
|
||||||
- 异常时仍工作的接口:无法取得:当前没有现场设备或故障时间点数据。
|
|
||||||
- 最后 100 行日志:无法取得:仓库中未提供本次故障对应的运行日志,当前未连接目标板。
|
|
||||||
- `com batch timeout` 是否连续出现:无法取得:没有现场串口日志。
|
|
||||||
- `free` 的 total/used/max-used:无法取得:当前未连接目标板 Shell。
|
|
||||||
- `thr.rollnor` 和 `thr.rollsou` 状态:无法取得:当前未连接目标板 Shell。
|
|
||||||
- `thr.nor` 和 `thr.sou` 状态:无法取得:当前未连接目标板 Shell。
|
|
||||||
- 最近一次复位原因:无法取得:没有启动日志或 RCC 复位标志快照。
|
|
||||||
|
|
||||||
## 后续补录要求
|
|
||||||
|
|
||||||
1. 在配置完整的构建机上重新执行 `scons -C apps/chrg -j4`,补录工具链版本、text/data/bss、镜像大小和 warning。
|
|
||||||
2. 下次现场复现且 Shell 尚可用时,立即按上述顺序保存六条诊断命令的原始输出和最后 100 行日志。
|
|
||||||
3. 所有后续修复必须基于 `c820aad` 已包含的业务逻辑和当前 HEAD,不得从 `origin/feature` 或 `master` 重新开始。
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,167 +0,0 @@
|
|||||||
# 功率板升级问题与修改计划
|
|
||||||
|
|
||||||
## 1. 升级链路
|
|
||||||
|
|
||||||
```text
|
|
||||||
上位机
|
|
||||||
↓
|
|
||||||
协议板 App
|
|
||||||
↓ 进入升级指令
|
|
||||||
协议板南向 UART
|
|
||||||
↓
|
|
||||||
功率板 Boot
|
|
||||||
↓ 0x06、0x43
|
|
||||||
协议板 App
|
|
||||||
↓
|
|
||||||
上位机
|
|
||||||
进入升级控制帧:
|
|
||||||
03 06 00 0F 00 FF F8 6B
|
|
||||||
跳转 App 控制帧:
|
|
||||||
03 06 00 0F 00 0F F8 2F
|
|
||||||
功率板 Boot 使用裸 BIN + YModem 接收升级数据。
|
|
||||||
2. 已确认的问题
|
|
||||||
2.1 协议板发送日志含义不准确
|
|
||||||
协议板日志:
|
|
||||||
[UPG] CTRL ENTER try=1 tx=0
|
|
||||||
tx=0 只表示发送请求已经提交到南向升级发送流程,不能证明 UART 已经在物理线上发送成功。
|
|
||||||
需要通过串口逻辑分析仪确认实际线路是否出现完整控制帧。
|
|
||||||
2.2 功率板 Boot 控制帧接收依赖一次完整 DMA 回调
|
|
||||||
当前 Boot 主要在以下条件同时满足时识别进入升级帧:
|
|
||||||
received_len == 8
|
|
||||||
usart1_dma_rx_buf[0] == 0x03
|
|
||||||
UPDATE_FRAME_MATCH
|
|
||||||
如果控制帧被 DMA 空闲中断拆成多次接收,当前逻辑可能无法在拼接完成后重新判断控制帧。
|
|
||||||
2.3 功率板 Boot 只有擦除成功后才发送应答
|
|
||||||
处理流程:
|
|
||||||
收到完整控制帧
|
|
||||||
↓
|
|
||||||
Flash_Erase_App_Region()
|
|
||||||
↓
|
|
||||||
擦除成功:发送 0x06、0x43
|
|
||||||
擦除失败:发送 0x15
|
|
||||||
因此:
|
|
||||||
- 完全没有响应:优先检查 UART 接收、帧匹配、通道切换和线路;
|
|
||||||
- 返回 0x15:重点检查 Flash 擦除;
|
|
||||||
- 返回 0x06 但协议板没有收到:检查南向返回线路和协议板接收线程。
|
|
||||||
2.4 Flash 分区注释与实际大小不一致
|
|
||||||
当前配置:
|
|
||||||
APP_FLASH_BASE_ADDR = 0x08003800
|
|
||||||
APP_FLASH_SIZE = 0x0000B000
|
|
||||||
0xB000 实际为 44 KB,而代码注释写成了 40 KB。
|
|
||||||
同时擦除配置为:
|
|
||||||
NbPages = 22
|
|
||||||
PAGE_SIZE = 0x800
|
|
||||||
22 页也是 44 KB。需要确认这是否符合实际功率板 Flash 分区规划。
|
|
||||||
2.5 南向通道和收发方向需要单独确认
|
|
||||||
协议板升级前会执行:
|
|
||||||
chrg_south_switch(ch)
|
|
||||||
串口发送前后还会切换 RS485 收发方向。通道选择错误、方向控制延迟不足或线路未接通,都可能导致功率板无法收到控制帧或协议板收不到 0x06。
|
|
||||||
3. 修改计划
|
|
||||||
3.1 完善功率板 Boot 控制帧接收
|
|
||||||
在 DMA 接收回调中:
|
|
||||||
1. 累积多次接收到的数据;
|
|
||||||
2. 达到 8 字节后统一匹配进入升级帧和跳转帧;
|
|
||||||
3. 匹配成功后设置对应 pending 标志;
|
|
||||||
4. 匹配失败时清理缓存并等待下一帧;
|
|
||||||
5. 增加接收长度和帧内容调试输出,或使用 GPIO 翻转辅助定位。
|
|
||||||
3.2 完善协议板发送状态
|
|
||||||
协议板需要区分:
|
|
||||||
- 发送请求提交成功;
|
|
||||||
- UART 实际发送完成;
|
|
||||||
- 功率板返回 0x06;
|
|
||||||
- 功率板返回 0x15;
|
|
||||||
- 等待超时。
|
|
||||||
日志中应明确打印实际发送长度和发送帧内容。
|
|
||||||
3.3 完善应答重发机制
|
|
||||||
控制帧和 YModem 数据帧均应保留最近一次发送内容:
|
|
||||||
- 等待 ACK 超时后重发;
|
|
||||||
- 收到 NAK 后重发;
|
|
||||||
- 超过最大重试次数后退出升级;
|
|
||||||
- 收到 CAN 后立即中止;
|
|
||||||
- 半帧超时后清理接收缓存并等待下一帧。
|
|
||||||
3.4 核对 Flash 配置
|
|
||||||
需要确认:
|
|
||||||
- 功率板 MCU 型号;
|
|
||||||
- Flash 页面大小;
|
|
||||||
- Boot 起始地址;
|
|
||||||
- App 起始地址;
|
|
||||||
- App 最大容量;
|
|
||||||
- Boot 工程链接地址;
|
|
||||||
- App 工程链接地址;
|
|
||||||
- YModem 文件最大长度。
|
|
||||||
确认后统一修正宏定义、擦除页数和注释。
|
|
||||||
3.5 保持升级状态期间停止普通南向轮询
|
|
||||||
进入升级模式后:
|
|
||||||
- 停止普通 Modbus 轮询;
|
|
||||||
- 锁定目标功率板通道;
|
|
||||||
- 只转发控制帧、YModem 数据帧和单字节应答;
|
|
||||||
- 升级结束或失败后恢复普通轮询。
|
|
||||||
4. 待验证项目
|
|
||||||
4.1 控制帧发送
|
|
||||||
使用逻辑分析仪确认协议板实际发送:
|
|
||||||
03 06 00 0F 00 FF F8 6B
|
|
||||||
确认:
|
|
||||||
- 波特率为 115200;
|
|
||||||
- 数据格式为 8-N-1;
|
|
||||||
- 通道选择正确;
|
|
||||||
- RS485 发送方向正确;
|
|
||||||
- 帧没有被截断。
|
|
||||||
4.2 功率板接收
|
|
||||||
在功率板 Boot 的:
|
|
||||||
HAL_UARTEx_RxEventCallback()
|
|
||||||
检查:
|
|
||||||
Size
|
|
||||||
usart1_dma_rx_buf[0..7]
|
|
||||||
期望:
|
|
||||||
Size = 8
|
|
||||||
03 06 00 0F 00 FF F8 6B
|
|
||||||
4.3 功率板帧处理
|
|
||||||
确认以下变量和流程:
|
|
||||||
g_update_prepare_pending = 1
|
|
||||||
Check_Updata()
|
|
||||||
Ymodem_HandleControlFrame()
|
|
||||||
Flash_Erase_App_Region()
|
|
||||||
记录 Flash 擦除返回值。
|
|
||||||
4.4 功率板应答
|
|
||||||
确认功率板 UART 线上依次发送:
|
|
||||||
06 43
|
|
||||||
其中:
|
|
||||||
- 0x06 表示控制帧处理成功;
|
|
||||||
- 0x43 表示进入 YModem 接收等待。
|
|
||||||
4.5 协议板接收
|
|
||||||
确认协议板南向接收线程能识别:
|
|
||||||
0x06
|
|
||||||
0x15
|
|
||||||
0x43
|
|
||||||
0x18
|
|
||||||
并将应答正确放入 YModem 应答队列。
|
|
||||||
4.6 YModem 数据传输
|
|
||||||
确认:
|
|
||||||
- 上位机发送的是裸 BIN;
|
|
||||||
- 首包为 YModem 元数据包;
|
|
||||||
- 数据包号连续;
|
|
||||||
- 功率板每包返回 0x06;
|
|
||||||
- 丢包或 CRC 错误时返回 0x15;
|
|
||||||
- 重发后包号状态正确;
|
|
||||||
- EOT 流程能够正常结束。
|
|
||||||
4.7 异常场景
|
|
||||||
需要测试:
|
|
||||||
- 控制帧拆包;
|
|
||||||
- 控制帧丢失;
|
|
||||||
- 0x06 丢失;
|
|
||||||
- YModem 数据包丢失;
|
|
||||||
- YModem 数据包 CRC 错误;
|
|
||||||
- 升级中途断电;
|
|
||||||
- 升级中途复位;
|
|
||||||
- BIN 文件超过 App 分区;
|
|
||||||
- Flash 擦除失败;
|
|
||||||
- 跳转帧发送失败。
|
|
||||||
5. 暂停调试时的结论
|
|
||||||
当前暂不进行硬件调试。后续恢复调试时,优先使用逻辑分析仪确认以下最小链路:
|
|
||||||
协议板发送控制帧
|
|
||||||
→ 功率板 DMA 收到 8 字节
|
|
||||||
→ 功率板识别控制帧
|
|
||||||
→ Flash 擦除成功
|
|
||||||
→ 功率板发送 0x06
|
|
||||||
→ 协议板接收到 0x06
|
|
||||||
只有这条链路确认成功后,再继续验证 YModem 数据包传输。
|
|
||||||
-111
@@ -1,111 +0,0 @@
|
|||||||
静态排查后,暂未看到明确的 ABBA 型互斥锁环。当前现象更像“内存破坏/资源泄漏后线程停滞”或“状态机无限重试”,而不是整个 RTOS 调度器死锁。
|
|
||||||
|
|
||||||
另外,代码中使用的是 STM32 内部 IWDG,不是外部独立看门狗。
|
|
||||||
|
|
||||||
**可疑点**
|
|
||||||
|
|
||||||
1. **高风险:南北向分包接收存在确定的越界写和泄漏路径**
|
|
||||||
|
|
||||||
[north](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_north.c:548) 和 [south](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_south.c:309) 在续接分包时计算:
|
|
||||||
|
|
||||||
```text
|
|
||||||
len_need = len_msg - 帧头长度
|
|
||||||
```
|
|
||||||
|
|
||||||
但此时 `pFrame->length` 已经包含之前收到的数据,正确的剩余长度应基于 `len_msg - pFrame->length`。当前代码却从 `payload[pFrame->length]` 开始写入整个“帧头后的总长度”。
|
|
||||||
|
|
||||||
例如总长 21 字节,首批已存 8 字节,下一次仍可能从偏移 8 写入 18 字节,最终写到偏移 26,越过 21 字节堆块。这会破坏相邻堆块、邮箱消息甚至 RT-Thread 内核对象,最终表现为随机线程卡死、互斥量异常或堆分配失败。
|
|
||||||
|
|
||||||
同时,分包超时路径只清除了 `findhead`:
|
|
||||||
|
|
||||||
- [chrg_north.c:627](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_north.c:627)
|
|
||||||
- [chrg_south.c:399](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_south.c:399)
|
|
||||||
|
|
||||||
没有释放 `pMB/payload`,也没有清除 `length/len_msg`。而且没有新数据时会提前 `continue`,超时检查根本不会执行。串口噪声、丢字节或正常分包都可能不断积累泄漏。
|
|
||||||
|
|
||||||
此外,payload 分配失败时只返回,没有释放刚分配的 `pMB`:
|
|
||||||
|
|
||||||
- [chrg_north.c:518](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_north.c:518)
|
|
||||||
- [chrg_south.c:280](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_south.c:280)
|
|
||||||
|
|
||||||
这是目前最符合“运行时间越长越容易出现”的可疑点。
|
|
||||||
|
|
||||||
2. **高风险:看门狗喂法无法覆盖业务线程死锁**
|
|
||||||
|
|
||||||
主线程每秒无条件喂狗:[main.c:36](D:/proj/char/chrg_v/apps/chrg/applications/main.c:36)。
|
|
||||||
|
|
||||||
北向轮询线程又在每轮无条件喂同一只狗:[chrg_roll_nor.c:421](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_roll_nor.c:421)。
|
|
||||||
|
|
||||||
因此即使 `thr.comm`、`thr.sou`、`thr.rollsou`、LCD 线程全部停止工作,只要主线程或北向轮询线程仍能调度,IWDG 就永远不会复位。这只是在检测“CPU/调度器是否完全停止”,没有检测业务线程是否健康。
|
|
||||||
|
|
||||||
驱动最终调用的是 `HAL_IWDG_Refresh()`:[drv_wdt.c:40](D:/proj/char/chrg_v/rt-thread/bsp/stm32/libraries/HAL_Drivers/drivers/drv_wdt.c:40)。代码中没有找到外部 WDI 引脚翻转或外部看门狗驱动。
|
|
||||||
|
|
||||||
3. **高风险:当前新增的南向批处理可能永久停在 `RUN_COM`**
|
|
||||||
|
|
||||||
南向批处理遇到 CRC 错误或应答超时后,不增加重试次数、不设置截止时间,也不清除任务:
|
|
||||||
|
|
||||||
- CRC 错误:[chrg_roll_sou.c:608](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_roll_sou.c:608)
|
|
||||||
- 应答超时:[chrg_roll_sou.c:627](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_roll_sou.c:627)
|
|
||||||
|
|
||||||
线程会一直重发同一个寄存器,`pending` 永远不清除,`run` 永远保持 `RUN_COM`,正常南向轮询无法恢复。这属于业务状态机死锁,调度器仍正常运行,所以看门狗不会复位。
|
|
||||||
|
|
||||||
这套批处理逻辑是当前工作区相对 `HEAD` 新增的,优先级很高。
|
|
||||||
|
|
||||||
4. **高风险:南向共享状态的互斥保护实际无效**
|
|
||||||
|
|
||||||
[chrg_set_sou_reg](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_roll_sou.c:435) 先在锁外写入:
|
|
||||||
|
|
||||||
```text
|
|
||||||
pROLL->ch
|
|
||||||
pROLL->reg
|
|
||||||
pROLL->value
|
|
||||||
```
|
|
||||||
|
|
||||||
随后互斥量只保护 `pROLL->run`。消费者也只在锁内读取 `run`,实际使用 `ch/reg/value` 时已经离开锁。
|
|
||||||
|
|
||||||
多个生产者包括 LCD、Modbus 和状态机可能交叉覆盖这些字段,形成“通道来自命令 A、寄存器来自命令 B、值来自命令 C”的组合。
|
|
||||||
|
|
||||||
批处理数组 `g_sou_com_batch` 同样由生产者和 `thr.rollsou` 同时读写,却没有共同的锁:[chrg_roll_sou.c:394](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_roll_sou.c:394)。
|
|
||||||
|
|
||||||
5. **中高风险:先切换 `RUN_COM`,再填充批处理数据**
|
|
||||||
|
|
||||||
[chrg_sink_diff_send_reg](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_comm.c:2338) 先调用 `chrg_sou_com_sou_set()` 将状态切到 `RUN_COM`,然后才追加寄存器。
|
|
||||||
|
|
||||||
`chrg_sink_work()` 也是相同顺序:[chrg_sink.c:541](D:/proj/char/chrg_v/apps/chrg/applications/utils/chrg_sink.c:541)。
|
|
||||||
|
|
||||||
如果消费者在状态切换后看到尚未填充的批次,会认为没有任务并切回自动模式;随后加入的 `pending` 数据可能一直无人处理。当前线程优先级降低了部分窗口概率,但没有从同步机制上消除竞态。
|
|
||||||
|
|
||||||
6. **中高风险:应答邮箱没有请求、通道或序号关联**
|
|
||||||
|
|
||||||
邮箱消息只有 `length + payload`:[chrg_def.h:95](D:/proj/char/chrg_v/apps/chrg/applications/utils/chrg_def.h:95)。
|
|
||||||
|
|
||||||
南北轮询线程默认“收到的下一帧就是刚才请求的响应”。南向批处理只检查 CRC,任何延迟到达的旧响应都可能让当前批次 `cur_idx++`:[chrg_roll_sou.c:574](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_roll_sou.c:574)。
|
|
||||||
|
|
||||||
在超时、重发、通道切换或邮箱积压后,请求与响应很容易错位,最终造成状态机停在错误步骤或无限重试。
|
|
||||||
|
|
||||||
7. **中风险:所有业务互斥量都是永久等待**
|
|
||||||
|
|
||||||
TTY、南北轮询互斥量统一使用 `RT_WAITING_FOREVER`。例如:
|
|
||||||
|
|
||||||
- [chrg_tty.c:457](D:/proj/char/chrg_v/apps/chrg/applications/bsp/chrg_tty.c:457)
|
|
||||||
- [chrg_comm.c:2246](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_comm.c:2246)
|
|
||||||
- [chrg_roll_nor.c:439](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_roll_nor.c:439)
|
|
||||||
|
|
||||||
目前没有发现确定的反向加锁环,但一旦锁所有者因堆破坏、状态机卡死或设备写阻塞而不再释放,其他线程会永久挂起,没有超时和故障上报。
|
|
||||||
|
|
||||||
8. **中风险:串口 RingBuffer 写入结果被忽略**
|
|
||||||
|
|
||||||
[chrg_north.c:623](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_north.c:623) 和 [chrg_south.c:383](D:/proj/char/chrg_v/apps/chrg/applications/thread/chrg_south.c:383) 没有检查 `rt_ringbuffer_put()` 实际写入长度。
|
|
||||||
|
|
||||||
缓冲区满时会静默丢字节,随后触发分包超时、泄漏和上述越界路径,是长期运行后出现问题的重要放大器。
|
|
||||||
|
|
||||||
**优先判断**
|
|
||||||
|
|
||||||
最可能的两条故障链是:
|
|
||||||
|
|
||||||
1. 串口分包 → 长度计算错误/超时泄漏 → 堆损坏或耗尽 → 某些业务线程永久等待;主线程继续喂狗。
|
|
||||||
2. 南向某条命令超时或响应错位 → `RUN_COM` 无限重发 → 南向业务永久停止;主线程和北向线程继续喂狗。
|
|
||||||
|
|
||||||
现场故障尚能进入 Shell 时,优先保存 `list_thread`、`list_mutex`、`list_mailbox`、`free` 输出,并检查是否持续打印 `com batch timeout, resend current reg`。这几项可以直接区分锁等待、堆耗尽和状态机无限重试。
|
|
||||||
|
|
||||||
未修改任何文件。
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user