数码之家

 找回密码
 立即注册
搜索
查看: 1532|回复: 10

最新版本uC-OS2-2.93.01已移植到STC8上,请帮忙查错, 每条错误感谢200元

[复制链接]
发表于 2023-8-22 09:54:11 | 显示全部楼层 |阅读模式
本帖最后由 钟山风雨起苍黄 于 2023-8-22 09:55 编辑

最新版本uC-OS2-2.93.01已移植到STC最新的 1T 8051, STC8H8K64U
===适用于STC8系列所有型号
===解决了网络上不同移植版本潜在的bug

===鼓励大家在STC官网 www.STCAIMCU.com 帮忙查错, 200元/每条错误, 感谢, 大家一起前行
许可改成 APACHE 2.0 也就是可以商业使用不用授权。具体可以查看APACHE 2.0内容。
声明:本移植版本参考了陈是知移植版本和STC网站上的原网友版, 另外测试例子使用杨为民老师移植的版本
一,提升速度
  1. 重要的变量使用data修饰

  2. 结构体指针变量使用xdata修饰
  3. 使用DPTR自增方式
      注意,使用DPTR自增方式,这部分代码不能硬件仿真,单独调试,可以全速运行。


os_cpu_a.A51文件,有测试信号。
P20    测试OSIntExit       运行时间  (有任务切换4us)(无任务2.83us)
P21    测试OSIntCtxSw  系统级切换任务时间    (8.6us)
P23    测试OSCtxSw       任务级切换任务时间    (8.7us)
P26    测试滴答定时器中断全过程时间 (有任务24.3us)   (无任务13us)
P27    测试OSTimeTick  运行时间      (有任11.2us)(无任务9.3us)
以上测试,选择 STC8H8K64U 工作时钟是 40MHz









os_cpu_a.A51文件,有测试信号。

P20    测试OSIntExit     运行时间  (有任务切换4us)(无任务2.83us)
P21    测试OSIntCtxSw  系统级切换任务时间  (8.6us)
P23    测试OSCtxSw      任务级切换任务时间    (8.7us)

P26    测试滴答定时器中断全过程时间     (有任务24.3us)   (无任务13us)
P27    测试OSTimeTick  运行时间     (有任11.2us)(无任务9.3us)
以上测试,选择工作时钟是40MHz


二,允许任务堆栈空间任意大小
修改了OSTaskCreate,增加stk_size入口

  • INT8U  OSTaskCreate (void   (*task)(void *p_arg),
  •                      void    *p_arg,
  •                      OS_STK  *ptos,
  •                      INT16U   stk_size,
  •                      INT8U    prio) large reentrant

复制代码
OS_STK  *OSTaskStkInit (void (*task)(void *pd), void *p_arg, OS_STK *ptos, INT16U opt)

对 OSTaskStkInit函数利用 opt 传入任务堆栈大小 实现不等长任务堆栈

三 ,临界区保护方法,支持方法2和方法3

  • #if OS_CRITICAL_METHOD==2
  • //执行OS_ENTER_CRITICAL()时,先将中断状态保存到堆栈,然后关中断;
  • //执行OS_EXIT_CRITICAL()时,再从堆栈中恢复原来的中断开/关状态。这种方法不会改变中断状态,避免前面的问题。
  • //但是,当用户使用的处理器有堆栈指针相对寻址模式时,可能出现严重错误。
  • //问题分析:OS_ENTER_CRITICAL()时导致中断切换任务的时候硬件堆栈多入了一个_push_(IE),
  • //解决方法:OSIntCtxSw()函数调整SP的时候应该多减1,原来SP=SP-4改为SP=SP-5
  • #include <intrins.h>
  • #define OS_ENTER_CRITICAL()do{_push_(IE);EA = 0;}while(0)   /* 利用堆栈保存中断状态,再关中断  */
  • #define OS_EXIT_CRITICAL()do{ _pop_ (IE);}while(0)          /* 将IE从堆栈弹出,恢复IE值    */
  • #endif
  • #if OS_CRITICAL_METHOD==3
  • //获取当前中断状态的值,并将其保存在C函数局部变量之中
  • //问题分析:可重入函数的局部变量cpu_sr会入仿真栈。导致中断切换任务的时候,仿真堆栈出问题。
  • //解决方法:OSIntCtxSw()函数执行时需要对仿真堆栈指针++操作。
  • #define OS_ENTER_CRITICAL() do{ cpu_sr=IE;EA = 0;}while(0)
  • #define OS_EXIT_CRITICAL()  do{ IE = cpu_sr; }while(0)
  • #endif

复制代码

四,支持软件定时器
之前移植的版本没有适配软件定时器功能。OS_VERSION >= 281 支持软件定时器。
移植过程中遇到一个困难,就是回调函数,函数指针问题。重点是指针ptmr需要加上xdata修饰。

  • typedef  void (code *OS_TMR_CALLBACK)(void xdata*ptmr, void *parg) large reentrant;

复制代码
五,解决RET和RETI混用问题
OSIntCtxSw 是在中断中调用的,需要调用RETI返回
OSStartHighRdy 运行第一个任务,应该用RET返回
OSCtxSw  在任务中调用的,应该用RET返回

