01 - 多种调用MULTIPLE CALL TO SEGMENT
使用RTX51 Tiny系统,Keil编译出现Warning:MULTIPLE CALL TO SEGMENT的时候,说明一个不可重入的函数Fun同时被2个或以上的任务调用,可能出现重入的情况,比如:
02 - 解决办法
在Keil的51编译器中,因为资源限制,函数都是不可重入的,并不是所有的函数被2个或以上的任务调用都会报这个Warning,而是被编译器Overlay处理的函数再被2个或以上的任务调用才会报Warning,解决的办法暂时有如下:
方法0(先行):重新设计代码。尽量让同一个资源只在一个任务中使用。
方法1(首选):建立多个备份或建立守护任务。目的是让2个或以上的任务不调用同一个函数,有N个任务在使用Fun,就复制N份,然后函数名不同,供每个任务调用,如果Fun内还有其他不可重入的函数A和B,那么A和B也要根据不同的Fun相应复制。
优点:没有重入问题
缺点:占用CODE和RAM,操作和维护麻烦
方法2(次选):使用链接器指令从Overlay分析中删除该不可重入的函数。Keil中【Options For Target】-【BL51 Misc】-【Overlay】-【添加_Fun !* 】,如果函数名是GetCheck,那么就添加_GETCHECK !*,多个函数用逗号隔开(官方文档)
优点:操作方便,Fun本身不会被Overlay处理
缺点:考虑增多,Fun依然不可重入,就要确保函数Fun执行期间不会发生重入的情况(如关闭时间片,使用协助调度)
方法3(慎用):降低Warning Level。编译器不报Warning。
优点:操作方便,一键屏蔽
缺点:可能有隐藏BUG,会把其他重要Warning都屏蔽掉,另外函数Fun没有任何的改变,所以要确保函数Fun执行期间不会发生重入的情况
方法4(避免):使用reentrant关键字修饰函数Fun。将启动模拟堆栈对函数进行局部变量压栈出栈的方式调用,但是函数也要重新定义储存模式为compact,因为RTX51 Tiny只支持compact模式的reentrant功能(官方文档),修饰后的代码如下:
void Fun(uint8_t data) compact reentrant
{
……
}
优点:函数变得可重入
缺点:模拟堆栈效率低下,compact比small慢,还可能发生堆栈踩踏情况(小白没有成功开启过,不要使用这个关键字)
03 - 总结
- 解决RTX Tiny多重调用的办法有:重新设计代码、建立函数备份、添加链接指令、降低Warning Level、使用reentrant关键字
- 01-【RTX51 Tiny入门】-RTX51 Full & Tiny简介
- 02-【RTX51 Tiny入门】-资源占用情况
- 03-【RTX51 Tiny入门】-内核组成
- 04-【RTX51 Tiny入门】-任务和调度器
- 05-【RTX51 Tiny入门】-OS API函数
- 06-【RTX51 Tiny入门】-查看RTX51 Tiny官方例程
- 07-【RTX51 Tiny入门】-使用RTX51 Tiny
- 08-【RTX51 Tiny入门】-Conf_tny.A51配置文件
- 09-【RTX51 Tiny初级】-K_TMO与K_IVL的区别和使用场合
- 10-【RTX51 Tiny初级】-os_send_signal()和os_set_ready()的区别和使用场合
- 11-【RTX51 Tiny初级】-os_wait和os_switch_task区别和使用场合
- 12-【RTX51 Tiny初级】-解决多重调用问题(MULTPLE CALL TOSEGMENT)
- 13-【RTX51 Tiny高级】-进行Task的划分与拆分
- 14-【RTX51 Tiny高级】-修改默认产生时间片的定时器T0为其它定时器
- 15-【RTX51 Tiny高级】-考虑Round-Robin的开启与关闭
- 16-【RTX51 Tiny高级】-解决Task之间的通讯和耦合问题
- 17-【RTX51 Tiny高级】-Task ID隐藏的优先级问题
- 18-【RTX51 Tiny高级】-系统架构的设计