DSPLink中readwrite简析

来源:互联网 发布:cms技术架构 编辑:程序博客网 时间:2024/05/29 17:29
 双核处理器中,不管要实现什么功能,ARM核和DSP核的通信始终是放在首位的,在嵌入式Linux中通过DSPLink来实现ARMDSP通信,DSPLinkUbuntu10.04主机中交叉编译完成后生成dsplinkk.ko模块,放在嵌入式Linux文件系统中,在ARM核中跑起嵌入式Linux后运行omapl138#insmod dsplinkk.ko加载dsplink驱动模块,运行ARM端的可执行程序:./readwritegpp readwrite.out 293601280 1024 10000  其中readwritegppARM端的可执行程序,readwrite.outDSP端的程序,293601280DSP执行的内存地址,1024是为程序分配的缓存大小,10000是执行次数。

首先是ARM端的程序


#if defined (DA8XXGEM)
  1.             if ( LINKCFG_config.dspConfigs [processorId]->dspObject->doDspCtrl
  2.                 == DSP_BootMode_NoBoot){
  3.                     /* strDspAddr(c_int00 address)and .args address arenot required
  4.                      * for noboot mode. ShmBaseAddr is not provided since
  5.                      * DSPLINK_shmBaseAddressis provided in linker commnad file.
  6.                      */
  7.                 strShmAddr = "0x0" ;
  8.                 strDspAddr = "0x0" ;
  9.                 strArgsAddr = "0x0" ;
  10.                 RDWR_shmAddr = RDWR_Atoll (strShmAddr) ;
  11.                 RDWR_dspAddr = RDWR_Atoll (strDspAddr) ;
  12.                 RDWR_argsAddr = RDWR_Atoll(strArgsAddr);
  13.                 /*For No bootmode Hard coding the values
  14.                 * since DSP side app is using the same values
  15.                 */
  16.                 strNumIterations = "1000";
  17.                 numIterations = atoi (strNumIterations) ;


if ( LINKCFG_config.dspConfigs [processorId]->dspObject->doDspCtrl

                ==  DSP_BootMode_NoBoot)


如上图在DSPLinkProgramers Guide文档中,DSPLink启动dsp的模式有3种方式,DSP_BootMode_NoBoot是指既不下载DSP端的程序也不跑DSP,一般都不会配置成这种模式,如果要修改配置成其他模式则需要在dsplink/BUILD/ CFG_OMAPL138GEM_SHMEM.c中修改LINKCFG_Dsp这个数据结构,

STATIC LINKCFG_Dsp LINKCFG_dspObject =

  1. {
  2.     "DA8XXGEM",/* NAME : Name of the DSP */
  3.     DspArch_C64x, /* ARCHITECTURE : DSP architecture */
  4.     "COFF",/* LOADERNAME: Name of the DSP executable loader */
  5.     FALSE,/* AUTOSTART: Autostart the DSP (Not supported)*/
  6.     "DEFAULT.OUT",/* EXECUTABLE: Executable for autostart*/
  7.     DSP_BootMode_Boot_Pwr,/* DOPOWERCTRL: Link does the Power Ctrl of DSP.*/
  8.     RESETCTRLADDR, /* RESUMEADDR : Resume address */
  9.     RESETCTRLADDR, /* RESETVECTOR : Reset Vector for the DSP */
  10. RESETCTRLSIZE, /* RESETCODESIZE :
  11. …………………….
  12. } ;


如上,一般启动模式都是DSP_BootMode_Boot_Pwr:


STATIC LINKCFG_Dsp LINKCFG_dspObject =
  1. {
  2.     "DA8XXGEM",/* NAME : Name of the DSP */
  3.     DspArch_C64x, /* ARCHITECTURE : DSP architecture */
  4.     "COFF",/* LOADERNAME: Name of the DSP executable loader */
  5.     FALSE,/* AUTOSTART: Autostart the DSP (Not supported)*/
  6.     "DEFAULT.OUT",/* EXECUTABLE: Executable for autostart*/
  7.     DSP_BootMode_Boot_Pwr, /* DOPOWERCTRL : Link does the Power Ctrl of DSP.*/
  8.     RESETCTRLADDR, /* RESUMEADDR : Resume address */
  9.     RESETCTRLADDR, /* RESETVECTOR : Reset Vector for the DSP */
  10. RESETCTRLSIZE, /* RESETCODESIZE :
  11. …………………….
  12. } ;


接下来是主函数

RDWR_Main ( dspExecutable,

                        strDspAddress,

                        dspAddress,

                        strBufferSize,

                        bufferSize,

                        strNumIterations,

                        numIterations,

                        processorId) ;  }

简要的,主函数主要有三个模块,

status = RDWR_Create (dspExecutable,

                                  strBufferSize,

                                  strNumIterations,

                                  processorId) ;

status = RDWR_Execute (dspAddress,

                                       bufferSize,

                                       numIterations,

                                       processorId) ;

RDWR_Delete (processorId) ;

即创建,运行,删除。

创建函数RDWR_Create主要是用PROC模块初始化加载dsp端程序,用POOL模块映射ARMDSP的内存空间,初始化消息机制MSGQ。主要内容如下:

status = PROC_setup (NULL) ;

status = PROC_attach (processorId, NULL) ;

status = POOL_open (POOL_makePoolId(processorId, SAMPLE_POOL_ID),

                            &SamplePoolAttrs) ;

status = MSGQ_open (SampleGppMsgqName, &SampleGppMsgq, NULL) ;

status = PROC_load (processorId, dspExecutable, NUM_ARGS, args) ;

status = PROC_start (processorId) ;

status = MSGQ_transportOpen (processorId, &mqtAttrs) ;

       status = MSGQ_locate (SampleDspMsgqName,

                                  &SampleDspMsgq,

                                  &syncLocateAttrs) ;

PROC_load()加载dsp的程序,POOL_open()如下图,用于配置共享内存,使ARMDSP端内存空间映射一致   

 且POOL_open()函数是消息机制MSGQ函数调用前的必经步骤,    


然后调用MSGQ_open (),MSGQ_transportOpen(),MSGQ_locate()等初始化一个消息队列,然后调用MSGQ_alloc ()在现有的pool内存池里面分配出一个samplemessage结构体,写入需要传送的消息数据,这里从内存区分配地址,可以保证samplemessage使用的是dspgpp共享内存区的地址,之后调用MSGQ_put函数把这个消息放到消息队列。

原创粉丝点击