使用check.h测试STM32寄存器裸机代码时遇段错误求助
STM32寄存器单元测试触发段错误的问题与解决方案
问题背景
使用check.h库对STM32F030F4的LED1_off函数做单元测试时触发段错误,移除函数内的寄存器操作语句后段错误消失。推测测试时程序试图访问PC自身的无效内存地址,需明确该测试需求是否可行,以及对应的解决或替代方案。
待测试函数代码
#define GPIOA_BASE 0x48000000 #define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14)) #define LED1 (*(volatile uint32_t *)(0)) #define OFF 0UL uint32_t LED1_off (void) { GPIOA_ODR |= (OFF << LED1); return GPIOA_ODR ; }
测试代码
START_TEST (test_LED1_off) { ck_assert_int_eq(0x48000014, LED1_off()); } END_TEST
错误信息
Running suite(s): FunctionsTests 66%: Checks: 3, Failures: 0, Errors: 1 tests/tests.c:31:E:Core:test_LED1_off:0: (after this point) Received signal 11 (Segmentation fault)
问题分析与解决方案
核心原因
PC的内存地址空间与STM32的外设地址空间完全独立:
GPIOA_ODR直接映射到STM32的外设地址0x48000014,这个地址在PC的用户态内存中未分配且不可访问,读写操作直接触发段错误。LED1的定义*(volatile uint32_t*)(0)会读取PC的地址0,而PC系统中地址0属于受保护的无效区域,访问必然崩溃。
需求可行性与解决方法
该测试需求完全可行,只需通过模拟硬件寄存器的方式避免直接访问PC的无效内存,具体方案如下:
1. 本地模拟寄存器(最简方案)
在测试代码中重新定义寄存器宏,将其指向PC内存中的普通变量,替代硬件地址映射:
// 测试代码中添加模拟变量与重定义 uint32_t mock_gpioa_odr = 0; #define GPIOA_ODR mock_gpioa_odr #define LED1 0 // 修正LED1定义为实际引脚位号,比如假设LED对应GPIOA的第0位 START_TEST (test_LED1_off) { // 初始化模拟寄存器值 mock_gpioa_odr = 0xFFFFFFFF; // 模拟初始状态 uint32_t result = LED1_off(); // 验证操作后寄存器值是否符合预期 ck_assert_int_eq(0xFFFFFFFE, result); } END_TEST
- 要点:必须修正
LED1的定义,将其改为引脚对应的位号(而非读取无效地址),否则仍会触发段错误。
2. 封装硬件操作+Mock框架
将寄存器操作封装为独立的硬件抽象函数,测试时用Mock框架(如CMock)替换这些函数,验证调用逻辑:
// 封装后的硬件操作函数(生产代码) void gpio_set_pin(uint32_t gpio_base, uint8_t pin, uint32_t state) { volatile uint32_t* odr = (volatile uint32_t*)(gpio_base + 0x14); if (state == OFF) { *odr &= ~(1UL << pin); } else { *odr |= (1UL << pin); } } uint32_t LED1_off(void) { gpio_set_pin(GPIOA_BASE, LED1_PIN, OFF); return *(volatile uint32_t*)(GPIOA_BASE + 0x14); }
测试时用CMock生成gpio_set_pin的Mock函数,验证是否以正确的参数调用,同时模拟返回的寄存器值。
3. 硬件在环测试(HIL)
若需验证真实硬件上的行为,可将测试代码编译为ARM架构二进制,下载到STM32开发板运行,通过串口、SWD调试接口获取测试结果。这种方式更贴近真实环境,但测试效率低于PC端单元测试。
替代测试方案
若暂时无法实现PC端模拟,可采用:
- 静态代码分析:检查寄存器操作的语法与逻辑正确性,比如位运算是否符合预期。
- 开发板上的集成测试:直接在STM32硬件上运行测试逻辑,通过LED状态、串口输出验证函数行为。
内容的提问来源于stack exchange,提问作者Norronas
相关产品推荐
相关产品推荐

