DSP-BIOS使用入门

article/2025/11/9 1:33:32

从环境说到搭建第一个工程

请注意,此文默认读者已经对DSP及CCS V3.3环境有一定的了解了,知道cmd文件的配置,知道新建工程,编译并连接仿真器下载!如果你对这些还都不熟悉,请先熟悉这些!当然,最好要有操作系统的基本概念——任务、调度、中断!

  1. 第一个问题:DSP/BIOS(好吧,我们一般这样写)是什么?

    是TI公司专门为DSP开发的嵌入式实时操作系统,既然是TI公司为自己的DSP开发的——官方的,当然性能是杠杠的了(当然,我还在入门,这点也是道听途说,没有实际体会)。既然说到实时操作系统,那还有哪些嵌入式实时操作系统呢?Linux是吗——不是,VxWorks——是,哦,还有一个小的开源系统——uCOS II也是。

  2. 问题二:要使用DSP/BIOS,需要安装什么环境呢?

    本文为CCS v3.3,默认就安装上DSP/BIOS,版本为V5.31.2(可以通过Help->About...菜单查看版本)。当然,如果需要其它版本(可以同时安装多个版本),可以到TI官网下载,链接:

    http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/bios/dspbios/index.html

    请注意:DSP处理器型号、CCS版本、DSP/BIOS版本之间存在兼容性,请注意选择!

    下载后安装到CCS所在目录,通过Help->About...中的Manager选择使用的BIOS版本!

    1

    本文使用的是CCS V3.3默认的DSP/BIOS版本,即V5.31.2。无特殊说明,本文的例子运行在TI的CCS 3.3软件仿真模式下,仿真环境配置如下(使用C6713处理器仿真):

    2

  3. 问题三:如何建立第一个BIOS工程?

    先建立一个普通工程,Project->New...,如下:

    3

    File->New->DSP/BIOS Configuration...新建DSP/BIOS配置文件,

    45

    保存一下,配置文件的后缀为*.tcf.

    配置文件和由配置文件自动生成的cmd文件添加到工程,

    6

    新建一个main.c文件,把main.c添加到工程(总是忘记这个然后还到处找问题),写个最简单的代码吧,

    int main(void)
    {return 0;
    }

    编译一下工程,此时出现错误提示:

    js: "./bios_first.tcf", line 11: Heaps are enabled, but the segment for DSP/BIOS Objects (MEM.BIOSOBJSEG) is not set correctly. Please create a heap in one of your data segments and set MEM.BIOSOBJSEG to it.
    

    没关系,在下一小节将看到怎么去掉该错误!

