feat(日志): 控制台迁到 RS232#1/UART5,USART1 让位给屏板链路
批 0 的第 2 项。USART1 是唯一 MCU 引脚直出的 TTL 通道,700 kbaud 的屏板 链路要用它,控制台必须先让开。 console_log.c 加一处端口收口块,换口只改这一段: CON_UART / CON_UART_IRQN / CON_UART_CLK_DISABLE/ENABLE / CON_UART_INIT 代码实际改动 4 处:con_tx_bounded 的 huart1.Instance(NULL 判据、counted 回退、赋值)与 con_uart_reinit 全函数体。其余是把描述当前行为的注释里的 USART1 换成「控制台串口」;历史变更记录(2026-10-02 / 10-24)里的 USART1 保持原样,那是当时的实况。 注意事项:UART5 在 APB1、USART1 在 APB2,时钟宏不能照抄; __HAL_RCC_UART5_CLK_ENABLE 定义在 stm32f4xx_hal_rcc_ex.h。 不改 UART 模式(2026-10-26 裁定:保持 UART_MODE_TX_RX,不动 RX 配置)。 MX_UART5_Init 在 Src/main.c:135,比 MX_USART1_UART_Init 晚几个初始化调用, 该窗口内的日志由 CON_UART.Instance == NULL 短路接住(记 dropped,不崩)。 构建:Code=236,460 RO=28,124 RW=1,876 ZI=137,084(Code 较迁移前 +4 B)。 台架验证(COM3 @115200,RS232#1 经 CN1.10/CN1.12): - 烧录回读 no difference found;8 个 required 锚点全中,无 forbidden; 启动到 net init: OK 用时 661 ms - 连续 10 分钟长稳:1218 行,零 [ERR]、零 dropped、零 tx_fault, 末行仍在正常 PROF 输出 - USART1 已无任何控制台写入(全文件 grep 只剩历史注释)
This commit is contained in:
+32
-20
@@ -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(那本账的语义是"软复位自愈次数")。
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:Console Single-Writer Logging — 控制台单写者日志(USART1 调试串口)
|
||||
* 模块名称:Console Single-Writer Logging — 控制台单写者日志(RS232#1 / UART5)
|
||||
* 模块功能:调试控制台单写者环形缓冲的公共 API:所有任务/上下文(含 printf)只把
|
||||
* 已格式化整行文本入环形缓冲,写者任务(defaultTask)为唯一
|
||||
* HAL_UART_Transmit 发送点(行级原子 + 指针可控)
|
||||
|
||||
@@ -47,10 +47,10 @@ dhara 失败类 +84;RO 另 +208,全是该失败类名表)→ `ER_IROM1`
|
||||
<!-- MEM_SNAPSHOT:BEGIN generated by scripts/check_mem_numbers.py -->
|
||||
| 区域 | 用量 | 容量 | 占比 |
|
||||
|---|---|---|---|
|
||||
| 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%** |
|
||||
<!-- MEM_SNAPSHOT:END -->
|
||||
|
||||
各区的容量与常量来源:
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<!-- MEM_BUDGET:BEGIN generated by scripts/ram_baseline.py -->
|
||||
| 区域 | 用量 | 容量 | 占比 | 门禁(≤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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user