1、DSPLINK介绍
GPP(General Purpose Processor)是指和DSP端通信的通用处理器,在本文特指OMAPL138平台的ARM端。
GPP OS:指通用处理器上的操作系统,本文特指OMAPL138平台ARM端Linux操作系统。
OS ADAPTATION LAYER:指操作系统抽象层,包含了DSPLINK需要的一些通用的OS服务部件,提供了一套通用的API接口,与OS的其他组件隔离。其他组件通过API访问,而不直接访问DSPLINK,此特性使DSPLINK可以方便的被移植到不同操作系统中。
LINK DRIVER:指连接驱动层,包含了基于GPP与DSP的物理连接的底层控制操作,负责GPP与DSP之间的数据传输和DSP的运行等操作。
PROCESSOR MANAGER:指进程管理层,它维护一个针对所有模块的Book-Keeping信息,通过 API给用户提供通过LINKDRIVER的控制操作。
DSP/BIOSTM LINK API:指提供给GPP端的接口,是非常轻小型的组件,API层可以认为是基于PROCESSOR MANAGER和 LINK DRIVER之上的层。
1.2 DSP端
DSP端在本文特指OMAPL138平台的DSP端。
DSP/BIOS:指DSP端的BIOS轻量级操作系统,同时它是一个实时操作系统。本文提到的DSPlink在ARM端是基于Linux系统,而在DSP端时基于DSP/BIOSTM。也就是说,如果使用DSPlink调用DSP,那么编写DSP程序时必须要选择操作DSP/BIOSTM支持。
LINK DRIVER:LINK DRIVER是DSP/BIOS中驱动的一部分,该部分驱动只负责基于物理连接之上与GPP之间的交互。DSP端没有DSPLINKAPI,和GPP之间的通信是基于DSP/BIOS中的SIO、GIO、MSGQ模块来实现的。
OTHER DRIVERS:指DSP端其他驱动程序。
GPP端的DSPLINK关键组件有PROC、CHNL、MSGQ、POOL、NOTIFY、MPCS、MPLIST、RINGIO。
1.3.1 PROC
PROC表述应用空间的DSP处理器,提供以下服务:
初始化DSP,使之能从GPP端进行访问
从GPP端加载DSP的代码至DSP处理器
从DSP代码制定的地址运行DSP程序
读写DSP端的地址空间
停止DSP端程序的运行
其他一些平台专有的控制操作
1.3.2 CHNL
CHNL是channel的缩写,该组件表述应用空间的一个逻辑数据传输通道,负责GPP与DSP之间的数据传输。通道channel的概念如下述:
一种GPP端与DSP端传输数据的方式
一个基于GPP与DSP的物理连接上的逻辑实体映射
唯一的数字标识,标记连接到DSP的一组channel中的某个channel
无方向性,通道方向可以配置
DSP端与GPP端的一条物理连接被多通道复用,被传输的数据中不包含目的地和源地址的任何信息,数据发送与接收端的数据通路需要在应用前进行显式的建立,采用issue-reclaim模式进行数据传输。
1.3.3 MSGQ
MSGQ是message queue的缩写,表述基于message的消息队列,负责GPP与DSP端的可变长度的短消息交互,基于DSP/BIOSTM的MSGQ模块实现。
message的发送接收都通过消息队列实现,消息接收者从消息队列接收信息,而消息发送者将数据写入到消息队列中,一个消息队列只可以有一个接收者,但可以有多个发送者。一个任务可以读写多个消息队列。
1.3.4 POOL
此模块提供了API 用于配置共享内存区域,同时还提供两个CPU间的缓存数据同步的API 接口。此模块提供如下功能:
通过调用打开(open)和关闭(close)配置共享内存区域
在共享内存区域内分配或释放缓存
分配的内存地址可以在不同的地址空间内转换
在不同CPU核之间实现内存数据的同步
1.3.5 NOTIFY
此组件允许应用程序为发生在远程处理器上的事件通知(Notification )注册,并发送事件通知给远程的处理器。允许应用程序为远程处理器上的事件注册一个带事件回调函数;使能应用程序发送事件通知到远程处理器;同时,应用程序也可以发送一个事件处理的选项值。
Notify组件为事件通知定义了优先级,优先级通过事件编号来实现,低编号的事件享有更高的优先级。如果事件通知不再需要使用,应用程序也可以实时注销其相应的回调函数。
1.3.6 MPCS
应用程序MPCS 实现GPP和DSP(Multi-ProcessorCritical Section)互斥访问共享
的数据结构。应用程序有时候需要定义属于自己的,并能够被多个处理器访问的数据结构,
用于多个处理器之间信息的通信。但是,应用程序必须保证多个处理器,或者每个处理上的各个任务之间互斥地访问这些数据结构,从而保证数据的连贯性。MPCS被用来实现这个功能。
在拥有可以共同访问的内存区域的多处理器系统中,可以实现GPP和DPS之间的MPCS 。而为了防止没有共享存储区域的情况出现,该模块内部实现了MPCS组件要求的带保护的同步。
MPCS组件提供了APIs接口来创建和删除MPCS实体,每个MPCS实体都通过一个系统唯一的字符串名字来标识。每一个需要使用MPCS的客户端都需要调用API打开函数来获取句柄。当不再需要使用MPCS时,通过相应的API函数来关闭句柄,同时也提供了进入和离开MPCS对象句柄指定的临界区域的API函数。
如果MPCS对象要求的存储空间由用户提供的话,它必须位于所有处理器都可以访问到的池(Pool)中;如果在创建对象的时候不提供存储空间,则指定池的ID号将被MPCS对象用来内部分配空间。
1.3.7 MPLIST
此组件提供GPP和DSP之间传输机制的双重循环连接列表。在GPP和DSP之间存在共享存储空间的设备上,该模块实现共享存储空间的连接列表。对于不存在共享存储空间的设备,该模块内部保持和远程处理器上连接列表的一致。
该组件提供了创建和删除MPLIST实体的APIs函数,每个MPLIST实体都通过一个系统唯一的字符串名字来标识。每一个需要使用MPLIST的客户端都需要调用API打开函数来获取句柄。当不再需要使用MPLIST时,通过相应的API函数来关闭句柄。
MPLIST组件提供的API函数,可以在列表最后加入一个新的元素,或者删除列表最前面的一个元素。也允许应用程序在某个已有的列表元素前插入一个缓冲,删除列表中任意一个指定的元素,并提供了检查列表是否为空的API函数。另外,还有API函数通过获取列表首元素的指针和指定元素后的一个元素,横断列表。
1.3.8 RING IO
该组件提供基于数据流的循环缓冲区。该组件允许在共享存储空间创建循环缓冲区,不同的处理都能够读取或者写入循环缓冲区。RINGIO组件允许通过写指针来获取数据缓冲区的空存储空间,当该存储空间被释放之后,相应存储空间可以被再次写入。
RINGIO组件允许读指针获取缓冲区中读取空间的有效数据。当被释放之后,相应存储空间的数据被标记为无效。每个RINGIO实体拥有一个读指针和一个写指针。RINGIO组件也有API 函数,可以使能数据属性的同步传输。如:EOS(End OfStream)、事件戳、流偏移地址等,也可能伴随着循环缓冲区的偏移值。
2、DSPLINK 配置
准备以下4个文件。
(1)bios_5_41_10_36.tar.gz //DSP/BIOS源码
(2)dsplink_linux_1_65_00_03.tar.gz //dsplink源码
(3)ti_cgt_c6000_7.3.0.tar.gz //dsp编译工具链
(4)xdctools_3_22_01_21.tar.gz //实时调试工具
备注:此版本DSPLINK仅适用于linux-2.6.33内核。需要使用linux-3.3内核请使用MCSDK的SYSLINK。
分别解压以上四个文件
Host# tarzxvf /mnt/hgfs/shareVM/bios_5_41_10_36.tar.gz -C ./
Host# tarzxvf /mnt/hgfs/shareVM/dsplink_linux_1_65_00_03.tar.gz -C ./
Host# tar zxvf/mnt/hgfs/shareVM/ti_cgt_c6000_7.3.0.tar.gz -C ./
Host# tarzxvf /mnt/hgfs/shareVM/xdctools_3_22_01_21.tar.gz -C ./
解压完成后,当前目录下就有了以下4个目录:
(1)bios_5_41_10_36
(2)dsplink_linux_1_65_00_03
(3)ti_cgt_c6000_7.3.0
(4)xdctools_3_22_01_21
进入dsplink_linux_1_65_00_03/dsplink目录,可以看到DSPLINK源码展开后的各个目录。
2.1.1 GPP端源码
dsplink_linux_1_65_00_03/dsplink/gpp目录解析
inc:相关的头文件。
src:dsplink源码和sample例程源码,用户可以编译和测试。
2.1.2 DSP端源码
dsplink_linux_1_65_00_03/dsplink/dsp目录解析
inc:相关的头文件。
src:dsplink源码和sample例程源码,用户可以编译和测试。
展开其各个目录。
2.2 DSPLINK配置
注意:本小结所有操作步骤务必在同一个窗口,否则会无法编译。
(1)修改环境变量“DSPLINK”
dsplink环境变量配置文件所在目录:dsplink_linux_1_65_00_03/dsplink/etc/host/scripts/Linux/
在当前目录运行命令“geditdsplinkenv.bash”打开配置文件dsplinkenv.bash。
将文件中的第51行:
“exportDSPLINK=$HOME/dsplink_1_65_00_03/dsplink”改为
“export DSPLINK=/home/tl/omapl138/dsplink_linux_1_65_00_03/dsplink”
保存退出文件编辑,在当前目录执行命令“sourcedsplinkenv.bash”会提示环境变量“DSPLINK”、“PATH”的值。
(2)配置编译参数
进入/ dsplink_linux_1_65_00_03/dsplink/config/bin目录,查看到当前目录下有dsplinkcfg.pl编译配置文件,在当前目录下执行以下命令:
perl dsplinkcfg.pl--platform=OMAPL138 --nodsp=1 --dspcfg_0=OMAPL138GEMSHMEM --dspos_0=DSPBIOS5XX--gppos=ARM --comps=ponslrmc
各个参数的解释:
perl:使用perl工具配置参数
--platform=OMAPL138:编译的平台是OMAPL138
--nodsp=1:只有一个dsp(dsplink支持一个arm跟多个dsp通信)
--dspcfg_0=OMAPL138GEMSHMEM:使用OMAPL138GEMSHMEM共享内存
--dspos_0=DSPBIOS5XX:dsp端使用的是bios5
--gppos=ARM:gpp端是ARM平台
--comps=ponslrmc:编译所有组件
若出现如下图的错误,请执行命令如下:
Host# source /dsplink_linux_1_65_00_03/dsplink/etc/host/scripts/Linux/dsplinkenv.bash
错误的原因在于通过“source dsplinkenv.bash”设置环境变量仅在当前窗口有效。在另外一个窗口操作时需要重新source。
(3)修改编译时GPPOS的路径和编译器路径
进入/dsplink_linux_1_65_00_03/dsplink/gpp/src目录,打开配置文件Rules.mk。
将第56~59行的内容:
ifeq("$(TI_DSPLINK_PLATFORM)", "OMAPL138")
KERNEL_DIR :=${HOME}/DaVinci-PSP-SDK-03.20.00.11/src/kernel/linux-03.20.00.11
TOOL_PATH := ${HOME}/toolchains/git/arm-2009q1-203/bin
endif #ifeq("$(TI_DSPLINK_PLATFORM)", "OMAPL138")
修改为以下内容:
ifeq("$(TI_DSPLINK_PLATFORM)", "OMAPL138")
KERNEL_DIR := /home/tl/omapl138/linux-2.6.33
TOOL_PATH := /home/tl/arm-2009q1/bin
endif #ifeq("$(TI_DSPLINK_PLATFORM)", "OMAPL138")
以上修改务必对应内核源码和交叉编译工具链源码目录所在路径,修改结果如下图:
(4)修改gpp端配置文件
进入/omapl138/dsplink_linux_1_65_00_03/dsplink/make/Linux目录,打开当前目录下的gpp端配置文件omapl138_arm.mk。
配置以下参数:
BASE_BUILDOS := /home/tl/omapl138/linux-2.6.33
(内核存放在位置,根据内核源码存放的目录而改动)
BASE-TOOLCHAIN := /home/tl/arm-2009q1
(交叉编译工具链存放在位置,根据工具链存放的目录而改动)
以上修改务必对应内核源码和交叉编译工具链源码目录所在路径,修改如下图:
(5)修改DSP端配置文件
进入omapl138/dsplink_linux_1_65_00_03/dsplink/make/DspBios目录,打开当前目录下的配置文件c674x_5.xx_linux.mk。
修改63~84行,配置以下参数:
BASE_INSTALL := /home/tl/omapl138
BASE_SABIOS := /home/tl/omapl138/bios_5_41_10_36
XDCTOOLS_DIR := /home/tl/omapl138/xdctools_3_22_01_21
BASE_CGTOOLS := /home/tl/omapl138/ti_cgt_c6000_7.3.0
以上修改务必对应bios_5_41_10_36、xdctools_3_22_01_2、ti_cgt_c6000_7.3.0目录所在路径.
3、DSPLINK编译
注意:本小结所有步骤应在上小结的终端窗口下继续操作,否则会出现编译错误现象。
3.1 GPP端DSPLINK编译
3.1.1 DSPLINK源码编译
切换到dsplink_linux_1_65_00_03/dsplink/gpp/src目录,这是GPP端源码所在目录,并运行“make”命令进行编译.
编译完成后,将会在以下目录产生gpp端的驱动程序镜像dsplinkk.ko文件: dsplink_linux_1_65_00_03/dsplink/gpp/export/BIN/Linux/OMAPL138/RELEASE
3.1.2示例程序编译
小节编译出来的示例程序是在gpp端运行的,首先切换到当前目录下的samples示例代码目录,再在运行“make”命令编译示例程序源码.
编译出来的gpp端可执行文件位于以下目录:
dsplink_linux_1_65_00_03/dsplink/gpp/export/BIN/Linux/OMAPL138/RELEASE
绿色图标*gpp文件就是gpp端的可执行文件:
3.2 DSP端DSPLINK编译
3.2.1 DSPLINK源码编译
进入/home/tl/omapl138/dsplink_linux_1_65_00_03/dsplink/dsp/src/目录,这是DSP端库文件源码所在目录,并运行“make”命令进行编译。
编译出来的库文件位于以下目录:
dsplink_linux_1_65_00_03/dsplink/dsp/export/BIN/DspBios/OMAPL138/OMAPL138GEM_0/RELEASE,以.lib结尾的文件就是库文件.
3.2.2 示例程序编译
首先切换到当前目录下的samples示例代码目录,再在运行“make”命令编译示例程序源码。
编译出来的dsp端可执行文件位于以下目录:dsplink_linux_1_65_00_03/dsplink/dsp/export/BIN/DspBios/OMAPL138/OMAPL138GEM_0/RELEASE/
以*.out结尾的文件就是dsp端的可执行文件:
4、DSPLINK例程演示
4.1 程序准备
程序演示需要将编译完成的GPP端和DSP端的程序和数据文件复制到开发板的文件系统。
(1)在虚拟机的建立存放GPP端和DSP端的程序的文件夹dsplink
Host# mkdir -p /demo/dsplink
(2)将dsplink相关程序放到新建立的dsplink文件夹
拷贝dsplinkk.ko:
Host# cp -a/dsplink_linux_1_65_00_03/dsplink/gpp/export/BIN/Linux/OMAPL138/RELEASE/dsplinkk.ko / demo/dsplink
拷贝所有以gpp后缀结尾的gpp端可执行程序:
Host# cp -a/home/tl/omapl138/dsplink_linux_1_65_00_03/dsplink/gpp/export/BIN/Linux/OMAPL138/RELEASE/*gpp ./
拷贝所有以.out后缀结尾的dsp程序可执行程序:
Host# cp -a/home/tl/omapl138/dsplink_linux_1_65_00_03/dsplink/dsp/export/BIN/DspBios/OMAPL138/OMAPL138GEM_0/RELEASE/*.out ./
(3)将存放dsplink文件夹拷贝到开发板
将dsplink文件夹拷贝到开发板的根目录下,完成后,进入开发板的dsplink目录。
4.2 运行dsplink演示程序
在运行所有演示程序之前,请先安装dsplink驱动程序dsplinkk.ko。在开发板的/dsplink目录中运行以下命令:
Target# insmod dsplinkk.ko
4.2.1、LOOP
LOOP示例阐明了在DSP/BIOSTMLINK中的基本数据流的概念。它实现了在GPP端的任务与DSP端任务的数据传输。DSP端应用程序采用SIO和GIO实现了TSK(任务)与SWI(软中断)。
LOOP例程演示操作的命令格式:./loopgpp<absolute path of DSP executable><BufferSize><number of transfers>< DSP Processor Id >:
指DSP端可执行文件的路径
Buffer Size:表示缓冲区大小;
number oftransfers:表示执行次数,值为0时执行无数次;
DSPProcessor Id:DSP处理器的Id号,值为0指DSP0, 值为1指DSP 1,当只有一个DSP时,此处可不填。
执行“./loopgpp”可以看到例程用法和参数的英文解释(其他例程英文解释查看方法一样)。
LOOP例程演示命令如下:
Target# ./loopgpploop.out 1024 1000
执行1000次,每次传输1Kbyte的数据量。
传输的内容对应在samples/loop/loop.c中已经定义好了。
可以看到填充的数据是0xE7。
4.2.2 MESSAGE
MESSAGE示例阐明了在DSP/BIOSTMLINK中的基本信息传递的概念。它实现了GPP端任务与DSP端任务之间的信息传递。DSP端应用程序采用MSGQ实现了TSK与SWI。
MESSAGE例程演示操作的命令格式如下:./messagegpp<absolute path of DSPexecutable><number of transfers><DSP Processor Id>
执行“./messagegpp”可以看到例程的用法和参数的英文解释
MESSAGEGPP例程演示命令如下:
Target# ./messagegppmessage.out 10000
传输10000次,运行命令后的结果如下图:
4.2.3 SCALE
SCALE示例阐明了在的数据流和信息的组合概念。它不仅实现了GPP端任务与DSP端任务之间的数据传递,而且从GPP端发送信息到DSP端。
DSP端应用程序采用SIO&MSGQ 和GIO&MSGQ实现了TSK与SWI。
SCALE例程演示操作的命令格式如下:./scalegpp<absolute path of DSP executable><BufferSize><number of transfers><DSP Processor Id>
执行“./scalegpp”可以看到例程的用法和参数的英文解释,如下图:
SCALE例程演示命令如下:
Target# ./scalegppscale.out 1024 100
执行100次,每次传输1Kbyte的数据量,运行命令后的结果如下图:
4.2.4 READWRITE
READWRITE示例阐明了大缓冲区通过直接读写DSP内部RAM来进行传输的概念。它实现了在GPP端和使用PROC_Read()和PROC_Write()API的DSP端以及两个DSP端之间的大尺寸数据缓冲器之间的数据与信息的传递和转换。DSP端应用程序采用MSGQ实现了TSK。
READWRITE例程演示操作的命令格式如下:./readwritegpp<absolute path of DSPexecutable><DSP address><buffersize><number oftransfers><DSP ProcessorId>
执行“./readwritegpp”可以看到例程的用法和参数的英文解释。
READWRITE例程演示命令如下:
Target# ./readwritegppreadwrite.out 293601280 1024 1000
293601280是DSP的内存地址,执行1000次,每次传输1Kbyte的数据量。
4.2.5 RING IO
RING_IO示例阐明了如何使用DSP/BIOSTMLINK中的RingIO部件以及在GPP与使用两个RingIO实例的DSP之间的数据流的方法。它实现了数据在GPP端运行的线程/进程的应用程序和DSP端之间的传递与转换。在Linux中,这个应用程序在某个过程中通过进程或者线程来运行。在PrOS中,它通过一系列任务来运行。在随后的部分应用程序中的每个线程/进程/任务被视为客户端。在DSP端,此应用程序阐述了使用RingIO来实现TSK的用法。
例程演示操作的命令格式如下:./ringiogpp<absolute path of DSPexecutable><RingIO data Buffer Size in bytes><number of bytes totransfer><DSP Processor Id>
执行“./ringiogpp”可以看到例程的用法和参数的英文解释。
RING_IO例程演示命令如下:
Target# ./ringiogppringio.out 10240 1000
执行1000次,数据缓冲区的大小是10KByte。
4.2.6 MPLIST
MPLIST示例阐明了如何使用DSP/BIOSTMLINK中的MPLIST的部件以及在GPP与使用多个处理器列表的DSP之间的数据流的方法。它实现了GPP端和DSP端之间的数据转换与传递。在DSP端,应用程序通过MPLIST实现了TSK。
MPLIST例程演示操作的命令格式如下:./mplistgpp<absolute path of DSPexecutable><number of iterarions for which to run thesample><number of elements to add at end of list><DSP ProcessorId>
执行“./mplistgpp”可以看到例程的用法和参数的英文解释。
MPLIST例程演示命令如下:
Target# ./mplistgppmplist.out 1000 100
执行1000次,每次在队列最后添加100个数据。
4.2.7 MPCSXFER
MPCSXFER示例阐明了通过一个拥有互斥访问保护的共享内存缓冲区的基本机制实现了数据在GPP端与DSP端之间的传递与转换。它通过使用MPCS的部件来为分配使用POOL组件的共享缓冲器提供一个访问保护机制。GPP与DSP两端的应用程序同步化是通过使用NOTIFY的部件来实现的。
DSP端应用程序通过使用MPCS,POOL和NOTIFY的部件来实现TSK。
MPCSXFER例程演示操作的命令格式如下:./mpcsxfergpp<absolute path of DSPexecutable><Buffer Size><number of transfers><DSPProcessorId>
执行“./mpcsxfergpp”可以看到例程的用法和参数的英文解释。
MPCSXFER例程演示命令如下:
Target# ./mpcsxfergppmpcsxfer.out 1024 1000
执行1000次,缓冲区的大小是1KByte。
详细的文档请查阅广州创龙资料:
http://pan.baidu.com/s/1eQ9YKRC?qq-pf-to=pcqq.c2c
更多关于DSPLINK的开发资料请参考如下网站:
http://wenku.baidu.com/search?word=DSPLINK&lm=0&od=0&pn=0
来源:oschina
链接:https://my.oschina.net/u/1773241/blog/291013