DSP/BIOS的配置方法

  1. 系统配置

    7

    在Global Setting上右键属性,设置DSP目标板时钟,CLKOUT时钟以及大小端模式。

    关于Call User Init Function选项,默认是打开的,如果连接有实体目标板,则最好在此处设置用户初始化PLL及EMIF等的代码的函数(有关PLL初始化话的代码参考其它C6713的工程)。否则软件仿真模式下,则去掉该选项能在运行时避免不少错误。

    接下来配置SDRAM及堆大小,

    89

    现在可以重新编译一下工程了,恭喜恭喜,编译成功!之前提示的堆错误就在这里解决的!

    现在,就需要根据需求对SDRAM的存储空间进行划分(就是以前没使用操作系统时要写cmd文件一样,这里的划分将自动生成或修改cmd文件)。使用DSP/BIOS很方便,在MEM上右键Insert MEM就可插入分区了!这部分功能对应到cmd上就是类似于cmd中MEMORY的功能,

    MEMORY
    {BOOT_RAM: o=00000000h,l=00000400h   IRAM    : o=00000400h,l=0003FC00h/* CE2: SDRM 256Mbit */SDRAM:  o = 80000000h,l=01000000h  /* 128Mbit */GB_MEM: o = 81000000h,l=01000000h  /* 128Mbit */ /* Flash */FLASH_BOOT : o=90000000h,l=00000400hFLASH_REST : o=90000400h,l=000FFB00h 
    }
    
  2. LOG的配置

    LOG功能说白了就是用来实现printf的,STS用来捕获任意对象的计数值。

    在LOG上右键Insert LOG,插入一个trace的打印对象,

    10

    在main.c中编写如下代码,

    #include "bios_firstcfg.h" // DSP/BIOS自动生成,可以在工程下找到,包含了对trace的声明以及相关头文件的包含int main(void)
    {LOG_enable(&trace);LOG_printf(&trace, "Hello DSP/BIOS %d.", 0); return 0;
    } 
    

    编译通过后装载程序,打开菜单DSP/BIOS->Message Log,运行程序效果如图,

    11

    注意,上面的程序中是通过LOG_printf函数而非printf打印消息的,其它的有关LOG的函数还有,

    LOG_disable. Disable the system log.
    LOG_enable. Enable the system log.
    LOG_error. Write a user error event to the system log.
    LOG_event. Append unformatted message to message log.
    LOG_event5. Append 5-argument unformatted message to log.
    LOG_message. Write a user message event to the system log.
    LOG_printf. Append formatted message to message log.
    LOG_printf4. Append 4-argument formatted message to log.
    LOG_reset. Reset the system log.
    

    好了,这是我们学习DSP/BIOS遇到的第1个模块(Module)——LOG模块。

    其实DSP/BIOS中还有很多模块,参考TI文档《SPRU430S:TMS320C6000 DSP/BIOS 5.x Application Programming Interface (API) Reference Guide》

    12

  3. 任务模块的配置

    操作系统最基本的就是任务,我们先来看看任务!新建两个任务,右键属性设置任务函数名,如图,

    13

    对TSK_task1做相同的配置,请注意,其中的Task function要在C函数前加下划线!

    在main函数中添加两个任务的代码,

    void func_task0(void)  // 对应刚才的_func_task0
    {static Uint16 TSK0 = 0;while (1) {   // 任务一般都有死循环,只执行一次的任务意义不大LOG_printf(&trace, "TSK0=%u", TSK0++);TSK_yield();}       
    }void func_task1(void)  // 对应刚才的_func_task1
    {static Uint16 TSK1 = 0;while (1) {LOG_printf(&trace, "TSK1=%u", TSK1++);TSK_yield();}       
    }
    

    重新编译装载,运行后在Message Log窗口下看到的效果如下:

    14

    操作系统的任务都是死循环的结构,要实现任务调度必须要让每个任务有空闲的时间,不妨把上面代码中的TSK_yield()注释掉,重新编译装载运行,此时程序会一直在func_task0中执行。

    TSK_yield在这里的作用就是如果有相同优先级的任务,则调度到同优先级的其它任务执行!

    TSK模块的属性有很多,除了设置函数名外,还可以设置优先级、输入参数等!调度函数也有很多,另一个常用的是使用睡眠调度函数——TSK_sleep,其使用如下:

    void func_task(void)
    {while(1) {// 处理代码TSK_sleep(100);  // 100表示系统时钟计数}
    }
    
  4. 软中断SWI模块的配置

    中断具有比任何任务都高的优先级,而其中硬件中断(HWI)又比软件中断(SWI)优先级更高。

    15

    软中断邮箱不是信号中的消息邮箱,但机制类似,上面的值为软中断邮箱的复位值!

    一旦软中断邮箱的值达到0时,触发软件中断,触发后一次执行完成(除非被硬件中断打断),执行完后软中断邮箱恢复到复位值!由于是一次执行完成,因此与任务不同,软中断中绝不会有死循环(否则就一直执行软中断,任务就别执行了)!

    接下来完成软中断函数中的内容:task1每执行2次,触发一次软中断,软中断计数值+1。

    void func_task1(void)  // 对应刚才的_func_task1
    {static Uint16 TSK1 = 0;while (1) {LOG_printf(&trace, "TSK1=%u", TSK1++);SWI_dec(&ADC_swi);  // 软中断邮箱计数值递减TSK_yield();}       
    }void swi_adc(void)
    {static Uint16 adc_cnt = 0;LOG_printf(&trace, "SWI_ADC=%u", adc_cnt++);// 一次执行完后,邮箱值恢复为初始值2
    }
    

    16

    SWI_dec()函数用于修改软中断邮箱的计数值,其它对软中断邮箱操作的函数还包括:

    void SWI_or(swi, mask);  // 邮箱值与mask进行或操作,当值为0时触发软中断
    SWI_Handle swi; /* SWI object handle*/
    Uns mask; /* value to be ORed */void SWI_andn(swi, mask);  // 邮箱值与mask进行与非操作,当值为0时触发软中断
    SWI_Handle swi; /* SWI object handle*/
    Uns mask /* inverse value to be ANDed */void SWI_inc(swi);  // Increment SWI’s mailbox value and post the SWI
    SWI_Handle swi; /* SWI object handle*/void SWI_dec(swi);  // Decrement SWI’s mailbox value and post if mailbox becomes 0
    SWI_Handle swi; /* SWI object handle*/
    

    6000系列的DSP软中断邮箱为32位,2000系列为16位。下面是从刘鑫茂的DSP/BIOS讲座PPT中截取的软中断邮箱函数的对比图及操作时邮箱值的变化过程图:

    1718

  5. 信号量SEM模块的配置

    信号量分互斥信号量和计数信号量,互斥信号量只有两种状态:可用于不可用,计数信号量通过设置一个计数值,如果计数值大于0,则任务请求该信号量时不被阻塞。

    19

    编写程序:现在是任务执行2次进一次软中断,这里将信号量初始值设为1,task0中使用SEM_pend等待信号量,task0执行1次就进入等待状态,再过一次,进入软中断,软中断中使用SEM_post发布信号量,信号量值增1,task0收到信号量后从等待状态返回,继续执行!

    20

    status = SEM_pend(sem, timeout);
    SEM_Handle sem; /* semaphore object handle */
    Uns timeout; /* return after this many system clock ticks */返回值:Bool status; /* TRUE if successful, FALSE if timeout */
    

    如果timeout=0表示不等待继续执行,SYS_FOREVER表示一直等待直到信号量的值大于0。SEM_post()函数相对简单,不赘述。

  6. 输入输出——实时数据交换模块配置

    不知注意到没有,软件仿真模式下,使用Load装载程序时总会弹出如下的警告框,

    22

    这就是RTDX模块没有配置的问题,在输入输出的RTDX模块上右键属性,配置如下,

    23

    配置好后,重新编译,Load时就不会再弹出那警告框了!

总结一下:其实,就让上文看到的一样,DSP/BIOS的模块还有很多,上面只是挑了几个比较常用的说了说,就光信号同步那一大块就还有消息邮箱、消息队列等,所谓举一反三,这些模块的功能及函数定义,或者想了解更多关于DSP/BIOS知识,都可以从下面的手册上找到:

  1. SPRU430S: TMS320C6000 DSP/BIOS 5.x Application Programming Interface (API) Reference Guide
  2. SPRU423F: TMS320 DSP BIOS User Guide
  3. SPRU616A: DSP-BIOS Driver Developer's Guide

除此之外,要想灵活的使用DSP/BIOS,毕竟它是一个操作系统,熟悉操作系统的基本概念很重要,如果学习或使用过uCOS ii或Linux这些去学习DSP/BIOS就小菜一碟了!

DSP/BIOS工程的启动顺序

  1. 初始化DSP:DSP/BIOS程序从C/C++环境入口c_int00开始运行。对于C6000平台,在c_int00开始处,系统栈指针(B15)和全局页指针(B14)被分别设置在堆栈断的末尾和.bss断的开始。控制寄存器AMR、IER、CSR等被初始化;

  2. 初始化.bss段:当堆栈被设置完成后,初始化任务被调用,利用.cinit的记录对.bss断的变量进行初始化;

  3. 调用BIOS_init初始化用到的各个模块:BIOS_init调用MOD_init对配置用到的各个模块进行初始化,包括HWI_init、HST_init、IDL_init等;

  4. 处理.pinit表:.pinit表包含一些指向初始化函数的指针,对C++程序,全局对象类的创建也在此时完成;

  5. 调用用户程序的main函数:用户main函数可以是C/C++函数或者汇编语言函数,对于汇编函数,使用_main的函数名。由于此时的硬件、软件中断还没有被使能,所以在用户主函数的初始化中需要注意,可以使能单独的中断屏蔽位,但是不能调用类似HWI_enable的接口来使能全局中断;

  6. 调用BIOS_start启动DSP/BIOS:BIOS_start在用户main函数退出后被调用,它负责使能使用的各个模块并调用MOD_startup启动每个模块。包括CLK_startup、PIP_startup、SWI_startup、HWI_startup等。当TSK管理模块在配置中被使用时,TSK_startup被执行,并且BIOS_start将不会结束返回;

  7. 执行idle循环:有两种方式进入idle循环。当TSK管理模块使能时,任务调度器运行的TSK_idle任务调用IDL_loop在其它任务空闲时进入idle循环;当TSK模块未被使用时,BIOS_start调用将返回,并执行IDL_loop进入永久的idle循环,此时硬件和软件中断可以抢占idle循环得到执行。由于idle循环中管理和主机的通信,因此主机和目标机之间的数据交互可以进行了

从上述的启动过程我们可以分析一下为什么在操作系统中main函数不需要使用while(1)死循环:因为在DSP/BIOS中,main函数只是被操作系统调用用来进行初始化的,执行完main函数后才能启动操作系统。这也给了我一个启示——如果我想在一个工程中既可以使用操作系统,又可以在某些情况下简单的禁用操作系统,只需定义一个宏开关main函数中while(1)循环就可以了!

DSP/BIOS在DSP项目中的地位

下图是TI公司倡导的DSP软件架构,

21

由图可知,

  1. 由CSL负责DSP芯片级外设的驱动,这部分是软件开发人员最底层的代码,DSP/BIOS负责底层的调度,方便应用层的管理,还有Driver模块,我认为是其它的非DSP芯片级的驱动,如USB/PCI等外设接口

  2. 中间层主要是算法相关的东西,TI提供了一个DSP算法的标准,只要按该标准编写的算法能很容易的实现不同DSP之间的移植

  3. 再上层就是应用程序了

这就是TI的DSP高端大气上档次的三层软件架构!

参考资料

  1. SPRU430S: TMS320C6000 DSP/BIOS 5.x Application Programming Interface (API) Reference Guide
  2. SPRU423F: TMS320 DSP BIOS User Guide
  3. SPRU616A: DSP-BIOS Driver Developer's Guide
  4. 刘鑫茂:DSP/BIOS讲座

http://chatgpt.dhexx.cn/article/NhPYrJuk.shtml

相关文章

【DSP】【第一篇】开始DSP学习

2022年6月14日 1. 部署开发环境 略。工作需要,TMS320C6678。 从今天开始学习DSP的知识。 后面会补充如何安装部署环境。 1.1 组件 1.1.1 SDK MCSDK(CCSv5,CCSv6)Path(全英文路径,无中文,无空格) 安装完之后&#xf…

DSP的入门学习(二)

DSP的入门学习(二) 1.了解所用的设备资源 图为 Code Composer Studio 6.0.0.00190 C/C开发环境 1.1 简单介绍建立一个CCS项目工程 上图所用到的是:硬件平台基于TMS320F28335芯片,软件平台基于TI的Code Composer Studio 6.0.0.…

[培训-DSP快速入门-1]:DSP概述(基本框架、CPU, GPU, FPGA比较,常见型号)

作者主页(文火冰糖的硅基工坊):https://blog.csdn.net/HiWangWenBing 本文网址:https://blog.csdn.net/HiWangWenBing/article/details/118885060 目录 引言: 第1部分 什么是DSP 第2部分 为什么需要DSP 第3部分 DSP的基本框架 第4部分 C…

DSP,从入门到入土

文章目录 前言一、DSP架构二、内存管理三、 多核并行处理1.1、主从模式1.2、数据流模式 四、多核同步4.1、共享存储区变量4.2、硬件信号量 五、Cache的使用六、DMA的使用七、一些编程tips7.1 关键字7.2 struct定义7.3 存储7.4 动态内存7.5 编译器选项 八、八核固化附录 前言 下…

用电器分析识别装置(H 题)--2021 年全国大学生电子设计竞赛

用电器分析识别装置(H 题)--2021 年全国大学生电子设计竞赛 一 任务二 要求1. 基本要求2.发挥部分 三 说明四 评分标准优秀作品开源参考(来源立创开源平台)文件 一 任务 设计并制作一个根据电源线电流的电参量信息分析…

2022年全国大学生电子设计竞赛—TI杯模拟电子系统设计专题邀请赛X题

一、简介 全国大学生电子设计竞赛“TI杯”模拟电子系统设计专题邀请赛,是全国大学生电子设计竞赛的一项专题邀请赛(以下简称邀请赛)。竞赛自2010年起每逢双年举办,并设TI杯。邀请赛贯彻全国大学生电子设计竞赛的宗旨,…

「2020年大学生电子设计竞赛分享」电源题,省一等奖!

点击上方“大鱼机器人”,选择“置顶/星标公众号” 福利干货,第一时间送达! 01 到底参不参赛? 嗡嗡嗡,随着手机的一声振动,锁屏弹出了消息提醒,没看全文,依稀瞄到2020……TI杯……几…

智能送药小车(F 题)--2021 年全国大学生电子设计竞赛

智能送药小车(F 题)--2021 年全国大学生电子设计竞赛 一 任务二 要求1.基本要求2.发挥部分 三 说明四 评分标准优秀作品开源参考(来源立创开源平台)文件 一 任务 设计并制作智能送药小车,模拟完…

电子设计竞赛设计总结报告写作

文末免费下载资料 内容提要 设计总结报告是电子设计竞赛作品的一个重要组成部分,占50分。本章介绍了设计总结报告的评分标准分析,设计总结报告的内容、要求与应注意的一些问题,给出了3个设计与总结报告示例。 知识要点: 设计总结…

2017年全国大学生电子设计竞赛综合测评题

2017年全国大学生电子设计竞赛综合测评题 题目如下: 题目要求电源只能使用5V单电源、给运放使用5V单电源供电。 方波发生电路 有点像梯形是因为multisim上的LM324跟不上变化的速度,使用题目中的AD2302即可。 输出为接近5V的方波,使用滑动变…

2022年全国大学生电子设计大赛省赛A题

2022年全国大学生电子设计大赛省赛A题 (交流电子负载) 文章目录 2022年全国大学生电子设计大赛省赛A题 (交流电子负载)前言一、总体思路二、模块设计1.半桥模块2.测量模块3.辅助电源模块 三、主电路搭建总结 前言 2022年全国大学生电子设计大赛省一第一名(受学校省…

2022暑期学校——简单实现2021年电子设计竞赛国赛题目

目录 设计目标: 设计思路: 设计方案: 电机驱动 1)时钟配置 2)SYS配置 3)PWM信号输出 4)电机控制思路 5)电机驱动代码 电脑通讯 1)CubeMx配置 2)电脑通讯代码 HC05蓝牙通讯 1)HC05原理讲解 2&am…

