首先是ARM端的程序
- if ( LINKCFG_config.dspConfigs [processorId]->dspObject->doDspCtrl
- == DSP_BootMode_NoBoot) {
- /* strDspAddr(c_int00 address) and .args address are not required
- * for noboot mode. ShmBaseAddr is not provided since
- * DSPLINK_shmBaseAddress is provided in linker commnad file.
- */
- strShmAddr = "0x0" ;
- strDspAddr = "0x0" ;
- strArgsAddr = "0x0" ;
- RDWR_shmAddr = RDWR_Atoll (strShmAddr) ;
- RDWR_dspAddr = RDWR_Atoll (strDspAddr) ;
- RDWR_argsAddr = RDWR_Atoll (strArgsAddr) ;
- /* For No bootmode Hard coding the values
- * since DSP side app is using the same values
- */
- strNumIterations = "1000";
- numIterations = atoi (strNumIterations) ;
if ( LINKCFG_config.dspConfigs [processorId]->dspObject->doDspCtrl
== DSP_BootMode_NoBoot)
如上图在DSPLink的Programers Guide文档中,DSPLink启动dsp的模式有3种方式, 而DSP_BootMode_NoBoot是指既不下载DSP端的程序也不跑DSP,一般都不会配置成这种模式,如果要修改配置成其他模式则需要在dsplink/BUILD/ CFG_OMAPL138GEM_SHMEM.c中修改LINKCFG_Dsp这个数据结构,
STATIC LINKCFG_Dsp LINKCFG_dspObject =
- {
- "DA8XXGEM", /* NAME : Name of the DSP */
- DspArch_C64x, /* ARCHITECTURE : DSP architecture */
- "COFF", /* LOADERNAME : Name of the DSP executable loader */
- FALSE, /* AUTOSTART : Autostart the DSP (Not supported) */
- "DEFAULT.OUT", /* EXECUTABLE : Executable for autostart */
- DSP_BootMode_Boot_Pwr, /* DOPOWERCTRL : Link does the Power Ctrl of DSP. */
- RESETCTRLADDR, /* RESUMEADDR : Resume address */
- RESETCTRLADDR, /* RESETVECTOR : Reset Vector for the DSP */
- RESETCTRLSIZE, /* RESETCODESIZE :
- …………………….
- } ;
如上,一般启动模式都是DSP_BootMode_Boot_Pwr:
- {
- "DA8XXGEM", /* NAME : Name of the DSP */
- DspArch_C64x, /* ARCHITECTURE : DSP architecture */
- "COFF", /* LOADERNAME : Name of the DSP executable loader */
- FALSE, /* AUTOSTART : Autostart the DSP (Not supported) */
- "DEFAULT.OUT", /* EXECUTABLE : Executable for autostart */
- DSP_BootMode_Boot_Pwr, /* DOPOWERCTRL : Link does the Power Ctrl of DSP. */
- RESETCTRLADDR, /* RESUMEADDR : Resume address */
- RESETCTRLADDR, /* RESETVECTOR : Reset Vector for the DSP */
- RESETCTRLSIZE, /* RESETCODESIZE :
- …………………….
- } ;
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模块映射ARM与DSP的内存空间,初始化消息机制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()如下图,用于配置共享内存,使ARM与DSP端内存空间映射一致
且POOL_open()函数是消息机制MSGQ函数调用前的必经步骤,
然后调用MSGQ_open (),MSGQ_transportOpen(),MSGQ_locate()等初始化一个消息队列,然后调用MSGQ_alloc ()在现有的pool内存池里面分配出一个samplemessage结构体,写入需要传送的消息数据,这里从内存区分配地址,可以保证samplemessage使用的是dsp和gpp共享内存区的地址,之后调用MSGQ_put函数把这个消息放到消息队列。