我的软件驱动一个在TI DSP TMS320f2812上运行C代码的嵌入式设备。
通信是通过USB串口仿真完成的。
在某个时候,设备端,我需要解析一条消息,意思是“用给定的参数调用给定地址的函数”。该信息包括:
在这里,我目前使用的代码:
typedef void (*void_fct_void) (void);
typedef void (*void_fct_int16) (int16);
typedef void (*void_fct_int32) (int32);
typedef void (*void_fct_2int32) (int32, int32);
...
Uint32 address;
Uint16 sizeIn;
address = HW_Usb_Read_4Bytes();
sizeIn = HW_Usb_Read_1Byte();
switch(sizeIn) {
case 0:
((void_fct_void) address)();
break;
case 2:
((void_fct_int16) address)(HW_Usb_Read_2Bytes());
break;
case 4:
((void_fct_int32) address)(HW_Usb_Read_4Bytes());
break;
case 8:
((void_fct_2int32) address)(HW_Usb_Read_4Bytes(), HW_Usb_Read_4Bytes());
break;
}我想知道是否没有办法使其更加通用,并避免切换,例如:
Uint32 address;
Uint16 sizeIn;
address = HW_Usb_Read_4Bytes();
sizeIn = HW_Usb_Read_1Byte();
putNbytesOnParamsStack(sizeIn); // magic function, will call HW_Usb_Read_1Byte 'sizeIn' times.
((void_fct_void) address)();的目标函数也很多,并且被嵌入式代码使用,我不能更改它们的签名.
发布于 2015-04-01 17:33:58
您可以使用利布菲 (如果它支持您的目标处理器体系结构、调用约定和ABI),它使您能够“模拟”一个arbirary调用。
但是,您应该传递一个指向数据的指针,而不是数据本身。
发布于 2015-04-01 16:37:26
可以使用内联程序集在堆栈上推送var:
__asm {
push sizeIn
; You can also call your fp using asm:
call address
; But it's not very safe because your compiler may not
; have saved its registries before the call
}然而,我想知道推动sizeIn如何能帮助您,难道您不需要推动HW_Usb_Read_NBytes()的结果吗?
编辑:
通过多次调用HW_Usb_Read_1Byte()并使用按位操作,您可以删除开关大小写。
int32 param = 0;
for (int i = 0; i < sizeIn; i++)
param |= (HW_Usb_Read_1Byte() << (i * 8));每次迭代得到的字节都会被我们读取到的位数移到左边,并附加到整数中。
但是,只有当读取的数据来自一个小的endian系统时,这才能起作用。如果您的API为每个数据大小提供了一个方法,则可能不是这样。
发布于 2015-04-02 10:11:16
正如莱利·阿夫隆所说,使用一些汇编代码是一种解决方案。
为此,我需要知道如何与我使用的DSP接口C和汇编语言。
这被称为呼叫约定。我发现关于它的文档很少,这一个是关于TMS320家族的,但是关于FPU的,TMS320f2812不是这样的。
我记得在连接JTAG时,我使用的版本可以混合源代码和ASM代码。
在这里,我可以从我当前的代码中看到:
// Case 0:
MOVL XAR7,@XAR2 ; put address in XAR7
LCR *XAR7 ; call the function
...
// Case 1:
LCR HW_Usb_Read_2Bytes ; get the data
MOVL XAR7,@XAR2 ; put address in XAR7
LCR *XAR7 ; call the function
...
// Case 2:
LCR HW_Usb_Read_4Bytes ; get the data
MOVL XAR7,@XAR2 ; put address in XAR7
LCR *XAR7 ; call the function
...我们可以看到,对HW_Usb_Read_{2|4}Bytes的调用所收回的数据没有得到处理。我认为被调用的函数将把它放在放置它们的堆栈上。
正如我所说的,HW_Usb_Read_4Bytes只调用HW_Usb_Read_2Bytes两次,并从两个UInt16组成一个UInt32。
TMS320C28x有一个RPT (第2.5.3节)操作,它允许执行单个指令多次。
我们可以想象出这样的解决方案:
RPT #N−1 ; Where #N is sizeIn/2
||LCR HW_Usb_Read_2Bytes ; get the data
MOVL XAR7,@XAR2 ; put address in XAR7
LCR *XAR7 ; call the function实际上,要做到这一点有一些制约因素:
address在XAR2中。https://stackoverflow.com/questions/29395665
复制相似问题