board_test.h
源文件路径:
midware/debug/board_test.h所属模块:midware/debug(设备中间件 - 板级调试/产线测试) 代码行数:73
1. 文件职责
本文件是单板自检模块(board_test.c)的对外头文件,核心职责有两个:一是定义测试结果位图——用 BOARD_TEST_U 联合体把 32 位结果字的每一位绑定到一个具名外设上,使 board_test.c 里可以写 u_single_board_test_result.bit.u8_rtc = 0 这样自解释的代码;二是导出测试使能/结果两个全局变量与 board_test() 入口,供 task_system_aux 驱动、供 Modbus 从机寄存器读写。
它处于"产线测试旁路"的接口位置:Modbus 工装通过寄存器把 g_u8_single_board_test_enable 置 1,task_system_aux 据此调用 board_test(),结果再由 Modbus 读回。头文件本身无逻辑,最终的数据消费者是上位机工装。
2. 关键数据结构与宏
| 名称 | 类型 | 说明 |
|---|---|---|
__BOARD_TEST_H__ | 宏(包含卫士) | 防止重复包含(board_test.h:11-12) |
FLASH_TEST__LEN | 宏(board_test.h:15,值 32) | 名义上用于 Flash 测试长度,实际在 board_test.c 与全工程内均未被引用,是死宏 |
BOARD_TEST_U | 联合体(board_test.h:17-65) | 单板测试结果容器,共 4 字节。u32 u32_all 与 struct{...} bit 共享同一空间,可整体读写也可按位读写 |
BOARD_TEST_U.u32_all | u32 | 32 位整体视图,board_test() 用它一次性置 0xFFFFFFFF 复位;Modbus 用它取高低 16 位 |
BOARD_TEST_U.bit.u8_eeprom | u8 位域(BYTE0 / bit0) | EEPROM 测试结果,0=通过,1=失败 |
BOARD_TEST_U.bit.u8_rtc | u8 位域(bit1) | PCF8563 RTC 测试结果 |
BOARD_TEST_U.bit.u8_flash | u8 位域(bit2) | SPI Flash 测试结果 |
BOARD_TEST_U.bit.u8_sdram | u8 位域(bit3) | 外部 SDRAM 读写测试结果 |
BOARD_TEST_U.bit.u8_rs485 | u8 位域(bit4) | RS485 双向测试结果 |
BOARD_TEST_U.bit.u8_usart2 | u8 位域(bit5) | USART2 自发自收测试结果 |
BOARD_TEST_U.bit.u8_usart3 | u8 位域(bit6) | 保留位;board_test() 中直接置 0,未做真实测试 |
BOARD_TEST_U.bit.u8_usart6 | u8 位域(bit7) | 由 USART5 自发自收测试写入(位名与实际外设不符) |
BOARD_TEST_U.bit.u8_w5500 | u8 位域(BYTE1 / bit8) | W5500 以太网 MAC 回读比对结果 |
BOARD_TEST_U.bit.u8_can1 | u8 位域(bit9) | CAN0/CAN1 互通测试结果 |
BOARD_TEST_U.bit.u8_can2 | u8 位域(bit10) | CAN1/CAN0 互通测试结果 |
BOARD_TEST_U.bit.u8_can3 | u8 位域(bit11) | 保留位;board_test() 中直接置 0,未做真实测试 |
BOARD_TEST_U.bit.u8_drm | u8 位域(bit12) | DRM 4 路信号 + AD 采样测试结果 |
BOARD_TEST_U.bit.u8_dido1 | u8 位域(bit13) | 干接点 DO1→DI1 回环测试结果 |
BOARD_TEST_U.bit.u8_dido2 | u8 位域(bit14) | 干接点 DO2→DI2 回环测试结果 |
BOARD_TEST_U.bit.bit15 | u8 位域(bit15) | 无名保留位 |
BOARD_TEST_U.bit.bit16 ~ bit31 | u8 位域(BYTE2/BYTE3) | 无名保留位,共 16 位 |
g_u8_single_board_test_enable | extern u8(board_test.h:67) | 单板测试使能标志,生产/消费见 board_test.c、modbus.c、ate.c |
u_single_board_test_result | extern BOARD_TEST_U(board_test.h:68) | 测试结果全局变量 |
3. 函数清单
本文件不含函数定义,仅含 1 个函数声明:
| 函数名 | 作用域 | 说明 |
|---|---|---|
board_test | 全局(声明,board_test.h:70) | 单板自检总入口,定义在 board_test.c:613,由 task_system_aux 周期调用 |
4. 核心逻辑解析
头文件本身无状态机与算法,因此这里说明它所定义的两件事如何被使用。
4.1 结果位图的语义约定
约定是反逻辑:0 = 测试通过,1 = 测试失败。理由是 u_single_board_test_result 的初值被设为 0xFFFFFFFF(board_test.c:37),board_test() 每次开始也把 u32_all 重置为 0xFFFFFFFF(board_test.c:620)。这样:
- 任何未被测试覆盖的位、任何提前
return的路径,都保持为1(失败); - 只有测试明确成功后,才由对应子函数把该位清 0。
对产线而言,这意味着"显示出 0 的一定真的测过并通过",不会出现"没测却显示通过"的假阴性,方向是安全侧。
4.2 位布局与字节边界
u32_all 是 32 位,bit 结构体按 BYTE0 → BYTE3 顺序排布 4 组 8 个 u8:1 位域,与 u32_all 在小端 ARM(GD32F407)上的字节顺序一致:bit0~7 落在 u32_all 的最低字节,bit24~31 落在最高字节。因此 Modbus 读寄存器时:
REG_SINGLE_BOARD_TEST_RESULT_H→(u16)(u32_all >> 16) & 0xFFFF(modbus.c:4214)取的是 bit16~31,全部是未使用的保留位;REG_SINGLE_BOARD_TEST_RESULT_L→(u16)(u32_all & 0xFFFF)(modbus.c:4225)取的是 bit0~15,即全部有意义的测试位。
也就是说,高 16 位寄存器对工装永远是 0xFFFF(全失败),因为没有任何测试会去清 bit16~bit31。这是一个明确的接口缺陷。
4.3 与 uCOS-II 的配合
无。头文件不涉及任务、信号量或邮箱;board_test() 是同步阻塞函数,由 task_system_aux 直接调用。
5. 对外接口
本文件导出
| 名称 | 类型 | 供谁使用 |
|---|---|---|
BOARD_TEST_U | 联合体类型 | board_test.c(定义结果变量)、midware/interface/modbus/modbus.c(通过 u32_all 取值) |
FLASH_TEST__LEN | 宏 | 无使用者(死宏) |
g_u8_single_board_test_enable | 全局变量声明 | midware/debug/ate.c:138/172(禁透传)、midware/interface/modbus/modbus.c:4212/4223/6937(读结果、置使能) |
u_single_board_test_result | 全局变量声明 | midware/interface/modbus/modbus.c:4214/4225 |
board_test(void) | 函数声明 | midware/auxiliary/system_aux.c:2083 |
本文件调用的外部函数/变量
仅 #include "chip.h"(board_test.h:13),取得 u8/u32 等基础类型。不调用任何函数、不引用外部变量。
6. 依赖关系
依赖
system/sys/chip.h(u8/u16/u32 基础类型定义)。
被依赖
midware/debug/board_test.c(本模块实现)midware/auxiliary/system_aux.c(#include "board_test.h",调用board_test())midware/debug/ate.c(#include "board_test.h",读g_u8_single_board_test_enable)midware/interface/modbus/modbus.c(读写两个全局变量;该文件经modbus.h一线间接包含或直接包含)
7. 备注与风险点
- 高 16 位永远为 1:
BOARD_TEST_U的 bit16~bit31 没有任何代码去清零,而board_test()每次把u32_all置0xFFFFFFFF,导致 Modbus 的REG_SINGLE_BOARD_TEST_RESULT_H恒为0xFFFF。工装若按"高位也是结果"理解会产生误判。 u8_usart6位名与实际外设不符:board_test.c中是 USART5 的自发自收测试写入此位(board_test.c:271-275),而hardware/usart5/usart5.c用的是 USART5 外设(PC6/PC7)。上位机按位名理解会找错硬件。u8_usart3/u8_can3未被任何测试写入,只由board_test()无条件置 0(通过),即对工装永远显示"通过"。u8_eeprom与u8_flash由同一个判据同时写(board_test.c:405-406/410-411),头文件把两者列为独立位,但实际无法区分。BIT位域依赖小端字节序:u32_all与bit结构体的映射关系在小端 ARM 上如注释所述,但没有编译期断言(对比工程其它头文件广泛使用的STATIC_ASSERT,例如ethernet.h:265),若将来移植到大端平台会静默错位。FLASH_TEST__LEN是死宏(board_test.h:15),定义后全工程无引用。- 文件头注释写成
@file :singleboardtest.h(board_test.h:2),与实际文件名不符,属历史重命名的遗留。 - 两个全局变量没有
volatile:g_u8_single_board_test_enable由 Modbus 任务写、task_system_aux与ate.c读,跨任务无保护也无volatile,存在优化读陈旧值的理论风险(实际工程中未观察到问题)。 BOARD_TEST_U使用了匿名内部结构体(只声明了联合体成员struct {...} bit;,未给结构体命名),属于 C11/编译器扩展友好的写法,但在某些严格模式下不可移植。