含FreeRTOS依赖项目中Ceedling单元测试报错求助
解决Ceedling单元测试中找不到FreeRTOS依赖的reent.h文件问题
问题概述
用Ceedling+Unity+CMock做单元测试的项目依赖FreeRTOS,构建测试时抛出错误,提示找不到reent.h:
FreeRTOS/Source/include/FreeRTOS.h:84:14: fatal error: reent.h: No such file or directory 84 | #include <reent.h>
环境信息
reent.h所在路径:C:/ST/STM32CubeIDE_1.9.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.0.202111181127/tools/arm-none-eabi/include- 项目
project.yml核心配置片段:
--- :project: :use_exceptions: FALSE :use_test_preprocessor: TRUE :build_root: build :test_file_prefix: test_ :ceedling_version: 0.31.1 :default_tasks: - test:all :paths: :source: - Core/App - FreeRTOS/Source/include # 其他源文件路径省略 :defines: :test: - STM32F407xx - USE_HAL_DRIVER # 其他宏定义省略 ...
已尝试但无效的方案
- 在
project.yml中直接添加该头文件的包含路径 - 用环境变量管理头文件包含路径
- 复制
reent.h到本地include目录
可行解决方案
1. 修正Ceedling的路径配置
Ceedling的路径分生产代码和测试代码两类,之前的配置可能只把工具链路径加到了:source下,但测试构建需要单独配置测试环节的包含路径。修改project.yml的:paths部分:
:paths: :source: - Core/App - FreeRTOS/Source/include # 其他源文件路径省略 :test: - test/source # 加入工具链头文件路径 - C:/ST/STM32CubeIDE_1.9.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.0.202111181127/tools/arm-none-eabi/include :includes: - Core/Inc - FreeRTOS/Source/include # 全局includes也加上工具链路径 - C:/ST/STM32CubeIDE_1.9.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.0.202111181127/tools/arm-none-eabi/include
注意Windows路径用正斜杠,或者把反斜杠转成\\。
2. 指定Ceedling使用ARM工具链编译器
Ceedling默认用系统的x86 gcc,但你的项目是ARM平台,必须指定STM32CubeIDE的ARM编译器。在project.yml中添加工具链配置:
:tools: :test_compiler: :executable: arm-none-eabi-gcc :arguments: - -std=c99 - -Wall - -Wextra # 手动指定工具链系统头文件路径 - -IC:/ST/STM32CubeIDE_1.9.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.0.202111181127/tools/arm-none-eabi/include # 其他编译参数按需添加
这样Ceedling用ARM编译器构建时,会自动识别自身的系统头文件,避免路径问题。
3. Mock FreeRTOS接口(推荐)
单元测试的核心是隔离业务代码和依赖,没必要真的依赖FreeRTOS库。直接MockxTaskNotifyWait()这类函数,完全绕开底层头文件:
#include "CMock.h" #include "FreeRTOS.h" // 手动Mock xTaskNotifyWait void xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait) { mock(); }
或者用CMock自动生成Mock,在project.yml中配置:
:cmock: :mock_prefix: mock_ :includes: - FreeRTOS/Source/include :mockable_headers: - FreeRTOS.h
这种方式不仅解决头文件问题,还能更灵活地控制测试场景。
Ceedling管理第三方依赖的最佳实践
- 优先Mock依赖:单元测试只关注业务逻辑,Mock掉FreeRTOS、硬件驱动这类底层依赖,既快又能避免环境冲突。
- 统一路径配置:把第三方依赖路径集中写在
project.yml里,用环境变量简化长路径,比如:
然后在系统环境变量里设:paths: :includes: - ${STM32_TOOLCHAIN_PATH}/arm-none-eabi/includeSTM32_TOOLCHAIN_PATH为工具链根目录。 - 用组件管理库:常用的第三方库(如FreeRTOS)可以做成Ceedling组件,通过
:components配置引入,方便复用和版本控制。 - 保持编译器一致:测试用的编译器要和生产环境一致,避免因编译器差异导致的头文件或编译错误。
内容的提问来源于stack exchange,提问作者THE TRECSPE THE TRECSPE
相关产品推荐
相关产品推荐

