CCSv5.5中DSP/BIOS的搭建说明:鉴于目前网络上关于如何在CCS5.5中怎么运用DSP/BIOS的详细指导十分不全面,本人在搜索过程中也是一头雾水,故写此文档,第一便于大家互相学习交流,第二方便本单位后续技术积累。文中截图系本人亲自操作截取。1:创建常规CCS5.5工程1)打开CCS,选择FileNewCCSProject。2)在Projectname栏输入要创建的工程名字,以test为例。3)在Family栏选定你所使用的DSP的家族系列,以C6000为例。4)在Variant栏选定你所使用的DSP系列,以C674xFloating-pointDSP为例,在后面的选框中选中具体的DSP型号。以TMS320C6748为例。5)在Connection栏选择你所使用的仿真器型号。6)Advancedsettings高级选项,主要时选择芯片的大小端,编译器版本,一般情况下这里不需要设置。7)在Projecttemplatesandexamples栏选中带main.c的空白工程。8)点击Finish按钮,完成。至此一个普通的CCS5.5工程就创建完毕,剩下的就BIOS如何引用过来的问题了。2:引入DSP/BIOS系统注1:因为刚才在创建工程的时候已经产生了一个名为C6748.cmd的链接命令文件,在这里需要删除这个链接命令文件,因为DSP/BIOS在创建的过程中会产生一份新的链接命令文件。并且新的链接命令文件会把一些用到的应用库包含进来,例如bios.a62,rtdx.lib,rts64plus.lib等程序库。大多数DSP/BIOS生成的链接命令文件会满足所有的存储段分配,也可以后续再通过MEM管理器进行控制。注2:假如你的工程之前有包含vectors.asm源文件,同样需要移除这个文件,因为DSP/BIOS会自动定义硬件中断向量表。就是说假如你使用了DSP/BIOS系统,中断向量的管理权也就交给了DSP/BIOS。好的,做好以上准备工作后,下面我们就开始一步一步的创建DSP/BIOS的应用,我们这里以一个最简单的应用例程进行说明,在这里会带领大家创建一个包含有两个任务的应用程序,第一个任务执行把LED点亮的工作,第二个任务执行把LED点灭的工作。添加DSP/BIOS配置到当前工程1)选择FileNewDSP/BIOSv5.xConfigurationFile。2)检查Filename栏的tcf文件名是否和你的工程名一致。这里名为test.tcf。点击Next按钮。3)选择所属的器件型号平台,我的是ti.platforms.evm6748,点击Next按钮。4)将默认选中三个DSP/BIOS特性选中,点击Finish按钮。Real-TimeAnalysis若禁止,则LOG、STS不可用。RTDX若禁止,则实时分析数据不可实现。TSKManager允许你使用信号量和任务让出功能。注:在这里会有一个叫做“指定xdc工具安装的”对话框弹出,我目前也不清楚在这里不指定会有什么影响,点击ok跳过貌似也没有什么影响,不知道是不是我的CCS安装引起的这个问题,有待研究,总之你先点击ok就行了,接着点击yes按钮。创建tcf文件完毕。在这里你可以先编译一下你所创建的工程,如果你是按照我所描述的步骤进行创建的话,编译应该是没有错误可以通过编译的。注:编译通过后你可以在左侧工程导航栏的Debug文件夹下看到一系列DSP/BIOS所创建的文件,如testcfg_c.c文件:定义DSP/BIOS结构体和内容。testcfg.cmd文件链接命令文件testcfg.h文件包含DSP/BIOS模块头文件、声明对象的外部变量。testcfg.s62文件DSP/BIOS配置的汇编文件testcfg.h62汇编语言头文件不好意思这一步忘记截图了,过程比较简单,照着做就行了。3:添加任务和信号量这一步就是创建DSP/BIOS各个管理模块的对象,首先对全局属性进行一下必要的设置,在左侧的工程导航栏双击test.tcf打开管理器。3.1:全局属性设置选中System栏下的GlobalSettings,右键,选择属性按钮,进行如下设置,这里主要是设置CPU运行的时钟,因为我将来要把我的DSP运行在300MHz的频率,外部接的晶振是25MHz,所以设置如下。3.2:LOG模块的设置LOG模块可以帮助我们调试将来的代码,可以利用模块本身的LOG_printf函数在CCS环境里面打印信息,对我们调试代码十分有用。而且占用的CPU资源很小,几乎不影响CPU的性能。下面说说具体的配置方法。选择Instrumentation子目录下的LOG-EventLogManager,右键选择InsertLOG,在打开的对话框中为你要创建的模块起个名字,一般以trace命名。如图:生成LOG对象之后如图所示这样LOG模块就设置好了,下面说一下使用举例,很简单LOG_printf(&trace,”Task1LEDon”);就可以在CCS的相应窗口中看到打印信息。3.3:PRD对象的创建PRD又叫周期函数管理器,它使用系统时钟CLK进行驱动,为任务的睡眠提供依据。很多DSP/BIOS函数都有一个超时参数timeout,例如你在任务中使用TSK_sleep()的函数,这个函数是一个具有超时参数的函数,被调用之后,当系统时钟的变化次数达到超时参数的值时,任务将会推出被阻塞状态。假如你的系统时钟配置分辨率设置为1ms,并且希望当前任务阻塞1s的时间,那么应该这样调用TSK_sleep();TSK_sleep(1000);任务将被阻塞1s钟。这里使用C6748的定时器0来做为CLK模块的驱动源,使用低分辨率时钟指定输入时钟源为25MHz。设置时间精度为1ms一次,具体配置如图所示。选择Scheduling子目录下的CLK-Manager,右键选择属性按钮。3.4:任务创建注:每个任务都拥有自己独立的堆栈,任务共有四种状态运行态(Running)就绪态(Ready)已被调度,等待执行挂起态(Block)也叫阻塞态,等待某个事件发生或某些资源可用终止态(Terminated)被终止,不会再执行其中相同优先级的任务,任务调度器会根据它们在配置工具里列出的顺序进行调度。空闲任务属于DSP/BIOS系统的后台线程,有限地最低,其它任何任务线程都可以抢占它,空闲任务用来监测系统状态或执行其它后台操作。创建步骤选择TSK–TaskManager,右键选择插入,并为每个任务起个名字,这里我命名了两个名称分别为TSK_ledon、TSK_ledoff的任务。优先级分别为2和3。两个任务一个用来点亮led,一个用来灭掉led。这样程序运行起来就会看到led在闪烁。创建的任务后如图:上述只是创建了任务,接下来还要在为每个任务指定一个函数入口名称。选中TSK_ledon,右键选择属性,进行设置,在弹出的对话框中选择Function选项,在Taskfunction:栏输入要调用的函数入口名称,这里我命名为taskledon。注:taskledon前面要加上一个下划线,这一点一定不能忘记。同样为TSK_ledoff任务指定入口函数名称为taskledoff。再此先将代码部分贴出来:首先在主函数开始前需要包含几个必要的头文件过来#includestd.h#includelog.h#includetsk.h#includetestcfg.h#includehw_types.h#includepsc.h#includesoc_C6748.h#includegpio.hvoidDelay(unsignedintdelay){while(delay--);}//主函数,我手里的板子在GP2_1上接的是一只Led。对应管脚号为34,主函数再此小工程里主要完成GPIO的初始化工作。intmain(void){PSCModuleControl(SOC_PSC_1_REGS,HW_PSC_GPIO,PSC_POWERDOMAIN_ALWAYS_ON,PSC_MDCTL_NEXT_ENABLE);HWREG(0x01C14138)=0x08000000u;GPIODirModeSet(SOC_GPIO_0_REGS,34,GPIO_DIR_OUTPUT);GPIOPinWrite(SOC_GPIO_0_REGS,34,GPIO_PIN_LOW);Delay(5000000);GPIOPinWrite(SOC_GPIO_0_REGS,34,GPIO_PIN_HIGH);SEM_post(&SEM0);return0;}voidtaskledon(){while(1){SEM_pend(&SEM0,SYS_FOREVER);GPIOPinWrite(SOC_GPIO_0_REGS,34,GPIO_PIN_LOW);TSK_sleep(500);//Delay(5000000);SEM_post(&SEM1);LOG_printf(&trace,TaskledonDONE);}}voidtaskledoff(){while(1){SEM_pend(&SEM1,SYS_FOREVER);GPIOPinWrite(SOC_GPIO_0_REGS,34,GPIO_PIN_HIGH);TSK_sleep(500);//Delay(5000000);SEM_post(&SEM0);LOG_printf(&trace,TaskledoffDONE);}}3.5:创建信号灯上述代码两个任务之间依赖信号灯来触发任务进入就绪状态,实现任务之间的同步和通信。信号灯有一个内部计数器,计有效的资源数,若信号灯大于0,任务请求该信号灯不会被阻塞。SEM_pend(sem,timeout):等待一个信号灯,如果信号灯值大于0,则对计数值做简单的减1并返回,否则等待SEM_post发布信号。超时参数允许任务等待直到超时,或无限等待(SYS_FOREVER),或者不等待(取值0),返回值代表请求信号灯是否成功。SEM_post(sem):发布信号灯。若有任务等待该信号灯,SEM_post会从等待队列中将该任务删除并将其放入就绪队列等待调度。如果没有任务等待这个信号,SEM_post则简单将计数值加1并返回。细心的你可能已经发现上述贴出来的示例代码用到了两个信号灯,分别为SEM0,SEM1。其中SEM0用来调度点亮LED的任务taskledon,SEM1用来调度灭掉LED的任务taskledoff。创建方法选择Synchronization子目录的SEM-SemaphoreManager,右键选择插入选项。如上图所示,创建两个信号灯,创建好后如下图所示:这样就可以在程序里面使用信号灯了。4:运行4.1:编译编译没有错误。4.2:运行运行过程中可以看到LED在不停的闪烁。暂停后可以看到的CCS界面的LOG模块的打印信息如下图:到此,恭喜你已经可以搭建简单的DSP/BIOS应用工程了。china_fpga@163.com