diff --git a/test/host/console_log/console_log_test.c b/test/host/console_log/console_log_test.c index 34975d52..80d72b6b 100644 --- a/test/host/console_log/console_log_test.c +++ b/test/host/console_log/console_log_test.c @@ -6,7 +6,7 @@ * 起是**整行独占**,不再是"无锁":M 族 TC-CONLOG-170 至 TC-CONLOG-179 钉"别的写者插不进 * 一行、让路行逐字节等同直发、让位不丢、真溢出才 [ERR]")、缓冲满有界等待与 * 丢弃可观测、TX 僵尸通道软复位自愈 + 300ms 冷却、DWT 与指令计数两种硬上界、 - * huart1.Instance 未初始化的 NULL 短路、fputc 重定向、drain 250ms 预算、 + * huart5.Instance 未初始化的 NULL 短路、fputc 重定向、drain 250ms 预算、 * 整行所有权(行级单一所有者,道G task-23)。 * * 为什么要主机侧单测(而不是只用台架): @@ -19,7 +19,7 @@ * * 桩的边界(细节见 stub/stm32f4_fake.h 头注释): * console_log.h / sys_events.h(含真实 SYS_EVT_CONSOLE_TX 位)用**真实头**; - * usart.h 用桩,但只暴露本模块访问的 huart1 + MX_USART1_UART_Init,寄存器位号 / + * usart.h 用桩,但只暴露本模块访问的 huart5 + MX_UART5_Init,寄存器位号 / * 枚举值照抄真实头;USART SR 的 TXE/TC、DWT CYCCNT、HAL_GetTick、临界区、 * __get_IPSR、vTaskDelay、osEventFlagsSet 做成可控 + 可观测的量。 * ⚠ 本文件**刻意不定义**任何 syslog_* / DBG_* 符号:console_log.c 哪天把"TX 故障 @@ -38,7 +38,7 @@ * 读后清、300ms 冷却两端、tick==0 也进冷却(哨兵撞值修好后为正向断言)、 * 半块 / 已上线仍判失败 * 090..106 DWT 惰性使能三处寄存器写、使能失败退回 20000 次指令计数、超时判据不读 - * HAL_GetTick(第 8b 轮台架动机)、huart1.Instance == NULL 短路两路 + + * HAL_GetTick(第 8b 轮台架动机)、huart5.Instance == NULL 短路两路 + * "未初始化绝不 reinit"(误自愈修好后为正向断言)+ 证据不蒸发 * 110..117 fputc 重定向(未注册直发 / 注册逐字节入环 / ISR 上下文裸发 / 环满时 ISR * 仍不等待) @@ -112,7 +112,7 @@ uint32_t SystemCoreClock = 168000000U; /* 与 MCU 端一致(168 MHz) */ USART_TypeDef g_con_uart; CoreDebug_Type g_con_core_debug; DWT_Type g_con_dwt; -UART_HandleTypeDef huart1; +UART_HandleTypeDef huart5; uint32_t con_uart_tx_n; uint8_t con_uart_tx[CON_UART_TX_MAX]; @@ -282,12 +282,12 @@ osStatus_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags) } /* 真实版是 CubeMX 生成的 HAL_UART_Init 封装;桩按脚本决定"软复位到底治没治好" */ -void MX_USART1_UART_Init(void) +void MX_UART5_Init(void) { s_mx_init_calls++; - huart1.Instance = &g_con_uart; - huart1.gState = HAL_UART_STATE_READY; - huart1.ErrorCode = HAL_UART_ERROR_NONE; + huart5.Instance = &g_con_uart; + huart5.gState = HAL_UART_STATE_READY; + huart5.ErrorCode = HAL_UART_ERROR_NONE; if (s_mx_repair != 0) { con_uart_txe_stuck = 0; con_uart_txe_after = 0; @@ -413,10 +413,10 @@ static void reset_all(void) s_mx_init_calls = 0U; s_mx_repair = 0; - huart1.Instance = &g_con_uart; - huart1.gState = HAL_UART_STATE_READY; - huart1.RxState = HAL_UART_STATE_READY; - huart1.ErrorCode = HAL_UART_ERROR_NONE; + huart5.Instance = &g_con_uart; + huart5.gState = HAL_UART_STATE_READY; + huart5.RxState = HAL_UART_STATE_READY; + huart5.ErrorCode = HAL_UART_ERROR_NONE; } /* ===================== 观察辅助 ===================== */ @@ -983,12 +983,12 @@ static void tc_dwt(void) "TC-CONLOG-099 the DWT branch declares timeout on the first spin (the ceiling really works, never burns 20000)"); } -/* ============ TC-CONLOG-100..106 huart1.Instance == NULL 短路 + 未初始化分诊 ============ */ +/* ============ TC-CONLOG-100..106 huart5.Instance == NULL 短路 + 未初始化分诊 ============ */ static void tc_null_uart(void) { - printf("-- TC-CONLOG-100..106 USART1 not initialised: yield, never reinit, keep proof --\n"); + printf("-- TC-CONLOG-100..106 UART5 not initialised: yield, never reinit, keep proof --\n"); reset_all(); - huart1.Instance = 0; + huart5.Instance = 0; dbg_console_write_raw("boom", 5U); CHECK(con_uart_tx_n == 0U && con_uart_txe_reads == 0U, "TC-CONLOG-100 with Instance==NULL not one register is touched (no dereference of address 0)"); @@ -996,7 +996,7 @@ static void tc_null_uart(void) "TC-CONLOG-101 DWT is still lazily enabled before the short circuit (ensure stays ahead of the NULL check)"); reset_all(); - huart1.Instance = 0; + huart5.Instance = 0; CHECK(dbg_console_write_line("early", 5U) == 5, "TC-CONLOG-102 the unattached path (pre-kernel) survives a missing UART and still returns the line length"); @@ -1004,7 +1004,7 @@ static void tc_null_uart(void) reset_all(); attach_writer(); (void)dbg_console_write_line("abc", 3U); - huart1.Instance = 0; /* 写者起来了但串口还没初始化 */ + huart5.Instance = 0; /* 写者起来了但串口还没初始化 */ s_mx_repair = 1; writer_drain(); CHECK(s_mx_init_calls == 0U && con_rcc_disables == 0U && con_nvic_clears == 0U, @@ -1014,7 +1014,7 @@ static void tc_null_uart(void) CHECK(dbg_console_dropped() == 1U && used_now() == 0U, "TC-CONLOG-105 the block that left the ring but never hit the wire counts as dropped"); - huart1.Instance = &g_con_uart; /* 串口随后初始化好 */ + huart5.Instance = &g_con_uart; /* 串口随后初始化好 */ con_uart_tx_n = 0U; writer_drain(); CHECK(tx_contains("[ERR] CONSOLE dropped 1 lines") && dbg_console_dropped() == 0U, @@ -1159,7 +1159,7 @@ static void tc_three_ledgers(void) reset_all(); attach_writer(); (void)dbg_console_write_line("xyz", 3U); - huart1.Instance = 0; + huart5.Instance = 0; writer_drain(); CHECK(dbg_console_dropped() == 1U && dbg_console_tx_timeout() == 0U && dbg_console_tx_fault() == 0U, @@ -1193,11 +1193,11 @@ static void tc_three_ledgers(void) con_dwt_step = SystemCoreClock / 4U; (void)dbg_console_write_line("0123456789ABCDEFGHIJ", 20U); /* 缓冲满丢 1 行 */ con_dwt_step = 0U; - huart1.Instance = 0; /* 告警那一发也发不出去 */ + huart5.Instance = 0; /* 告警那一发也发不出去 */ writer_drain(); CHECK(dbg_console_dropped() >= 1U, "TC-CONLOG-148 drop count survives while the channel is unavailable (evidence no longer washed away)"); - huart1.Instance = &g_con_uart; + huart5.Instance = &g_con_uart; con_uart_tx_n = 0U; writer_drain(); CHECK(tx_contains("[ERR] CONSOLE dropped") && dbg_console_dropped() == 0U, diff --git a/test/host/console_log/run_unit_test.py b/test/host/console_log/run_unit_test.py index 44c97d1f..483c5503 100644 --- a/test/host/console_log/run_unit_test.py +++ b/test/host/console_log/run_unit_test.py @@ -10,7 +10,7 @@ 缓冲满两条上界 (DWT 周期 / 200 tick)与丢弃计数、[ERR] 告警行不经环(不递归)、TX 僵尸通道软复位 自愈 + 故障即止 + 300ms 冷却(含无符号回绕)、DWT 使能失败退回 20000 次指令计数、 - huart1.Instance==NULL 短路、fputc 重定向、drain 250ms 预算、行级单一所有者。 + huart5.Instance==NULL 短路、fputc 重定向、drain 250ms 预算、行级单一所有者。 工具链与判定委托 test/host/common/unit_test_harness.py。 为什么要主机侧单测(而不是只用台架): @@ -26,7 +26,7 @@ docs/子系统设计/控制台单写者日志设计说明.md(G1~G5 / K1~K5 / §12 ORE 僵尸通道)。 桩的边界:console_log.h 与 sys_events.h 用真实头(SYS_EVT_CONSOLE_TX 位定义一改即 - 编译期报错);usart.h 是桩但只暴露本模块访问的 huart1 + MX_USART1_UART_Init, + 编译期报错);usart.h 是桩但只暴露本模块访问的 huart5 + MX_UART5_Init, USART SR 位号、DWT/CoreDebug 位掩码、HAL_StatusTypeDef 枚举值均照抄真实头, 宿主编不动的那条 main.h -> stm32f4xx_hal.h -> core_cm4.h 链由 stub/stm32f4_fake.h 以普通结构体替代(理由写在该文件头注释里)。 diff --git a/test/host/console_log/stub/stm32f4_fake.h b/test/host/console_log/stub/stm32f4_fake.h index ed7db951..5f285c9b 100644 --- a/test/host/console_log/stub/stm32f4_fake.h +++ b/test/host/console_log/stub/stm32f4_fake.h @@ -2,7 +2,7 @@ * 模块名称:主机侧单测桩 - 假 HAL/CMSIS 寄存器面 + 内核入口(console_log 模块专用) * 模块功能:让 App/log/console_log.c 在 PC 上编起来,并把它依赖的硬件/内核面做成 * **可脚本控制**的模型: - * ① USART1:TXE/TC 可注入「就绪 / 永远不就绪(僵尸通道)/ 前 N 次不就绪」; + * ① 假串口外设:TXE/TC 可注入「就绪 / 永远不就绪(僵尸通道)/ 前 N 次不就绪」; * 写进 DR 的字节被收进一条上线字节日志,并按「一次 TC 就绪 = 一块」记块长。 * ② DWT CYCCNT:每次访问推进 con_dwt_step 个周期(= 给时间定价), * CTRL 的 CYCCNTENA 可脚本成「写不进去」以走 con_tx_counted 支路。 @@ -19,7 +19,7 @@ * DWT_Type.CTRL/CYCCNT + DWT_CTRL_CYCCNTENA_Msk=bit0、CoreDebug_Type.DEMCR + * CoreDebug_DEMCR_TRCENA_Msk=bit24(core_cm4.h) * HAL_StatusTypeDef{OK=0,ERROR=1,BUSY=2,TIMEOUT=3}(stm32f4xx_hal_def.h) - * HAL_UART_STATE_RESET=0x00、HAL_UART_ERROR_NONE=0x00、USART1_IRQn=7 + * HAL_UART_STATE_RESET=0x00、HAL_UART_ERROR_NONE=0x00、UART5_IRQn=7 * UART_HandleTypeDef 只搬本模块访问的 4 个字段(Instance/gState/RxState/ErrorCode), * 余下(Init/Lock/...)刻意不搬:抄半份 HAL 结构只会更快与真实头漂移。 * @@ -52,11 +52,11 @@ #include /* ===== 与真实头同值的位 / 枚举(来源见文件头) ===== */ -#define USART_SR_TXE_Msk (0x0080U) /* USART1->SR bit7 发送寄存器空 */ -#define USART_SR_TC_Msk (0x0040U) /* USART1->SR bit6 发送完成 */ +#define USART_SR_TXE_Msk (0x0080U) /* SR bit7 发送寄存器空 */ +#define USART_SR_TC_Msk (0x0040U) /* SR bit6 发送完成 */ #define DWT_CTRL_CYCCNTENA_Msk (0x00000001U) #define CoreDebug_DEMCR_TRCENA_Msk (0x01000000U) -#define USART1_IRQn 7 +#define UART5_IRQn 7 #define HAL_UART_STATE_RESET 0x00U #define HAL_UART_STATE_READY 0x20U @@ -75,7 +75,7 @@ typedef enum { extern uint32_t SystemCoreClock; /* ------------------------------------------------------------------ */ -/* ① 假 USART1 */ +/* ① 假串口外设 */ /* ------------------------------------------------------------------ */ typedef struct { volatile uint32_t SR; @@ -368,7 +368,7 @@ extern uint32_t con_nvic_clears; extern uint32_t con_rcc_disables; extern uint32_t con_rcc_enables; #define __NVIC_ClearPendingIRQ(irqn) do { (void)(irqn); con_nvic_clears++; } while (0) -#define __HAL_RCC_USART1_CLK_DISABLE() do { con_rcc_disables++; } while (0) -#define __HAL_RCC_USART1_CLK_ENABLE() do { con_rcc_enables++; } while (0) +#define __HAL_RCC_UART5_CLK_DISABLE() do { con_rcc_disables++; } while (0) +#define __HAL_RCC_UART5_CLK_ENABLE() do { con_rcc_enables++; } while (0) #endif /* STM32F4_FAKE_H */ diff --git a/test/host/console_log/stub/usart.h b/test/host/console_log/stub/usart.h index bc22ea7c..e6690061 100644 --- a/test/host/console_log/stub/usart.h +++ b/test/host/console_log/stub/usart.h @@ -1,8 +1,10 @@ /* * 模块名称:主机侧单测桩 - usart.h(console_log 模块专用) * 模块功能:与真实 Inc/usart.h 对本模块可见的部分逐字一致:extern UART_HandleTypeDef - * huart1; + void MX_USART1_UART_Init(void);(真实那份还声明 huart2~5 与 - * MX_USART2~5_UART_Init,本模块只碰 USART1,搬多出来的声明没有意义)。 + * huart5; + void MX_UART5_Init(void);(真实那份还声明 huart1~4 与 + * MX_USART1~3_UART_Init / MX_UART4_Init,本模块只碰 UART5,搬多出来的声明 + * 没有意义)。 + * 2026-10-29 批 0:控制台从 USART1 迁到 RS232#1/UART5,本桩随之改。 * ⚠ 仅供 test/host/console_log/ 使用,不参与 MCU 构建。 * 真实 Inc/usart.h 的 include 链(main.h -> stm32f4xx_hal.h -> stm32f4xx.h -> * core_cm4.h)在宿主上编不动,寄存器面由 stm32f4_fake.h 提供(理由见该文件头)。 @@ -14,7 +16,7 @@ #include #include "stm32f4_fake.h" -extern UART_HandleTypeDef huart1; -void MX_USART1_UART_Init(void); +extern UART_HandleTypeDef huart5; +void MX_UART5_Init(void); #endif /* USART_H */