找回密码
 立即注册
楼主: 杨***

STC单片机uC/OS-II移植记(3):整理移植源

[复制链接]

该用户从未签到

61

主题

622

回帖

1万

积分

荣誉版主

积分
10816
 楼主| 发表于 2023-7-30 23:20:53 | 显示全部楼层
熊仔 发表于 2023-7-30 19:54
uCOS-II 在其他芯片是支持不等长任务堆栈的。
只是作者设计这个os的时候没有考虑到8051这么奇葩的data空间 ...

既然你觉得有必要,我就升级一下我移植的uC/OS-II版本,支持一下不等长堆栈。说实话,我也看不惯等长堆栈的限制,早就想废掉这个限制了
回复 支持 反对 送花

使用道具 举报

该用户从未签到

61

主题

622

回帖

1万

积分

荣誉版主

积分
10816
 楼主| 发表于 2023-7-31 00:46:14 | 显示全部楼层
熊仔 发表于 2023-7-30 19:54
uCOS-II 在其他芯片是支持不等长任务堆栈的。
只是作者设计这个os的时候没有考虑到8051这么奇葩的data空间 ...

你想要的8051单片机上的不等长堆栈的uC/OS-II来了,这是微山x51-UCOSII-RTOS的V2.1版本,其中专门设置了新的建立不等长堆栈任务的函数“uCx51_TaskCreate”,见下图:

建立不等长堆栈任务.jpg

欢迎继续你讨论和提出改进意见,共同促进RTOS在STC单片机上的应用。
下面是STC8H单片机上的V2.1版本的uC/OS-II
uCx51_uCOSII_V21_STC8H_LIB_Demo.rar (60.55 KB, 下载次数: 27)

回复 支持 反对 送花

使用道具 举报

该用户从未签到

11

主题

329

回帖

872

积分

荣誉版主

积分
872
发表于 2023-7-31 10:49:21 | 显示全部楼层

谢谢回答,并修改了代码。

大概看了下。提供的是LIB文件,看不到具体实现的过程。只能通过汇编看。

对杨老师移植的版本最大的疑问是系统竟然用2个定时器。
定时器0 :LCALL _?OSTimeTick                     1kHz
定时器3 :LCALL _?uCx51_IntSched          10kHz


太浪费定时器了吧。为啥不能合并再一起?
还有 改动把IntNesting改成uCx51_IntNesting变量。导致其他函数改动太大了。
和作者的思路不在一起,我认为不应该改,把IntNesting 变量用data声明就好,加快速度。当然OSLockNesting也改data。



然后改下函数OSIntEnter,判断去掉,省时间。
void  OSIntEnter (void) large reentrant
{
    if (OSRunning == OS_TRUE) {
//        if (OSIntNesting < 255u) {//这句没用,不可能有255个中断
            OSIntNesting++;    /* Increment ISR nesting level                        */
//        }
    }
}

原函数先用判断OSRunning是否为1,才对OSIntNesting++。
杨老师的版本直接对uCx51_IntNesting++。

点评

常言道授人以鱼不如授人以渔,意思是要培养学生的动脑筋动手能力。因此对于学生提出的问题,如果我觉得学生能够通过自己的努力解决,我通常不会直接给他答案,一般是说你自己去试试,你自己会得到答案的。如果学生试  详情 回复 发表于 2023-7-31 17:24
回复 支持 反对 送花

使用道具 举报

该用户从未签到

61

主题

622

回帖

1万

积分

荣誉版主

积分
10816
 楼主| 发表于 2023-7-31 17:24:11 | 显示全部楼层
本帖最后由 杨为民 于 2023-7-31 17:25 编辑
熊仔 发表于 2023-7-31 10:49
谢谢回答,并修改了代码。

大概看了下。提供的是LIB文件,看不到具体实现的过程。只能通过汇编看。

