栈整改不抬栈:删旧档迁移、FIL静态化、日志行缓冲按模块收紧、钩子脱离HAL,defaultTask链5312→2776B
This commit is contained in:
+1
-1
@@ -80,7 +80,7 @@ docs/
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
| [`配置文件设计说明.md`](子系统设计/配置文件设计说明.md) | `/config.ini` 配置引擎:分层、解析、持久化与旧档迁移 |
|
||||
| [`配置文件设计说明.md`](子系统设计/配置文件设计说明.md) | `/config.ini` 配置引擎:分层、解析、原子持久化(旧 NCFG 档已废弃) |
|
||||
| [`网络配置说明.md`](子系统设计/网络配置说明.md) | 网口设置页:IP/掩码/网关,UI 保存即时生效 |
|
||||
| [`系统墙钟时间维护说明.md`](子系统设计/系统墙钟时间维护说明.md) | `sys_clock`:RTC 基准、tick 回绕防护、30 天惰性再基准化 |
|
||||
| [`控制台单写者日志设计说明.md`](子系统设计/控制台单写者日志设计说明.md) | 控制台日志单写者模型(避免多任务交错输出) |
|
||||
|
||||
+14
-14
@@ -8,39 +8,39 @@
|
||||
</style>
|
||||
</defs>
|
||||
<text x="440.0" y="22" text-anchor="middle" class="title">FreeRTOS 任务栈预算(48KB 堆,2026-09-21 已迁 CCM)</text>
|
||||
<text x="440.0" y="40" text-anchor="middle" class="legend-text" fill="#777">数据: 2026-09-21 @build + FTP 128KB 实测(data/stack_report_20260921.md)</text>
|
||||
<text x="440.0" y="40" text-anchor="middle" class="legend-text" fill="#777">数据: 2026-10-10 @build + 开机/空闲实测(data/stack_report_20261010.md);最坏 = max(静态最坏链, 实测峰值)</text>
|
||||
<text x="190" y="54" class="legend-text" fill="#555">浅色条 = 分配栈 深色条 = 最坏占用(max(静态最坏, 实测峰值)) 下方文字 = 实测余量/判定</text>
|
||||
<text x="186" y="72" text-anchor="end" dominant-baseline="central" class="label" fill="#333">defaultTask</text>
|
||||
<rect class="bar-seg" x="190" y="64" width="162.5" height="16" fill="#BBDEFB" rx="3"/>
|
||||
<rect x="190" y="64" width="110.1" height="16" fill="#2196F3" rx="3"/>
|
||||
<text x="190" y="91" dominant-baseline="central" class="legend-text" fill="#333">配置 4096B | 实测峰值 2136B | 最坏 2776B | 余量 1320B (32%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="190" y="91" dominant-baseline="central" class="legend-text" fill="#333">配置 4096B | 实测峰值 2152B | 最坏 2776B | 余量 1320B (32%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="186" y="112" text-anchor="end" dominant-baseline="central" class="label" fill="#333">netTask</text>
|
||||
<rect class="bar-seg" x="190" y="104" width="162.5" height="16" fill="#BBDEFB" rx="3"/>
|
||||
<rect x="190" y="104" width="23.3" height="16" fill="#2196F3" rx="3"/>
|
||||
<text x="190" y="131" dominant-baseline="central" class="legend-text" fill="#333">配置 4096B | 实测峰值 588B | 最坏 588B | 余量 3508B (85%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<rect class="bar-seg" x="190" y="104" width="152.3" height="16" fill="#BBDEFB" rx="3"/>
|
||||
<rect x="190" y="104" width="74.3" height="16" fill="#2196F3" rx="3"/>
|
||||
<text x="190" y="131" dominant-baseline="central" class="legend-text" fill="#333">配置 3840B | 实测峰值 920B | 最坏 1872B | 余量 1968B (51%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="186" y="152" text-anchor="end" dominant-baseline="central" class="label" fill="#333">ftpTask</text>
|
||||
<rect class="bar-seg" x="190" y="144" width="162.5" height="16" fill="#BBDEFB" rx="3"/>
|
||||
<rect x="190" y="144" width="47.0" height="16" fill="#2196F3" rx="3"/>
|
||||
<text x="190" y="171" dominant-baseline="central" class="legend-text" fill="#333">配置 4096B | 实测峰值 1184B | 最坏 1184B | 余量 2912B (71%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<rect x="190" y="144" width="48.2" height="16" fill="#2196F3" rx="3"/>
|
||||
<text x="190" y="171" dominant-baseline="central" class="legend-text" fill="#333">配置 4096B | 实测峰值 740B | 最坏 1216B | 余量 2880B (70%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="186" y="192" text-anchor="end" dominant-baseline="central" class="label" fill="#333">testTask</text>
|
||||
<rect class="bar-seg" x="190" y="184" width="325.0" height="16" fill="#FFE0B2" rx="3"/>
|
||||
<rect x="190" y="184" width="13.8" height="16" fill="#FF9800" rx="3"/>
|
||||
<text x="190" y="211" dominant-baseline="central" class="legend-text" fill="#333">配置 8192B | 实测峰值 348B | 最坏 348B | 余量 7844B (95%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<rect x="190" y="184" width="19.7" height="16" fill="#FF9800" rx="3"/>
|
||||
<text x="190" y="211" dominant-baseline="central" class="legend-text" fill="#333">配置 8192B | 实测峰值 496B | 最坏 496B | 余量 7696B (93%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="186" y="232" text-anchor="end" dominant-baseline="central" class="label" fill="#333">uiTask</text>
|
||||
<rect class="bar-seg" x="190" y="224" width="650.0" height="16" fill="#FFE0B2" rx="3"/>
|
||||
<rect x="190" y="224" width="151.7" height="16" fill="#FF9800" rx="3"/>
|
||||
<text x="190" y="251" dominant-baseline="central" class="legend-text" fill="#333">配置 16384B | 实测峰值 3824B | 最坏 3824B | 余量 12560B (76%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<rect x="190" y="224" width="159.3" height="16" fill="#FF9800" rx="3"/>
|
||||
<text x="190" y="251" dominant-baseline="central" class="legend-text" fill="#333">配置 16384B | 实测峰值 4016B | 最坏 4016B | 余量 12368B (75%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="186" y="272" text-anchor="end" dominant-baseline="central" class="label" fill="#333">timeSyncTask</text>
|
||||
<rect class="bar-seg" x="190" y="264" width="81.2" height="16" fill="#BBDEFB" rx="3"/>
|
||||
<rect x="190" y="264" width="16.7" height="16" fill="#2196F3" rx="3"/>
|
||||
<text x="190" y="291" dominant-baseline="central" class="legend-text" fill="#333">配置 2048B | 实测峰值 420B | 最坏 420B | 余量 1628B (79%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<rect x="190" y="264" width="40.6" height="16" fill="#2196F3" rx="3"/>
|
||||
<text x="190" y="291" dominant-baseline="central" class="legend-text" fill="#333">配置 2048B | 实测峰值 616B | 最坏 1024B | 余量 1024B (50%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="186" y="314" text-anchor="end" dominant-baseline="central" class="label" fill="#333">idle</text>
|
||||
<rect class="bar-seg" x="190" y="308" width="20.3" height="12" fill="#90A4AE" rx="2"/>
|
||||
<text x="214.3125" y="314" dominant-baseline="central" class="legend-text" fill="#333">512B(未实测)</text>
|
||||
<text x="186" y="336" text-anchor="end" dominant-baseline="central" class="label" fill="#333">timer</text>
|
||||
<rect class="bar-seg" x="190" y="330" width="40.6" height="12" fill="#90A4AE" rx="2"/>
|
||||
<text x="234.625" y="336" dominant-baseline="central" class="legend-text" fill="#333">1024B(未实测)</text>
|
||||
<text x="190" y="360" class="label" fill="#555">堆总量: 49152B (48KB, RW_CCM) 任务栈合计: 38912B (38.0KB) + 内核栈 1536B</text>
|
||||
<text x="190" y="360" class="label" fill="#555">堆总量: 49152B (48KB, RW_CCM) 任务栈合计: 38656B (37.8KB) + 内核栈 1536B</text>
|
||||
<text x="190" y="376" class="label" fill="#555">实测: free=8784B / min_ever=4848B(2026-09-21,含 FTP 负载) 判定: 6/6 PASS(余量 ≥ max(1024B, 配置×30%))</text>
|
||||
<rect x="190" y="400" width="10" height="10" fill="#2196F3" rx="2"/>
|
||||
<text x="204" y="408" class="legend-text" fill="#333">Normal 优先级</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
+11
-10
@@ -47,8 +47,6 @@ digraph refgraph_full {
|
||||
"Drivers/BSP/NET/net_types.h" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Drivers/BSP/NETCFG/net_cfg.c" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Drivers/BSP/NETCFG/net_cfg.h" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Drivers/BSP/NETCFG/net_cfg_legacy.c" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Drivers/BSP/NETCFG/net_cfg_legacy.h" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Drivers/BSP/RS485/rs485.c" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Drivers/BSP/RS485/rs485.h" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Drivers/BSP/SD2506/sd2506.c" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
@@ -93,6 +91,7 @@ digraph refgraph_full {
|
||||
"Drivers/BSP/dbg_log.h" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" [fillcolor="#f3f4f6", color="#9ca3af"];
|
||||
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h" [fillcolor="#f3f4f6", color="#9ca3af"];
|
||||
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h" [fillcolor="#f3f4f6", color="#9ca3af"];
|
||||
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h" [fillcolor="#f3f4f6", color="#9ca3af"];
|
||||
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h" [fillcolor="#f3f4f6", color="#9ca3af"];
|
||||
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h" [fillcolor="#f3f4f6", color="#9ca3af"];
|
||||
@@ -106,6 +105,7 @@ digraph refgraph_full {
|
||||
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h" [fillcolor="#f3f4f6", color="#9ca3af"];
|
||||
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h" [fillcolor="#f3f4f6", color="#9ca3af"];
|
||||
"Inc/FreeRTOSConfig.h" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Inc/adc.h" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Inc/dma.h" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Inc/gpio.h" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Inc/i2c.h" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
@@ -124,6 +124,7 @@ digraph refgraph_full {
|
||||
"Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h" [fillcolor="#f3f4f6", color="#9ca3af"];
|
||||
"Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h" [fillcolor="#f3f4f6", color="#9ca3af"];
|
||||
"Middlewares/Third_Party/FreeRTOS/Source/include/task.h" [fillcolor="#f3f4f6", color="#9ca3af"];
|
||||
"Src/adc.c" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Src/dma.c" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Src/freertos.c" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
"Src/gpio.c" [fillcolor="#dbeafe", color="#1d4ed8"];
|
||||
@@ -207,7 +208,6 @@ digraph refgraph_full {
|
||||
"App/fs/vol_lock.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
|
||||
"App/log/console_log.c" -> "App/app/sys_events.h" [color="#2563eb", penwidth=1.0];
|
||||
"App/log/console_log.c" -> "App/log/console_log.h" [color="#2563eb", penwidth=1.0];
|
||||
"App/log/console_log.c" -> "App/log/sys_log.h" [color="#2563eb", penwidth=1.0];
|
||||
"App/log/console_log.c" -> "Inc/usart.h" [color="#2563eb", penwidth=1.0];
|
||||
"App/log/console_log.c" -> "Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h" [color="#94a3b8", penwidth=0.7];
|
||||
"App/log/console_log.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h" [color="#94a3b8", penwidth=0.7];
|
||||
@@ -343,16 +343,9 @@ digraph refgraph_full {
|
||||
"Drivers/BSP/NET/net_types.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
|
||||
"Drivers/BSP/NETCFG/net_cfg.c" -> "App/cfg/cfg_file.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/NETCFG/net_cfg.c" -> "Drivers/BSP/NETCFG/net_cfg.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/NETCFG/net_cfg.c" -> "Drivers/BSP/NETCFG/net_cfg_legacy.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/NETCFG/net_cfg.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/NETCFG/net_cfg.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
|
||||
"Drivers/BSP/NETCFG/net_cfg.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
|
||||
"Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "App/cfg/cfg_file.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "App/cfg/cfg_file_store.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "Drivers/BSP/NETCFG/net_cfg.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "Drivers/BSP/NETCFG/net_cfg_legacy.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
|
||||
"Drivers/BSP/RS485/rs485.c" -> "Drivers/BSP/RS485/rs485.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/RS485/rs485.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/SD2506/sd2506.c" -> "Drivers/BSP/SD2506/sd2506.h" [color="#2563eb", penwidth=1.0];
|
||||
@@ -363,6 +356,9 @@ digraph refgraph_full {
|
||||
"Drivers/BSP/TPAFE5160/tpafe5160.c" -> "Drivers/BSP/TPAFE5160/tpafe5160.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/TPAFE5160/tpafe5160.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/TPAFE5160/tpafe5160.c" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/TPAFE5160/tpafe5160.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h" [color="#94a3b8", penwidth=0.7];
|
||||
"Drivers/BSP/TPAFE5160/tpafe5160.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/task.h" [color="#94a3b8", penwidth=0.7];
|
||||
"Drivers/BSP/TPAFE5160/tpafe5160.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
|
||||
"Drivers/BSP/TPAFE5160/tpafe5160.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/UI/ui_content_page.c" -> "Drivers/BSP/UI/ui_content_page.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/UI/ui_content_page.c" -> "Drivers/BSP/UI/ui_deco.h" [color="#2563eb", penwidth=1.0];
|
||||
@@ -409,6 +405,7 @@ digraph refgraph_full {
|
||||
"Drivers/BSP/UI/ui_net_sink.c" -> "Drivers/BSP/NET/net_types.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/UI/ui_net_sink.c" -> "Drivers/BSP/UI/ui_net_sink.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/UI/ui_net_sink.c" -> "Drivers/BSP/UI/ui_net_sink_backend.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/UI/ui_net_sink.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/UI/ui_net_sink.c" -> "test/board/net_latency_test.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/UI/ui_net_sink.c" -> "test/board/test_config.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/UI/ui_net_sink.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
|
||||
@@ -456,12 +453,14 @@ digraph refgraph_full {
|
||||
"Drivers/BSP/dbg_log.h" -> "Drivers/BSP/dbg_cfg.h" [color="#2563eb", penwidth=1.0];
|
||||
"Drivers/BSP/dbg_log.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
|
||||
"Inc/FreeRTOSConfig.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
|
||||
"Inc/adc.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
|
||||
"Inc/dma.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
|
||||
"Inc/gpio.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
|
||||
"Inc/i2c.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
|
||||
"Inc/iwdg.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
|
||||
"Inc/main.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h" [color="#94a3b8", penwidth=0.7];
|
||||
"Inc/spi.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
|
||||
"Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h" [color="#94a3b8", penwidth=0.7];
|
||||
"Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h" [color="#94a3b8", penwidth=0.7];
|
||||
"Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h" [color="#94a3b8", penwidth=0.7];
|
||||
"Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h" [color="#94a3b8", penwidth=0.7];
|
||||
@@ -476,6 +475,7 @@ digraph refgraph_full {
|
||||
"Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h" [color="#94a3b8", penwidth=0.7];
|
||||
"Inc/stm32f4xx_hal_conf.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
|
||||
"Inc/usart.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
|
||||
"Src/adc.c" -> "Inc/adc.h" [color="#2563eb", penwidth=1.0];
|
||||
"Src/dma.c" -> "Inc/dma.h" [color="#2563eb", penwidth=1.0];
|
||||
"Src/freertos.c" -> "App/app/sys_events.h" [color="#2563eb", penwidth=1.0];
|
||||
"Src/freertos.c" -> "App/sync/time_sync.h" [color="#2563eb", penwidth=1.0];
|
||||
@@ -508,6 +508,7 @@ digraph refgraph_full {
|
||||
"Src/main.c" -> "Drivers/BSP/SD2506/sd2506.h" [color="#2563eb", penwidth=1.0];
|
||||
"Src/main.c" -> "Drivers/BSP/TPAFE5160/tpafe5160.h" [color="#2563eb", penwidth=1.0];
|
||||
"Src/main.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
|
||||
"Src/main.c" -> "Inc/adc.h" [color="#2563eb", penwidth=1.0];
|
||||
"Src/main.c" -> "Inc/dma.h" [color="#2563eb", penwidth=1.0];
|
||||
"Src/main.c" -> "Inc/gpio.h" [color="#2563eb", penwidth=1.0];
|
||||
"Src/main.c" -> "Inc/i2c.h" [color="#2563eb", penwidth=1.0];
|
||||
|
||||
+123
-68
@@ -221,14 +221,6 @@
|
||||
"path": "Drivers/BSP/NETCFG/net_cfg.h",
|
||||
"class": "fp"
|
||||
},
|
||||
{
|
||||
"path": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
|
||||
"class": "fp"
|
||||
},
|
||||
{
|
||||
"path": "Drivers/BSP/NETCFG/net_cfg_legacy.h",
|
||||
"class": "fp"
|
||||
},
|
||||
{
|
||||
"path": "Drivers/BSP/RS485/rs485.c",
|
||||
"class": "fp"
|
||||
@@ -537,6 +529,14 @@
|
||||
"path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h",
|
||||
"class": "tp"
|
||||
},
|
||||
{
|
||||
"path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h",
|
||||
"class": "tp"
|
||||
},
|
||||
{
|
||||
"path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h",
|
||||
"class": "tp"
|
||||
},
|
||||
{
|
||||
"path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h",
|
||||
"class": "tp"
|
||||
@@ -621,6 +621,10 @@
|
||||
"path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h",
|
||||
"class": "tp"
|
||||
},
|
||||
{
|
||||
"path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h",
|
||||
"class": "tp"
|
||||
},
|
||||
{
|
||||
"path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_bus.h",
|
||||
"class": "tp"
|
||||
@@ -677,6 +681,14 @@
|
||||
"path": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c",
|
||||
"class": "tp"
|
||||
},
|
||||
{
|
||||
"path": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c",
|
||||
"class": "tp"
|
||||
},
|
||||
{
|
||||
"path": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c",
|
||||
"class": "tp"
|
||||
},
|
||||
{
|
||||
"path": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c",
|
||||
"class": "tp"
|
||||
@@ -757,6 +769,10 @@
|
||||
"path": "Inc/FreeRTOSConfig.h",
|
||||
"class": "fp"
|
||||
},
|
||||
{
|
||||
"path": "Inc/adc.h",
|
||||
"class": "fp"
|
||||
},
|
||||
{
|
||||
"path": "Inc/dma.h",
|
||||
"class": "fp"
|
||||
@@ -4725,6 +4741,10 @@
|
||||
"path": "Middlewares/Third_Party/FreeRTOS/Source/timers.c",
|
||||
"class": "tp"
|
||||
},
|
||||
{
|
||||
"path": "Src/adc.c",
|
||||
"class": "fp"
|
||||
},
|
||||
{
|
||||
"path": "Src/dma.c",
|
||||
"class": "fp"
|
||||
@@ -5883,12 +5903,6 @@
|
||||
"kind": "fp-fp",
|
||||
"include": "sys_events.h"
|
||||
},
|
||||
{
|
||||
"from": "App/log/console_log.c",
|
||||
"to": "App/log/sys_log.h",
|
||||
"kind": "fp-fp",
|
||||
"include": "sys_log.h"
|
||||
},
|
||||
{
|
||||
"from": "App/log/console_log.h",
|
||||
"to": "外部/系统头文件",
|
||||
@@ -7029,12 +7043,6 @@
|
||||
"kind": "fp-fp",
|
||||
"include": "net_cfg.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/NETCFG/net_cfg.c",
|
||||
"to": "Drivers/BSP/NETCFG/net_cfg_legacy.h",
|
||||
"kind": "fp-fp",
|
||||
"include": "net_cfg_legacy.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/NETCFG/net_cfg.c",
|
||||
"to": "App/cfg/cfg_file.h",
|
||||
@@ -7059,42 +7067,6 @@
|
||||
"kind": "fp-ext",
|
||||
"include": "stddef.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
|
||||
"to": "外部/系统头文件",
|
||||
"kind": "fp-ext",
|
||||
"include": "string.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
|
||||
"to": "Drivers/BSP/NETCFG/net_cfg_legacy.h",
|
||||
"kind": "fp-fp",
|
||||
"include": "net_cfg_legacy.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
|
||||
"to": "Drivers/BSP/NETCFG/net_cfg.h",
|
||||
"kind": "fp-fp",
|
||||
"include": "net_cfg.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
|
||||
"to": "App/cfg/cfg_file.h",
|
||||
"kind": "fp-fp",
|
||||
"include": "cfg_file.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
|
||||
"to": "App/cfg/cfg_file_store.h",
|
||||
"kind": "fp-fp",
|
||||
"include": "cfg_file_store.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
|
||||
"to": "Drivers/BSP/dbg_log.h",
|
||||
"kind": "fp-fp",
|
||||
"include": "dbg_log.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/RS485/rs485.c",
|
||||
"to": "Drivers/BSP/RS485/rs485.h",
|
||||
@@ -7143,6 +7115,12 @@
|
||||
"kind": "fp-fp",
|
||||
"include": "main.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/TPAFE5160/tpafe5160.c",
|
||||
"to": "外部/系统头文件",
|
||||
"kind": "fp-ext",
|
||||
"include": "string.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/TPAFE5160/tpafe5160.c",
|
||||
"to": "Drivers/BSP/TPAFE5160/tpafe5160.h",
|
||||
@@ -7155,6 +7133,18 @@
|
||||
"kind": "fp-fp",
|
||||
"include": "main.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/TPAFE5160/tpafe5160.c",
|
||||
"to": "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h",
|
||||
"kind": "fp-tp",
|
||||
"include": "FreeRTOS.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/TPAFE5160/tpafe5160.c",
|
||||
"to": "Middlewares/Third_Party/FreeRTOS/Source/include/task.h",
|
||||
"kind": "fp-tp",
|
||||
"include": "task.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/TPAFE5160/tpafe5160.c",
|
||||
"to": "Drivers/BSP/dbg_log.h",
|
||||
@@ -7473,6 +7463,12 @@
|
||||
"kind": "fp-fp",
|
||||
"include": "net_latency_test.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/UI/ui_net_sink.c",
|
||||
"to": "Drivers/BSP/dbg_log.h",
|
||||
"kind": "fp-fp",
|
||||
"include": "dbg_log.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/BSP/UI/ui_net_sink.h",
|
||||
"to": "外部/系统头文件",
|
||||
@@ -8397,6 +8393,30 @@
|
||||
"kind": "tp-tp",
|
||||
"include": "stm32f4xx_hal_conf.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h",
|
||||
"to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h",
|
||||
"kind": "tp-tp",
|
||||
"include": "stm32f4xx_hal_def.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h",
|
||||
"to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h",
|
||||
"kind": "tp-tp",
|
||||
"include": "stm32f4xx_ll_adc.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h",
|
||||
"to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h",
|
||||
"kind": "tp-tp",
|
||||
"include": "stm32f4xx_hal_adc_ex.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h",
|
||||
"to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h",
|
||||
"kind": "tp-tp",
|
||||
"include": "stm32f4xx_hal_def.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h",
|
||||
"to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h",
|
||||
@@ -8583,6 +8603,12 @@
|
||||
"kind": "tp-tp",
|
||||
"include": "stm32f4xx_hal_def.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h",
|
||||
"to": "Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h",
|
||||
"kind": "tp-tp",
|
||||
"include": "stm32f4xx.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_bus.h",
|
||||
"to": "Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h",
|
||||
@@ -8667,6 +8693,18 @@
|
||||
"kind": "tp-tp",
|
||||
"include": "stm32f4xx_hal.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c",
|
||||
"to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h",
|
||||
"kind": "tp-tp",
|
||||
"include": "stm32f4xx_hal.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c",
|
||||
"to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h",
|
||||
"kind": "tp-tp",
|
||||
"include": "stm32f4xx_hal.h"
|
||||
},
|
||||
{
|
||||
"from": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c",
|
||||
"to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h",
|
||||
@@ -8787,6 +8825,12 @@
|
||||
"kind": "fp-ext",
|
||||
"include": "stdint.h"
|
||||
},
|
||||
{
|
||||
"from": "Inc/adc.h",
|
||||
"to": "Inc/main.h",
|
||||
"kind": "fp-fp",
|
||||
"include": "main.h"
|
||||
},
|
||||
{
|
||||
"from": "Inc/dma.h",
|
||||
"to": "Inc/main.h",
|
||||
@@ -8855,8 +8899,8 @@
|
||||
},
|
||||
{
|
||||
"from": "Inc/stm32f4xx_hal_conf.h",
|
||||
"to": "外部/系统头文件",
|
||||
"kind": "fp-ext",
|
||||
"to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h",
|
||||
"kind": "fp-tp",
|
||||
"include": "stm32f4xx_hal_adc.h"
|
||||
},
|
||||
{
|
||||
@@ -38853,6 +38897,12 @@
|
||||
"kind": "fp-tp",
|
||||
"include": "lvgl.h"
|
||||
},
|
||||
{
|
||||
"from": "Src/adc.c",
|
||||
"to": "Inc/adc.h",
|
||||
"kind": "fp-fp",
|
||||
"include": "adc.h"
|
||||
},
|
||||
{
|
||||
"from": "Src/dma.c",
|
||||
"to": "Inc/dma.h",
|
||||
@@ -38991,6 +39041,12 @@
|
||||
"kind": "fp-tp",
|
||||
"include": "cmsis_os.h"
|
||||
},
|
||||
{
|
||||
"from": "Src/main.c",
|
||||
"to": "Inc/adc.h",
|
||||
"kind": "fp-fp",
|
||||
"include": "adc.h"
|
||||
},
|
||||
{
|
||||
"from": "Src/main.c",
|
||||
"to": "Inc/dma.h",
|
||||
@@ -39970,13 +40026,13 @@
|
||||
"stddef.h",
|
||||
"stdint.h"
|
||||
],
|
||||
"Drivers/BSP/NETCFG/net_cfg_legacy.c": [
|
||||
"string.h"
|
||||
],
|
||||
"Drivers/BSP/SD2506/sd2506.c": [
|
||||
"stdio.h",
|
||||
"string.h"
|
||||
],
|
||||
"Drivers/BSP/TPAFE5160/tpafe5160.c": [
|
||||
"string.h"
|
||||
],
|
||||
"Drivers/BSP/UI/ui_content_page.c": [
|
||||
"string.h"
|
||||
],
|
||||
@@ -40145,7 +40201,6 @@
|
||||
"stdint.h"
|
||||
],
|
||||
"Inc/stm32f4xx_hal_conf.h": [
|
||||
"stm32f4xx_hal_adc.h",
|
||||
"stm32f4xx_hal_can.h",
|
||||
"stm32f4xx_hal_can_legacy.h",
|
||||
"stm32f4xx_hal_cec.h",
|
||||
@@ -41600,13 +41655,13 @@
|
||||
]
|
||||
},
|
||||
"stats": {
|
||||
"files_indexed": 1420,
|
||||
"includes_parsed": 5700,
|
||||
"resolved": 4630,
|
||||
"unresolved": 1070,
|
||||
"files_indexed": 1425,
|
||||
"includes_parsed": 5706,
|
||||
"resolved": 4637,
|
||||
"unresolved": 1069,
|
||||
"nodes_fp": 147,
|
||||
"nodes_tp": 1259,
|
||||
"ext_names": 352
|
||||
"nodes_tp": 1264,
|
||||
"ext_names": 351
|
||||
},
|
||||
"include_dirs": [
|
||||
"Inc",
|
||||
|
||||
+1762
-1756
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 358 KiB After Width: | Height: | Size: 361 KiB |
@@ -87,17 +87,19 @@ digraph refgraph_module {
|
||||
"BSP/NET" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×2"];
|
||||
"BSP/NET" -> "test" [color="#2563eb", penwidth=1.2, label="×2"];
|
||||
"BSP/NET" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×3"];
|
||||
"BSP/NETCFG" -> "App" [color="#2563eb", penwidth=1.2, label="×3"];
|
||||
"BSP/NETCFG" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×2"];
|
||||
"BSP/NETCFG" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×3"];
|
||||
"BSP/NETCFG" -> "App" [color="#2563eb", penwidth=1.2, label="×1"];
|
||||
"BSP/NETCFG" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×1"];
|
||||
"BSP/NETCFG" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×2"];
|
||||
"BSP/RS485" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×1"];
|
||||
"BSP/SD2506" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×1"];
|
||||
"BSP/SD2506" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×2"];
|
||||
"BSP/SD2506" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×1"];
|
||||
"BSP/TPAFE5160" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×1"];
|
||||
"BSP/TPAFE5160" -> "FreeRTOS" [color="#2563eb", penwidth=1.2, label="×2"];
|
||||
"BSP/TPAFE5160" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×2"];
|
||||
"BSP/TPAFE5160" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×1"];
|
||||
"BSP/UI" -> "App/log" [color="#2563eb", penwidth=1.2, label="×2"];
|
||||
"BSP/UI" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×5"];
|
||||
"BSP/UI" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×6"];
|
||||
"BSP/UI" -> "BSP/NET" [color="#2563eb", penwidth=1.2, label="×2"];
|
||||
"BSP/UI" -> "BSP/NETCFG" [color="#2563eb", penwidth=1.2, label="×1"];
|
||||
"BSP/UI" -> "LVGL" [color="#2563eb", penwidth=1.2, label="×9"];
|
||||
@@ -112,7 +114,7 @@ digraph refgraph_module {
|
||||
"FreeRTOS" -> "CMSIS" [color="#94a3b8", penwidth=0.7, label="×1"];
|
||||
"FreeRTOS" -> "Src/Inc (CubeMX)" [color="#94a3b8", penwidth=0.7, label="×1"];
|
||||
"FreeRTOS" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×14"];
|
||||
"HAL" -> "CMSIS" [color="#94a3b8", penwidth=0.7, label="×14"];
|
||||
"HAL" -> "CMSIS" [color="#94a3b8", penwidth=0.7, label="×15"];
|
||||
"HAL" -> "Src/Inc (CubeMX)" [color="#94a3b8", penwidth=0.7, label="×1"];
|
||||
"HAL" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×1"];
|
||||
"LVGL" -> "FatFs" [color="#94a3b8", penwidth=0.7, label="×1"];
|
||||
@@ -133,7 +135,7 @@ digraph refgraph_module {
|
||||
"Src/Inc (CubeMX)" -> "BSP/TPAFE5160" [color="#2563eb", penwidth=1.2, label="×1"];
|
||||
"Src/Inc (CubeMX)" -> "CMSIS" [color="#2563eb", penwidth=1.2, label="×1"];
|
||||
"Src/Inc (CubeMX)" -> "FreeRTOS" [color="#2563eb", penwidth=1.2, label="×4"];
|
||||
"Src/Inc (CubeMX)" -> "HAL" [color="#2563eb", penwidth=1.2, label="×15"];
|
||||
"Src/Inc (CubeMX)" -> "HAL" [color="#2563eb", penwidth=1.2, label="×16"];
|
||||
"Src/Inc (CubeMX)" -> "lftpd" [color="#2563eb", penwidth=1.2, label="×1"];
|
||||
"Src/Inc (CubeMX)" -> "test" [color="#2563eb", penwidth=1.2, label="×3"];
|
||||
"Src/Inc (CubeMX)" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×4"];
|
||||
|
||||
+555
-541
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 104 KiB |
@@ -372,9 +372,11 @@ sequenceDiagram
|
||||
- 实现:`defaultTask` 每 2 s `f_stat` 比对 (size, mtime),连续 2 次稳定才重载(沉降去抖);`[network]` 段变化 → `SYS_EVT_NET_RECONFIG` → 网络重建(代次 +1,服务自愈)。
|
||||
- 判据:FTP 改 IP 后 2~5 s 生效(网络重建含等链路 ≤3 s)。
|
||||
|
||||
**FR-CFG-4 旧档迁移**
|
||||
- 需求:旧固件的 `/cfg/netcfg.bin`(NCFG 二进制)首启自动迁移为 INI 并删除旧文件。
|
||||
- 判据:迁移后日志 `cfg file: legacy NCFG migrated`,配置保留。
|
||||
**FR-CFG-4 旧档迁移**(已取消 · 2026-10-10)
|
||||
- 原需求:旧固件的 `/cfg/netcfg.bin`(NCFG 二进制)首启自动迁移为 INI 并删除旧文件——**已取消,不再实现**。
|
||||
- 现口径:旧档若存在则被**忽略**(不读、不删、不迁移),配置直接回落工厂默认(`/config.ini` `[network]` 段模板)。
|
||||
- 取消理由:该一次性路径把整条配置写链(`net_cfg_save → cfg_file_save → cfg_store_write_atomic → f_rename → FatFS → dhara FTL`)挂进启动期调用图,defaultTask 静态最坏栈链 +600 B;本仓库不存在携带旧档的设备。
|
||||
- 判据:卷上残留 `/cfg/netcfg.bin` 时开机不产生任何迁移日志、旧档不被改动,`/config.ini` 按工厂默认生成。
|
||||
|
||||
**FR-CFG-5 扩展性**
|
||||
- 需求:未来所有模块配置(ADC/RS-485/端口等)进同一文件、按段组织。
|
||||
@@ -577,7 +579,7 @@ mac=00:00:00:00:00:00
|
||||
| 需求 | 要求 | 落地 |
|
||||
|---|---|---|
|
||||
| **自恢复** | 任务死锁/饿死/断言死循环 → 硬件复位 | IWDG + 心跳位图(§5.7) |
|
||||
| **掉电不丢配置** | 配置原子写 + 旧档迁移 | tmp+rename + NCFG→INI 迁移 |
|
||||
| **掉电不丢配置** | 配置原子写(旧档迁移已取消,2026-10-10) | tmp+rename;旧 `/cfg/netcfg.bin` 不读、不删、不迁移 |
|
||||
| **错误可追溯** | 错误码分级/透传/留痕,不吞不猜 | 错误码通道四要素(分类/透传/分级/留痕) |
|
||||
| **存储自愈** | 卷损坏可探针/自愈;丢弃可观测 | 卷健康探针 + 丢弃计数 + TX 僵尸通道自愈 |
|
||||
| **不误杀** | 正常长耗时窗口不触发复位 | 启动段不喂狗 + 心跳切片 + 白名单 |
|
||||
@@ -888,3 +890,4 @@ cfg-file-unit-test、test-suite-switch、gitlint。
|
||||
| 日期 | 变更 | 说明 |
|
||||
|---|---|---|
|
||||
| 2026-10-05 | 初版 | 基于项目全量内容(架构 / 子系统 / UI / 测试 / 硬件网表 / 待办)编写完整产品需求设计文档:产品定位、六层架构与任务模型、V0.1 硬件规格、10 类功能需求(含 2 项待实现)、接口规范、非功能需求、UI 规格、待实现项与路线图、验收判据 |
|
||||
| 2026-10-10 | FR-CFG-4 旧档迁移**取消** | 删除旧固件 `/cfg/netcfg.bin`(NCFG 二进制)的首启自动迁移:旧档若存在则被忽略(不读、不删、不迁移),配置回落工厂默认。理由:该一次性路径把整条配置写链挂进启动期调用图,defaultTask 静态最坏栈链 +600 B,而本仓库不存在携带旧档的设备;`net_cfg_legacy.c/h` 与 `cfg_store_legacy_path()` 一并移除。§7.1「掉电不丢配置」同步 |
|
||||
|
||||
+72
-19
@@ -18,7 +18,7 @@
|
||||
- F407 另有 **64KB CCM RAM**:**已于 2026-09-21 启用**并把 FreeRTOS 堆迁入(§1.2)
|
||||
- 起步时没有任何运行时测量手段:不知道每个任务实际用了多少栈,改栈全靠拍脑袋
|
||||
|
||||
当前状态(**以 §2.1 受管快照为准**,由 `.map` 自动生成):RW_IRAM1 **84,960 / 131,072 B(64.8%)**、RW_CCM **49,184 / 65,280 B(75.3%)**。⚠️ **任务栈:2026-10-04 重采(产品构建 V5 30 min 负载)显示 `defaultTask` 峰值升至 3664B/4096(余量 432B ≈ 10%,已低于 30% 判据)**,详见 §2.3 注与 `../待处理内容.md` §6(登记 `待处理内容.md` S-1)。
|
||||
当前状态(**以 §2.1 受管快照为准**,由 `.map` 自动生成):RW_IRAM1 **89,168 / 131,072 B(68.0%)**、RW_CCM **49,184 / 65,280 B(75.3%)**。✅ **任务栈:2026-10-10 削链后 `defaultTask` 实测峰值 2152B/4096(余 47%)、静态最坏链 2776B(余 32%)**,6 任务全过 `stack_report.py` 判据(曾于 2026-10-04 升至 3664B/4096 ≈ 10%,登记为 S-1,现已销项),详见 §2.3 与"2026-10-10 复测"小节。
|
||||
|
||||
本方案三个目标:
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
<!-- MEM_SNAPSHOT:BEGIN generated by scripts/check_mem_numbers.py -->
|
||||
| 区域 | 用量 | 容量 | 占比 |
|
||||
|---|---|---|---|
|
||||
| ER_IROM1 | 268,128 B (261.84 KB) | 1,048,576 B (1024 KB) | 25.6% |
|
||||
| RW_IRAM1 | 85,040 B (83.05 KB) | 131,072 B (128 KB) | 64.9% |
|
||||
| ER_IROM1 | 267,528 B (261.26 KB) | 1,048,576 B (1024 KB) | 25.5% |
|
||||
| RW_IRAM1 | 89,168 B (87.08 KB) | 131,072 B (128 KB) | 68.0% |
|
||||
| RW_CCM | 49,184 B (48.03 KB) | 65,280 B (64 KB) | 75.3% |
|
||||
| **Flash (ROM 合计)** | **268,876 B (262.6 KB)** | 1,048,576 B (1024 KB) | **25.6%** |
|
||||
| **Flash (ROM 合计)** | **268,276 B (262.0 KB)** | 1,048,576 B (1024 KB) | **25.6%** |
|
||||
<!-- MEM_SNAPSHOT:END -->
|
||||
|
||||
各区的容量与常量来源:
|
||||
@@ -51,7 +51,7 @@
|
||||
| FreeRTOS 堆 (heap_4) | 48 KB(49,152 B),**位于 RW_CCM**;实测 `free=8,784 / min_ever=4,848` B | `Inc/FreeRTOSConfig.h:71` `configTOTAL_HEAP_SIZE` |
|
||||
| C 库堆/栈 (startup) | 512 B / 1 KB,启动期 main() 用 | map `startup_stm32f407xx.o` HEAP/STACK 节 |
|
||||
|
||||
### 2.2 静态大项排行(2026-09-21 当前,完整台账 `data/ram_report_20260921.md`)
|
||||
### 2.2 静态大项排行(2026-10-10 当前,完整台账 `data/ram_report_20261010.md`)
|
||||
|
||||
**RW_IRAM1(主 SRAM)**,按 ZI/RW 合计降序:
|
||||
|
||||
@@ -72,6 +72,11 @@
|
||||
| 13–17 | ≤560 | `spi.o` / `usart.o` / `lftpd_io.o` / `lv_init.o` / `net_socket.o` | 外设句柄、`FIL`、LVGL 全局、socket 表 |
|
||||
| 其余 | ~1.7 KB | 约 25 个 .o | 小型 RW/ZI |
|
||||
|
||||
> **2026-10-10 栈整改带来的静态增量(+4,128 B,本质是"把 528 B 的 `FIL` 从栈搬到 BSS")**:
|
||||
> `sys_log_mcu.o` 1,912 B(3 处 `FIL` 静态化 = 1,584 + 证据行缓冲 192)、`default_task.o` 2,712 B
|
||||
> (卷探针 `FIL` 528 + `default_fatfs`/`fs_work`)、`cfg_file_store_mcu.o` 1,104 B(2 处 `FIL` = 1,056)。
|
||||
> 同期 Flash **−600 B**(删旧档迁移)。台账:`data/ram_report_20261010.md`。
|
||||
|
||||
**RW_CCM(CCM)**:`heap_4.o` 49,184 B(FreeRTOS 堆 49,152 B + RW 32 B)——2026-09-21 由主 SRAM 迁入(§1.2),不再计入主 SRAM。
|
||||
|
||||
**静态合计(以 §2.1 受管快照为准)**:RW_IRAM1 **87,040 B(85.00 KB / 128 KB,66.4%)** + RW_CCM **49,184 B(48.03 KB / 64 KB,75.0%)** = **136,224 B(RW+ZI)**。
|
||||
@@ -86,20 +91,18 @@
|
||||
|
||||
`Src/freertos.c` 中 `osThreadAttr_t.stack_size` 单位为**字节**(CubeMX 生成代码,`1024 * 4` 表示 4096 字节):
|
||||
|
||||
> ⚠️ **下表"实测峰值"列为 2026-09-21 快照,已过时**:2026-10-04 产品构建(`suite=NONE`)V5 30 min
|
||||
> 真实负载重采(串口 `[STACK]`,证据 `/tmp/v5_soak_serial_20261003.log`)——**defaultTask 3664B/4096
|
||||
> (余量 432B ≈ 10%,已低于 30% 判据,登记 S-1)**、ftpTask 2516B/4096(38%)、netTask 1228B/4096(70%)、
|
||||
> uiTask 4060B/16384(75%)、timeSyncTask 792B/2048(61%)、testTask 496B/8192(93%)。
|
||||
> 栈水位随 A2/A3/A4 + IWDG + 卷锁 + 堆告警等陆续入链持续上升,**本表需随 `stack_report.py` 重新基线**。
|
||||
> ✅ **本表已于 2026-10-10 重新基线**(产品构建 `suite=NONE`,开机 + 空闲采样,静态链取 `stack_report.py`)。
|
||||
> 此前 2026-10-04 的 V5 30 min 重采曾把 defaultTask 推到 **3664B/4096(余量 432B ≈ 10%,登记 S-1)**;
|
||||
> 2026-10-10 的栈整改(**未抬栈**,见 §4 阶段 0 的"2026-10-10 复测")把它压回 **2152B/4096**,S-1 已销项。
|
||||
|
||||
| 任务 | 配置栈 | 字节 | 实际职责 | 2026-09-21 实测峰值(§0.6) |
|
||||
| 任务 | 配置栈 | 字节 | 实际职责 | 2026-10-10 实测峰值 / 静态最坏链 |
|
||||
|---|---|---|---|---|
|
||||
| uiTask | `4096*4` | 16KB | LVGL 1bpp 离屏渲染(渲染缓冲在静态区,栈只走调用链) | 3824 B(余量 76%)→ 可大幅缩减 |
|
||||
| netTask | `1024*4` | 4KB | CH395F 轮询(DMA 搬运,栈压力小) | 588 B(余量 85%) |
|
||||
| ftpTask | `1024*4` | 4KB | lftpd FTP 服务 | 1184 B(余量 71%,§1.4 静态化后) |
|
||||
| testTask | `2048*4` | 8KB | 测试套件(产品构建空转;存储套件深链需要) | 348 B(产品构建) |
|
||||
| defaultTask | `1024*4` | 4KB | FatFS 挂载/探针 + 配置引擎 + syslog + 栈水位探针 | 2136 B(余量 47%) |
|
||||
| timeSyncTask | `512*4` | 2KB | TCP 时间同步 | 420 B(余量 79%) |
|
||||
| uiTask | `4096*4` | 16KB | LVGL 1bpp 离屏渲染(渲染缓冲在静态区,栈只走调用链) | 4016 B(余 75%)/ 静态 1336 B → 可大幅缩减 |
|
||||
| netTask | `960*4` | 3.75KB | CH395F 轮询(DMA 搬运,栈压力小) | 920 B(余 76%)/ 静态 1872 B |
|
||||
| ftpTask | `1024*4` | 4KB | lftpd FTP 服务 | 740 B(余 81%)/ 静态 1216 B |
|
||||
| testTask | `2048*4` | 8KB | 测试套件(产品构建不创建;存储套件深链需要) | 未创建 / 静态 496 B |
|
||||
| defaultTask | `1024*4` | 4KB | FatFS 挂载/探针 + 配置引擎 + syslog + 栈水位探针 | 2152 B(余 47%)/ 静态 2776 B |
|
||||
| timeSyncTask | `512*4` | 2KB | TCP 时间同步 | 616 B(余 69%)/ 静态 **1024 B**(= ISR 底线,无再加深空间) |
|
||||
| idle(内核) | `configMINIMAL_STACK_SIZE=128` | 0.5KB | 空闲 | 未观测(未取句柄) |
|
||||
| timer(内核) | `configTIMER_TASK_STACK_DEPTH=256` | 1KB | 软定时器 | 未观测 |
|
||||
|
||||
@@ -322,7 +325,7 @@ void vApplicationMallocFailedHook(void)
|
||||
|
||||
要点与边界:
|
||||
|
||||
- defaultTask 的静态最坏链是**配置保存/旧档迁移**路径,不是首启探针路径:
|
||||
- defaultTask 的静态最坏链是**配置保存/旧档迁移**路径,不是首启探针路径(**2026-09-21 当时的链;旧档迁移已于 2026-10-10 删除、日志行缓冲已按模块收紧,现链见下方"2026-10-10 复测"**):
|
||||
`net_cfg_load → net_cfg_legacy_migrate → net_cfg_save → cfg_file_save → s_write_template → s_write_doc → cfg_store_write_atomic → f_rename → follow_path → dir_next → create_chain → put_fat → move_window → sync_window → disk_write → ftl_flush_cache → dhara_map_write → prepare_write → auto_gc → dhara_map_gc → ... → trace_path → dhara_journal_read_meta → dhara_nand_read → gd5f_read_from_cache → HAL_SPI_Receive → ... → SPI_WaitFlagStateUntilTimeout`。
|
||||
**2776 B > 2048 B** → 512 words 栈必然溢出,与 2026-09-21 实测完全一致。
|
||||
- 帧宽榜直接点名宽度大户(自身帧):`s_append` 704 B(FIL 512 + 记录 64 + 时间戳)、`StartDefaultTask` 560 B(探针 `FIL __chk`)、`cfg_store_read`/`cfg_store_write_atomic` 576 B、LVGL 绘制 624/560/400 B——与 §1.4 的整改项对得上。**lftpd 三项已于 2026-09-21 静态化(§1.4),已退出帧宽榜前 15**(原 `handle_control_channel` 1104 B、`receive_file`/`send_file` 1088 B、`send_response` 800 B)。
|
||||
@@ -330,6 +333,56 @@ void vApplicationMallocFailedHook(void)
|
||||
- testTask 在产品构建里只是 `osDelay` 空循环(168 B);2048 words 是给**存储套件构建**(`TEST_SUITE_STORAGE`)预留的,测套件时应重跑本脚本看该构建的静态值。
|
||||
- **测 ftpTask 的复现配方**:设备就绪后跑 `& '.venv\Scripts\python.exe' test/host/ftp_speed_test.py --size 128`(STOR 128KB + RETR + 逐字节比对),再按上面命令叠加串口日志出报告。**不要用裸 TCP 工具探测 21 端口**——CH395F 单客户端复用,探测会占掉唯一会话(见 FTP 指南 §8.9)。
|
||||
|
||||
#### 2026-10-10 复测:**不抬栈**把 defaultTask 从 FAIL 拉回 PASS(S-1 销项)
|
||||
|
||||
触发点:登记簿 S-1(2026-10-04 实测 defaultTask 3664B/4096,余量 10%)。叠加静态链后判据更严——
|
||||
**静态最坏链已涨到 5312 B > 配置 4096 B(margin −1216 B)**。本次刻意**不动栈值**,改为削链:
|
||||
|
||||
| 任务 | 配置 (B) | 静态最坏 改前 → 改后 | 实测峰值 改前 → 改后 | 判定 |
|
||||
|---|---|---|---|---|
|
||||
| **defaultTask** | 4096 | **5312 → 2776** | 3392 → **2152** | FAIL → **PASS(余 1320 B / 32%)** |
|
||||
| netTask | 3840 | 2664 → 1872 | 1008 → 920 | PASS(51%) |
|
||||
| ftpTask | 4096 | 1800 → 1216 | 756 → 740 | PASS(70%) |
|
||||
| uiTask | 16384 | 1536 → 1336 | 4024 → 4052 | PASS(75%) |
|
||||
| **timeSyncTask** | 2048 | **1736 → 1024** | 760 → 616 | FAIL → **PASS(余 1024 B = ISR 底线,正好卡住)** |
|
||||
| testTask | 8192 | 928 → 496 | —(产品构建不创建) | PASS(93%) |
|
||||
|
||||
四个杠杆(按收益排序,只动自研代码,第三方 dhara/FatFS/HAL 一行未改):
|
||||
|
||||
1. **删旧档 NCFG 迁移**(`Drivers/BSP/NETCFG/net_cfg_legacy.c/h` 整体移除,链 −600 B):
|
||||
`net_cfg_load` 无条件调 `net_cfg_legacy_migrate()`,把整条配置**写**链(`net_cfg_save →
|
||||
cfg_file_save → s_write_template → s_write_doc → cfg_store_write_atomic → f_rename → FTL`)
|
||||
挂进启动期调用图。本仓库无携带 `/cfg/netcfg.bin` 的设备 → 按"不保留旧档兼容"处置;
|
||||
旧档若存在则**忽略**(不读、不删、不迁移),配置回落工厂默认。
|
||||
2. **6 处局部 `FIL` 改函数级 `static`**(每处 −528 B):`Lib/FatFs/ffconf.h` `FF_FS_TINY=0` →
|
||||
`FIL` 内含 `buf[FF_MAX_SS]` = 512 B。落点 `App/log/sys_log_mcu.c`(3 处)、
|
||||
`App/cfg/cfg_file_store_mcu.c`(2 处)、`App/task/default_task.c` 探针宏(1 处)。
|
||||
安全性依据:整个 FIL 生命周期都在 `vol_lock_wait()/release()` 区间内(跨任务被卷锁串行化)
|
||||
+ 配置引擎/syslog 写者单任务属主(P1-3)。先例 = 2026-09-21 lftpd 9 处大局部缓冲静态化。
|
||||
3. **日志行缓冲按模块收紧 + 时间戳缓冲并入行缓冲**(每个日志调用点原内联 `192 + 32 = 224 B`):
|
||||
`dbg_log.h` 新增 `DBG_LINE_BUF_MAX`(默认仍 = `DBG_CON_LINE_MAX` 192),深链模块
|
||||
(`nand_ftl.c`/`gd5f2gq5ue.c`/`cfg_file.c`/`net_cfg.c`/`net_socket.c`/`ch395f.c`/`time_sync.c`/
|
||||
`default_task.c`)收到 **128**;`DBG_TS_BUF_MAX` 32 → 24 且与行缓冲共用一个数组。
|
||||
实测链上 9 个帧各含一份行缓冲 → **仅这一项就占 defaultTask 最坏链约 1.5 KB**。
|
||||
⚠ 取值须 ≥ 该模块最长日志行(各文件注释里已给出实测行长),否则该行被截断。
|
||||
4. **内核钩子脱离 HAL 发送路径**:`configASSERT` 在 FreeRTOS 内部可达 → `vApplicationAssertFailed`
|
||||
挂在**每个**任务的最坏链尾;它原走 `dbg_console_write_raw → con_tx_bounded →
|
||||
(DWT 不可用时)HAL_UART_Transmit → UART_WaitOnFlagUntilTimeout`。现 `con_tx_bounded` 的
|
||||
DWT 回退改为**指令计数上界**(`CON_TX_GUARD_MAX`),HAL 尾巴从所有链上消失;钩子自身
|
||||
`name[49]/num[16]/rev[16]` 改 static + 原地反转、去掉 `HAL_Delay`(断言现场 tick 未必可信)。
|
||||
|
||||
代价与复核:静态 BSS **+4,128 B**(ZI 133,524 → 137,652;RW_IRAM1 64.9% → 68.1%),Flash 反而 −36 B;
|
||||
FreeRTOS 堆不变(`free=17248 / min_ever=9312`)。验证链:`@build` 0/0 → `@test` 真机 PASS(含烧录回读)
|
||||
→ `stack_report.py` **6/6 PASS**。
|
||||
|
||||
顺带揪出并修掉的**两个静态虚高源**:① `dbg_console_drain` 故障路径调 `syslog_post` →
|
||||
`write_line → con_append → drain → syslog_post → write_line` **调用图成环**(运行时有
|
||||
`s_con_draining` 重入标志挡着不会真递归,但 armlink 把整条日志尾巴在每个任务上多叠一层)——
|
||||
现改为置标志、由写者任务在 drain 之外补记 run.log(`dbg_console_tx_fault_log_take()`);
|
||||
② 上述 HAL 发送回退。**教训:静态链异常高时先查"链尾是不是日志/钩子",再动业务代码。**
|
||||
|
||||
**留作候选、本轮刻意未做**:① **共享静态行缓冲池**(`dbg_console_line_claim()/release()` 发还栈上数组,改为从 2 个静态槽领取)——可再削每条日志帧的全部 152 B(全链再省 ~1.3 KB),但把"日志缓冲在调用者栈上"改成"跨任务共享 + 抢占失败即丢行",**改变日志并发语义**,需配套主机侧单测才动;② `timeSyncTask` 静态余量已正好等于 1024 B ISR 底线,**该链上再加任何调用都必须先抬栈**(已在 `Src/freertos.c` 栈注释里写明)。
|
||||
|
||||
#### 阶段 0 验收
|
||||
|
||||
- 串口可见 `[STACK]` 报告:每任务 `peak_used/free_min` + 堆 `free/min_ever`
|
||||
@@ -393,7 +446,7 @@ ISR 余量:该任务运行期间可能被中断打断的最深中断链(SPI/
|
||||
| netTask | 4KB | **2KB** | 实测 588B → 1024+1024=2048B |
|
||||
| ftpTask | 4KB | **3KB** | 实测 1184B(§1.4 静态化后)→ 1776+1024=2800B → 3KB;再降须放宽 ISR 余量并复测 |
|
||||
| testTask | 8KB | **2KB** | 产品构建空转(实测 348B)→ 1024+1024;存储套件构建按该构建静态值另放大 |
|
||||
| defaultTask | 4KB | **保持 4KB** | 静态最坏 2776B(配置保存/旧档迁移深链,§0.6)→ 缩减必溢出 |
|
||||
| defaultTask | 4KB | **保持 4KB** | 2026-10-10 削链后静态最坏 2776B / 实测 2152B(余 32%);曾达 5312B 溢出判据,见"2026-10-10 复测" |
|
||||
| timeSyncTask | 2KB | **保持 2KB** | 实测 420B → 1024+1024=2048B,无缩减空间 |
|
||||
|
||||
缩减后任务栈合计 38,912 → 21,504 B(**省 17,408 B / ~17 KB**,全部在 CCM 堆内,主 SRAM 不受影响)。
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
# STM32F4-Base RAM/Flash Usage Report
|
||||
|
||||
> Generated: 2026-10-10 09:17 Map: `STM32F407-Demo.map`
|
||||
|
||||
## 1. Grand Totals (全局总量)
|
||||
|
||||
| Metric | Value |
|
||||
|---|---|
|
||||
| Code (inc. data) | 252,092 B (246.2 KB) |
|
||||
| RO Data | 15,436 B (15.1 KB) |
|
||||
| RW Data (initialized) | 748 B (0.73 KB) |
|
||||
| ZI Data (zero-init) | 137,652 B (134.4 KB) |
|
||||
| **Total RO (Code + RO)** | **267,528 B (261.3 KB)** |
|
||||
| **Total RW (RW + ZI) = SRAM used** | **138,400 B (135.16 KB)** |
|
||||
| **Total ROM (Code + RO + RW init)** | **268,276 B (262.0 KB)** |
|
||||
|
||||
## 2. 执行区水位 (Execution Regions)
|
||||
|
||||
| Region | Base | Size | Max | Util% |
|
||||
|---|---|---|---|---|
|
||||
| ER_IROM1 | 0x08000000 | 267,528 B (261.26 KB) | 1,048,576 B (1024 KB) | 25.5% |
|
||||
| RW_CCM | 0x10000000 | 49,184 B (48.03 KB) | 65,280 B (64 KB) | 75.3% |
|
||||
| UNINIT_CCM | 0x1000FF00 | 48 B (0.05 KB) | 256 B (0 KB) | 18.8% |
|
||||
| RW_IRAM1 | 0x20000000 | 89,168 B (87.08 KB) | 131,072 B (128 KB) | 68.0% |
|
||||
|
||||
## 3. RW_IRAM1 逐符号明细(ZI + RW,按大小降序)
|
||||
|
||||
| # | Address | Size (B) | Size (KB) | Type | Section | Object |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 1 | 0x200083F0 | 40,960 | 40.00 | Zero | .bss | lv_mem_core_builtin.o |
|
||||
| 2 | 0x20013DF2 | 6,746 | 6.59 | Zero | .bss | ui_net_sink.o |
|
||||
| 3 | 0x200123F0 | 6,408 | 6.26 | Zero | .bss | ui_port.o |
|
||||
| 4 | 0x200048C4 | 6,200 | 6.05 | Zero | .bss | nand_ftl.o |
|
||||
| 5 | 0x200060FC | 4,616 | 4.51 | Zero | .bss | lftpd.o |
|
||||
| 6 | 0x200031B0 | 4,104 | 4.01 | Zero | .bss | ch395f.o |
|
||||
| 7 | 0x200016E0 | 4,096 | 4.00 | Zero | .bss | console_log.o |
|
||||
| 8 | 0x20002718 | 2,712 | 2.65 | Zero | .bss | default_task.o |
|
||||
| 9 | 0x20000F68 | 1,912 | 1.87 | Zero | .bss | sys_log_mcu.o |
|
||||
| 10 | 0x20007B48 | 1,720 | 1.68 | Zero | .bss | cmsis_os2.o |
|
||||
| 11 | 0x2000756C | 1,220 | 1.19 | Zero | .bss | tasks.o |
|
||||
| 12 | 0x20000B18 | 1,104 | 1.08 | Zero | .bss | cfg_file_store_mcu.o |
|
||||
| 13 | 0x20015850 | 1,024 | 1.00 | Zero | | startup_stm32f407xx.o |
|
||||
| 14 | 0x200041B8 | 800 | 0.78 | Zero | .bss | gd5f2gq5ue.o |
|
||||
| 15 | 0x20000858 | 704 | 0.69 | Zero | .bss | cfg_file.o |
|
||||
| 16 | 0x20004604 | 704 | 0.69 | Zero | .bss | net_socket.o |
|
||||
| 17 | 0x200003B8 | 560 | 0.55 | Zero | .bss | spi.o |
|
||||
| 18 | 0x200005E8 | 552 | 0.54 | Zero | .bss | usart.o |
|
||||
| 19 | 0x20007304 | 552 | 0.54 | Zero | .bss | lftpd_io.o |
|
||||
| 20 | 0x20008200 | 496 | 0.48 | Zero | .bss | lv_init.o |
|
||||
| 21 | 0x20007A30 | 280 | 0.27 | Zero | .bss | timers.o |
|
||||
| 22 | 0x200044F8 | 268 | 0.26 | Zero | .bss | rs485.o |
|
||||
| 23 | 0x20000134 | 152 | 0.15 | Data | .data | lftpd.o |
|
||||
| 24 | 0x20013CF8 | 152 | 0.15 | Zero | .bss | ui_menu_view.o |
|
||||
| 25 | 0x20000358 | 84 | 0.08 | Zero | .bss | i2c.o |
|
||||
| 26 | 0x20000310 | 72 | 0.07 | Zero | .bss | adc.o |
|
||||
| 27 | 0x20000810 | 72 | 0.07 | Zero | .bss | stm32f4xx_hal_timebase_tim.o |
|
||||
| 28 | 0x200002CC | 65 | 0.06 | Zero | .bss | freertos.o |
|
||||
| 29 | 0x2000752C | 64 | 0.06 | Zero | .bss | queue.o |
|
||||
| 30 | 0x200001D0 | 60 | 0.06 | Data | .data | tasks.o |
|
||||
| 31 | 0x200026E0 | 56 | 0.05 | Zero | .bss | task_watchdog.o |
|
||||
| 32 | 0x20013D90 | 49 | 0.05 | Zero | .bss | ui_page_runlog.o |
|
||||
| 33 | 0x20013DC1 | 49 | 0.05 | Zero | .bss | ui_page_selftest.o |
|
||||
| 34 | 0x20000064 | 44 | 0.04 | Data | .data | task_watchdog.o |
|
||||
| 35 | 0x200000D4 | 44 | 0.04 | Data | .data | net_socket.o |
|
||||
| 36 | 0x20000100 | 36 | 0.04 | Data | .data | net_cfg.o |
|
||||
| 37 | 0x20000000 | 32 | 0.03 | Data | .data | freertos.o |
|
||||
| 38 | 0x20000298 | 32 | 0.03 | Data | .data | ui_standby.o |
|
||||
| 39 | 0x200044D8 | 32 | 0.03 | Zero | .bss | tpafe5160.o |
|
||||
| 40 | 0x20000044 | 24 | 0.02 | Data | .data | console_log.o |
|
||||
| 41 | 0x20000024 | 20 | 0.02 | Data | .data | cfg_file.o |
|
||||
| 42 | 0x200000B4 | 20 | 0.02 | Data | .data | gd5f2gq5ue.o |
|
||||
| 43 | 0x2000020C | 20 | 0.02 | Data | .data | timers.o |
|
||||
| 44 | 0x20000250 | 18 | 0.02 | Data | .data | ui_menu.o |
|
||||
| 45 | 0x20000124 | 16 | 0.02 | Data | .data | nand_ftl.o |
|
||||
| 46 | 0x200002B8 | 16 | 0.02 | Data | .data | ui_net_sink.o |
|
||||
| 47 | 0x20000038 | 12 | 0.01 | Data | .data | sys_log_mcu.o |
|
||||
| 48 | 0x200000A0 | 12 | 0.01 | Data | .data | stm32f4xx_hal.o |
|
||||
| 49 | 0x200000C8 | 12 | 0.01 | Data | .data | tpafe5160.o |
|
||||
| 50 | 0x20000224 | 12 | 0.01 | Data | .data | port.o |
|
||||
| 51 | 0x20000244 | 12 | 0.01 | Data | .data | ui_port.o |
|
||||
| 52 | 0x2000026C | 12 | 0.01 | Data | .data | ui_content_page.o |
|
||||
| 53 | 0x20000278 | 12 | 0.01 | Data | .data | ui_page_password.o |
|
||||
| 54 | 0x200003AC | 12 | 0.01 | Zero | .bss | iwdg.o |
|
||||
| 55 | 0x2000005C | 8 | 0.01 | Data | .data | sys_clock.o |
|
||||
| 56 | 0x20000094 | 8 | 0.01 | Data | .data | default_task.o |
|
||||
| 57 | 0x20000230 | 8 | 0.01 | Data | .data | ff.o |
|
||||
| 58 | 0x20000238 | 8 | 0.01 | Data | .data | ffsystem.o |
|
||||
| 59 | 0x20000264 | 8 | 0.01 | Data | .data | ui_menu_view.o |
|
||||
| 60 | 0x20000288 | 8 | 0.01 | Data | .data | ui_page_runlog.o |
|
||||
| 61 | 0x20000290 | 8 | 0.01 | Data | .data | ui_page_selftest.o |
|
||||
| 62 | 0x20000020 | 4 | 0.00 | Data | .data | app_main.o |
|
||||
| 63 | 0x20000090 | 4 | 0.00 | Data | .data | vol_lock.o |
|
||||
| 64 | 0x2000009C | 4 | 0.00 | Data | .data | net_task.o |
|
||||
| 65 | 0x200000AC | 4 | 0.00 | Data | .data | system_stm32f4xx.o |
|
||||
| 66 | 0x200001CC | 4 | 0.00 | Data | .data | lftpd_io.o |
|
||||
| 67 | 0x20000220 | 4 | 0.00 | Data | .data | cmsis_os2.o |
|
||||
| 68 | 0x20000240 | 4 | 0.00 | Data | .data | lv_textarea.o |
|
||||
| 69 | 0x200002C8 | 4 | 0.00 | Data | .data | mc_w.l(errno.o) |
|
||||
| 70 | 0x200000B0 | 2 | 0.00 | Data | .data | ch395f.o |
|
||||
| 71 | 0x20000284 | 2 | 0.00 | Data | .data | ui_page_net_cfg.o |
|
||||
| | | **89,155** | **87.07** | | | **Total** |
|
||||
|
||||
## 4. Image Component Sizes(RW + ZI > 0,按大小降序)
|
||||
|
||||
| # | Object | Code | RO | RW | ZI | RW+ZI |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 1 | heap_4.o | 512 | 69 | 32 | 49,152 | 49,184 |
|
||||
| 2 | lv_mem_core_builtin.o | 410 | 0 | 0 | 40,960 | 40,960 |
|
||||
| 3 | ui_net_sink.o | 1,102 | 67 | 16 | 6,746 | 6,762 |
|
||||
| 4 | ui_port.o | 418 | 0 | 12 | 6,408 | 6,420 |
|
||||
| 5 | nand_ftl.o | 2,082 | 83 | 16 | 6,200 | 6,216 |
|
||||
| 6 | lftpd.o | 5,336 | 503 | 152 | 4,616 | 4,768 |
|
||||
| 7 | console_log.o | 968 | 55 | 24 | 4,096 | 4,120 |
|
||||
| 8 | ch395f.o | 2,796 | 345 | 2 | 4,104 | 4,106 |
|
||||
| 9 | default_task.o | 2,048 | 229 | 8 | 2,712 | 2,720 |
|
||||
| 10 | sys_log_mcu.o | 2,078 | 83 | 12 | 1,912 | 1,924 |
|
||||
| 11 | cmsis_os2.o | 1,216 | 0 | 4 | 1,720 | 1,724 |
|
||||
| 12 | tasks.o | 4,034 | 0 | 60 | 1,220 | 1,280 |
|
||||
| 13 | cfg_file_store_mcu.o | 380 | 24 | 0 | 1,104 | 1,104 |
|
||||
| 14 | startup_stm32f407xx.o | 36 | 392 | 0 | 1,024 | 1,024 |
|
||||
| 15 | gd5f2gq5ue.o | 3,930 | 478 | 20 | 800 | 820 |
|
||||
| 16 | net_socket.o | 6,682 | 779 | 44 | 704 | 748 |
|
||||
| 17 | cfg_file.o | 5,922 | 810 | 20 | 704 | 724 |
|
||||
| 18 | spi.o | 584 | 0 | 0 | 560 | 560 |
|
||||
| 19 | lftpd_io.o | 1,198 | 0 | 4 | 552 | 556 |
|
||||
| 20 | usart.o | 884 | 0 | 0 | 552 | 552 |
|
||||
| 21 | lv_init.o | 156 | 0 | 0 | 496 | 496 |
|
||||
| 22 | timers.o | 1,232 | 0 | 20 | 280 | 300 |
|
||||
| 23 | rs485.o | 120 | 0 | 0 | 268 | 268 |
|
||||
| 24 | ui_menu_view.o | 2,034 | 108 | 8 | 152 | 160 |
|
||||
| 25 | task_watchdog.o | 1,098 | 137 | 44 | 104 | 148 |
|
||||
| 26 | freertos.o | 656 | 452 | 32 | 65 | 97 |
|
||||
| 27 | i2c.o | 168 | 0 | 0 | 84 | 84 |
|
||||
| 28 | adc.o | 392 | 0 | 0 | 72 | 72 |
|
||||
| 29 | stm32f4xx_hal_timebase_tim.o | 152 | 0 | 0 | 72 | 72 |
|
||||
| 30 | queue.o | 2,840 | 0 | 0 | 64 | 64 |
|
||||
| 31 | ui_page_runlog.o | 168 | 93 | 8 | 49 | 57 |
|
||||
| 32 | ui_page_selftest.o | 168 | 93 | 8 | 49 | 57 |
|
||||
| 33 | tpafe5160.o | 704 | 67 | 12 | 32 | 44 |
|
||||
| 34 | net_cfg.o | 828 | 103 | 36 | 0 | 36 |
|
||||
| 35 | ui_standby.o | 1,208 | 159 | 32 | 0 | 32 |
|
||||
| 36 | ui_menu.o | 816 | 137 | 18 | 0 | 18 |
|
||||
| 37 | (incl. Padding) | 312 | 87 | 6 | 7 | 13 |
|
||||
| 38 | iwdg.o | 28 | 0 | 0 | 12 | 12 |
|
||||
| 39 | port.o | 762 | 73 | 12 | 0 | 12 |
|
||||
| 40 | stm32f4xx_hal.o | 116 | 0 | 12 | 0 | 12 |
|
||||
| 41 | ui_content_page.o | 1,720 | 199 | 12 | 0 | 12 |
|
||||
| 42 | ui_page_password.o | 686 | 167 | 12 | 0 | 12 |
|
||||
| 43 | ff.o | 7,962 | 282 | 8 | 0 | 8 |
|
||||
| 44 | ffsystem.o | 204 | 20 | 8 | 0 | 8 |
|
||||
| 45 | sys_clock.o | 1,788 | 286 | 8 | 0 | 8 |
|
||||
| 46 | app_main.o | 1,660 | 65 | 4 | 0 | 4 |
|
||||
| 47 | lv_textarea.o | 3,632 | 48 | 4 | 0 | 4 |
|
||||
| 48 | net_task.o | 1,452 | 72 | 4 | 0 | 4 |
|
||||
| 49 | system_stm32f4xx.o | 16 | 24 | 4 | 0 | 4 |
|
||||
| 50 | vol_lock.o | 92 | 0 | 4 | 0 | 4 |
|
||||
| 51 | errno.o | 8 | 0 | 4 | 0 | 4 |
|
||||
| 52 | ui_page_net_cfg.o | 1,004 | 93 | 2 | 0 | 2 |
|
||||
| | **All .o files** | **252,092** | **15,436** | **748** | **137,652** | **138,400** |
|
||||
|
||||
## 5. Flash (Code + RO Data) Top-30(按大小降序)
|
||||
|
||||
| # | Object | Code | RO Data | Code+RO |
|
||||
|---|---|---|---|---|
|
||||
| 1 | ff.o | 7,962 | 282 | 8,244 |
|
||||
| 2 | lv_draw_sw_blend_to_rgb565_swapped.o | 7,648 | 0 | 7,648 |
|
||||
| 3 | net_socket.o | 6,682 | 779 | 7,461 |
|
||||
| 4 | lv_draw_sw_blend_to_rgb565.o | 7,020 | 0 | 7,020 |
|
||||
| 5 | cfg_file.o | 5,922 | 810 | 6,732 |
|
||||
| 6 | lftpd.o | 5,336 | 503 | 5,839 |
|
||||
| 7 | lv_draw_sw_blend_to_argb8888.o | 5,412 | 0 | 5,412 |
|
||||
| 8 | lv_draw_sw_blend_to_i1.o | 5,272 | 0 | 5,272 |
|
||||
| 9 | lv_indev.o | 4,958 | 0 | 4,958 |
|
||||
| 10 | ui_font_cn_12.o | 0 | 4,626 | 4,626 |
|
||||
| 11 | lv_draw_sw_blend_to_rgb888.o | 4,560 | 0 | 4,560 |
|
||||
| 12 | lv_obj_pos.o | 4,526 | 16 | 4,542 |
|
||||
| 13 | lv_refr.o | 4,486 | 0 | 4,486 |
|
||||
| 14 | gd5f2gq5ue.o | 3,930 | 478 | 4,408 |
|
||||
| 15 | lv_draw_sw_transform.o | 4,340 | 0 | 4,340 |
|
||||
| 16 | lv_obj_style.o | 4,138 | 0 | 4,138 |
|
||||
| 17 | lv_obj_scroll.o | 4,126 | 0 | 4,126 |
|
||||
| 18 | lv_label.o | 4,042 | 45 | 4,087 |
|
||||
| 19 | tasks.o | 4,034 | 0 | 4,034 |
|
||||
| 20 | lv_draw_sw_mask.o | 3,862 | 0 | 3,862 |
|
||||
| 21 | lv_draw_sw_blend_to_l8.o | 3,778 | 0 | 3,778 |
|
||||
| 22 | lv_buttonmatrix.o | 3,586 | 125 | 3,711 |
|
||||
| 23 | lv_textarea.o | 3,632 | 48 | 3,680 |
|
||||
| 24 | stm32f4xx_hal_spi.o | 3,586 | 0 | 3,586 |
|
||||
| 25 | lv_draw_sw_blend_to_al88.o | 3,560 | 0 | 3,560 |
|
||||
| 26 | lv_draw_sw_blend_to_argb8888_premultiplied.o | 3,332 | 0 | 3,332 |
|
||||
| 27 | lv_draw_sw_box_shadow.o | 3,246 | 0 | 3,246 |
|
||||
| 28 | ch395f.o | 2,796 | 345 | 3,141 |
|
||||
| 29 | lv_indev_scroll.o | 3,068 | 0 | 3,068 |
|
||||
| 30 | lv_obj.o | 2,982 | 43 | 3,025 |
|
||||
| | **All .o files** | **252,092** | **15,436** | **267,528** |
|
||||
|
||||
> 自洽校验:per-file 252,092/15,436/748/137,652 vs Grand Totals 252,092/15,436/748/137,652(CodeΔ=+0 / ROΔ=+0 / RWΔ=+0 / ZIΔ=+0;精确一致(含 '('incl. Generated)'-'(incl. Padding)' 台账行))→ **PASS**
|
||||
@@ -0,0 +1,79 @@
|
||||
# Stack budget report
|
||||
|
||||
- Source: `MDK-ARM\STM32F407-Demo\STM32F407-Demo.htm` (Keil static call graph)
|
||||
- Linker run: Sat Oct 10 10:13:26 2026
|
||||
- Global maximum stack usage: **2776 B** (any call tree)
|
||||
- Runtime watermark: 5 task(s) from `tools\serial_tool\state\serial.log`
|
||||
|
||||
Rule: `margin = cfg - max(static_max_depth, runtime_peak)` must be >= max(1024 B ISR, 30% of cfg).
|
||||
|
||||
| Task | Entry | Cfg (B) | Static max (B) | Runtime peak (B) | Worst (B) | Margin (B) | Margin % | Verdict |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| defaultTask | `StartDefaultTask` | 4096 | 2776 | 2152 | 2776 | 1320 | 32% | PASS |
|
||||
| netTask | `StartNetTask` | 3840 | 1872 | 920 | 1872 | 1968 | 51% | PASS |
|
||||
| ftpTask | `StartFtpTask` | 4096 | 1216 | 740 | 1216 | 2880 | 70% | PASS |
|
||||
| uiTask | `StartUiTask` | 16384 | 1336 | 4016 | 4016 | 12368 | 75% | PASS |
|
||||
| testTask | `start_test_task` | 8192 | 496 | - | 496 | 7696 | 93% | PASS |
|
||||
| timeSyncTask | `time_sync_task` | 2048 | 1024 | 616 | 1024 | 1024 | 50% | PASS |
|
||||
|
||||
`Static max` = armlink worst-case call-tree depth; `Runtime peak` = measured high-water mark (boot + whatever workload ran before the sample); `Worst` = max of the two, which is what the verdict is computed from.
|
||||
|
||||
Runtime heap: free=17248 B, min_ever=9312 B
|
||||
|
||||
## Worst call chain per task
|
||||
|
||||
### defaultTask: 2776 B (own frame 0 B)
|
||||
|
||||
```
|
||||
StartDefaultTask -> default_task_func -> storage_bring_up -> net_cfg_load -> cfg_file_load -> s_write_template -> s_write_doc -> cfg_store_write_atomic -> f_rename -> sync_fs -> disk_ioctl -> ftl_flush_cache -> dhara_map_write -> prepare_write -> auto_gc -> dhara_map_gc -> try_recover -> raw_gc -> trace_path -> dhara_journal_read_meta -> dhara_nand_read -> gd5f_read_from_cache -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_USART1_UART_Init -> HAL_UART_Init -> HAL_UART_MspInit -> HAL_GPIO_Init
|
||||
```
|
||||
|
||||
### netTask: 1872 B (own frame 0 B)
|
||||
|
||||
```
|
||||
StartNetTask -> net_task_func -> net_process_messages -> net_send_locked -> net_poll -> handle_disconnect_event -> net_relisten_try -> net_relisten_locked -> ch395f_read_recv_buf -> ch395f_spi_dma_transfer -> ch395f_spi_fault_set -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_USART1_UART_Init -> HAL_UART_Init -> HAL_UART_MspInit -> HAL_GPIO_Init
|
||||
```
|
||||
|
||||
### ftpTask: 1216 B (own frame 24 B)
|
||||
|
||||
```
|
||||
StartFtpTask -> lftpd_start -> lftpd_inet_listen -> net_bind -> ch395f_open_socket -> ch395f_poll_cmd_status -> ch395f_get_cmd_status -> ch395f_write_cmd -> ch395f_spi_fault_set -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_USART1_UART_Init -> HAL_UART_Init -> HAL_UART_MspInit -> HAL_GPIO_Init
|
||||
```
|
||||
|
||||
### uiTask: 1336 B (own frame 0 B)
|
||||
|
||||
```
|
||||
StartUiTask -> ui_task_func -> ui_menu_init -> ui_menu_view_init -> lv_obj_create -> lv_obj_class_init_obj -> lv_theme_apply -> lv_obj_remove_style_all -> lv_obj_remove_style -> lv_obj_refresh_style -> refresh_children_style -> refresh_children_style (Cycle)
|
||||
```
|
||||
|
||||
### testTask: 496 B (own frame 224 B)
|
||||
|
||||
```
|
||||
start_test_task -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_USART1_UART_Init -> HAL_UART_Init -> HAL_UART_MspInit -> HAL_GPIO_Init
|
||||
```
|
||||
|
||||
### timeSyncTask: 1024 B (own frame 152 B)
|
||||
|
||||
```
|
||||
time_sync_task -> time_sync_open_listener -> net_bind -> ch395f_open_socket -> ch395f_poll_cmd_status -> ch395f_get_cmd_status -> ch395f_write_cmd -> ch395f_spi_fault_set -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_USART1_UART_Init -> HAL_UART_Init -> HAL_UART_MspInit -> HAL_GPIO_Init
|
||||
```
|
||||
|
||||
## Frame-size ranking (own frame, top 15)
|
||||
|
||||
| Bytes | Function |
|
||||
|---|---|
|
||||
| 624 | `lv_draw_sw_arc` |
|
||||
| 624 | `draw_indic` |
|
||||
| 560 | `draw_main` |
|
||||
| 400 | `draw_line_skew` |
|
||||
| 352 | `lv_draw_sw_triangle` |
|
||||
| 352 | `net_stack_bring_up` |
|
||||
| 344 | `s_append` |
|
||||
| 328 | `lv_obj_redraw` |
|
||||
| 328 | `view_frame_draw_cb` |
|
||||
| 320 | `wd_stall_evidence` |
|
||||
| 312 | `nc_draw_cb` |
|
||||
| 304 | `lv_draw_label_iterate_characters` |
|
||||
| 304 | `lv_draw_sw_box_shadow` |
|
||||
| 304 | `sys_clock_init` |
|
||||
| 304 | `draw_cursor` |
|
||||
@@ -193,9 +193,10 @@ sequenceDiagram
|
||||
|
||||
### 4.4 裸发(`dbg_console_write_raw`)
|
||||
|
||||
- 有界:`len > 256 → 256`(截尾);单次阻塞 `HAL_UART_Transmit`(超时 `0xFFFF`),不持临界区、不等待状态;
|
||||
- 有界:`len > 256 → 256`(截尾);发送走 `con_tx_bounded`(**寄存器级轮询 TXE/TC**,超时判据 = DWT `CYCCNT`,`CON_TX_TIMEOUT_CYC` = 100 ms 对应周期数),不持临界区、不等待状态;
|
||||
- **2026-10-10:DWT 不可用时改走 `con_tx_counted`(指令计数上界 `CON_TX_GUARD_MAX`),不再回退 `HAL_UART_Transmit`**。两个理由:① HAL 的超时判据是 `HAL_GetTick`——断言/停摆现场 tick 未必在走;② `HAL_UART_Transmit → UART_WaitOnFlagUntilTimeout` 这条尾巴会被 armlink 挂进**每个**碰日志的任务的最坏栈链(`configASSERT` 在 FreeRTOS 内部可达 → 三个内核钩子都在链尾),实测每条链多背 64 B;
|
||||
- 适用:内核前 / 未注册期、ISR、异常钩子(栈溢出 / 堆失败)、崩溃上报;
|
||||
- 调用方纪律:**只交已知合法的缓冲**——钩子侧先做指针范围校验(Flash / SRAM / CCM 窗口)并拷入本地缓冲再发,TCB 指针不接触 UART(`Src/freertos.c vApplicationStackOverflowHook`,2026-09-24 加固;指针不可信时发占位文本,"上报崩溃的代码不能再崩一次")。
|
||||
- 调用方纪律:**只交已知合法的缓冲**——钩子侧先做指针范围校验(Flash / SRAM / CCM 窗口)并拷入本地缓冲再发,TCB 指针不接触 UART(`Src/freertos.c vApplicationStackOverflowHook`,2026-09-24 加固;指针不可信时发占位文本,"上报崩溃的代码不能再崩一次")。2026-10-10 补充:钩子里的 `name[49]/num[16]` 改**函数级 static**(终点路径、打印完即复位,无并发)——放栈上会让这 81 B 出现在每个任务的最坏链上;行号转换改原地反转,去掉 `HAL_Delay`(`con_tx_bounded` 已等 TC)。
|
||||
|
||||
### 4.5 `fputc` 重定向(MicroLIB `printf`)
|
||||
|
||||
@@ -225,16 +226,21 @@ sequenceDiagram
|
||||
| `dbg_console_writer_attach` | `void (void)` | 写者任务、主循环前 | 注册唯一写者 | 仅一次(defaultTask) |
|
||||
| `dbg_console_drain` | `void (void)` | **仅写者任务** | 排空环并发出 + 刷丢弃计数 | defaultTask 主循环周期调用 |
|
||||
| `dbg_console_dropped` | `uint32_t (void)` | 任意 | 诊断:累计丢弃行数 | 外部读取 |
|
||||
| `dbg_console_tx_fault_log_take` | `uint8_t (void)` | **仅写者任务** | 取并清"TX 故障待上报"标志 | 2026-10-10 加:drain 内**不得**调 `syslog_post`(会成环),由 defaultTask 在 drain 之外补记 run.log |
|
||||
| `fputc` | `int (int ch, FILE *f)` | `printf` 调用点 | MicroLIB retarget 钩子 → 逐字节 `con_append` | 须为全局符号(C 库链接) |
|
||||
|
||||
## 6. 常量
|
||||
|
||||
| 常量 | 值 | 定义处 | 含义 |
|
||||
|------|-----|--------|------|
|
||||
| `DBG_CON_LINE_MAX` | 192 | `console_log.h` | 单行文本上限(含结尾 `'\0'`);`DBG_PRINT` 宏行缓冲尺寸;超限截断 |
|
||||
| `DBG_CON_LINE_MAX` | 192 | `console_log.h` | 单行文本上限(含结尾 `'\0'`);环形缓冲/入环截断上限;超限截断 |
|
||||
| `DBG_LINE_BUF_MAX` | = `DBG_CON_LINE_MAX`(深链模块设 **128**) | `dbg_log.h` | **调用点栈上行缓冲尺寸**(2026-10-10 加)。已收紧:`nand_ftl`/`gd5f2gq5ue`/`cfg_file`/`net_cfg`/`net_socket`/`ch395f`/`time_sync`/`default_task`。取值须 ≥ 该模块最长日志行,否则该行被截断 |
|
||||
| `DBG_TS_BUF_MAX` | 24 | `dbg_log.h` | 时间戳文本缓冲(`sys_clock_get_str` 恒写 19 字符 + `'\0'`);与行缓冲**共用一个数组** |
|
||||
| `DBG_CON_RING_SIZE` | 4096 | `console_log.c` | 环形缓冲字节数(必须为 2 的幂) |
|
||||
| `DBG_CON_CHUNK_MAX` | 256 | `console_log.c` | 写者单次发送上限 = 裸发上限 |
|
||||
| `DBG_CON_WAIT_MS` | 200 | `console_log.c` | 缓冲满时生产者最长等待(1ms/轮,仍满 → 丢弃 + 计数) |
|
||||
| `CON_TX_TIMEOUT_CYC` | `SystemCoreClock/10` | `console_log.c` | 裸发硬上界 = 100 ms 对应 DWT 周期数 |
|
||||
| `CON_TX_GUARD_MAX` | 20000 | `console_log.c` | DWT 不可用时的**计数**上界(每字节 / TC 各数一次;115200 下一字节约需 3000 次轮询,留 6 倍余量) |
|
||||
| 写者循环超时 | 50 ms | `App/task/default_task.c` | `osEventFlagsWait` 兜底周期 |
|
||||
|
||||
## 7. 失效模式与可观测性
|
||||
@@ -247,7 +253,7 @@ sequenceDiagram
|
||||
| ISR 直发撞写者发送中 | 立即 `HAL_BUSY` 返回 → 丢失,不挂死 | 未计数 | ISR 日志频率极低,best-effort 语义 |
|
||||
| 内核状态损坏(栈溢出 / 堆耗尽) | 钩子裸发固定文本 → 复位(栈溢出)/ 仅告警(堆) | `[ERR] STACK OVERFLOW task=…` / `[ERR] MALLOC FAILED …`;任务名范围校验 + 本地拷贝,TCB 指针不入 UART | — |
|
||||
| 调用方指针损坏(脏指针) | 无法进入 UART(缓冲恒为环 / 模块本地) | 2026-09-24 HardFault 路径结构性消除 | — |
|
||||
| UART 物理失效(发送卡死 / 超时) | `HAL_UART_Transmit` 返回 `HAL_TIMEOUT`;调用点忽略返回值(best-effort 控制台),该块丢弃 | 不入丢弃计数(与"缓冲满"独立);UART 故障由其他可观测面暴露(自检 / 其余日志) | 已知缺口:超时未计数(v2 可加超时计数) |
|
||||
| UART 物理失效(发送卡死 / 超时) | `con_tx_bounded` 在 DWT 上界内返回 `HAL_TIMEOUT` → 该块丢弃 + **UART 重初始化**(僵尸通道自愈,§12) | 2026-10-10 起:drain 内**只置标志** `s_con_tx_fault_log`,由 defaultTask 在 drain 之外 `syslog_post(SYSLOG_RUN, "console tx fault, uart reinit")` 补记 run.log(旧实现直接在 drain 里调 `syslog_post` → `write_line → con_append → drain → syslog_post → write_line` **调用图成环**,静态栈在每个任务上多叠一条日志尾巴) | 已知缺口:丢弃计数与故障计数不分离 |
|
||||
| `sys_evt` 对象缺失(句柄 NULL) | 唤醒空操作,50ms 兜底 | 至多 50ms 时延 | — |
|
||||
|
||||
## 8. 内存预算
|
||||
@@ -256,10 +262,12 @@ sequenceDiagram
|
||||
|----|------|------|
|
||||
| `s_con_ring` | 4096 B | BSS(SRAM1,非 CCM) |
|
||||
| `s_con_head/tail/drop/writer_up/writer_task` | ≈14 B | BSS |
|
||||
| 生产者行缓冲 `__con_line`(`DBG_PRINT` 宏局部) | 192 B/调用 | 调用者任务栈(入环后即释放,峰值非累积) |
|
||||
| 生产者行缓冲 `__con_line`(`DBG_EMIT` 宏局部) | 默认 192 B + 时间戳 24 B;**深链模块 128 + 24 B**/调用 | 调用者任务栈(入环后即释放,峰值非累积) |
|
||||
|
||||
**结论:静态 +4.1KB(SRAM1);FreeRTOS 堆零增量、无新任务/栈、无新内核对象。** 2026-09-25 实测:`heap free=8776B, min_ever=4816B`(CCM 堆不受影响);`__con_line` 192B 峰值在各任务既有栈预算内(任务栈按 2026-09-21 实测峰值 ×1.5 + 1KB ISR 余量定档,见 AGENTS.md 任务栈表;当日栈水位复测 6 任务全 PASS)。
|
||||
|
||||
> ⚠️ **2026-10-10 修正"行缓冲不贵"的结论**:行缓冲是**每个日志调用点**在栈上内联的一份数组,会进 armlink 最坏调用链。实测 defaultTask 那条最深链上 **9 个帧各含一份**(192 + 32 B)→ **约 1.5 KB 纯粹是日志行缓冲**,是该项目静态栈链的第一大项。处置 = `dbg_log.h` 新增 `DBG_LINE_BUF_MAX`(深链模块收到 128)+ 时间戳缓冲并入行缓冲(32 → 24),**未抬栈**即把该链 5312 → 2776 B。核算与前后对比见 `docs/内存管理/RAM使用分析与优化方案.md`"2026-10-10 复测"。
|
||||
|
||||
## 9. 设计决策与否决的替代方案
|
||||
|
||||
| # | 替代方案 | 否决 / 采纳理由 |
|
||||
@@ -334,3 +342,4 @@ sequenceDiagram
|
||||
| v1.0 | 2026-09-25 | 初版:完整设计说明(背景根因 / 单写者模型 / 详细设计 / API / 参数 / 失效模式 / 内存预算 / 设计决策 / 验证记录);实现位于 `App/log/console_log.{h,c}` |
|
||||
| v1.1 | 2026-09-25 | 文件拆分同步:写者任务体迁至 `App/task/default_task.c`(`Src/freertos.c` 只留 CubeMX 接线与崩溃钩子);§3.2 文件清单 / §4.3 / §6 / §11 位置引用更新 |
|
||||
| v1.2 | 2026-10-02 | 新增 §12 ORE 僵尸通道(台架 gen-288 实证:节奏性喂狗饥饿,非死等;缓解已做、TX-only 根治待办)+ §11 时间线两条 10-02 记录;§13 新增 O4;原 §12/§13 顺延为 §13/§14 |
|
||||
| v1.3 | 2026-10-10 | 栈链整改(**未抬栈**)三处:① 裸发改为纯寄存器轮询——DWT 不可用时走 `con_tx_counted`(计数上界),**不再回退 `HAL_UART_Transmit`**(tick 依赖不可信 + 其调用链污染所有任务最坏栈链);② 切断 `drain → syslog_post → write_line` **调用图成环**,改为置标志 + 写者任务在 drain 之外补记(新 API `dbg_console_tx_fault_log_take`);③ 行缓冲按模块可收紧(`dbg_log.h` 新增 `DBG_LINE_BUF_MAX`,深链模块 128)+ 时间戳缓冲并入行缓冲(32 → 24)。§4.4 / §5 / §6 / §7 / §8 同步;实测 defaultTask 静态最坏链 5312 → 2776 B |
|
||||
|
||||
+13
-12
@@ -1,6 +1,6 @@
|
||||
# 网口设置页配置说明
|
||||
|
||||
> 版本:v2.1 日期:2026-09-14
|
||||
> 版本:v2.2 日期:2026-10-10
|
||||
> 适用工程:STM32F4-Base(STM32F407ZGTx + CH395F 以太网控制器)
|
||||
> 范围:UI「网口设置」页可配置的网口参数(IP 地址 / 子网掩码 / 默认网关 / MAC 地址)——
|
||||
> 参数与默认值、持久化、生效链路、页面操作与权限。
|
||||
@@ -13,7 +13,7 @@
|
||||
|---|---|
|
||||
| **可配置** | IP 地址、子网掩码、默认网关、MAC 地址 |
|
||||
| **入口** | 屏幕:`通讯参数 → 网口设置`(修改密码 `123` 可编辑;查看密码 `000` 只读) |
|
||||
| **存储** | NAND Flash 文件 `/config.ini`(INI `[network]` 段,通用配置文件,掉电不丢);旧版 `/cfg/netcfg.bin` 首启自动迁移 |
|
||||
| **存储** | NAND Flash 文件 `/config.ini`(INI `[network]` 段,通用配置文件,掉电不丢);旧版 `/cfg/netcfg.bin` **不再读取**(存在则忽略,见 §3.2) |
|
||||
| **生效** | 按「保存」后**立即生效**(网络重建约 1~3s,既有 TCP 连接会断开,无需重启) |
|
||||
| **工厂默认** | `192.168.1.100` / `255.255.255.0` / `192.168.1.1` / 芯片内置 MAC |
|
||||
|
||||
@@ -83,17 +83,18 @@ mac=00:00:00:00:00:00
|
||||
|
||||
完整设计(引擎 / 双端 / 并发模型 D15)见 `docs/子系统设计/配置文件设计说明.md`。
|
||||
|
||||
### 3.2 旧版档迁移(首启)
|
||||
### 3.2 旧版二进制档 `/cfg/netcfg.bin`:已不再兼容(2026-10-10)
|
||||
|
||||
旧版格式 `/cfg/netcfg.bin`(28B:magic `'NCFG'` + ver + CRC-16/MODBUS + 18B 字段,格式拥有者 `net_cfg_legacy.c`):
|
||||
旧版格式 `/cfg/netcfg.bin`(28B:magic `'NCFG'` + ver + CRC-16/MODBUS + 18B 字段)的"首次启动自动迁移"已于 **2026-10-10 删除**(`net_cfg_legacy.c/h` 整体移除,该格式的解析代码不再存在)。
|
||||
|
||||
| `/config.ini` 缺失 | `/cfg/netcfg.bin` | 行为 |
|
||||
| `/config.ini` | `/cfg/netcfg.bin` | 行为 |
|
||||
|---|---|---|
|
||||
| 是 | 有效(magic/ver/CRC 通过) | 4 字段转 INI 行 → 写 `/config.ini`(带旧值)→ **删旧档** |
|
||||
| 是 | 缺失 / 无效 | 生成出厂模板;**保留旧档**(留人工检查) |
|
||||
| 否 | — | 正常加载现有文件(不迁移) |
|
||||
| 缺失 | 存在(有效或无效都一样) | 生成出厂模板 → **工厂默认**;旧档**被忽略**(不读、不删、不迁移) |
|
||||
| 缺失 | 缺失 | 生成出厂模板 → 工厂默认 |
|
||||
| 存在 | — | 正常加载现有文件 |
|
||||
|
||||
迁移单向:旧档转换后删除(避免双数据源);新文件存在时恒跳过。
|
||||
- **删除理由**:该一次性路径把整条配置**写**链(`net_cfg_save → cfg_file_save → cfg_store_write_atomic → f_rename → FatFS → dhara FTL`)无条件挂进启动期调用图,使 defaultTask 的 armlink 静态最坏栈链 **+600 B**;而本仓库不存在携带旧档的设备。
|
||||
- **对使用方的影响**:卷上仍残留旧档的设备升级本版本后,网口配置**回落工厂默认**(`192.168.1.100/24`、gw `.1`),需经 UI「网口设置」或 FTP 上传 `/config.ini` 重新配置。
|
||||
|
||||
### 3.3 存储后端(双端)
|
||||
|
||||
@@ -125,7 +126,7 @@ sequenceDiagram
|
||||
DT-->>NT: 置 SYS_EVT_STORAGE_READY(就绪屏障)
|
||||
NT->>NT: 等 SYS_EVT_STORAGE_READY(≤10s;超时用工厂默认继续)
|
||||
NT->>CFG: net_cfg_load()
|
||||
Note over CFG: 注册 [network] 段 → 首启自动迁旧档 → 读 /config.ini;缺失/非法键 → 工厂默认
|
||||
Note over CFG: 注册 [network] 段 → 读 /config.ini;缺失/非法键 → 工厂默认
|
||||
CFG-->>NT: RAM 副本(有效)
|
||||
NT->>CFG: net_cfg_get() → net_cfg_fmt_ipv4()
|
||||
CFG-->>NT: "192.168.001.100"
|
||||
@@ -212,7 +213,6 @@ ENTER 进入选中地址行 → `↑/↓` 调活动字节(0..255 **环绕**)
|
||||
| 文件 | 职责 |
|
||||
|---|---|
|
||||
| `Drivers/BSP/NETCFG/net_cfg.h/.c` | 配置核心:RAM 副本 + 工厂默认 + 加载/保存编排 + MAC 影子 + IPv4 格式化([network] 段注册) |
|
||||
| `Drivers/BSP/NETCFG/net_cfg_legacy.c` | 旧版 NCFG 二进制格式拥有者:首启一次性迁移(校验 → 物化 → 删旧档) |
|
||||
| `App/cfg/cfg_file.h/.c` | 通用配置文件引擎(双端共享核心:解析/校验/外科保存/模板/沉降轮询) |
|
||||
| `App/cfg/cfg_file_store.h` | 存储后端接口(带路径的文件操作) |
|
||||
| `App/cfg/cfg_file_store_mcu.c` | MCU 后端:FatFS `/config.ini`(`/config.TMP` + `f_rename` 原子写) |
|
||||
@@ -226,7 +226,7 @@ ENTER 进入选中地址行 → `↑/↓` 调活动字节(0..255 **环绕**)
|
||||
|
||||
| API | 说明 |
|
||||
|---|---|
|
||||
| `net_cfg_load()` | 注册 `[network]` 段 + 旧档迁移 + 从 `/config.ini` 加载到 RAM 副本;缺失/非法键回退工厂默认(恒返回 0) |
|
||||
| `net_cfg_load()` | 注册 `[network]` 段 + 从 `/config.ini` 加载到 RAM 副本;缺失/非法键回退工厂默认(恒返回 0) |
|
||||
| `net_cfg_save()` | 经 cfg_file 引擎写 `/config.ini`(外科手术式保存);0 成功 / -1 失败 |
|
||||
| `net_cfg_request_apply()` | 请求立即应用(页面保存成功后调用) |
|
||||
| `net_cfg_set_apply_cb()` | 注册"立即应用"平台回调 |
|
||||
@@ -265,5 +265,6 @@ ENTER 进入选中地址行 → `↑/↓` 调活动字节(0..255 **环绕**)
|
||||
|
||||
| 日期 | 变更 |
|
||||
|---|---|
|
||||
| 2026-10-10 | v2.2:**删除旧档 NCFG 迁移**——`net_cfg_legacy.c/h` 整体移除、`cfg_store_legacy_path()` 撤销;旧档 `/cfg/netcfg.bin` 若存在则被忽略(不读、不删、不迁移),配置回落工厂默认。理由:该一次性路径把整条配置写链挂进启动期调用图,defaultTask 静态最坏栈链 +600 B,且本仓库无携带旧档的设备 |
|
||||
| 2026-09-14 | v2.1:存储迁移至**通用配置文件** `/config.ini`(INI `[network]` 段,cfg_file 引擎:逐键校验 / 外科手术式保存 / 原子写 / 旧档首启迁移 / 沉降轮询);`net_cfg_store.*` 弃用(由 `cfg_file_store.*` 取代);对外 API 不变 |
|
||||
| 2026-09-10 | MAC 显示改为常识格式 **`A4:94:B6:12:34:56`**(冒号分隔,17 字符);页面布局左移(名 x=4 / 值 x=54)以容纳 102px 宽度,编辑光标段偏移随之为 3i |
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
| 项 | 现状 |
|
||||
|---|------|
|
||||
| 卷 | GD5F2GQ5UE SPI NAND **256MB**(2048 块 × 64 页 × 2KB),dhara FTL(磨损均衡/坏块管理),FatFS FAT32,`FF_USE_LFN=0` → **文件名必须 8.3** |
|
||||
| FTP | lftpd 根目录 = 卷根 `/`;现有文件 `/config.ini`、`/cfg/netcfg.bin`(均 8.3) |
|
||||
| FTP | lftpd 根目录 = 卷根 `/`;现有文件 `/config.ini`(8.3);旧档 `/cfg/netcfg.bin` 已废弃——现固件不读不写也不删(仅可能残留在旧设备上) |
|
||||
| 并发 | `FF_FS_REENTRANT=1` + 系统锁(`ffsystem.c` osMutex):单次 `f_*` 调用受保护,**多调用序列(open→seek→write→close)需单写者纪律** |
|
||||
| 墙钟 | `sys_clock_get_str(buf,20)` → `"YYYY-MM-DD HH:MM:SS"`;`sys_clock_get()` → Unix 秒(失败 = `UINT32_MAX`);SD2506 RTC + timeSyncTask TCP 校时 |
|
||||
| 挂载 | defaultTask:`f_mount(forced=1)`,空卷自动 `f_mkfs` FAT32,成功后置 `SYS_EVT_STORAGE_READY` |
|
||||
|
||||
+23
-25
@@ -34,7 +34,7 @@
|
||||
| ③ | FatFS 零并发保护(`FF_FS_REENTRANT=0`,应用层无锁) | ftpTask(FTP 传输)/ defaultTask(配置加载/保存/轮询)并发触卷 → 卷损坏 | `FF_FS_REENTRANT=1` + ffsystem.c 互斥钩子(§5.4)+ 三条一致性协议(D15:tmp+rename / 沉降去抖 / 单写者) |
|
||||
| ④ | 无变更检测 | FTP 上传后不生效(需重启) | defaultTask 每 2s `f_stat` 轮询(size + mtime)(§5.3) |
|
||||
| ⑤ | `FF_FS_NORTC=1` → 时间戳恒为固定值 | mtime 不变 → 无法检测"同尺寸编辑"(如 IP 尾段 100→200) | `NORTC=0` + `get_fattime`(复用调试日志墙钟源,运行期零 I2C)(§5.5) |
|
||||
| ⑥ | 固件升级无迁移 | 现场设备升级后用户配置丢失(回工厂默认) | NCFG blob → INI 自动迁移(§9) |
|
||||
| ⑥ | 固件升级无迁移 | 现场设备升级后用户配置丢失(回工厂默认) | NCFG blob → INI 自动迁移(§9;该迁移已于 2026-10-10 撤销) |
|
||||
| ⑦ | RAM 静态区仅余 5.8 KB(占用 95.4%) | 不能新增大静态缓冲 | 稳态零增量 + 暂态堆缓冲(§8) |
|
||||
|
||||
### 1.3 非目标(本期不做)
|
||||
@@ -57,7 +57,7 @@
|
||||
| D7 | 线程安全 | **`FF_FS_REENTRANT=1` + `Lib/FatFs/ffsystem.c`**(`ff_mutex_*` → osMutex,超时 1s) | FatFs 官方可重入方案;每次 f_* 调用加锁/放锁(逐次粒度,不长期阻塞 FTP 传输);`FR_TIMEOUT` 防死锁 |
|
||||
| D8 | 时间戳 | **`FF_FS_NORTC=0` + `get_fattime`(复用 `sys_clock` 墙钟,与调试日志时间戳同源)** | mtime 为真实时间、与日志时间戳一致;墙钟 = 开机 RTC 基准 + tick 推进,运行期零 I2C;墙钟无效时回退固定值(有开机告警) |
|
||||
| D9 | 写原子性 | **一切写入 = 临时文件 + `f_rename`**(设备保存 / FTP STOR / 出厂模板统一:先写 `<名>.TMP`(8.3 兼容),关文件成功后 rename 目标) | 同目录 rename = 单目录项写入,卷锁下原子 → 并发读者只见"旧完整文件或新完整文件",半截窗口结构消除;STOR 中途掉电仅残留 TMP(无害);逐键容错 + 下次保存自愈为次级兜底 |
|
||||
| D10 | 旧档迁移 | 新固件首启:NCFG blob → INI,**迁移后删除旧文件** | 防现场升级丢配置;否决"保留旧文件"(双数据源、陈旧值混乱) |
|
||||
| D10 | 旧档迁移 | ~~新固件首启:NCFG blob → INI,迁移后删除旧文件~~ → **2026-10-10 撤销:旧档不读、不删、不迁移** | 原理由:防现场升级丢配置;否决"保留旧文件"(双数据源、陈旧值混乱)。**撤销理由**:该一次性路径把整条配置写链(`net_cfg_save → cfg_file_save → cfg_store_write_atomic → f_rename → FatFS → dhara FTL`)挂进启动期调用图,defaultTask 静态最坏栈链 +600 B;本仓库不存在携带旧档的设备 → 按"不保留旧档兼容"处置(见 §9.1) |
|
||||
| D11 | 出厂默认 | 文件缺失时**自动生成带注释模板**并落盘 | 首启 / 恢复出厂场景;文件自身即"格式手册" |
|
||||
| D12 | 恢复出厂 | **FTP `DELE /config.ini`**(下次上电重新生成) | 本期不做 UI 入口(开放问题 O1) |
|
||||
| D13 | 双端 | 共享 `cfg_file` 核心 + 平台 store 后端(沿用 net_cfg_store 模式) | MCU = FatFS `/config.ini`;模拟器 = 宿主文件 `sim_config.ini` |
|
||||
@@ -130,7 +130,7 @@ mac=00:00:00:00:00:00
|
||||
|
||||
| 场景 | 加载行为 | 保存行为 |
|
||||
|---|---|---|
|
||||
| 文件不存在 | 工厂默认;自动生成模板(有旧 blob 时优先迁移,见 §9) | 写当前值 |
|
||||
| 文件不存在 | 工厂默认;自动生成模板(旧 blob 若存在也**不读、不迁移**,见 §9.1) | 写当前值 |
|
||||
| 段缺失 / 键缺失 | 该键取工厂默认 | 补写缺失键(段缺失则补整段) |
|
||||
| 键值非法 | 该键取工厂默认 + 日志 | 重写为合法值(自愈) |
|
||||
| 文件 > 4KB / 严重损坏 | 全部工厂默认 + `DBG_ERROR` | 整文件重生成(已知数据保留,未知内容丢失) |
|
||||
@@ -155,7 +155,7 @@ mac=00:00:00:00:00:00
|
||||
| `Lib/FatFs/ffconf.h` | 修改 | MCU | `FF_FS_REENTRANT` 0→1;`FF_FS_NORTC` 1→0 |
|
||||
| `App/util/sys_clock.c/.h` | 修改 | MCU | 新增 `sys_clock_get_time()`(日历时间获取器);改归 ④中间件层,自 `App/` 移入 `App/util/` |
|
||||
| `Drivers/BSP/NETCFG/net_cfg.h/.c` | 重构 | 双端 | `net_cfg_*` API 不变;load/save 走 cfg_file;注册 `[network]` 段 |
|
||||
| `Drivers/BSP/NETCFG/net_cfg_legacy.c` | **新增** | 双端 | 旧 NCFG blob 解析 + 迁移 |
|
||||
| `Drivers/BSP/NETCFG/net_cfg_legacy.c` | **已删除**(2026-10-10;曾于 P3 新增) | — | 旧 NCFG blob 解析 + 迁移;随"不保留旧档兼容"整体移除(见 §9.1) |
|
||||
| `Drivers/BSP/NETCFG/net_cfg_store.h` / `net_cfg_store_mcu.c` | **删除** | — | 由 `cfg_file_store.*` 取代 |
|
||||
| `simulator/sim/net_cfg_store_sim.c` | **删除** | 模拟器 | 由 `cfg_file_store_sim.c` 取代 |
|
||||
| `App/task/net_task.c` | 修改 | MCU | 主循环每 2s `cfg_file_poll()` |
|
||||
@@ -234,11 +234,7 @@ sequenceDiagram
|
||||
participant NS as 网络层
|
||||
DT->>FS: f_mount(无卷自动 f_mkfs)
|
||||
alt /config.ini 不存在
|
||||
alt 存在旧 /cfg/netcfg.bin
|
||||
DT->>FS: 读旧 blob 校验 → 转写 /config.ini → 删旧文件
|
||||
else 无旧文件
|
||||
DT->>FS: 生成出厂模板 → 写 /config.ini
|
||||
end
|
||||
DT->>FS: 生成出厂模板 → 写 /config.ini(旧 /cfg/netcfg.bin 不读、不删、不迁移)
|
||||
end
|
||||
DT->>FS: net_cfg_load():读 /config.ini → 解析入 RAM 副本(含 [network] 段注册)
|
||||
DT->>NT: 置 SYS_EVT_STORAGE_READY(= 卷挂载 + 配置就绪)
|
||||
@@ -385,11 +381,11 @@ void *cfg_store_alloc(size_t size); /* 失败返回 NULL,由调用方
|
||||
void cfg_store_free(void *p_buf); /* NULL 安全;只接受 cfg_store_alloc 返回值 */
|
||||
uint32_t cfg_store_heap_free(void); /* 空闲堆诊断量;模拟器恒 0 */
|
||||
|
||||
/* 路径由后端提供(MCU: /config.ini、/config.TMP、/cfg/netcfg.bin;
|
||||
* 模拟器: sim_config.ini、sim_config.ini.tmp、sim_netcfg.bin) */
|
||||
/* 路径由后端提供(MCU: /config.ini、/config.TMP;
|
||||
* 模拟器: sim_config.ini、sim_config.ini.tmp)
|
||||
* 注:旧版遗留档 getter cfg_store_legacy_path() 已于 2026-10-10 随旧档迁移删除 */
|
||||
const char *cfg_store_config_path(void);
|
||||
const char *cfg_store_tmp_path(void);
|
||||
const char *cfg_store_legacy_path(void);
|
||||
```
|
||||
|
||||
### 6.3 未来模块接入模板
|
||||
@@ -427,7 +423,7 @@ void adc_cfg_init(void)
|
||||
### 6.4 net_cfg 兼容承诺
|
||||
|
||||
- `net_cfg_load/save/get/set/get_mac/set_active_mac/fmt_ipv4/set_apply_cb/request_apply` **签名与语义全部不变**
|
||||
- 内部:`net_cfg_load` = 段注册 + 旧档迁移(`net_cfg_legacy_migrate`)+ `cfg_file_load`;`net_cfg_save` = `cfg_file_save`
|
||||
- 内部:`net_cfg_load` = 段注册 + `cfg_file_load`(旧档迁移已于 2026-10-10 删除);`net_cfg_save` = `cfg_file_save`
|
||||
- UI 页(`ui_page_net_cfg.c`)、启动流程(`net_task.c`)、模拟器入口(`main.c`)的**调用点无需改动**
|
||||
|
||||
## 7. 双端支持
|
||||
@@ -437,11 +433,11 @@ void adc_cfg_init(void)
|
||||
| 后端 | `cfg_file_store_mcu.c`(FatFS) | `cfg_file_store_sim.c`(宿主文件) |
|
||||
| 文件路径 | `/config.ini`(NAND 卷根) | `sim_config.ini`(工作目录) |
|
||||
| mtime 来源 | FAT 打包时间(`fdate<<16\|ftime`,分钟级粒度) | 宿主文件系统(秒级) |
|
||||
| 旧档迁移 | `/cfg/netcfg.bin`(NCFG blob) | `sim_netcfg.bin`(同格式) |
|
||||
| 旧档(已废弃) | `/cfg/netcfg.bin` **不读、不删、不迁移**(2026-10-10) | `sim_netcfg.bin` 同样不读、不删、不迁移 |
|
||||
| 变更轮询 | defaultTask 2s | 主循环 2s(编辑器改动 2s 内反映) |
|
||||
| 弃用 | — | `net_cfg_store_sim.c` 删除 |
|
||||
|
||||
模拟器行为:首跑无 `sim_config.ini` 而有 `sim_netcfg.bin` → 自动迁移并删旧文件;运行中用编辑器改 `sim_config.ini` → 2s 内自动重载(模拟器无网络重建概念,[network] 段"应用" = 刷新 RAM 副本)。
|
||||
模拟器行为:首跑无 `sim_config.ini` → 生成出厂模板(残留的 `sim_netcfg.bin` 被忽略);运行中用编辑器改 `sim_config.ini` → 2s 内自动重载(模拟器无网络重建概念,[network] 段"应用" = 刷新 RAM 副本)。
|
||||
|
||||
## 8. 内存预算
|
||||
|
||||
@@ -464,27 +460,28 @@ void adc_cfg_init(void)
|
||||
|
||||
## 9. 兼容与迁移
|
||||
|
||||
### 9.1 旧文件迁移(新固件首启)
|
||||
### 9.1 旧文件迁移:已删除(2026-10-10)
|
||||
|
||||
旧 NCFG 二进制档 `/cfg/netcfg.bin` 的"首启自动迁移"已整体删除(`net_cfg_legacy.c/h` 移除、`cfg_store_legacy_path()` 撤销)。现行为:
|
||||
|
||||
```
|
||||
/config.ini 缺失?
|
||||
├─ 是 → /cfg/netcfg.bin 存在且有效(magic/ver/CRC)?
|
||||
│ ├─ 是 → 4 字段转 INI 行 → 原子写 /config.ini → 删旧文件
|
||||
│ │ 日志: "cfg file: legacy NCFG migrated"
|
||||
│ └─ 否 → 生成出厂模板
|
||||
├─ 是 → 生成出厂模板 → 工厂默认
|
||||
│ (/cfg/netcfg.bin 无论存在与否、有效与否:不读、不删、不迁移)
|
||||
└─ 否 → 正常加载现有文件
|
||||
```
|
||||
|
||||
- 迁移单向:旧文件转换后删除(避免双数据源)
|
||||
- 旧 blob 损坏:按不存在处理 → 出厂模板(旧文件保留,可人工查看)
|
||||
- 旧格式(28B:magic 'NCFG' + ver + CRC-16/MODBUS + 18B 字段)已无解析代码;`App/util` 的 CRC-16/MODBUS 模块随之失去唯一调用者
|
||||
- **删除理由**:该一次性路径把整条配置**写**链(`net_cfg_save → cfg_file_save → cfg_store_write_atomic → f_rename → FatFS → dhara FTL`)挂进启动期调用图,使 defaultTask 的 armlink 静态最坏栈链 **+600 B**;而本仓库不存在携带旧档的设备
|
||||
- 残留旧档不会被自动清理,需要时可经 FTP 手工删除(该文件对现固件无任何作用)
|
||||
|
||||
### 9.2 现场升级 / 降级场景
|
||||
|
||||
| 场景 | 行为 |
|
||||
|---|---|
|
||||
| 旧设备(有 netcfg.bin)升级新固件 | 自动迁移,用户配置保留 |
|
||||
| 旧设备(有 netcfg.bin)升级新固件 | 旧档**被忽略**(不读、不删、不迁移)→ 配置回落工厂默认,需经 UI / FTP 重新配置(2026-10-10 起) |
|
||||
| 新设备 / 格式化卷 | 出厂模板 |
|
||||
| 新文件被**旧固件**读(降级) | 旧固件只读 `/cfg/netcfg.bin`(已删)→ 工厂默认;**降级需人工恢复网口配置**(已知限制,O2) |
|
||||
| 新文件被**旧固件**读(降级) | 旧固件只读 `/cfg/netcfg.bin`——现固件不读也不删该文件,故它仍在卷上、旧固件按旧值运行;**新旧固件配置互不同步**(已知限制,O2) |
|
||||
| 含未来段的新文件被旧固件读 | 旧固件不读该文件 → 文件不受影响 |
|
||||
|
||||
### 9.3 恢复出厂
|
||||
@@ -515,7 +512,7 @@ void adc_cfg_init(void)
|
||||
|---|---|---|
|
||||
| `cfg file: loaded OK` | 上电加载成功 | Required(P4 起纳入 `@test`) |
|
||||
| `cfg file: factory template written` | 首启 / 删文件 | 条件(手工) |
|
||||
| `cfg file: legacy NCFG migrated` | 旧文件迁移 | 条件(真机首次升级) |
|
||||
| `cfg file: legacy NCFG migrated` | 旧文件迁移 | **已作废**(2026-10-10 旧档迁移删除,该标记不再产生) |
|
||||
| `cfg file: saved OK` | UI 保存 | 条件(手工) |
|
||||
| `cfg file: change detected` | FTP 上传 | 条件(P7 闭环) |
|
||||
| `cfg file: ... FAILED` | 任何失败 | Forbidden |
|
||||
@@ -589,3 +586,4 @@ void adc_cfg_init(void)
|
||||
| 2026-09-22 | v1.12:**E-01 超长守卫根治**(错误码传播审计第一档 #3,commit d030cb0)——poll 的"超长=损坏"检查写在截断后读长(`s_load_file` 读长钉死 4096)上**恒假=死码**,超长文件被截断当有效解析 → 界外静默回工厂默认 → 基线粘住 → 用户配置销毁链。① poll 沉降分支判定改用 `cfg_store_stat` 真实 `st.size` 且**先于读取**,超长走"工厂默认 + 重建模板 + `cfg poll oversized` 自检留痕",**刻意不触发段回调**(避免按工厂 IP 重建网络造成静默失联,保留 FTP 修复通道,保存/重启收敛)② `s_surgical` 输出上限 `CFG_OUT_MAX`(5120) 收紧至 `CFG_FILE_MAX_LEN`(4096),超限走溢出中止路径(原文件不动 + `cfg save overflow` 自检)——消除"合法写出 4097~5120B 文件 = 下次开机销毁"的雷 ③ `s_write_doc` 唯一落盘闸口硬拒 >4096B(结构性保证)④ load 超长分支补 `cfg load oversized` 自检;`cfg_file.h` v1.2 契约同步;模拟器 cfgtest 新增两回归锁(4160B 伪造 → poll 判损坏重建;4000B 注释文件 → save 拒写且原文件未动)。**台架验证暴露并修复**:`cfg_store_write_atomic` MCU 后端 `f_rename` 对已存在目标返回 `FR_EXIST` 不覆盖 → 设备端一切"目标存在的覆盖写"(UI 保存/模板重建)静默失败、仅首启建文件成功——v1.9 已为模拟器后端修过同款(MSVC `rename()` C1117),MCU 侧漏了对称修复;修复 = rename 前先 `unlink` 目标(commit 70f1cc8)。双端 0 错 0 警、cfgtest PASS、台架 FTP 5047B 用例 poll/load 双路径自愈 PASS(重建 523B 工厂模板 + selftest 留痕 + 不掉线)、`@test` 默认闭环 PASS、ST-LINK 全片回读一致 |
|
||||
| 2026-10-03 | v1.13:**真机验证 PASS(A1 闭环)**——v1.11 的 P0-1 堆分配改造在真机上验证通过:`[CFG] load: OK (523B, heap free 8840B)`(**经 FreeRTOS 堆分配**,即 512B C 堆约束的验收点);Forbidden `FAIL`/`[ERR]` 零命中;FTP 改配置 IP→`192.168.1.101` 后**复位即加载生效**(`[NET_CFG] load: OK ip=192.168.1.101` + 芯片 `IP_INF` .101 + 21 端口探测可达),原档恢复后复测回 .100。真机全闭环 `@test` PASS 7/7。**台架步骤与判据见 `测试说明/实机测试实施指南.md` §3 / §10** |
|
||||
| 2026-10-04 | **P0-1 真机独立复跑 PASS(二次确认,代码零改动)**——`@build` 0/0(增量,无源文件新于镜像)→ `@test` **VERDICT PASS(rc=0)**:`[2026-10-04 00:01:21][CFG] load: OK (523B, heap free 8840B)` + `[NET_CFG] load: OK ip=192.168.1.100`,Forbidden `FAIL`/`ERROR`/`HardFault`/`[ERR]` 零命中,`selftest: no fault record`(先清掉 2026-10-02/03 故障注入窗口遗留的 67 条台账)→ ST-LINK 全片回读 `No difference found`(`0x08000000~0x08040F9B`)。**本次为 `待处理内容.md` §4.1「待验证」唯一未闭环项(P0-1)的收口**,该节现已清空 |
|
||||
| 2026-10-10 | v1.14:**删除旧档 NCFG 迁移(D10 撤销)**——`Drivers/BSP/NETCFG/net_cfg_legacy.{c,h}` 整体移除、`cfg_store_legacy_path()` 撤销(MCU / 模拟器后端与主机单测 `test/host/cfg_file/cfg_file_test.c` 同步删除),`net_cfg_load` 不再调用 `net_cfg_legacy_migrate()`;旧档 `/cfg/netcfg.bin` 若存在则被**忽略**(不读、不删、不迁移),配置回落工厂默认。理由:该一次性路径把整条配置写链挂进启动期调用图,defaultTask 静态最坏栈链 **+600 B**(该链整体 5312 → 2776 B,另三个杠杆见 `docs/内存管理/RAM使用分析与优化方案.md`),而本仓库不存在携带旧档的设备。连带影响:`App/util` 的 CRC-16/MODBUS 失去唯一调用者(现为零调用者);模拟器 `--cfgtest` 不再覆盖迁移场景;§2 D10 / §3.5 / §4.2 / §5.1 / §6.2 / §6.4 / §7 / §9 / §11.1 同步 |
|
||||
|
||||
+18
-18
@@ -38,7 +38,7 @@
|
||||
| 级别 | 数量 | 关键项 |
|
||||
|---|---|---|
|
||||
| **P1** | 1 (+1 收尾) | **P1-1 ADC 采样路径产品构建中死亡**;P1-10 测试固件构建实测闭环(主体已闭环,见 §3.1) |
|
||||
| 登记簿 | 10 | 网络:N-2(49s 日志静默,**低风险观察项**)、N-3(L5 基线重验)、N-4(pending 二期)、N-16(A2/A4 专项负向验证)、N-17(探针窗口心跳缺口);存储/日志:**S-1(defaultTask 栈余量 10%,需尽快处理)**、S-3(USART1 TX-only 根治)、S-4(dhara 重试自旋)、S-5(可选全序列卷锁);硬件:**N-18(8 路电气量分属两转换器 = V0.1 缺陷,V0.2 改版项)** |
|
||||
| 登记簿 | 9 | 网络:N-2(49s 日志静默,**低风险观察项**)、N-3(L5 基线重验)、N-4(pending 二期)、N-16(A2/A4 专项负向验证)、N-17(探针窗口心跳缺口);存储/日志:**S-3(USART1 TX-only 根治)**、S-4(dhara 重试自旋)、S-5(可选全序列卷锁);硬件:**N-18(8 路电气量分属两转换器 = V0.1 缺陷,V0.2 改版项)** |
|
||||
| 测试/基础设施 | 5 | T-7(CI runner 未就绪)+ 测试架构专项 **S12**(断言宏)、**S1-c**(可选单测)、**A-4**(采集链路测试约束)、**A-5 残余**(CI 体积门禁盲区) |
|
||||
|
||||
> **网络侧另有 E-xx 未闭环项**(E-12/15/16/23/24/25/26/27/28/30/47/48/49/50/58/59/61,共 17 项)
|
||||
@@ -51,8 +51,9 @@
|
||||
2. **真正的产品功能缺口在 ADC 与 RS-485 采集链路**:`adc_task`/`rs485_task` 均为空桩,
|
||||
DTU 的核心职责(数据采集与转发)**尚未实现**。这既是 P1-1 的根源,也是 E-59 那条
|
||||
"休眠缺陷闸门"的另一面——不是缺陷难修,而是**功能没接**。
|
||||
3. **验证债已基本还清,重心是"功能债" + 一项栈风险**:剩余验证债仅 **N-3(L5 基线重锁,
|
||||
待 PC peer)** 与 **S-1(defaultTask 栈余量已跌至 10%,见 §6)**。
|
||||
3. **验证债已基本还清,重心是"功能债"**:剩余验证债仅 **N-3(L5 基线重锁,待 PC peer)**
|
||||
(原 **S-1 栈风险已于 2026-10-10 削链闭环并销项**:defaultTask 静态最坏链 5312 → 2776 B、
|
||||
实测峰值 3392 → 2152 B,**未抬栈**,见 `docs/内存管理/RAM使用分析与优化方案.md`)。
|
||||
**当前最值得投入的是阶段 B(ADC/RS485 功能)**。
|
||||
|
||||
---
|
||||
@@ -72,7 +73,7 @@
|
||||
| 序 | 任务 | 前置 | 说明 |
|
||||
|---|---|---|---|
|
||||
| **B0** | **产品定义确认**(阻塞项) | — | 需甲方明确:① 采集是否持续 ② 采样率(**通道语义已于 2026-10-09 确认并固化 → `docs/硬件平台/ADC通道映射说明.md`**:UA/UB/UC/UN=`AIN1~4`、IA/IB/IC/IN=`AIN8~11`、V_ZL2=温度、其余 8 路备用;主板只做监视/辅助测量,计量在子板。**注意:8 路电气量分属 TPAFE/STM32 两片转换器属 V0.1 硬件缺陷 → N-18**,主板侧不得做跨转换器的相位/功率类运算) ③ 转发目标(MODBUS RTU?上行 TCP?)④ `APP_ADC_ENABLE`/`APP_RS485_ENABLE` 语义。**B1/B2 的规模完全取决于此** |
|
||||
| **B1** | **ADC 采集链路实现**(消化 P1-1;E-58 已闭环) | B0 + **E-59 门禁**(TPAFE 侧已满足) | 周期 CONVST 重触发 + `adc_task` 消费 **`tpafe5160_snapshot()`**(**2026-10-10 驱动契约已修**:E-44 FRSTDATA 有效性校验 + `init()` 首帧自检返 `-3`、E-45 帧序号取代就绪电平标志、E-58 临界区原子快照;旧 `get_buf`/`data_ready`/`clear_ready` **已删**,删除前零调用者);`adc_task.c` **已挂进 `uvprojx`**(此前 Keil/模拟器两边都不注册 = 永不编译;simulator 无任务层,只挂 Keil);**仍欠**:栈预算核算(两任务未入 `freertos.c` 栈表,建任务前后各跑 `stack_report.py`;先处理 S-1)+ 消费者本体 + 建任务走 **L1(`.ioc` 的 `FREERTOS.Tasks01`)**;**取数必须按 `docs/硬件平台/ADC通道映射说明.md`**(TPAFE `buf[2]=IA`/`buf[5]=UN`/`buf[6]=UA`;STM32 侧 ADC1 **已于 2026-10-09 生成**:`hadc1` + `MX_ADC1_Init()`、9 通道 Rank1~9、144 cycles、ADCCLK=21 MHz、软件触发,网名 ADC17=PC4 用 `ADC_CHANNEL_14`;⚠ 全仓库至今**无 `HAL_ADC_Start`** → STM32 侧一路未跑) |
|
||||
| **B1** | **ADC 采集链路实现**(消化 P1-1;E-58 已闭环) | B0 + **E-59 门禁**(TPAFE 侧已满足) | 周期 CONVST 重触发 + `adc_task` 消费 **`tpafe5160_snapshot()`**(**2026-10-10 驱动契约已修**:E-44 FRSTDATA 有效性校验 + `init()` 首帧自检返 `-3`、E-45 帧序号取代就绪电平标志、E-58 临界区原子快照;旧 `get_buf`/`data_ready`/`clear_ready` **已删**,删除前零调用者);`adc_task.c` **已挂进 `uvprojx`**(此前 Keil/模拟器两边都不注册 = 永不编译;simulator 无任务层,只挂 Keil);**仍欠**:栈预算核算(两任务未入 `freertos.c` 栈表,建任务前后各跑 `stack_report.py`;原 S-1 栈风险已于 2026-10-10 **削链销项**,defaultTask 现静态 2776/4096 余 32%、实测 2152 B)+ 消费者本体 + 建任务走 **L1(`.ioc` 的 `FREERTOS.Tasks01`)**;**取数必须按 `docs/硬件平台/ADC通道映射说明.md`**(TPAFE `buf[2]=IA`/`buf[5]=UN`/`buf[6]=UA`;STM32 侧 ADC1 **已于 2026-10-09 生成**:`hadc1` + `MX_ADC1_Init()`、9 通道 Rank1~9、144 cycles、ADCCLK=21 MHz、软件触发,网名 ADC17=PC4 用 `ADC_CHANNEL_14`;⚠ 全仓库至今**无 `HAL_ADC_Start`** → STM32 侧一路未跑) |
|
||||
| **B2** | **RS-485 采集链路实现**(消化 E-50、E-49) | B0 + **E-59 门禁**(**尚未满足**:E-50 / E-49 未修) | 双缓冲 + 序号(防包撕裂)+ DE 收尾(超时路径等 TC)+ 协议状态机(`App/protocol/` 正是为此预留) |
|
||||
|
||||
**建议**:驱动契约与编译接线已在 2026-10-10 铺完 → B1 的下一步是**栈预算 + 建任务(L1)**,
|
||||
@@ -84,7 +85,6 @@
|
||||
|---|---|---|---|
|
||||
| **C1** | **pending 二期(ACCEPT + SEND)** | 沿一期机制扩展;同期消化 E-25(net_select 语义)、E-24/E-27/E-28(跨上下文收口);基线重锁 + 探针族扩充 + 看门狗接 selftest。**设计基线见 §5.1** | 第二档 #2 / N-4 |
|
||||
| **C3** | **存储侧日志管线**(消化 N-2) | 丢弃可观测性**代码已具备**(`console_log.c` `s_con_drop`+`[ERR] CONSOLE dropped`、`sys_log_mcu.c` 队列满 `DBG_ERROR`、TX 僵尸通道自愈);V5 30 min 日志**未复现 49s 静默**(运行期 >10s 静默全为 ~28s、均在 `e02_probe` 窗口内=N-17)。剩余:与 S8(非阻塞日志)合并评估 + **S-3(USART1 TX-only 结构根治)** | N-2 / S-3 |
|
||||
| **C4** ⚠️ | **defaultTask 栈余量**(S-1,**需尽快处理**) | **2026-10-04 实测 3664/4096(余量 432 B ≈ 10%,远低于 30% 判据)**。处置:栈 4096→4608(CCM 堆余量可覆盖 +512B)或 GC 链局部削减;**建议随阶段 B 之前先做** | S-1 |
|
||||
| **C5** | 一档剩余 | E-49(RS485 DE 收尾)、E-15(ringbuf 定去留——**已确认零调用者,倾向删除**)、E-61(SD2506 注释订正)、E-16(cfg_file 段名长度)、E-26(UDP 定案,倾向移除)、E-23、E-30 | 一档/二档 |
|
||||
| **C6** | **USART1 TX-only 结构根治**(S-3) | 灭 ORE 僵尸机制根源:改 `.ioc` 令 USART1 不使能 RX / PA10 不复用为 `USART1_RX` → CubeMX 重生成 → 跑 `check_cubemx_survival.py`。属结构性改动,需单开一轮 + 复跑台架闭环 | S-3 |
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
【阶段 B 功能】 B0 产品定义确认 ─┬─ B3 E-59 门禁固化(并行)
|
||||
(当前最高优先) └─ E-58 原子快照 → B1 ADC → B2 RS485
|
||||
↓
|
||||
【阶段 C 结构】 C1 pending 二期 ─ C3 日志管线(N-2/S-3) ─ C4 栈(S-1)
|
||||
【阶段 C 结构】 C1 pending 二期 ─ C3 日志管线(N-2/S-3)
|
||||
─ C5 收口 ─ C6 USART1 TX-only
|
||||
↓
|
||||
【阶段 D 常态】 D2 N-3 / D5 N-16 负向 / D6 N-17 探针窗口
|
||||
@@ -145,7 +145,6 @@
|
||||
|
||||
| # | 事项 | 发现 | 证据与现状 | 出处 |
|
||||
|---|---|---|---|---|
|
||||
| S-1 | defaultTask 静态最坏链余量贴线:`storage_bring_up → … → dhara GC → SPI` 链 | 2026-09-22;2026-10-04 重采升级 | **2026-10-04 重采(升级为需尽快处理)**:产品构建(`suite=NONE`)V5 30 min 真实负载实测 **3664B/4096(余量 432B = 10%)**,**已远低于 30% 判据**。处置:栈 4096→4608(CCM 堆余量可覆盖 +512B)或 GC 链缓冲局部削减;建议**提前到阶段 B 之前**处理 | 本文件 §2.2 C4 / §6 |
|
||||
| S-3 | **USART1 TX-only 结构根治(灭 ORE 僵尸机制)**——ORE 锁存在外设软复位后毫秒级重锁(PA10 悬空 + RX 使能),是 2026-10-02 台架"背靠背 drain 拉长主循环 → 喂狗节奏饥饿 → IWDG 误复位"的**机制根源**。现仅有缓解(单次 drain 250ms 预算 + 发送故障后 300ms 冷却),**未根治** | 2026-10-02(台架 gen-288) | **待办**:改 `.ioc` 令 USART1 为 TX-only → CubeMX 重生成 → 跑 `scripts/check_cubemx_survival.py`。结构性改动,需单开一轮并复跑台架闭环 | `子系统设计/控制台单写者日志设计说明.md` §12(含 O4) |
|
||||
| S-4 | **dhara 重试自旋残留**——`try_recover()` 的 `DHARA_MAX_RETRIES`(8) 自旋在坏块密集时仍可能长时间占用 defaultTask(喂狗点) | 2026-10-02 | 低优先:现有 `vol_lock` + 喂狗节奏缓解;若台架再出"存储侧喂狗饥饿"再排期 | `Lib/dhara/map.c` |
|
||||
| S-5 | **可选全序列卷锁**——现卷锁仅覆盖 `syslog` / `cfg` / `lftpd` 三条路径(`vol_lock_wait(0)` try 语义),其它潜在访问点(如 UI 读日志)未纳入 | 2026-10-02 | 待评估:先确认是否真有第二写者;无则关闭本项 | `App/fs/vol_lock.{c,h}` |
|
||||
@@ -244,8 +243,8 @@ S14 已在 workflow 显式提示"体积门禁未执行"(`::notice::`)并在
|
||||
|
||||
**完成判据**:存在**强制的**体积校验路径(CI 侧或本地侧),且文档明确其边界。
|
||||
|
||||
> **注**:本项与 §2.2 C4(**S-1:defaultTask 栈 3664/4096 ≈ 10%**,需尽快处理)是同一话题的两面
|
||||
> ——S-1 是**具体风险**,本项是**门禁缺口**。
|
||||
> **注**:本项与栈预算是同一话题的两面——**具体栈风险(原 S-1)已于 2026-10-10 削链闭环销项**
|
||||
> (defaultTask 静态最坏链 5312 → 2776 B、实测 3392 → 2152 B,**未抬栈**),本项仍是**门禁缺口**。
|
||||
|
||||
---
|
||||
|
||||
@@ -311,21 +310,22 @@ S14 已在 workflow 显式提示"体积门禁未执行"(`::notice::`)并在
|
||||
|
||||
## 6. 诊断基线(供后续对照)
|
||||
|
||||
> **2026-10-04 重采**:栈/堆 = **运行时高水位**(产品构建 `suite=NONE`,V5 30 min 真实负载,串口 `[STACK]`,
|
||||
> 证据 `/tmp/v5_soak_serial_20261003.log`);静态区 = `.map` 受管快照。
|
||||
> ⚠️ **栈水位较 2026-09-21 基线明显上升**(defaultTask 2136→**3664 B**、ftpTask 1184→**2516 B**),
|
||||
> 系功能与加固陆续入链所致。**S-1 需尽快处理**,见 §2.2 C4。
|
||||
> **2026-10-10 重采(栈)/ 2026-10-04 重采(堆)**:栈 = **运行时高水位 + armlink 静态最坏链双口径**
|
||||
> (产品构建 `suite=NONE`,开机 + 空闲采样,串口 `[STACK]` + `stack_report.py`);静态区 = `.map` 受管快照。
|
||||
> ✅ **栈水位已回落**:2026-10-04 曾升到 defaultTask **3664 B**(登记 S-1);2026-10-10 削链
|
||||
> (删旧档迁移 + `FIL` 静态化 + 日志行缓冲按模块收紧 + 钩子脱离 HAL)后实测 **2152 B**、
|
||||
> 静态最坏链 **2776 B**,**未抬栈**即达标。完整核算见 `docs/内存管理/RAM使用分析与优化方案.md`。
|
||||
|
||||
| 项 | 当前值(2026-10-04) | 出处 |
|
||||
| 项 | 当前值(栈:2026-10-10;其余:2026-10-04) | 出处 |
|
||||
|---|---|---|
|
||||
| 产品构建 Flash (ER_IROM1) | 266,632 B / 1024 KB(25.4%);ROM 合计 **267,372 B** | `.map` 受管快照 |
|
||||
| 产品构建 RW_IRAM1 | **84,960 / 131,072 B(64.8%)** | `.map` 受管快照(`RAM使用分析与优化方案.md` §2.1) |
|
||||
| 产品构建 RW_CCM | 49,184 / 65,280 B(75.3%) | 同上 |
|
||||
| 实测堆 | free=8,664 / **min_ever=4,728 B** | V5 串口 `[STACK] heap` |
|
||||
| **defaultTask 栈峰值** | **3664 / 4096(余量 432 B ≈ 10%,⚠️ 低于 30% 判据)** | V5 串口 `[STACK]`(产品构建) |
|
||||
| netTask 栈峰值 | 1228 / 4096(余量 70%) | 同上 |
|
||||
| ftpTask 栈峰值 | 2516 / 4096(余量 38%) | 同上 |
|
||||
| uiTask 栈峰值 | 4060 / 16384(余量 75%) | 同上 |
|
||||
| **defaultTask 栈峰值** | **2152 / 4096(余 1944 B = 47%);静态最坏链 2776 B(余 32%)** | `[STACK]` + `stack_report.py`(产品构建) |
|
||||
| netTask 栈峰值 | 920 / 3840(余 76%);静态 1872 B | 同上 |
|
||||
| ftpTask 栈峰值 | 740 / 4096(余 81%);静态 1216 B | 同上 |
|
||||
| uiTask 栈峰值 | 4016 / 16384(余 75%);静态 1336 B | 同上 |
|
||||
| timeSyncTask 栈峰值 | 792 / 2048(余量 61%) | 同上 |
|
||||
| testTask 栈峰值(产品态空转) | 496 / 8192(余量 93%) | 同上 |
|
||||
| 队列响应性(挂起客户端) | 92.5ms(pending 一期) | `e02_probe.py` |
|
||||
|
||||
@@ -126,7 +126,7 @@ if (sys_evtHandle != NULL) {
|
||||
> 因此只在 netTask 上下文广播。
|
||||
|
||||
### Step 3 defaultTask 置位存储就绪(生产者)
|
||||
在 `defaultTask` 完成 FTL/FatFS 挂载 **+ 网络配置加载(`net_cfg_load`,含首启旧档迁移;失败回退工厂默认)** 后:
|
||||
在 `defaultTask` 完成 FTL/FatFS 挂载 **+ 网络配置加载(`net_cfg_load`;旧档 `/cfg/netcfg.bin` 不读、不迁移,失败回退工厂默认)** 后:
|
||||
```c
|
||||
osEventFlagsSet(sys_evtHandle, SYS_EVT_STORAGE_READY);
|
||||
```
|
||||
|
||||
+3
-2
@@ -163,7 +163,7 @@ flowchart LR
|
||||
end
|
||||
```
|
||||
|
||||
- 掉电持久化:`net_cfg` 配置(通用配置文件 `/config.ini`,INI `[network]` 段,cfg_file 引擎),保存后下次上电生效、或立即生效(网络重建)、外部变更 4s 沉降后自动重载;旧版 NCFG 二进制(`/cfg/netcfg.bin`)首启自动迁移。
|
||||
- 掉电持久化:`net_cfg` 配置(通用配置文件 `/config.ini`,INI `[network]` 段,cfg_file 引擎),保存后下次上电生效、或立即生效(网络重建)、外部变更 4s 沉降后自动重载;旧版 NCFG 二进制(`/cfg/netcfg.bin`)**已不再读取**——存在则忽略(不读、不删、不迁移),配置回落工厂默认(自动迁移已于 2026-10-10 删除)。
|
||||
- 日志记录:`sys_log` 引擎写定长 64B 文本记录到 `/log/run.log`(运行记录)与 `/log/selftest.log`(自检记录),defaultTask 唯一写者,FTP 可直下(详见 `docs/子系统设计/运行与自检记录设计说明.md`);实时调试流 = 控制台单写者日志(USART1,4KB 环形缓冲 + defaultTask 唯一发送,详见 `docs/子系统设计/控制台单写者日志设计说明.md`)。
|
||||
- NAND 坏块表(BBT)持久化在保留块池,不交给 dhara 管理。
|
||||
|
||||
@@ -266,7 +266,7 @@ STM32F4-Base/
|
||||
│ ├── SD2506/ RTC
|
||||
│ ├── RS485/ 半双工串口
|
||||
│ ├── NET/ net_socket / net_select / lftpd
|
||||
│ ├── NETCFG/ 网口配置(INI [network] 段 + 旧档 NCFG 迁移)
|
||||
│ ├── NETCFG/ 网口配置(INI [network] 段)
|
||||
│ ├── UI/ LVGL UI(与模拟器共用)
|
||||
│ └── dbg_log.h/dbg_cfg.h 分级日志
|
||||
├── Lib/ 第三方:LVGL v9.2、FatFs、FreeRTOS、CMSIS
|
||||
@@ -343,3 +343,4 @@ flowchart LR
|
||||
| 2026-09-21 | **栈宽整改落地(内存方案 §1.4:lftpd 大局部缓冲静态化)**:`Drivers/BSP/NET/lftpd/lftpd.c` + `lftpd_log.c` 共 **9 处**大局部数组(`message[256]`/`response[512]`/`name[256]`×2/`buffer[1024]`×2/`read_buffer[512]`/`arg_buf[512]`/`client` 会话上下文/日志 `buffer[256]`)改为函数级 `static`(lftpd 单客户端、全部在 ftpTask 内串行);**ftpTask 实测峰值 3480 → 1184 B(余量 15% → 71%,判定 PASS)**,静态调用图 2528 → 472 B,代价静态 BSS +4,616 B(RW_IRAM1 82,048 / 131,072 B,余量仍 ~48 KB);§2.1 栈实测数据同步,原"涨栈到 1600 words"方案取消;FTP 功能回归 10/10 + 128KB 逐字节一致 |
|
||||
| 2026-09-24 → 09-25 | **控制台单写者日志**(09-24 实证驱动:多任务并发日志字符级交错 + HardFault 脏指针直达 UART):4KB 环形缓冲 + defaultTask 唯一发送(行级原子 + 指针可控)+ 内核前/ISR/异常钩子有界直发回退 + `fputc` 收敛到单写者路径;09-24 初版实施于 `Src/usart.c` USER CODE 区,09-25 迁出至 `App/log/console_log.{h,c}`(HAL 生成文件不含应用代码),`dbg_log.h` 改 `#include "console_log.h"`(调用点零改动),`Src/usart.c` 恢复纯 CubeMX 形态;`@build` 0/0 + `@test` PASS;详见 `docs/子系统设计/控制台单写者日志设计说明.md` |
|
||||
| 2026-09-25 | **defaultTask 任务体文件拆分**:`Src/freertos.c` 的 `StartDefaultTask` 任务体(存储 bring-up / 配置引擎属主 / 控制台单写者 attach+drain / syslog 落盘 / LED / 栈水位探针 `stack_probe_poll`)整体迁至 `App/task/default_task.c`(`default_task_func()`,与其余任务文件同址);`freertos.c` 恢复"CubeMX 接线 + 崩溃钩子"形态(719→361 行),`@build` 0/0 复验;栈配置属性仍定义于 `freertos.c`(`stack_report` 数据源不变) |
|
||||
| 2026-10-10 | **删除旧档 NCFG 迁移(栈整改)**:`Drivers/BSP/NETCFG/net_cfg_legacy.{c,h}` 整体移除、`cfg_store_legacy_path()` 撤销,`net_cfg_load` 不再调用 `net_cfg_legacy_migrate()`;旧档 `/cfg/netcfg.bin` 若存在则被忽略(不读、不删、不迁移),配置回落工厂默认。理由:该一次性路径把整条配置写链挂进启动期调用图,defaultTask 静态最坏栈链 +600 B,本仓库无携带旧档的设备。同轮栈整改(未抬栈):defaultTask 静态最坏链 5312 → 2776 B / 实测峰值 3392 → 2152 B、timeSyncTask 1736 → 1024 B,6 任务全 PASS;代价静态 BSS +4,128 B |
|
||||
|
||||
@@ -328,7 +328,7 @@ static void phaseN_run(void) {
|
||||
| `App/cfg/cfg_file.c` | 1250 行 | ✅ 已覆盖(139 断言,2026-10-02 S1-b) | 后端抽象(`cfg_file_store.h`) | 内存虚拟 FS 桩;**首测即抓出外科手术保存死码 P0**(见 §5) |
|
||||
| `App/log/sys_log_mcu.c` | — | ⬜ 候选 | 记录编解码(定长 64B) | 编解码纯逻辑;写入端依赖 FatFS + 队列,测编解码即可 |
|
||||
| `App/util/time_sync.c` | — | ⬜ 候选 | 协议帧编解码 | 报文组装/解析纯逻辑;网络收发不测 |
|
||||
| `Drivers/BSP/NETCFG/net_cfg_legacy.c` | — | ⬜ 候选 | 旧档 NCFG 迁移 + 自复制 CRC | CRC 校验与旧格式解析;可与 cfg_file 同桩 |
|
||||
| `Drivers/BSP/NETCFG/net_cfg_legacy.c` | — | ⛔ 已删除(2026-10-10) | — | 旧档 NCFG 迁移整体移除(旧档 `/cfg/netcfg.bin` 不读、不删、不迁移),测试候选随之撤销 |
|
||||
| `App/net/*`(网络栈上层) | — | ⬜ 待评估 | 依赖 socket/CH395F | 纯协议状态机部分或可测,需先确认抽象质量 |
|
||||
| `App/util/rs485.c` | — | ⏸ 待功能实现 | — | 上游 B2;当前为空桩 |
|
||||
| `Drivers/BSP/TPAFE5160/*.c` | — | ❌ 不适格 | — | 寄存器序列为主,需真机时序 |
|
||||
@@ -615,6 +615,7 @@ CI 只在 push / PR 时跑,且需 runner 就绪。**提交前自查、或 runn
|
||||
|
||||
| 日期 | 变更 |
|
||||
|---|---|
|
||||
| 2026-10-10 | §4.2.1 台账:`Drivers/BSP/NETCFG/net_cfg_legacy.c` 由 `⬜ 候选` 改为 **`⛔ 已删除`**——旧档 NCFG 迁移整体移除(`net_cfg_legacy.{c,h}` 删除、`cfg_store_legacy_path()` 撤销;旧档 `/cfg/netcfg.bin` 不读、不删、不迁移,配置回落工厂默认),该测试候选随之撤销 |
|
||||
| 2026-10-02 | **S6**:`test/run_all_suites.py` 新增 **`--check-build`**(只编译不烧录,纯离机,不需要 MCU/串口/ST-LINK);新增 **§3.6.1** 说明其解决的问题(测试构建无独立门禁,2026-08~09 CH395F 套件实例)、判定语义与用法。**实测 4 套件全部 `BUILD_OK: 0 errors, 0 warnings`**(即 T-4 提到的"CH395F 不可编译"已修复) |
|
||||
| 2026-10-02 | **S1-b + S2**:新增 **§4.2.1「L0.5 适格模块台账」**(判据 + 模块状态表 + "两条实证":sys_clock / cfg_file 首测即各抓一处生产缺陷);§4.1 登记 `test/host/cfg_file/` 新单测。同步新增 [`配置文件单元测试说明.md`](配置文件单元测试说明.md)(含抓出的 `s_encode` 返回值误判 P0 缺陷记录) |
|
||||
| 2026-10-02 | **S3 + S14**:§9.1 第 2 条改正(原文"强制跑 `mem-numbers`"自相矛盾 → 改为"按 `.map` 有无自适应跳过")并加 🔴 门禁盲区声明;§9.2 补 S3 结果可见性(`Tee-Object` 落盘 + `$GITHUB_STEP_SUMMARY` + `::notice::` 汇总行,不用 `actions/upload-artifact`)。另:§4.1 登记 `test/host/sys_clock/` 新单测(S1-a) |
|
||||
|
||||
+11
-7
@@ -507,12 +507,15 @@ $env:DTU_KEIL_UV4 = 'D:\NotExist\UV4.exe' # 仅当前会话,不动用户级
|
||||
|
||||
| 任务 | 栈大小 | 优先级 |
|
||||
|---|---|---|
|
||||
| defaultTask | 2048 | Normal |
|
||||
| netTask | 4096 | Normal |
|
||||
| ftpTask | 4096 | Normal |
|
||||
| testTask | 4096 | BelowNormal |
|
||||
| uiTask | 16384 | BelowNormal |
|
||||
| timeSyncTask | 2048 | Normal |
|
||||
| defaultTask | 1024 | Normal |
|
||||
| netTask | 960 | Normal |
|
||||
| ftpTask | 1024 | Normal |
|
||||
| testTask | 2048 | BelowNormal |
|
||||
| uiTask | 4096 | BelowNormal |
|
||||
| timeSyncTask | 512 | Normal |
|
||||
|
||||
> 上表由 `scripts/gen_task_table.py` 同源(唯一来源 `Src/freertos.c` / `.ioc` 的 `FREERTOS.Tasks01`);
|
||||
> 2026-10-10 栈整改**未改任何栈值**,靠削调用链达标(详见 `docs/内存管理/RAM使用分析与优化方案.md`)。
|
||||
|
||||
> 挖潜方向(未实施):SRAM3 64 KB / CCM 64 KB 未映射——详见 `docs/内存管理/`。
|
||||
> 部署侧含义:**不要做任何需要额外 RAM 的固件定制**,新增功能先过内存预算。
|
||||
@@ -540,7 +543,7 @@ $env:DTU_KEIL_UV4 = 'D:\NotExist\UV4.exe' # 仅当前会话,不动用户级
|
||||
|
||||
| 参数 | 工厂默认 | 修改方式 |
|
||||
|---|---|---|
|
||||
| IP | **192.168.1.100**(静态,无 DHCP) | 屏幕 `通讯参数 → 网口设置`(修改密码 `123`)保存后**立即生效**(网络重建约 1~3 s);或预置 `/config.ini`(INI;旧版 `/cfg/netcfg.bin` 首启自动迁移) |
|
||||
| IP | **192.168.1.100**(静态,无 DHCP) | 屏幕 `通讯参数 → 网口设置`(修改密码 `123`)保存后**立即生效**(网络重建约 1~3 s);或预置 `/config.ini`(INI;旧版 `/cfg/netcfg.bin` **不再读取**——存在则忽略、不迁移,配置回落工厂默认,2026-10-10 起) |
|
||||
| 子网掩码 | 255.255.255.0(/24) | 同上 |
|
||||
| 默认网关 | 192.168.1.1 | 同上 |
|
||||
| MAC | 全零 = 芯片内置 MAC | 同上(全零是"使用芯片内置 MAC"的哨兵,不是"MAC 为 0") |
|
||||
@@ -644,6 +647,7 @@ $env:DTU_KEIL_UV4 = 'D:\NotExist\UV4.exe' # 仅当前会话,不动用户级
|
||||
|
||||
| 日期 | 变更 |
|
||||
|---|---|
|
||||
| 2026-10-10 | **删除旧档 NCFG 迁移**(升级/迁移口径变更):旧固件遗留的 `/cfg/netcfg.bin` 不再"首启自动迁移"——旧档若存在则被忽略(不读、不删、不迁移),配置直接回落工厂默认(`/config.ini` `[network]` 段模板)。`net_cfg_legacy.c/h` 与 `cfg_store_legacy_path()` 已移除;携带旧档的设备升级后需经 UI 或 FTP 重新配置网口。§五 现场部署 IP 行同步 |
|
||||
| 2026-10-02 | **模拟器构建修复**(配置引擎重构遗留):`simulator/CMakeLists.txt` 的配置文件引擎引用同步到迁移后位置——包含目录 `App/`→`App/cfg/`(`cfg_file.h`/`cfg_file_store.h`)、源文件 `App/cfg_file.c`→`App/cfg/cfg_file.c`、包含目录 `test/`→`test/board/`(`test_config.h`/`net_latency_test.h`);全量 include 离线核查无其他断链,模拟器全量构建恢复(`--cfgtest` 四场景 PASS,rc=0)。§2.12 验证链 ⑤ 行同步更新 |
|
||||
| 2026-10-02 | 更正 Device Pack 必装范围:`Keil::CMSIS` pack 不再列为必装项——本工程不依赖它(核心头文件由仓库 `Drivers/CMSIS/` 提供,`.uvprojx` 只引用 DFP pack;2026-10-02 本机实测未装 CMSIS pack 构建 0/0 通过),且其 keil.com 直链(5.7.0~6.1.0)均已下架 404;必装的只有 `Keil::STM32F4xx_DFP`(3.1.1,与 `.uvprojx` PackID 一致)。§2.2 / 第 2 步 / 搭建清单 / §2.10 同步更正 |
|
||||
| 2026-10-02 | 新增 §2.12「跨机验证(第二台机器 / 换机验收清单)」:变量配置 + sanity check → 六步验证链(含期望结果与失败诊断,含模拟器既有 CMake 问题标注)→ 反向 fail-fast 测试 → 通过判定,作为方案跨机验收的标准操作 |
|
||||
|
||||
Reference in New Issue
Block a user