C 我拦截对微控制器寄存器的调用

C 我拦截对微控制器寄存器的调用,c,embedded,cpu-registers,intercept,C,Embedded,Cpu Registers,Intercept,TI MSP430嵌入式C的单元测试。单元测试将在使用GCC编译的Linux主机上运行。这个项目相当大,主要是遗留代码 对诸如PCIN_L、PCOUT_L和PCDIR_L等寄存器进行读写操作时,编译这些寄存器时会生成错误,表明它们未声明。这是正确的,因为在主机上运行时不存在这样的寄存器。 早些时候,我学会了截取对函数符号的调用,并将这些调用重定向到伪函数,只返回预定义的值。这是我使用链接器选项-Wl-wrap,someSymbol完成的 这会将对AbsentFunction的所有调用重定向到_w

TI MSP430嵌入式C的单元测试。单元测试将在使用GCC编译的Linux主机上运行。这个项目相当大,主要是遗留代码

对诸如PCIN_L、PCOUT_L和PCDIR_L等寄存器进行读写操作时,编译这些寄存器时会生成错误,表明它们未声明。这是正确的,因为在主机上运行时不存在这样的寄存器。 早些时候,我学会了截取对函数符号的调用,并将这些调用重定向到伪函数,只返回预定义的值。这是我使用链接器选项-Wl-wrap,someSymbol完成的

这会将对AbsentFunction的所有调用重定向到_wrap_AbsentFunction。 不过我也在我的收银机上试过了,你运气不好

Makefile:
LDFLAGS=-Wl --wrap,PCDIR_L
SOURCES=WrappedSymbols.c

WrappedSymbols.c:
char __wrap_PCDIR_L;

是否有可能像我对函数所做的那样对寄存器进行类似的操作?我不希望在项目代码中引入更改。

MSP430设备的寄存器名称都在特定于设备的头文件中声明。虽然您不一定能够轻松模拟这些寄存器的行为,但您可以编写自己的等效文件,将寄存器映射到程序可访问的内存位置


模仿端口寄存器、串行端口状态寄存器和其他寄存器的按位功能将是一项艰巨的任务。

您可以通过创建包含以下声明的假处理器头,将内存映射处理器外围寄存器声明为易失性数据:

extern volatile uint16_t PCDIR_L ;
它们当然不会像外围寄存器那样工作,但它允许构建代码


更好的方法是构建硬件抽象层,以便通过函数API而不是直接访问硬件进行外围访问,然后您可以创建模拟硬件行为的伪API。

至少,请准确显示在实际代码中如何访问寄存器。只需编写读取/写入寄存器的小助手函数。您可以将其包装。@unwind,在MSP430c54c.h中:在外部链接中定义P6DIR PCDIR\U h。h:在外部链接中定义PA\U引脚作为输出P6DIR |=0x30。c:PA\U引脚作为输出`@这是一个很好的选择。我宁愿不改变原来的代码,但如果我必须,我必须!很抱歉上面评论中的格式设置,我试图在其中获取som换行符,但随后超过了5分钟的限制。我可以在编译器中说应该使用哪个MSP430x54x.h头文件,我的头文件包含上面的声明还是原始的?还是我被迫在原始代码中引入if-defined-UNITTEST,在includes之间切换。。。您的抽象API与Hans在右上方的解决方案相同?@Enok82:最简单的解决方案是在不同的目录中有两个单独的MSP430x54x.h文件,并为单元测试构建提供不同的包含文件搜索路径。它正在工作。不过我必须把外人移走。有两个MSP430x54x.h头文件,我使用-isystem dir gcc选项切换到自己的头文件,如下所示:gcc-isystem/myincludes/-cfoo.c。其他可用选项还有-I,它等于-isystem和-iNote,用于包含的本地头文件,而不是。。。多谢各位@Enok82:如果没有外部,您将实例化一个对象,而不是简单地声明一个对象。如果头包含在多个编译单元中并且它们是链接的,则会导致问题。我假设您知道给定一个声明,您还需要在其他地方的.c文件中使用一个定义。是的,我知道externs的用法。在这种情况下,没有其他自然的地方可以放置对象的实例化。除了在别处实例化它们之外,还会创建重复项,这将是一个很难更新的问题。我正在考虑用类似的方式包装声明/实例化:ifndef INSTANTIATE\u GLOBALS\n define EXT extern\n else\n define EXT\n endif,然后使用EXT而不是extern声明变量。实例化全局变量将在入口点模块包含的头文件中定义和未定义。该解决方案看起来与Clifford建议的类似?
extern volatile uint16_t PCDIR_L ;