DSP

DSPLink中readwrite简析

2019-07-13 14:50发布

 双核处理器中,不管要实现什么功能,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 are not required
  4.                      * for noboot mode. ShmBaseAddr is not provided since
  5.                      * DSPLINK_shmBaseAddress is 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函数把这个消息放到消息队列。