常言道授人以鱼不如授人以渔,意思是要培养学生的动脑筋动手能力。因此对于学生提出的问题,如果我觉得学生能够通过自己的努力解决,我通常不会直接给他答案,一般是说你自己去试试,你自己会得到答案的。如果学生试了还不行,我会与他交流问题卡在哪里,然后再一起去找出解决的方法。所以关于我移植范例中的两个定时器能不能合在一起,你可以去试试,也可以想一想为什么,欢迎把你试的和想的结果分享在这里。这次介绍如何移植uC/OS-II,我选择了最简单的实验设备,发了大概10篇有关的帖子,就是希望各位有兴趣的读者能够亲自试一试,亲自尝一尝RTOS梨子的滋味
回复 支持 反对 送花

使用道具 举报

该用户从未签到

11

主题

329

回帖

872

积分

荣誉版主

积分
872
发表于 2023-7-31 21:56:48 | 显示全部楼层
本帖最后由 熊仔 于 2023-7-31 22:51 编辑

刚测试了下,定时器3的LCALL _?uCx51_IntSched        是可以合并到定时器0的。

看到杨老师写的 STC单片机uC/OS-II移植记(6):RTOS系统中断研究与测量  
没有明确说明用2个定时器的原因。

通过分析,这样做,很可能是为了准确测量切换任务各函数执行时间。

把中断任务切换函数弄到定时器3,这时,定时器0只管系统节拍处理,可以测量定时器0的中断时间。
P26口的高电平时间就是执行时间。
如果不是这个原因还请杨老师明示下。

通过查看汇编代码:
P21 测量系统(中断)级别切换任务时间
P23 测量任务级别切换任务时间



点评

在范例程序中使用两个定时器除了准确测量任务切换时间,还有以下的目的: (1)给出规范的RTOS中断ISR写法,比较两个ISR就可以学习到哪些是固定部分,用户自己的程序应该放在什么地方。 (2)说明一个RTOS系统的节拍  详情 回复 发表于 2023-8-1 10:19
回复 支持 反对 送花

使用道具 举报

该用户从未签到

11

主题

329

回帖

872

积分

荣誉版主

积分
872
发表于 2023-7-31 22:16:19 | 显示全部楼层
本帖最后由 熊仔 于 2023-7-31 22:27 编辑

目前移植的os,还发现2处瑕疵。
1,新建任务入口参考 void    *p_arg, 初始化堆栈的时候没有保存到任务堆栈中。
2,系统(中断)级别切换任务 里面调用了两次OSTaskSwHook 钩子函数。应该删除一次。

如果把保存堆栈函数后面的调用OSTaskSwHook 删除,就是统一在进入后调用OSTaskSwHook钩子函数。任务级别切换也需要在入口进行调用OSTaskSwHook钩子函数。

点评

(1)我压根不赞同给单片机RTOS的任务函数设置上面输入参数,所以不高兴保存它,我自己写的RTOS的任务函数都没有参数。 (2)uC/OS-II一次任务切换调用两次钩子函数,在任务实际切换前后各调用一次。它这样设计的目  详情 回复 发表于 2023-8-1 09:55
回复 支持 反对 送花

使用道具 举报

该用户从未签到

11

主题

329

回帖

872

积分

荣誉版主

积分
872
发表于 2023-7-31 23:07:40 | 显示全部楼层
本帖最后由 熊仔 于 2023-7-31 23:11 编辑

还发现一个重要瑕疵,如果当前有任务调度,会导致随后任务级OSCtxSw 任务切换函数执行。





逻辑分析仪抓的波形可以说明,P21高电平脉冲后,紧接着P23高电平脉冲。说明OSCtxSw 任务级切换调用了一次。

点评

(1)一个事件发生后,又发生了另一个事件,两个事件未必关联,也未必有是因果关系。就像大哥先生了个儿子,然后同一年二哥也生了个儿子,两者未必有关联,也未必为因果。我们在思考问题和评价问题时要避免落入这种  详情 回复 发表于 2023-8-1 09:38
回复 支持 反对 送花

使用道具 举报

该用户从未签到

61

主题

622

回帖

1万

积分

荣誉版主

积分
10816
 楼主| 发表于 2023-8-1 09:38:09 | 显示全部楼层
熊仔 发表于 2023-7-31 23:07
还发现一个重要瑕疵,如果当前有任务调度,会导致随后任务级OSCtxSw 任务切换函数执行。

