我正在尝试为嵌入式应用程序开发一个新特性,我想使用一种测试驱动的方法来这样做。
该项目是用纯C编写的,正在使用IAR嵌入式Workbench 6.60.1.5104开发。我的目标是一个LPC1788,它是一个Cortex-M3设备,所有的开发都是在64位的Windows 7机器上完成的。现在,我更倾向于让单元测试在PC上运行,而不是在目标硬件上运行(RAM非常有限)。
我偶然发现了一本关于这个主题的有用的书“嵌入式C的测试驱动开发”,它给我指明了像团结、CppUTest、Ceedling等工具。在研究了这些东西之后,我认为我最好的选择是为我的项目配置Ceedling (它使用了Unity )。但是,我不确定我需要采取哪些步骤来配置Ceedling来使用我当前的IAR工具链。
我已经安装了Ceedling并创建了“闪烁”示例项目,我正在尝试使用IAR工具链来构建和测试它。我已经将iccarm.exe添加到我的path中,并编辑了blinky/project.yml,如下所示:
---
# Notes:
# This is a fully tested project that demonstrates the use
# of a timer ISR to blink the on board LED of an Arduino UNO
:project:
:use_exceptions: FALSE
:use_test_preprocessor: TRUE
:use_auxiliary_dependencies: TRUE
:build_root: build
:release_build: TRUE
:test_file_prefix: test_
#You'll have to specify these
:environment:
- :mcu: atmega328p
- :f_cpu: 16000000UL
- :serial_port: COM8 #change this to the serial port you are using!!!
- :objcopy: avr-objcopy
# Uncomment these lines if you are using windows and don't have these tools in your path
# - :path:
# - C:\mingw\bin
# - C:\WinAVR-20100110\bin
# - C:\WinAVR-20100110\utils\bin
# - #{ENV['PATH']}
:extension:
:executable: .bin
:release_build:
:output: blinky
:paths:
:test:
- +:test/**
- -:test/support
:source:
- src/**
:support:
- test/support
:defines:
# in order to add common defines:
# 1) remove the trailing [] from the :common: section
# 2) add entries to the :common: section (e.g. :test: has TEST defined)
:commmon: &common_defines []
:test:
- *common_defines
- TEST
:test_preprocess:
- *common_defines
- TEST
:tools:
:release_compiler:
:executable: avr-gcc
:arguments:
- ${1}
- -DTARGET
- -DF_CPU=#{ENV['F_CPU']}
- -mmcu=#{ENV['MCU']}
- -Iinclude/
- -Wall
- -Os
- -c
- -o ${2}
:release_linker:
:executable: avr-gcc
:arguments:
- -mmcu=#{ENV['MCU']}
- ${1}
- -o ${2}.bin
:cmock:
:mock_prefix: mock_
:when_no_prototypes: :warn
:enforce_strict_ordering: TRUE
:plugins:
- :ignore
:treat_as:
uint8: HEX8
uint16: HEX16
uint32: UINT32
int8: INT8
bool: UINT8
:tools:
:test_file_preprocessor:
:executable: iccarm
:name: 'IAR test file preprocessor'
:test_includes_preprocessor:
:executable: iccarm
:name: 'IAR test includes preprocessor'
:test_compiler:
:executable: iccarm
:name: 'IAR test compiler'
:test_linker:
:executable: iccarm
:name: 'IAR test linker'
:release_compiler:
:executable: iccarm
:name: 'IAR release compiler'
:release_linker:
:executable: iccarm
:name: 'IAR release linker'
:plugins:
:load_paths:
- vendor/ceedling/plugins
:enabled:
- stdout_pretty_tests_report
- module_generator
...这与默认的project.yml之间唯一的区别是第二个:tools部分下的内容。
我的猜测是,我正朝着正确的方向前进,但我不确定iccarm.exe是否是用于工具链所有这些部分的正确的可执行文件,以及需要传递哪些参数。
如果我可以配置Ceedling来构建和测试使用IAR工具链的盲点项目,我希望我能够为我的实际项目应用相同的配置。如果我现在尝试运行rake,就会得到以下输出:
$ rake
Test 'test_BlinkTask.c'
-----------------------
rake aborted!
Errno::ENOENT: No such file or directory @ rb_sysopen - build/test/preprocess/files/test_BlinkTask.c
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator_extractor.rb:18:in `readlines'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator_extractor.rb:18:in `extract_base_file_from_preprocessed_expansion'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator_file_handler.rb:14:in `preprocess_file'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator.rb:40:in `preprocess_file'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator.rb:12:in `block in setup'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator_helper.rb:33:in `preprocess_test_file'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator.rb:25:in `preprocess_test_and_invoke_test_mocks'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/test_invoker.rb:42:in `block in setup_and_invoke'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/test_invoker.rb:32:in `setup_and_invoke'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/tasks_tests.rake:11:in `block (2 levels) in <top (required)>'
Tasks: TOP => default => test:all
(See full trace by running task with --trace)
--------------------
OVERALL TEST SUMMARY
--------------------
No tests executed.我认为这是因为测试文件预处理器应该将测试文件复制到build/test/preprocess/files目录下,而这种情况目前没有发生。
经过一番探索,我发现这个用于统一的示例配置文件看起来很有帮助。它面向一个IAR /Cortex M3环境,就像我正在使用的环境一样。这可能会指示我需要在Ceedling project.yml中指定哪些配置选项。
如果我可以让Ceedling使用IAR工具链来构建和测试blinky项目,我希望我能够调整它以适应实际的项目。任何帮助都将不胜感激。
发布于 2016-12-15 12:13:03
这是一场斗争,但我相信我已经成功地配置了Ceedling来帮助测试我的项目。希望这对任何希望在IAR项目中使用Ceedling的人都有帮助。
Ceedling有一个命令(ceedling new <proj_name>),允许您使用Ceedling期望的结构创建新项目。您还可以指定现有项目的名称,在这种情况下,它只添加必要的文件以使其与Ceedling兼容,这就是我对项目所做的。
作为参考,在执行以下步骤后,我的项目结构如下所示:
.
├── build
│ ├── artifacts
│ │ └── test
│ ├── docs
│ ├── exe
│ ├── list
│ ├── logs
│ ├── obj
│ ├── temp
│ └── test
│ ├── cache
│ ├── dependencies
│ ├── list.i
│ ├── mocks
│ ├── out
│ ├── results
│ ├── runners
│ └── tests.map
├── project.yml
├── rakefile.rb
├── src
│ └── main
│ ├── c
│ │ ├── canDatabase.c
│ ├── include
│ │ ├── canDatabase.h
│ ├── python
│ └── resources
├── test
│ ├── support
│ └── test_canDatabase.c
├── <my_project>.dep
├── <my_project>.ewd
├── <my_project>.ewp
├── <my_project>.eww
├── vendor
│ └── ceedling
│ ├── docs
│ ├── lib
│ ├── plugins
│ └── vendor
└── version.properties之后,我查看了IAR工具的参考手册,并在构建示例项目时研究了IAR嵌入式工作台的输出,如@user694733所建议的那样。我使用这些信息编辑我的project.yml,如下所示:
:project:
:use_exceptions: FALSE
:use_test_preprocessor: FALSE
:use_auxiliary_dependencies: TRUE
:build_root: build
:release_build: FALSE
:test_file_prefix: test_
:environment:
- :path:
- 'C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.5\arm\bin'
- 'C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.5\common\bin'
- #{ENV['PATH']}
:extension:
:executable: .out
:paths:
:test:
- +:test/**
- -:test/support
:source:
- src/main/c/**
- src/main/include/**
- src/main/resources/**
:support:
- test/support
:defines:
:commmon: &common_defines []
:test:
- *common_defines
- TEST
:test_preprocess:
- *common_defines
- TEST
:cmock:
:mock_prefix: mock_
:when_no_prototypes: :warn
:enforce_strict_ordering: TRUE
:plugins:
- :ignore
- :callback
:treat_as:
uint8: HEX8
uint16: HEX16
uint32: UINT32
int8: INT8
bool: UINT8
:tools:
:test_compiler:
:executable: iccarm
:name: 'IAR test compiler'
:arguments:
- -D _DLIB_FILE_DESCRIPTOR=1
- --debug
- --endian=little
- --cpu=Cortex-M3
- -e
- --fpu=None
- -Ol
- --preprocess "build/test/list"
- --dlib_config "C:/Program Files (x86)/IAR Systems/Embedded Workbench 6.5/arm/INC/c/DLib_Config_Normal.h"
- -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE
- -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR
- -o "${2}"
- --diag_suppress=Pa050
- '"${1}"'
:test_linker:
:executable: ilinkarm
:name: 'IAR test linker'
:arguments:
- --vfe
- --redirect _Printf=_PrintfFull
- --redirect _Scanf=_ScanfFull
- --semihosting
- --config "C:/Program Files (x86)/IAR Systems/Embedded Workbench 6.5/arm/config/generic_cortex.icf"
- --map "build/test/tests.map"
- -o "${2}"
- '"${1}"'
:test_fixture:
:executable: cspybat
:name: 'CSpyBat test runner'
:arguments:
- '"C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.5\arm\bin\armproc.dll"'
- '"C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.5\arm\bin\armsim2.dll"'
- '"${1}"'
- --plugin "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.5\arm\bin\armbat.dll"
- --backend -B
- --endian=little
- --cpu=Cortex-M3
- --fpu=None
- --semihosting
:plugins:
:load_paths:
- vendor/ceedling/plugins
:enabled:
- stdout_pretty_tests_report
- module_generator
...这似乎是一种适合测试代码的配置,用于在Cortex-M3设备上工作。
我还编辑了rakefile.rb,以确保在每次测试运行之前清除生成的测试文件,因为这是一致打印测试结果所必需的。
PROJECT_CEEDLING_ROOT = "vendor/ceedling"
load "#{PROJECT_CEEDLING_ROOT}/lib/ceedling.rb"
Ceedling.load_project
task :default => %w[ clean test:all ]那时,我能够定义和运行单元测试。下面是test_canDatabase.c的摘录
#include "unity.h"
#include "canDatabase.h"
uint32_t actualId;
uint8_t actualPayload[8];
uint8_t actualPayloadLen;
uint8_t actualCanPort;
void mockHandler(uint32_t id, uint8_t payload[8], uint8_t payloadLen, uint8_t canPort)
{
actualId = id;
actualPayloadLen = payloadLen;
actualCanPort = canPort;
for (int i=0; i < payloadLen; i++)
{
actualPayload[i] = payload[i];
}
}
void setUp(void)
{
actualId = 0;
actualPayloadLen = 0;
actualCanPort = 0;
for (int i=0; i < 8; i++)
{
actualPayload[i] = 0;
}
CANDB_Init(mockHandler);
}
void tearDown(void) {}
void test_Register_Tx_Definition()
{
// GIVEN a CAN Tx message definition.
CAN_TX_MESSAGE_DEFINITION_T definition;
definition.id = 0;
// WHEN we register the definition in the CAN database.
int err = CANDB_RegisterTxDefinition(definition);
// THEN the database should return SUCCESS (0x0).
TEST_ASSERT_EQUAL_MESSAGE(0x0, err, "Registration should succeed");
}
void test_Register_Tx_Definition_Twice()
{
// GIVEN a CAN Tx message definition.
CAN_TX_MESSAGE_DEFINITION_T definition;
definition.id = 0;
// WHEN we register the definition once.
CANDB_RegisterTxDefinition(definition);
// AND we register the definition again.
int err = CANDB_RegisterTxDefinition(definition);
// THEN the database should return SUCCESS (0x0).
TEST_ASSERT_EQUAL_MESSAGE(0x0, err, "Re-registration should succeed");
}现在,我可以通过从终端调用"ceedling“(项目根目录是当前的工作目录)来运行自动化测试:
$ ceedling
---------------------
BUILD FAILURE SUMMARY
---------------------
Unit test failures.
Cleaning build artifacts...
(For large projects, this task may take a long time to complete)
Test 'test_canDatabase.c'
-------------------------
Generating runner for test_canDatabase.c...
Compiling test_canDatabase_runner.c...
Compiling test_canDatabase.c...
Compiling unity.c...
Compiling canDatabase.c...
Compiling cmock.c...
Linking test_canDatabase.out...
Running test_canDatabase.out...
-----------
TEST OUTPUT
-----------
[test_canDatabase.c]
- ""
- " IAR C-SPY Command Line Utility V6.6.0.2752"
- " Copyright 2000-2013 IAR Systems AB."
- ""
- ""
-------------------
FAILED TEST SUMMARY
-------------------
[test_canDatabase.c]
Test: test_Register_More_Than_Max_Allowed_Definitions
At line (84): "Expected 1 Was 0. Registration > CANDB_MAX_TX_DEFINITIONS should fail"
Test: test_Activate_Tx_Definition_With_Hardcoded_Payload
At line (124): "Expected 0x00000001 Was 0x00000000. Incorrect ID"
--------------------
OVERALL TEST SUMMARY
--------------------
TESTED: 4
PASSED: 2
FAILED: 2
IGNORED: 0发布于 2020-04-22 19:07:32
您的回答非常有用,我正在为Cortex-M4和IAR7.5开发类似的方法,并考虑分享我添加的部分project.yml。
:tools:
:test_compiler:
:executable: iccarm
:name: 'IAR test compiler'
:arguments:
- -D _DLIB_FILE_DESCRIPTOR=1
- --diag_suppress Pa050,Pa082,Pa039,Pe186
- --no_cse
- --no_unroll
- --no_inline
- --no_code_motion
- --no_tbaa
- --no_clustering
- --no_scheduling
- --debug
- --endian=little
- --cpu=Cortex-M4
- -e
- --fpu=VFPv4_sp
- --dlib_config "C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.5\arm\INC\c\DLib_Config_Normal.h"
- --preprocess "build/test/list"
- -On
- --c++
- --no_exceptions
- --no_rtti
- -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE
- -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR
- -o "${2}"
- '"${1}"'
:test_linker:
:executable: ilinkarm
:name: 'IAR test linker'
:arguments:
- --vfe
- --redirect _Printf=_PrintfFull
- --redirect _Scanf=_ScanfFull
- --semihosting
- --keep __checksum
- --entry __iar_program_start
- --place_holder __checksum,4,.checksum,4
- --define_symbol __checksum_begin=0x8020000
- --define_symbol __checksum_end=0x80dfffb
- --no_exceptions
- --config "C:\Users\jseinfeld\RubymineProjects\m4\common\cb\proj\flash.icf"
- --map "build/test/m4.map"
- -o "${2}"
- '"${1}"'
:test_fixture:
:executable: cspybat
:name: 'CSpyBat test runner'
:arguments:
- '"C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.5\arm\bin\armproc.dll"'
- '"C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.5\arm\bin\armsim2.dll"'
- '"${1}"'
- --plugin "C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.5\arm\bin\armbat.dll"
- --backend -B
- --endian=little
- --cpu=Cortex-M4
- --fpu=VFPv4_sp
- --semihostinghttps://stackoverflow.com/questions/41140188
复制相似问题