这段时间一直在做这个,没有即使把工作总结,吃了很多亏,因此要吸取教训。
前几天做了个实验,ARM端将8×8的一个数组发送给DSP端。DSP端对这个数组进行DCT运算,然后将得到的数组返回给ARM端。目的是演示双核通信的简单实现流程。
首先我们必须实现ARM端程序,程序要实现的功能是启动DSP核,加载DSP任务,然后对其操作。值得注意的是,在ARM端中把DSP任务只是看成ARM的外设,在系统中,对这些设备文件进行操作即是对DSP任务操作。ARM端程序很好实现。
其次要实现DSP端任务,该任务的作用是对ARM端发送过来的数组进行DCT运算,然后发送给ARM。任务模型可以参考DSPGATEWAY自带的例子。
其中所遇到的问题:
1:DSPGATEWAY例子的CMD文件要有所修改,好想它的中断地址设置有问题,提示有冲突。
2:想要利用数据的拼拆以节省ipbuf占用空间,就要考虑编译器差异这个问题了。arm端编译器(arm-linux-gcc)和DSP端编译器(CCS)对一些数据类型的编译不同。例如ARM端对short 分配16bit int分配32bit,而DSP端对short 和int类型都分配16bit。
在arm端我们用char类型的数组来保存原始yuv数据(在这个实验中我们指定一个特定的8×8的数组),将两个8位数据拼接成一个16位数据,高位放前一个数据。
static int strcpy8to16(short *d,char *s)
{ int i=0;
int cnt = 0;
for (i=0;i<64;i=i+2) {
*d = *s++;
/* *d++ = (*d << 8)|*s++; */
*d++ = (*d << 8)|(0xff&*s++)
cnt++;
}dsp端在dct之前,将数据拆分成两个16位数据(因DSP端short类型就是16位)。在拼拆的时候还有个问题困扰我们很久,就是没注意到负数符号扩张问题。在ARM和DSP端都必须注意。
static int strcpy16to8(short *d, short *s)
{
int cnt = 0,i=0;
char tmp=0;//slove problem
for (i=0;i<32;i++)
{ tmp=(*s&0xff00)>>8;
if(tmp&0x80)
*(d++) = 0xff00|tmp;
else
*(d++) = tmp;
tmp= *s++&0x00ff;
if(tmp&0x80)
*(d++) = 0xff00|tmp;
else
*(d++) = tmp;
cnt++;
}
return cnt;
} |