diff --git a/App/log/console_log.c b/App/log/console_log.c index 41386b23..e8c43b24 100644 --- a/App/log/console_log.c +++ b/App/log/console_log.c @@ -1,5 +1,5 @@ /* - * 模块名称:Console Single-Writer Logging — 控制台单写者日志(USART1)实现 + * 模块名称:Console Single-Writer Logging — 控制台单写者日志(RS232#1 / UART5)实现 * 模块功能:控制台单写者日志的环形缓冲 + 唯一写者发送实现(API 见 console_log.h); * 兼载 MicroLIB printf 底层 fputc 重定向 * 适用平台:STM32F407ZGTx(仅 MCU 端) @@ -99,6 +99,18 @@ * 与当场直发逐字节相同。ISR / 调度器未启动两种上下文放行(不许等)。 * 约束:不新增任务、不动态分配;环形缓冲为 BSS(SRAM1,非 CCM),无 DMA 可达性冲突。 */ + +/* ===== 控制台端口(单点收口)===== + * 换口只改这一段:句柄 / IRQn / 初始化函数。时钟宏随句柄走——UART5 在 APB1、 + * USART1 在 APB2,别照抄;串口模式与波特率在 Src/usart.c 的 MX_*_Init 里,本模块不管。 + * 2026-10-29 批 0:USART1 让位给屏板链路(700 kbaud 只有它 MCU 引脚直出),控制台迁 + * RS232#1/UART5。缘由、端子与验收见 docs/任务规划/屏板链路.md 的批 0。 */ +#define CON_UART huart5 +#define CON_UART_IRQN UART5_IRQn +#define CON_UART_CLK_DISABLE() __HAL_RCC_UART5_CLK_DISABLE() +#define CON_UART_CLK_ENABLE() __HAL_RCC_UART5_CLK_ENABLE() +#define CON_UART_INIT() MX_UART5_Init() + #define DBG_CON_RING_SIZE 4096U /* 环形缓冲字节数(必须为 2 的幂) */ #define DBG_CON_CHUNK_MAX 256U /* 写者单次 HAL_UART_Transmit 字节上限 */ #define DBG_CON_WAIT_MS 200U /* 缓冲满时生产者最长等待(ms),仍满则丢弃并计数 */ @@ -140,7 +152,7 @@ static volatile uint8_t s_con_draining; /* 1 = 处于 drain 中(重入保 static volatile uint8_t s_con_writer_up; /* 1 = 写者已注册(此后走环形缓冲) */ static volatile uint8_t s_con_dwt_up; /* 1 = DWT CYCCNT 已使能(硬上界基准可用) */ static TaskHandle_t s_con_writer_task; /* 写者任务句柄(自等保护用) */ -/* 行级单一所有者(道G task-23,O1 第二实例):USART1 数据寄存器同一时刻只允许 +/* 行级单一所有者(道G task-23,O1 第二实例):控制台串口数据寄存器同一时刻只允许 * 一个上下文在逐字节轮询写入。NULL = 空闲。 * ⚠ 这不是"锁",是**所有权凭证**:拿不到就当场让路,绝不排队等待(见 * con_tx_try_claim 函数头:裸发一行 @115200 约 7.8 ms,把它包进临界区等于给 @@ -228,7 +240,7 @@ static void con_dwt_ensure(void) { * 入口参数:u - USART 寄存器基址(调用方已判非 NULL) USART_TypeDef * * p_buf - 待发数据;len - 字节数 * 返回值:HAL_OK - 已发出;HAL_TIMEOUT - 计数上界内未完成(本块放弃) - * 限定条件:USART1 已初始化 + * 限定条件:控制台串口已初始化 * 函数说明:刻意不用 HAL_UART_Transmit——理由见 CON_TX_GUARD_MAX 处注释 * (tick 依赖不可信 + 其调用链污染所有任务的最坏栈链) */ @@ -258,12 +270,12 @@ static HAL_StatusTypeDef con_tx_counted(USART_TypeDef *u, const uint8_t *p_buf, * 函数功能:有界裸发送(不依赖 uwTick / HAL 超时) * 入口参数:p_buf - 待发数据;len - 字节数(调用方已限 ≤ DBG_CON_CHUNK_MAX) * 返回值:HAL_OK - 已全部写入发送寄存器;HAL_TIMEOUT - 有界上界内未完成 - * 限定条件:USART1 已初始化 + * 限定条件:控制台串口已初始化 * 函数说明:寄存器级轮询 TXE/TC,超时判据用 DWT CYCCNT(CON_TX_TIMEOUT_CYC); * DWT 未使能时走 con_tx_counted(指令计数上界,2026-10-10 取代 * HAL_UART_Transmit 回退)。本函数只做 TX, * 不触碰 RX/错误标志——僵尸通道自愈由调用方按返回值处理。 - * ⚠ USART1 未初始化(huart1.Instance == NULL,如 HAL_Init 早期或 + * ⚠ 控制台串口未初始化(CON_UART.Instance == NULL,如 HAL_Init 早期或 * 断言/故障上报路径)时立即返回 HAL_ERROR:否则会解引用 NULL 去读写 * 地址 0(flash 别名区)→ 在故障处理里再触发故障(2026-10-02 台架实测)。 */ @@ -273,14 +285,14 @@ static HAL_StatusTypeDef con_tx_bounded(const uint8_t *p_buf, uint16_t len) { uint16_t i; con_dwt_ensure(); - if (huart1.Instance == NULL) { - return HAL_ERROR; /* USART1 未初始化:无可用通道,安全让位(不是超时,不记超时账) */ + if (CON_UART.Instance == NULL) { + return HAL_ERROR; /* 控制台串口未初始化:无可用通道,安全让位(不是超时,不记超时账) */ } if (s_con_dwt_up == 0U) { - return con_tx_counted(huart1.Instance, p_buf, len); + return con_tx_counted(CON_UART.Instance, p_buf, len); } - u = huart1.Instance; + u = CON_UART.Instance; t0 = DWT->CYCCNT; for (i = 0U; i < len; i++) { while ((u->SR & USART_SR_TXE) == 0U) { @@ -299,7 +311,7 @@ static HAL_StatusTypeDef con_tx_bounded(const uint8_t *p_buf, uint16_t len) { } /* - * 函数功能:尝试取得"USART1 整行发送所有权"(**非阻塞**,道G task-23) + * 函数功能:尝试取得"控制台串口整行发送所有权"(**非阻塞**,道G task-23) * 返回值:CON_TX_HELD 已持有(发完必须 con_tx_release)/ CON_TX_BYPASS 放行且不记账 * / CON_TX_NO 别人正持有整行,调用方须让路 * 限定条件:任意上下文(内部只有一次几条指令的临界区,绝不睡眠、绝不长期关中断) @@ -473,7 +485,7 @@ uint8_t dbg_console_writer_ready(void) { } /* - * 函数功能:USART1 僵尸通道自愈(清错误锁存 + 整外设重初始化) + * 函数功能:控制台串口僵尸通道自愈(清错误锁存 + 整外设重初始化) * 函数说明:**RX 使能了却从不读 DR** → 线上任意一个字节或一个噪声沿使 RXNE 置位后无人读, * 下一个事件即锁存 ORE(常伴 NE/FE/PE);ORE 只能靠"先读 SR 再读 DR"清除 ⇒ 永不自愈。 * 锁存后 HAL 轮询 TX 恒快速失败(控制台静默、系统不复位);发送器卡死状态则使 TXE @@ -484,13 +496,13 @@ uint8_t dbg_console_writer_ready(void) { * (详见 docs/子系统设计/控制台单写者日志设计说明.md §12)。 */ static void con_uart_reinit(void) { - __NVIC_ClearPendingIRQ(USART1_IRQn); - __HAL_RCC_USART1_CLK_DISABLE(); - __HAL_RCC_USART1_CLK_ENABLE(); - huart1.gState = HAL_UART_STATE_RESET; - huart1.RxState = HAL_UART_STATE_RESET; - huart1.ErrorCode = HAL_UART_ERROR_NONE; - (void)MX_USART1_UART_Init(); + __NVIC_ClearPendingIRQ(CON_UART_IRQN); + CON_UART_CLK_DISABLE(); + CON_UART_CLK_ENABLE(); + CON_UART.gState = HAL_UART_STATE_RESET; + CON_UART.RxState = HAL_UART_STATE_RESET; + CON_UART.ErrorCode = HAL_UART_ERROR_NONE; + (void)CON_UART_INIT(); } /* @@ -512,7 +524,7 @@ void dbg_console_drain(void) { return; /* 重入保护:写者自记录不触发嵌套 drain */ } - /* 整行所有权(道G task-23):本函数按块直写 USART1->DR,若此刻别的应用上下文 + /* 整行所有权(道G task-23):本函数按块直写 CON_UART->DR,若此刻别的应用上下文 * 还在未注册期那条裸发里发到自己一半(attach 就发生在 defaultTask 里,与别的 * 任务裸发**可以**前后脚撞上),两边就会逐字节交错——那正是本卡要修的形态。 * 拿不到就**本轮让位**:tail 不推进 => 环里一条不少,主循环 ≤50 ms 后再试, @@ -560,7 +572,7 @@ void dbg_console_drain(void) { if (st != HAL_OK) { if (st == HAL_ERROR) { - /* 2026-10-24 修复:USART1 **未初始化**(huart1.Instance == NULL, + /* 2026-10-24 修复:控制台串口 **未初始化**(CON_UART.Instance == NULL, * 只可能出现在 HAL_Init 早期或断言/故障上报路径)与"僵尸通道"是两回事: * 这里**绝不做外设重初始化**——那会在 HAL 尚未就绪时跑 MspInit 重配 * RCC/GPIO;也不计 tx_fault(那本账的语义是"软复位自愈次数")。 diff --git a/App/log/console_log.h b/App/log/console_log.h index d1fccc8c..1dec33ae 100644 --- a/App/log/console_log.h +++ b/App/log/console_log.h @@ -1,5 +1,5 @@ /* - * 模块名称:Console Single-Writer Logging — 控制台单写者日志(USART1 调试串口) + * 模块名称:Console Single-Writer Logging — 控制台单写者日志(RS232#1 / UART5) * 模块功能:调试控制台单写者环形缓冲的公共 API:所有任务/上下文(含 printf)只把 * 已格式化整行文本入环形缓冲,写者任务(defaultTask)为唯一 * HAL_UART_Transmit 发送点(行级原子 + 指针可控) diff --git a/docs/内存管理/RAM使用分析与优化方案.md b/docs/内存管理/RAM使用分析与优化方案.md index e849d09c..0e987c7a 100644 --- a/docs/内存管理/RAM使用分析与优化方案.md +++ b/docs/内存管理/RAM使用分析与优化方案.md @@ -47,10 +47,10 @@ dhara 失败类 +84;RO 另 +208,全是该失败类名表)→ `ER_IROM1` | 区域 | 用量 | 容量 | 占比 | |---|---|---|---| -| ER_IROM1 | 264,580 B (258.38 KB) | 1,048,576 B (1024 KB) | 25.2% | +| ER_IROM1 | 264,584 B (258.38 KB) | 1,048,576 B (1024 KB) | 25.2% | | RW_IRAM1 | 81,536 B (79.62 KB) | 131,072 B (128 KB) | 62.2% | | RW_CCM | 57,376 B (56.03 KB) | 65,280 B (64 KB) | 87.9% | -| **Flash (ROM 合计)** | **266,456 B (260.2 KB)** | 1,048,576 B (1024 KB) | **25.4%** | +| **Flash (ROM 合计)** | **266,460 B (260.2 KB)** | 1,048,576 B (1024 KB) | **25.4%** | 各区的容量与常量来源: diff --git a/docs/内存管理/RAM预算台账.md b/docs/内存管理/RAM预算台账.md index 54b8cf8d..e7d38b57 100644 --- a/docs/内存管理/RAM预算台账.md +++ b/docs/内存管理/RAM预算台账.md @@ -15,7 +15,7 @@ | 区域 | 用量 | 容量 | 占比 | 门禁(≤92%) | |---|---|---|---|---| -| ER_IROM1 (Flash) | 264,580 B | 1,048,576 B | 25.2% | 参考 | +| ER_IROM1 (Flash) | 264,584 B | 1,048,576 B | 25.2% | 参考 | | RW_CCM | 57,376 B | 65,280 B | 87.9% | PASS | | UNINIT_CCM | 48 B | 256 B | 18.8% | 参考 | | RW_IRAM1 | 81,536 B | 131,072 B | 62.2% | PASS | diff --git a/scripts/ram_baseline.tsv b/scripts/ram_baseline.tsv index a550ef23..18056dc7 100644 --- a/scripts/ram_baseline.tsv +++ b/scripts/ram_baseline.tsv @@ -11,4 +11,4 @@ date code ro rw zi er_irom1 er_pct iram1 iram1_pct ccm ccm_pct top_rwzi 2026-10-26 231712 25560 1520 136216 257272 24.5 80312 61.3 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4003;default_task.o=2736 2026-10-27 235372 26392 1572 136924 261764 25.0 81072 61.9 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4055;default_task.o=2736 2026-10-28 236456 28124 1876 137084 264580 25.2 81536 62.2 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4055;default_task.o=2736 -2026-10-29 236456 28124 1876 137084 264580 25.2 81536 62.2 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4055;default_task.o=2736 +2026-10-29 236460 28124 1876 137084 264584 25.2 81536 62.2 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4055;default_task.o=2736 diff --git a/scripts/size_attestation.json b/scripts/size_attestation.json index d0f60d61..8a9c33ec 100644 --- a/scripts/size_attestation.json +++ b/scripts/size_attestation.json @@ -1,15 +1,15 @@ { - "built_at": "2026-10-29T17:51:46+08:00", - "fingerprint": "d9848eb18efe7902c936a791c0b649900c0088d4f2c582e0a71d9998ba9ae0f4", + "built_at": "2026-10-29T18:43:32+08:00", + "fingerprint": "bfe075e7093727025c3ba21e3057445a6c23ec4b0193c7e14286cc6ca60f6f1f", "fingerprint_files": 1452, "fingerprint_source": "git-index", "gated_regions": [ "RW_IRAM1", "RW_CCM" ], - "git_head": "c51ac2e8ef09dbd51b1e81a82b73becc55ca1c3e", + "git_head": "27a700b0d81cde580d88f783d6cb661aac248516", "map": "MDK-ARM/STM32F407-Demo/STM32F407-Demo.map", - "map_mtime": 1793267423, + "map_mtime": 1793270606, "pct": { "ER_IROM1": 25.23, "RW_CCM": 87.89, @@ -19,7 +19,7 @@ "regions": { "ER_IROM1": { "max": 1048576, - "size": 264580 + "size": 264584 }, "RW_CCM": { "max": 65280, @@ -37,7 +37,7 @@ "schema": 2, "scope_note": "\u540c\u7801\u51ed\u8bc1\uff1a\u6307\u7eb9\u8986\u76d6\u56fa\u4ef6\u4f53\u79ef\u76f8\u5173\u6e90\u7801\uff0c\u53e3\u5f84\u89c1\u672c\u811a\u672c docstring", "sizes": { - "code": 236456, + "code": 236460, "ro_data": 28124, "rw_data": 1876, "zi_data": 137084