You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F439ZI无OS无文件系统环境下GCOV代码覆盖率数据UART输出改造问题求助

STM32F439ZI无OS无文件系统环境下GCOV代码覆盖率数据UART输出改造问题求助

嘿,我刚好在裸机STM32项目里踩过GCOV覆盖率输出的坑,给你分享一下我是怎么把.gcda数据通过UART发出去的,亲测在F4系列上有效!

首先得搞明白:GCOV默认是依赖标准C库的文件IO来写.gcda文件的,咱们裸机没文件系统,核心就是劫持这些文件操作函数,把数据转去UART发送,具体步骤如下:

一、重定向标准C库的文件操作函数

GCOV在输出覆盖率数据时会调用fopen、fwrite、fclose这些函数,我们自己实现这些函数,让它们绕开文件系统直接用UART:

1. 重写fopen

让它返回一个非空的虚拟文件指针,骗GCOV认为文件打开成功:

#include "stm32f4xx_hal.h"
#include <stdio.h>

// 虚拟文件结构体,只要非空就行
static FILE dummy_gcov_file;

FILE *fopen(const char *path, const char *mode) {
    // 这里可以忽略path和mode参数,因为咱们不需要真的打开文件
    return &dummy_gcov_file;
}

2. 重写fwrite

把原本要写入文件的字节直接通过UART发送:

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
    // 用HAL_UART_Transmit发送数据,这里假设你已经初始化了huart1
    HAL_UART_Transmit(&huart1, (uint8_t*)ptr, size * nmemb, HAL_MAX_DELAY);
    // 返回实际发送的成员数,让GCOV认为写入成功
    return nmemb;
}

3. 重写fclose

可以在这里加个结束标记,方便上位机识别.gcda数据的结尾:

int fclose(FILE *stream) {
    // 发送4个0xFF作为数据结束标记,上位机接收时可以用这个来截断数据
    uint8_t eof_marker[] = {0xFF, 0xFF, 0xFF, 0xFF};
    HAL_UART_Transmit(&huart1, eof_marker, sizeof(eof_marker), HAL_MAX_DELAY);
    return 0; // 返回0表示关闭成功
}

二、重写GCOV的刷新函数

GCOV有个__gcov_flush()函数,默认会触发数据写入文件,我们可以自定义它,主动触发覆盖率数据的输出:

// 要包含GCOV的头文件
#include <gcov.h>

void __gcov_flush(void) {
    // 调用GCOV内部的__gcov_dump(),它会把覆盖率数据写入我们"打开"的虚拟文件
    __gcov_dump();
    // 如果需要,也可以在这里额外发送一些标识信息
}

三、编译与运行注意事项

  • 编译时必须加上GCOV相关参数:-fprofile-arcs -ftest-coverage,链接时也要带上,同时建议用-O0优化等级,避免编译器把我们重写的函数优化掉
  • 确保UART初始化要早于GCOV的任何操作,比如在main()函数开头先调用MX_USART1_UART_Init()
  • 触发覆盖率输出:你可以在程序的某个节点调用__gcov_flush(),比如按键按下时、定时中断里,或者程序结束前
  • 上位机处理:用串口助手把接收到的二进制数据(要去掉我们加的结束标记)保存成.gcda文件,比如和你的main.gcno文件放在一起,然后运行gcov main.c就能生成覆盖率报告了

踩过的坑提醒

  • 不要用非阻塞UART发送,调试阶段用阻塞的HAL_UART_Transmit更稳妥,避免数据丢失
  • 重写的函数要确保被编译器链接到,必要时可以给函数加__attribute__((used))属性,防止被优化掉
  • 如果GCOV还是没反应,检查编译参数是否正确,有没有把-fprofile-arcs -ftest-coverage加到所有需要统计覆盖率的源文件上

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 07:42:59