电子设计大赛-放大器类题目分析

关注v-x-公-众-号:【嵌入式基地】 后-台-回-复:【电赛】 即可获资料 回复【编程】即可获取 包括有:C、C、C#、JAVA、Python、JavaScript、PHP、数据库、微信小程序、人工智能、嵌入式、Linux、Unix、QT、物联网、算法导论、大数据等资料 电子…

电子设计大赛-信号源类题目分析

文末下载完整资料 实用信号源的设计和制作[2] (第2届,1995年) (1)设计任务 在给定15V电源电压条件下,设计并制作一个正弦波和脉冲波信号源。 (2)设计要求 ①基本要求 第1部分&…

电子设计大赛-仪器仪表类题目分析

文末下载完整资料 简易电阻、电容和电感测试仪[2](第二届,1995年) (1)设计任务   设计并制作一台数字显示的电阻、电容和电感参数测试仪,示意框图如图1.3.23所示。 (2)设计要求 ①基本要求…

2015年电子设计竞赛题目解析-数字频率计

2015年电子设计竞赛题目-数字频率计题目解析 本期将讲解2015年电子设计竞赛数字频率计的硬件及软件实现方法 一、题目解读 通过阅读题目,总结出以下设计要点: 1、测频率。要求测量幅值从10mVrms到1Vrms,频率从1Hz到100MHz的正弦波的频率&…

2018年全国大学生电子设计竞赛TI杯赛题简单回顾和准备经验分享

华南理工大学 陈艺荣 邮箱:eecyryoumail.scut.edu.cn 1、2018年TI杯赛题 A:利用TI公司指定的高精度ADC芯片制作一个万用表,要求能够测量电流、电压、电阻。精度要求忘记了。这个ADC芯片是使用I2C通信的。如果不熟悉I2C通信协议&…

2021 年全国大学生电子设计竞赛实施过程说明

2021 年全国大学生电子设计竞赛实施过程说明 文章目录 2021 年全国大学生电子设计竞赛实施过程说明一、 竞赛组织与规则1.学校组织2.参赛报名3.竞赛组织方式4.巡视员选派及其职责5.公布竞赛器件仪器清单6.开…

信号失真度测量装置(A 题)--2021 年全国大学生电子设计竞赛试题

信号失真度测量装置(A 题)--2021 年全国大学生电子设计竞赛试题 一 任务二 要求1.基本要求2. 发挥部分 三 说明优秀作品开源参考(来源立创开源平台) 一 任务 设计制作信号失真度测量装置,对来自函数/任意波形发生器的…