DSPLink中readwrite简析

  双核处理器中,不管要实现什么功能,ARM 核和DSP 核的通信始终是放在首位的,在嵌入式Linux 中通过DSPLink 来实现ARM DSP 通信,DSPLink Ubuntu10.04 主机中交叉编译完成后生成dsplinkk.ko 模块,放在嵌入式Linux 文件系统中,在ARM 核中跑起嵌入式Linux 后运行omapl138#insmod dsplinkk.ko 加载dsplink 驱动模块,运行ARM 端的可执行程序:./readwritegpp readwrite.out 293601280 1024 10000   其中readwritegpp ARM 端的可执行程序,readwrite.out DSP 端的程序,293601280 DSP 执行的内存地址,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函数把这个消息放到消息队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值