在DSP28335上使用RTOS的经验总结

一、前言

F28335棣属于TI C2000 DSP系列,它在电控相关的行业有较多的应用。但是因为种种原因,某些行业因为无“芯”可用,也会将它作为通用芯片使用。少得可怜的资料加上年代久远的CPU架构,要在这上面使用RTOS变得异常艰难。

二、混乱的SYS/BIOS

1.到底是SYS/BIOS、DSP/BIOS还是TI-RTOS?

28335官方主推使用的RTOS是SYS/BIOS,只是网络上几乎找不到实践项目,很多资料因为年代久远甚至描述得相互冲突。光是搞明白它们之间的关系,就花了我相当长的时间。

  • TI-RTOS:TI嵌入式生态系统的最新名称,它不仅包括了内核(SYS/BIOS)、还包含网络栈、文件系统等其他组件,适用于最新的TI CPU。
  • SYS/BIOS :TI-RTOS 的内核,28335只适用于它
  • DSP/BIOS :在一些老的资料中出现,其实它是SYS/BIOS的前身,在6.30版本改名SYS/BIOS
  • XDCtools :包含了SYS/BIOS包,也是它的构建工具
2.不推荐使用SYS/BIOS的理由

虽然SYS/BIOS是官方钦点的RTOS系统,我却不推荐刚准备入坑的人在F28335上使用或学习它,原因有:

  1. 从官方用户手册来看,SYS/BIOS的使用和构建与主流OS差异较大,学习的收益极低;
  2. DSP主要应用场景并不使用RTOS,因为成本和生态它的生存空间还不断被ARM挤压,感觉连TI自己都快放弃了。所以这极可能是一个大坑,出现了问题根本找不到相关资料。

三、移植UCOS的问题和改进

除了SYS/BIOS、网络资料中流传最广的是一份OS应用是由micrium的移植的ucosii代码,然而测试时却发现,这份代码存在不能调度抢断的问题。要理解和解决这个问题首先要从C2000系列CPU的栈空间架构和中断流程讲起。

1.28335的栈机制和中断流程
  • 28335由于设计得比较早,并不具备常见的双堆栈机制,也就是说应用和中断会共用同一个栈。
  • 根据手册和自己的测试,C2000的CPU级中断的过程如下(忽略外设级和PIE级):
    image.png

1、中断锁存至IFRx中(其中x为中断线号),如果IERx有效且INTM为0,CPU响应中断;
2、cpu保存上下文环境到栈空间(包括了IER寄存器状态);
3、IFRx 置0,IERx置 0,INTM 置 1;
4、从向量表获取中断处理函数地址并执行;
5、恢复INTM,从栈空间恢复IER。
6、中断返回

2.问题分析

接下来以两个任务的系统调度为例看看为什么会发生异常。假设系统运行了两个任务,分别为线程A和B,当前运行线程A,接下来发生以下事件:
1.tick调度中断触发,CPU进入中断开始执行调度;
2.cpu因为中断保存上下文环境,此时IER被保存到线程A的栈空间;
3.调度器算法结果为系统切换到线程B;
4.切换SP到线程B的栈空间,为线程B恢复上下文环境;
5.继续执行中断第5步,即从线程B栈上下文环境恢复IER。
很显然,调度完成后,IERx并没有正确地在中断后恢复。如果线程B不主动执行调度切回到线程A,被置0的IERx将一直无法恢复,tick中断一直处于屏蔽状态,系统任务也无法完成切换。

3.IERx的恢复

IERx不能恢复这一坑,一度让我觉得无解,为此甚至使用了双定时器tick这样的骚操作。直到最近才找到较好的解决办法,timer tick函数的主要部分实现如下:

_KTS_TIMER2_ISR:
...
    ; 保存任务上下文到TCB中
...
    ; 获取IER值
	PUSH    ST1
	POP     AL
	TBIT    AL, #4
	SB      SPA_BIT_SET, TC ;TC = 1 跳到SPA_BIT_SET去获取IER
	MOV     AR7, *-SP[46]
	SB      SAVE_IER, UNC ; 已获取到IER, 跳到 SAVE_IER
SPA_BIT_SET:
	MOV     AR7, *-SP[48]
SAVE_IER:
	MOVL    *SP++, XAR7 ; 保存IER到当前任务的堆栈
...
   ;  判断是任务主动执行的调度还是timer_tick函数触发
   ;  timer_tick触发时执行tick处理函数
...
    LCR  _KTS_SV_Handle  ;  执行调度函数
   ; 需要理解,IER的恢复是在下一个调度的任务中完成。
    MOVL    XAR7, *--SP  ; 从"上一个"任务的堆栈,获得IER
	MOVL    XAR0, #_kts_p_current
	MOVL    XAR0, *XAR0
	MOVL    XAR0, *XAR0
	MOV     @SP, AR0  ; 切换到"新"任务
...
   ; 从TCB中恢复"新"任务上下文环境
...

四、其他问题

  • DSP奇葩16位数据总线,不支持很多GNU特性,对初次上手的人非常不友好;
  • 所有任务应用栈必须额外预留中断栈的空间,包括空闲任务。
  • TI的printf函数会在栈上申请520字的内存,打印浮点,还会额外再申请520字。所以,不是有特别有需求,可以放弃浮点打印并使用精简的mini-printf函数。

五、总结

考虑收益问题,资料匮乏的情况下,学习一项过时的技术是愚蠢的。因此,总结就是,有条件还是尽量换平台,如果实在要用,需要充分考虑填坑的难度。

参考资料

[TI-RTOS Kernel (SYS/BIOS)User’s Guide] https://www.ti.com.cn/cn/lit/ug/spru430f/spru430f.pdf?ts=1628091876454
[TI SYS/BIOS的 创建工程实例] https://blog.csdn.net/xiaoluoshan/article/details/53785059
[micrium ucOSii_in_DSP28335] https://github.com/RanFang66/ucOSii_in_DSP28335
[TMS320x2833x, 2823x System Control and Interrupts Reference Guide]

  • 15
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值