(1)一个事件发生后,又发生了另一个事件,两个事件未必关联,也未必有是因果关系。就像大哥先生了个儿子,然后同一年二哥也生了个儿子,两者未必有关联,也未必为因果。我们在思考问题和评价问题时要避免落入这种下意识的陷阱中。
(2)作为课后作业,就用我在这个帖子中给的程序,你试试证明这两者有或者没有因果关系。如果三天后没有试出来,提醒我给出答案。

点评

找到问题了,Task_A 任务休眠进入的任务切换。 Task_A优先级最高,中断抢占调度,之后翻转IO马上就进入OSTimeDly引起一次任务调度。  详情 回复 发表于 2023-8-1 15:28
回复 支持 反对 送花

使用道具 举报

该用户从未签到

61

主题

622

回帖

1万

积分

荣誉版主

积分
10816
 楼主| 发表于 2023-8-1 09:55:23 | 显示全部楼层
熊仔 发表于 2023-7-31 22:16
目前移植的os,还发现2处瑕疵。
1,新建任务入口参考 void    *p_arg, 初始化堆栈的时候没有保存到任务堆栈 ...

(1)我压根不赞同给单片机RTOS的任务函数设置上面输入参数,所以不高兴保存它,我自己写的RTOS的任务函数都没有参数。
(2)uC/OS-II一次任务切换调用两次钩子函数,在任务实际切换前后各调用一次。它这样设计的目的是在任务切换前让用户检测任务切换条件是否满足,决定是否进行切换,而在任务切换后,新任务尚未执行之前再调用一次钩子函数,一是可以用来启动一些本任务需要的工作,二是可以用来向其他任务发送信息和执行某些操作,以此实现各个任务之间的协调工作。
(3)uC/OS-II的这种在任务切换前后两次调用钩子函数,是一种很周全的考虑,只是在一般情况下用不到而已。我写的学习版RTOS,这两个钩子函数回调都省了,方便入门者学习。

点评

关于1,解决也很简单,通用指针通过R3,R2,R1传参。保存下就好。当然杨老师不喜欢传参不处理也行,或许有人跟着其他资料实验测试,用到传参的例子,会有问题调试半天。 关于2,系统(中断)级别切换任务 里面调用了  详情 回复 发表于 2023-8-1 13:29
回复 支持 反对 送花

使用道具 举报

该用户从未签到

61

主题

622

回帖

1万

积分

荣誉版主

积分
10816
 楼主| 发表于 2023-8-1 10:19:36 | 显示全部楼层
熊仔 发表于 2023-7-31 21:56
刚测试了下,定时器3的LCALL _?uCx51_IntSched        是可以合并到定时器0的。

看到杨老师写的 STC单片机 ...

在范例程序中使用两个定时器除了准确测量任务切换时间,还有以下的目的:
(1)给出规范的RTOS中断ISR写法,比较两个ISR就可以学习到哪些是固定部分,用户自己的程序应该放在什么地方。
(2)说明一个RTOS系统的节拍的两个基本部分是可以分开的,“_?OSTimeTick”决定了“Sleep”功能的时间精度,这里是1毫秒,“_?uCx51_IntSched”决定了RTOS的实时响应时间。
(3)调节定时器3可以具体测量在STC8H上33MHz情况下的实时响应时间,经实际测试可以达到小于15微秒(定时器3工作在60KHz)。本论坛介绍的PLC对应的逻辑响应时间是15毫秒,对比之下RTOS响应时间比PLC快几十到几百倍,因此使用RTOS的DCS系统在工业控制中超越PLC成为主流。
(4)使用两个定时器可以研究中断嵌套保护的作用,含定时器0则可以研究在RTOS中采用STC单片机定时器0的不可屏蔽中断模式的可行性(你有兴趣修改一下模式试试)

点评

杨老师回答的 很详细,受益匪浅。谢谢。  详情 回复 发表于 2023-8-1 13:10
回复 支持 反对 送花

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2024-4-29 23:07 , Processed in 0.083218 second(s), 67 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表