| | 网站首页 | 新闻 | SOPC | FPGA | DSP | ARM | 嵌入式操作系统 | 下载 | 所有产品 | 留言 | 论坛 | 购买指南 | 网络协议 | 驱动设计 | | |
![]() |
![]() |
| 您现在的位置: 21嵌入式控制研究室 >> DSP >> DSP应用 >> 文章正文 |
|
|||||
| uC/OS_II在DSP芯片TMS320F281x上的移植 | |||||
| 作者:佚名 文章来源:本站原创 点击数: 更新时间:2005-11-29 | |||||
|
一、uC/OS_II嵌入式实时系统简介 uC/OS是一个多任务的实时性嵌入式操作系统,它的实时性内核源码是免费公开的,它同时提供了内存管理的接口和函数,因而uC/OS得到了广泛的应用。uC/OS的绝大部分采用ANSI C写成,具有很强的移植性,uC/OS可以移植到大多数的8位,16位,32位甚至64位微处理器、微控制器及数字信号处理器上。 uC/OS正常运行需要处理器满足以下条件:1)处理器的C编译器能够产生可重入的代码;2)用C语言就可以打开或关闭中断;3)处理器支持中断,并能产生定时中断;4)处理器支持能够容纳一定数量的硬件堆栈;5)处理器具有将寄存器、堆栈指针读出和存储到堆栈中的指令。[1] uC/OS移植的过程比较简单,只需用户根据移植目标硬件修改相应的数据类型定义,并用汇编语言编写几个函数,具体的步骤如下: 1)根据处理器结构修改OS_CPU.H中的数据类型的定义; 2)根据处理器堆栈结构在OS_CPU.H中定义堆栈增长方向; 3)根据处理器指令在OS_CPU.H中定义三个宏; 4)在OS_CPU.C中实现六个简单的函数,实际上只需修改一个,其它的无需改动; 5)在OS_CPU.ASM中编写四个汇编语言函数; 6)开发其它用户自定义功能,如文件系统管理任务,通信管理任务,AD转换任务,PWM发生器管理任务等。 二、TMS320F281x系列数字信号处理器(DSP)简介 TMS320F281x(以后简称F281x)是TI公司最新一代的2000系列32位定点DSP控制器,是目前控制领域最先进的处理器之一。其频率高达150MHz,可以大大提高控制系统的控制精度和芯片的处理能力。F28x系列芯片提供浮点数学函数库,可以实现浮点运算。F2812集成了128KB的闪存,优化的事件管理器和可编程通用计数器,还包括了16通道的12位ADC转换器。片上集成了SCI,SPI,McBSP,URAT及eCAN等标准通信接口。[2] 移植uC/OS_II到F2812上需要注意的问题包括: 1)数据类型定义,对于F2812,所有的整数类型包括字符型,短整数和整数及其对应的无符号数类型都是相同的,都用16位的二进制数表示。长整数和无符号的长整数用32位的二进制数表示。用基2的补码表示有符号数。所有的浮点数包括单精度数,双精度数和长双精度数都是相同的表示方式即符合IEEE标准的单精度数; 2)F2812没有硬件堆栈,堆栈是在数据区存储器实现,堆栈增长方向是自下向上的,堆栈指针存储在专门的堆栈指针寄存器SP中;这一点于2407不同(2407有8个硬件堆栈,堆栈指针存储在AR1中); 3)F2812汇编指令集相对F2407有了很大的不同,寄存器数量也有所增加; 4)F2812的中断处理过程中,CPU会自动将部分寄存器内容压入堆栈,然后将返回地址压入堆栈,上述动作只需9个指令周期既可完成,因此具有较高的中断相应速度,这对提高系统的实时性有很大的帮助; 5)F2812有三个时钟计数器,其中Timer1和Timer2可以为实时操作系统使用,Timer0可供应用程序使用; 三、uC/OS_II在F281x上的移植 根据以上特点,可以编写uC/OS的移植程序函数,函数的编写方法可以参照文献[1]中的第八章,在此只列出于硬件有关的部分函数的移植源代码: 寄存器内容保存和恢复子程序: ;CPU响应中断时,按顺序自动保存下列寄存器内容: ;T,ST0,AH,AL,PH,PL,AR1,AR0,DP,ST1,DBGSTAT,IER,PC ;其它寄存器内容需要手工进行压栈保护 ;恢复时只要安相反的顺序进行出栈操作即可[3] _CTX_SAVE: pop RPC ;恢复RPC内容 push AR1H:AR0H ;保存其它寄存器内容 push XAR2 push XAR3 push XAR4 push XAR5 push XAR6 push XAR7 push XT LRETR ;返回调用主程序 _CTX_REST: pop XT ;首先恢复其它寄存器内容 pop XAR7 pop XAR6 pop XAR5 pop XAR4 pop XAR3 pop XAR2 pop AR1H:AR0H EINT ;允许CPU相应中断 IRET ;模拟中断返回 堆栈初始化函数的C语言代码: 该函数初始化由task指向的任务所需要的堆栈空间,完成后堆栈中保存的内容与系统复位后各寄存器的内容一致。该函数的编写需要注意F281x的堆栈地址是从下向上增长的,并且应该与寄存器内容的保护和恢复顺序一致。 void *OSTaskStkInit(void (* task)(void *pd), void *pdata, void *ptos, INT16U opt){ INT16U *stk; INT16U *pp; opt=opt; //Load stack optointer stk=(INT16U *)ptos; //ST0 = 0,T = 0 *stk++ = (INT16U) 0x2000; *stk++ = (INT16U) 0x2200; //AL = 0,AH = 0 *stk++ = (INT16U) 0x0000; *stk++ = (INT16U) 0x0000; //PL = 0,PH = 0 */ *stk++ = (INT16U) 0x0000; *stk++ = (INT16U) 0x0000; //AR0 = 0,AR1 = 0 *stk++ = (INT16U) 0x0000; *stk++ = (INT16U) 0x0000; //ST1 = 0,DP = 0 *stk++ = (INT16U) 0x0000; *stk++ = (INT16U) 0x0000; //IER = 0 ,DBGSTAT = 0 *stk++ = (INT16U) 0x0000; *stk++ = (INT16U) 0x0000; //Interrupt return address *stk++ = (INT16U) task; pp =(INT16U *) &task; *pp ++; *stk++ = (INT16U) *pp; ptos = stk; //AR0H = 0,AR1H = 0 *stk++ = (INT16U) 0x0000; *stk++ = (INT16U) 0x0000; //AR2 = 0,AR2H = 0 *stk++ = (INT16U) 0x0000; *stk++ = (INT16U) 0x0000; //AR3 = 0,AR3H = 0 *stk++ = (INT16U) 0x0000; *stk++ = (INT16U) 0x0000; //AR4 = 0,AR4H = 0 *stk++ = (INT16U) 0x0000; *stk++ = (INT16U) 0x0000; //AR5 = 0,AR5H = 0 *stk++ = (INT16U) 0x0000; *stk++ = (INT16U) 0x0000; //AR6 = 0,AR6H = 0 *stk++ = (INT16U) 0x0000; |
|||||
| 文章录入:fengfeiyi 责任编辑:fengfeiyi | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 管理登录 | | |
![]() |
站长:康草科技 |