这三个函数最后部分的代码都一样。之前移植的版本统一用RETI返回,导致混用。
本移植提供2个解决方法,原则是OSIntCtxSw 函数提前退出中断,统一用RET返回

  • ;方法1:直接把  OSIntCtxSw_in函数地址入栈,由RETI中断返回,跳转到OSIntCtxSw_in函数,共6T
  •         MOV DPTR,#OSIntCtxSw_in
  •         PUSH DPL
  •         PUSH DPH
  •         RETI
  •          ;方法2:;巧妙的利用函数返回RETI执行了中断完毕,跳转到下一条语句。这样任务可以无忧使用RET作为返回,共9T。
  •         LCALL    RE_RETI
  •         LJMP OSIntCtxSw_in
  • RE_RETI:        RETI

复制代码
显然方法1更优秀
当然还有方法3,3个函数独立,不要共同出口。这里不推荐,浪费代码空间。

六,关于中断嵌套的做法
提供了2个中断例子:
定时器1 中断演示允许中断嵌套
定时器3 中断演示禁止中断嵌套


  • ; ==== 定时器1 中断服务程序 =============
  • ;演示允许中断嵌套
  • EXTRN CODE  (_?Timer1_Handler)
  • Timer1_ISR:
  •       USING 0        ;工作寄存器0
  •       CLR EA  ;调用OSIntEnter之前先关中断
  • ;SETB P20
  •       PUSHALL            ;现场保护
  •       LCALL _?OSIntEnter        ;通知内核进入中断     
  •       SETB EA  ;允许中断嵌套
  •       
  •       LCALL _?Timer1_Handler
  •       
  •       LCALL _?OSIntExit   ;通知内核退出中断
  •       POPALL      ;恢复现场   
  • ;CLR P20
  •       RETI
  •       
  •       
  • ; ==== 定时器3 中断服务程序 =============
  • ;演示禁止中断嵌套
  • EXTRN CODE  (_?Timer3_Handler)
  • Timer3_ISR:
  •       USING 0        ;工作寄存器0
  • ;SETB P20;
  •       CLR EA      ;禁止中断嵌套
  •       PUSHALL            ;现场保护
  •       LCALL _?Timer3_Handler
  •       POPALL      ;恢复现场   
  • ;CLR   P20
  •       SETB  EA   ;中断函数执行完毕,重新允许中断
  •       RETI

复制代码

对于OSIntEnter 还有更优秀的做法,在中断里面直接OSIntNesting++,我之前另一帖子有讲,需要改动源码。
推荐使用OSIntEnter 函数。

七,堆栈初始化函数,对void *p_arg正确做法

    //R3、R2、R1用于传递任务参数p_arg,其中R3代表存储器类型,R2为高字节偏移,R1为低字节位移。
    *stk++ = (INT16U)p_arg & 0xFF;          // R1
    *stk++ = (INT16U)p_arg >> 8;            // R2
    *stk++ = (INT32U)p_arg >> 16;           // R3   存储器类型有code(0xFF),xdata(0x01),data(0x00),idata(0x00),pdata(0xFE)

八,统一用寄存器组0,加快出入栈速度
汇编使用 USING 0

  • ;定义压栈出栈宏
  • PUSHALL    MACRO
  •         PUSH PSW
  •         PUSH ACC
  •         PUSH B
  •         PUSH DPL
  •         PUSH DPH
  •         PUSH AR0
  •         PUSH AR1
  •         PUSH AR2
  •         PUSH AR3
  •         PUSH AR4
  •         PUSH AR5
  •         PUSH AR6
  •         PUSH AR7
  •         ENDM
  • POPALL    MACRO
  •         POP  AR7
  •         POP  AR6
  •         POP  AR5
  •         POP  AR4
  •         POP  AR3
  •         POP  AR2
  •         POP  AR1
  •         POP  AR0
  •         POP  DPH
  •         POP  DPL
  •         POP  B
  •         POP  ACC
  •         POP  PSW
  •         ENDM


源码从这下载:


https://www.stcaimcu.com/forum.php?mod=viewthread&tid=3934&page=1&extra=#pid26085



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
发表于 2023-8-22 10:23:21 来自手机浏览器 | 显示全部楼层
不懂就问:这个uC-OS2-2.93.01是干什么用的?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-22 10:27:13 | 显示全部楼层

RTOS, 实时操作系统
利用 RTOS 进行任务调度,减少任务调度的压力,享受该生态的其他各种支持的兼容组件的便利性
回复 支持 反对

使用道具 举报

发表于 2023-8-22 11:18:24 | 显示全部楼层
低速低资源使用OS毫无实用价值
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-22 14:32:26 | 显示全部楼层
STC8H8K64U, STC32G12K128的高速高资源,用 RTOS 正好

www.STCAI.com
回复 支持 反对

使用道具 举报

发表于 2023-8-22 20:25:22 | 显示全部楼层
8位MCU玩OS,真的是只能玩玩……
复杂的的应用,资源不够;不复杂的应用,裸奔更方便……
回复 支持 反对

使用道具 举报

发表于 2023-8-22 20:47:22 | 显示全部楼层
51用rtos的话ram占用怎么样
回复 支持 反对

使用道具 举报

发表于 2023-8-23 08:16:03 | 显示全部楼层
没玩过OS,不好评论
回复 支持 反对

使用道具 举报

发表于 2023-8-23 13:36:33 来自手机浏览器 | 显示全部楼层
是的,我也没玩过也不会玩,不好评论。
回复 支持 反对

使用道具 举报

发表于 2023-8-23 17:11:11 | 显示全部楼层
漂亮!!!大力支持,回去试试
回复 支持 反对

使用道具 举报

发表于 2023-8-23 19:36:29 来自手机浏览器 | 显示全部楼层
8k64效果怎么样?
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-2 06:30 , Processed in 0.249600 second(s), 11 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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