我有一个C代码,它是为一个ATmega16芯片编写的,它充满了关键字,比如:
flash, eeprom, bit
和宏(?)喜欢
interrupt [TIM1_OVF] void timer1_ovf_isr(void)在函数签名之前。
现在我要做的是编写和运行单元测试,以验证控制器单元逻辑的正确性,并且我希望能够在任何计算机上运行这些测试,而不需要有代码所代表的“设备”。
我搜索了很多,遇到了“抽象硬件”和“用存根替换它们”之类的解决方案,但我不知道如何在代码中抽象“中断TIM1_OVF”之类的东西!
我想知道是否有什么特殊的工具可以提供运行这类代码的环境?
还有,如果我做错了,谁能给我指明正确的方向?修改或重写(!)微控制器的代码可能不是一种选择?
谢谢一堆。
发布于 2015-12-02 20:18:06
您的示例不是ISO C代码,它们是编译器特定的扩展,它们在AVR编译器中并不常见,更不用说体系结构了。在许多情况下,可以通过定义只需要很少或根本不修改代码的宏来解决这些问题。为了使您的代码在任何情况下都可移植,即使是在不同供应商的AVR编译器之间,在任何情况下这样做都是一个好主意,尽管可能需要多种技术的结合。
大多数编译器支持“始终包含”选项,该选项允许从命令行中包含一个头文件,并在源代码中包含一个显式的#include指令。使用兼容性宏创建一个标头,并将其隐式地包含在代码中,或者在代码中显式地包含它,这是一种有用的技术。例如,对于您提到的问题,您可能有:
// compatability.h
#if !defined COMPATABILITY_INCLUDE
#define COMPATABILITY_INCLUDE
#if defined __IAR_SYSTEMS_ICC__
#define INTERRUPT( irq, handler ) __interrupt [irq] void handler(void)
#elif defined _WIN32
#define INTERRUPT( irq, handler ) void handler(void)
#define __flash const
#define __eeprom const
#define __bit char
#else
#error Unknown toolchain/environment
#endif
#endif这将从Win32代码中删除内存位置限定符,并将__bit定义为char。中断处理程序宏将将处理程序转换为Win32上的常规函数,但确实需要修改代码,但由于每个工具链的操作方式不同,这也许不是坏事。
例如,在本例中,您将更改:
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
...
}至
INTERRUPT( TIM_OVF, timer1_ovf_isr )
{
...
}请注意,您应该在可压缩文件中使用接近目标宏-例如,我猜到了IAR;您可能使用的是不同的编译器。您的编译器文档应该指定可用的预定义宏,或者源锻造上的预定义编译器宏“项目”是一个有用的资源。
有些转换可能在语义上更改代码,例如在某些情况下将__bit替换为char,例如,如果为位分配一个大于1的值,然后与1相比,嵌入的目标很可能产生真,而在PC构建时则不会。最好将其转换为_Bool,但编译器可能会对隐式转换发出警告。我的建议也不一定是最好的转换--参考编译器的手册获得精确的语义,并决定如何最好地将它们转换为测试生成的标准C。
保留专有语义的另一种方法是使用调试器脚本在指令集模拟器中运行单元测试(如果可以实现硬件交互存根的话),但是这种方法使得无法使用现成的单元测试框架(如CUnit )。
发布于 2015-12-02 17:10:44
根据您的工具链,您可能已经有AVR模拟器可用,这将允许您运行您的单元测试在任何PC上。例如,IAR提供了一个支持终端窗口的AVR模拟器“C-间谍”,它可以显示寄存器值,可以支持中断的生成,等等。假设您保持单元大小合理,您不需要大量的基础设施或短接口来完成这项工作。
在目标平台(与目标编译器一起)上运行单元测试的一个很大好处是,与在PC环境中运行相比,您可以考虑平台将导致的任何特定行为(endianness、word大小、编译器或库特性等)。
https://stackoverflow.com/questions/34040052
复制相似问题