DSP

DSP/BIOS的搭建

2019-07-13 09:49发布

                                                                                         CCSv5.2中DSP/BIOS的搭建

前言:             DSP/BIOS是TI公司专门为DSP开发的嵌入式实时操作系统,主要分为五大部分如下图左边所示:
1.创建常规的CCS5.2工程

              (1)打开CCS,选择Project -> New CCS Project.               (2)在 Project name 栏输入要创建的工程名字                  (3) 在Family栏选定你所使用的DSP的家族系列                     (4) 在Variant栏选定你所使用的DSP系列               (5) 在Connection栏选择你所使用的仿真器型号。 
              (6) Advanced settings高级选项,主要时选择芯片的大小端,编译器版本,一般情况下这里不需要设置。 
              (7)在Project templates and examples栏选中带main.c的空白工程。               (8)点击Finish按钮,完成。 如图:
                                  2.引入DSP/BIOS系统


               注1:因为刚才在创建工程的时候已经产生了一个名为C6455.cmd的链接命令文件,在这里需要删除这个链接命令文件,因为DSP/BIOS在创建的过程中会产生一份新的链接命令文件。并且新的链接命令文件会把一些用到的应用库包含进来,例如bios.a62,rtdx.lib,rts64plus.lib等程序库。大多数DSP/BIOS生成的链接命令文件会满足所有的存储段分配,也可以后续再通过MEM管理器进行控制。
               注2:假如你的工程之前有包含vectors.asm源文件,同样需要移除这个文件,因为DSP/BIOS会自动定义硬件中断向量表。就是说假如你使用了DSP/BIOS系统,中断向量的管理权也就交给了DSP/BIOS。                       我们这里以一个最简单的应用例程进行说明,在这里会带领大家创建一个包含有两个任务的应用程序,第一个任务执行把LED点亮的工作,第二个任务执行把LED点灭的工作。

      1) 选择工程名 New > Other  如图选中 DSP/BIOS v5.x Configuration File  点击Next    如图:           (2) 选择所属的器件型号平台,点击Next按钮   如图:                             (3)将默认选中三个DSP/BIOS特性选中,点击Finish按钮。      Real-Time Analysis   若禁止,则LOGSTS不可用。      RTDX                 若禁止,则实时分析数据不可实现。      TSK Manager         允许你使用信号量和任务让出功能。

     在这里你可以先编译一下你所创建的工程,如果你是按照我所描述的步骤进行创建的话,编译应该是没有错误可以通过编译的。 :编译通过后你可以在左侧工程导航栏的Debug文件夹下看到一系列DSP/BIOS所创建的文件,如 testcfg_c.c文件:   定义DSP/BIOS结构体和内容。 testcfg.cmd文件     链接命令文件 testcfg.h文件       包含DSP/BIOS模块头文件、声明对象的外部变量。 testcfg.s62文件    DSP/BIOS配置的汇编文件 testcfg.h62 文件    汇编语言头文件  如图:

3.DSP/BIOS系统配置

    (1)全局属性设置           在左侧的工程导航栏双击test.tcf打开管理器,选中System 栏下的Global Settings,右键,选择属性按钮,进行如下设置,这里主要是设置CPU运行的时钟,因为我将来要把我的DSP运行在1GHz的频率,外部接的晶振是20MHz,所以设置如下。

     内存段设置    鼠标右键MEM-Memory Section Manager点击Properties如图 取消 No Dynamic Memory Heaps 选项
鼠标右键IRAM点击Properties 如图 选择 created a heap in this memory 并设置大小 如图 鼠标右键MEM-Memory Section Manager点击Properties 并设置Segment  For DSP/BIOS Object 和  Segment For malloc/free 如图




(2)LOG模块的设置          注:LOG模块可以帮助我们调试将来的代码,可以利用模块本身的LOG_printf函数在CCS环境里面打印信息,对我们调试代码十分有用。而且占用的CPU资源很小,几乎不影响CPU的性能。         选择Instrumentation子目录下的LOG-Event Log Manager,右键选择Insert LOG,在打开的对话框中为你要创建的模块起个名字,一般以trace命名。如图:

下面说一下使用举例,很简单 LOG_printf(&trace,”Task1  LED  on”); 就可以在CCS的相应窗口中看到打印信息。
(3)PRD对象的创建
      PRD又叫周期函数管理器,它使用系统时钟CLK进行驱动,为任务的睡眠提供依据。很多DSP/BIOS函数都有一个超时参数timeout,例如你在任务中使用TSK_sleep()的函数,这个函数是一个具有超时参数的函数,被调用之后,当系统时钟的变化次数达到超时参数的值时,任务将会推出被阻塞状态。      假如你的系统时钟配置分辨率设置为1ms,并且希望当前任务阻塞1s的时间,那么应该这样调用TSK_sleep();  TSK_sleep(1000);  任务将被阻塞1s钟。这里使用C6455的定时器0来做为CLK模块的驱动源,使用低分辨率时钟指定输入时钟源为20MHz。设置时间精度为1ms一次. 

     选择Scheduling子目录下的CLK-Manager,右键选择属性按钮。如图:
(4)任务创建        
:每个任务都拥有自己独立的堆栈,任务共有四种状态 运行态(Running) 就绪态(Ready)        已被调度,等待执行 挂起态(Block)         也叫阻塞态,等待某个事件发生或某些资源可用 终止态(Terminated)    被终止,不会再执行     其中相同优先级的任务,任务调度器会根据它们在配置工具里列出的顺序进行调度。空闲任务属于DSP/BIOS系统的后台线程,有限地最低,其它任何任务线程都可以抢占它,空闲任务用来监测系统状态或执行其它后台操作。        选择 TSK – Task Manager ,右键选择插入,并为每个任务起个名字,这里我命名了两个名称分别为TSK_ledon、TSK_ledoff的任务。优先级分别为2和1。两个任务一个用来点亮led,一个用来灭掉led。这样程序运行起来就会看到led在闪烁。  创建后如图:
         上述只是创建了任务,接下来还要在为每个任务指定一个函数入口名称。         选中TSK_ledon,右键选择属性,进行设置,在弹出的对话框中选择Function选项,在Task  function:栏输入要调用的函数入口名称,这里我命名为taskledon。 
:taskledon前面要加上一个下划线,这一点一定不能忘记。 如图:

同样为TSK_ledoff任务指定入口函数名称为taskledoff。
再此先将代码部分贴出来:
首先在主函数开始前需要包含几个必要的头文件过来
#include
#include #include #include "testcfg.h" 
#include "hw_types.h"
#include "psc.h" #include "soc_C6748.h" #include "gpio.h"
void Delay(unsigned int delay)
{
    while(delay--);
}
//主函数,我手里的板子在GP2_1上接的是一只Led。对应管脚号为34,主函数再此小工程里主要完成GPIO的初始化工作。
int main(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);      return 0;

void taskledon()
{
    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, "Task ledon DONE");    
     }  } 
void taskledoff()
{
    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, "Task ledoff DONE");   
     } }
    (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-Semaphore Manager,右键选择插入选项。   

最后运行 编译,编译没有错误这样就搭建简单的DSP/BIOS应用工程了。