Files
wandering1 7c8669e52a feat(屏板): USART1 700 kbaud + 收中断传输层 sb_link(1-2/1-3)
批 1 的 1-2 / 1-3:把屏板(DTU-LCD)发来的 6 B 帧 A 在 USART1 上稳定收下来。

1-2 波特率:.ioc 不保存任何 UART 的波特率(只有
USART1.IPParameters=VirtualMode),GUI 里改也不落盘,所以只能在
Src/usart.c 的 USER CODE BEGIN USART1_Init 2 区覆盖 huart1.Init.BaudRate
后重调一次 HAL_UART_Init(第二次调用时 gState 已非 RESET,HAL 只重算
BRR、不再跑 MspInit,GPIO/DMA/NVIC 不会被重配)。开机日志实测
BRR=0x0078,与理论值 84 MHz/(16x700 kHz)=7.5 逐位相符,误差 0%。

1-3 收中断:新建 Drivers/BSP/ScreenLink/sb_link.c/h——16 B 缓冲 + IDLE
中断断帧、帧 A 校验、错误中断里按 RM0090 清 ORE/NE/FE/PE、周期统计上报。
HAL_UARTEx_RxEventCallback / HAL_UART_ErrorCallback 是全局单例(唯一实现
在 rs485.c),故只在那里各加一行转发,按句柄过滤放在 sb_link 内。

台架实测(PC + USB 转 TTL 顶替屏板,COM6@700000)撞出两个真问题:
- 错误回调里无条件重挂 -> 出现 err=160 / rearm=160 同步增长,看着像每帧
  都重挂失败。真因是 HAL 把 NE/FE/PE 归为非阻塞型(接收照跑、RxState 仍是
  BUSY_RX),此时 ReceiveToIdle_IT 只会返回 HAL_BUSY。改为仅当
  RxState == HAL_UART_STATE_READY(ORE 那类阻塞型)时才重挂。
- 日志字面量里带中文 -> ARMCC #870-D invalid multibyte character
  sequence。字面量一律纯 ASCII,中文只写注释。

验证:主机单测 81/81 PASSED(test/host/sb_link/,其中按 RM0090 的清除语义
把"必须 SR->DR 顺序才清得掉 ORE"钉成断言);Keil 0 错误 0 警告;台架
rx == 发送帧数、ok == rx、crc=0、len=0、size=6、keys 随按键帧递增;先用
错波特率灌 64 B 垃圾(len=31、bits=0x06)后自动恢复且 rearm=0。
新增 test/host/screenlink_bench.py 作为可复跑的屏板激励(--key / --glitch-baud)。
2026-10-29 20:13:18 +08:00

59 lines
1.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 模块名称:主机侧单测桩 - dbg_log.h(sb_link 模块专用)
* 模块功能:把 DBG_INFO / DBG_ERROR 换成"写进一个可读的行缓冲",于是用例能断言
* 「打了几行、第一行说了什么」,而不是只能靠人看台架串口。
* ⚠ 仅供 test/host/sb_link/ 使用,不参与 MCU 构建。
* 真实 dbg_log.h 会拉进 console_log.h / sys_clock.h(App 层)并带时间戳,
* 本模块的用例只关心"有没有上报",故整份替换掉,不搬那条链。
* 创建日期:2026-10-29
*/
#ifndef DBG_LOG_H
#define DBG_LOG_H
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#define SB_LOG_MAX (32U)
#define SB_LOG_LINE_MAX (192U)
static char sb_log[SB_LOG_MAX][SB_LOG_LINE_MAX];
static uint32_t sb_log_n;
static void sb_log_add(const char *p_lvl, const char *p_fmt, ...)
{
va_list ap;
size_t used;
if (sb_log_n >= SB_LOG_MAX) {
return;
}
(void)snprintf(sb_log[sb_log_n], SB_LOG_LINE_MAX, "%s ", p_lvl);
used = strlen(sb_log[sb_log_n]);
va_start(ap, p_fmt);
(void)vsnprintf(sb_log[sb_log_n] + used, (size_t)(SB_LOG_LINE_MAX - used), p_fmt, ap);
va_end(ap);
sb_log_n++;
}
static void sb_log_reset(void)
{
sb_log_n = 0U;
sb_log[0][0] = '\0';
}
/* 第 idx 行是否包含 needle(idx 越界返回 0) */
static int sb_log_has(uint32_t idx, const char *p_needle)
{
if ((idx >= sb_log_n) || (idx >= SB_LOG_MAX)) {
return 0;
}
return (strstr(sb_log[idx], p_needle) != NULL) ? 1 : 0;
}
#define DBG_INFO(...) sb_log_add("INFO", __VA_ARGS__)
#define DBG_ERROR(...) sb_log_add("ERR", __VA_ARGS__)
#endif /* DBG_LOG_H */