找回密码
 立即注册
查看: 2804|回复: 83

最新版本uC-OS2-2.93.01已移植到STC32G上,请帮忙查错

[复制链接]

该用户从未签到

11

主题

329

回帖

872

积分

荣誉版主

积分
872
发表于 2023-9-18 00:33:59 | 显示全部楼层 |阅读模式
uCOS-II-2.93.01 for STC32G12K128 请帮忙查错
本移植参考STC论坛网友tzz1983的移植方案,使用定时器4模拟软件中断PendSv
一,使用注意:
本移植整个工程统一使用寄存器组0,用户不能修改寄存器组。寄存器组1,2,3共24字节用于data/edata区。
中断函数执行完毕,执行RETI返回前不建议关闭中断总开关。如果关闭一般认为是程序员的Bug。
系统启动前不能开中断,不然OSIntNesting一直会++。
二,void OSStartHighRdy(void)行数提供了3种方法切换到第一个任务。
  1. <font size="3">//方法1:使用ERET返回,返回前需要从新调整堆栈的内容,由于任务第一次运行,R4,R5,R6 给任何值都没关系。
  2.     //读取任务的SP
  3.     __asm   { MOV   DR4,OSTCBCur    }   
  4.     __asm   { MOV   WR2,@WR6+0x2    }   
  5.     __asm   { MOV   DR60,DR0        }
  6.    
  7.     //寄存器出栈
  8.     __asm   { POP   PSW     }               
  9.     __asm   { POP   DR0     }               
  10.     __asm   { POP   DR4     }               
  11.     __asm   { POP   DR8     }               
  12.     __asm   { POP   DR12    }               
  13.     __asm   { POP   DR16    }               
  14.     __asm   { POP   DR20    }               
  15.     __asm   { POP   DR24    }               
  16.     __asm   { POP   DR28    }               
  17.     __asm   { POP   DR56    }               
  18.     //PC和PSW1出栈
  19.     __asm   { POP   R4      }               
  20.     __asm   { POP   R6      }               
  21.     __asm   { POP   R5      }               
  22.     __asm   { POP   PSW1    }
  23.    
  24.     //把返回地址格式做成ERET的返回格试
  25.     __asm   { PUSH  R5    }               
  26.     __asm   { PUSH  R4    }               
  27.     __asm   { PUSH  R6    }
  28.     __asm   { SETB  EA      }
  29.     //用ERET指令转移到任务中去, 0XAA是ERET指令的编码
  30.     __asm   { DB    0AAH    }     
  31. //方法2:使用RETI返回,由于系统刚开始,其他中断都没有开始触发。用RETI完全没问题的。   
  32.    
  33.          //读取任务的SP
  34.     __asm   { MOV   DR4,OSTCBCur    }   
  35.     __asm   { MOV   WR2,@WR6+0x2    }   
  36.     __asm   { MOV   DR60,DR0        }
  37.    
  38.     //寄存器出栈
  39.     __asm   { POP   PSW     }               
  40.     __asm   { POP   DR0     }               
  41.     __asm   { POP   DR4     }               
  42.     __asm   { POP   DR8     }               
  43.     __asm   { POP   DR12    }               
  44.     __asm   { POP   DR16    }               
  45.     __asm   { POP   DR20    }               
  46.     __asm   { POP   DR24    }               
  47.     __asm   { POP   DR28    }               
  48.     __asm   { POP   DR56    }               
  49.     __asm   { SETB  EA      }
  50.     __asm   { RETI    }
  51. //方法3:使用PendSvIsr中断切换到第一个任务
  52. //巧妙指向DR0内存位置。SP保存到任务控制块的时候,实际操作是MOV   DR0,DR0,也就是DR0值不变     
  53.     OSTCBCur      = (OS_TCB *)0;   
  54.     PendSv_GenerateSWInterrupt();
  55.     EA = 1;
  56.     while(1);</font>
复制代码


三,优化了OS_CPU_PendSVHandler中断函数
  1. <font size="3">void OS_CPU_PendSVHandler( void )
  2. {
  3.     //函数入口标号,中断跳转到入口标号,解决huge和large存储模式不一样函数名字不一样的问题。
  4.     __asm   {OS_CPU_PendSVHandler_00:  }
  5.     //寄存器入栈
  6.     __asm   { PUSH  DR56    }               
  7.     __asm   { PUSH  DR28    }               
  8.     __asm   { PUSH  DR24    }               
  9.     __asm   { PUSH  DR20    }               
  10.     __asm   { PUSH  DR16    }               
  11.     __asm   { PUSH  DR12    }               
  12.     __asm   { PUSH  DR8     }               
  13.     __asm   { PUSH  DR4     }               
  14.     __asm   { PUSH  DR0     }               
  15.     __asm   { PUSH  PSW     }
  16.    
  17.    
  18.     //SP保存到任务控制块                        
  19.     __asm   { MOV   DR0,DR60 }           
  20.     __asm   { MOV   DR4,OSTCBCur }   
  21.     __asm   { MOV   @WR6+0x2,WR2 }
  22.    
  23.    
  24.     //保存并关EA  ,其实EA=0问题也不大,如果中断返回的时候EA=0,这个很明显是程序员的bug
  25.     __asm   { SETB  C                }
  26.     __asm   { JBC   EA,PendSvIsr_01  }
  27.     __asm   { CLR   C                }
  28.     __asm   { PendSvIsr_01:          }
  29.     __asm   { PUSH  PSW              }
  30.     OSTaskSwHook();
  31.     OSPrioCur = OSPrioHighRdy;
  32.     OSTCBCur  = OSTCBHighRdy;
  33.     //恢复EA
  34.     __asm{  POP   PSW       }
  35.     __asm{   MOV   EA,C     }
  36.    
  37.     //读取任务的SP
  38. // ;OSTCBCur  = OSTCBHighRdy; 的汇编
  39. //        MOV      DR4,OSTCBHighRdy
  40. //        MOV      OSTCBCur,DR4
  41. //说明DR4的值已经是OSTCBCur,下面这条可以屏蔽
  42. //    __asm   { MOV   DR4,OSTCBCur    }   
  43.     __asm   { MOV   WR2,@WR6+0x2    }   
  44.     __asm   { MOV   DR60,DR0        }
  45.    
  46.     //寄存器出栈
  47.     __asm   { POP   PSW     }               
  48.     __asm   { POP   DR0     }               
  49.     __asm   { POP   DR4     }               
  50.     __asm   { POP   DR8     }               
  51.     __asm   { POP   DR12    }               
  52.     __asm   { POP   DR16    }               
  53.     __asm   { POP   DR20    }               
  54.     __asm   { POP   DR24    }               
  55.     __asm   { POP   DR28    }               
  56.     __asm   { POP   DR56    }               
  57.     //中断返回
  58.     __asm   { RETI }           
  59. }</font>
复制代码


四,函数入口标号,中断跳转到入口标号,解决huge和large存储模式不同,函数名字不一样的问题。
/*-----------------------------------------------------------*
PendSv 向量入口引导
*-----------------------------------------------------------*/


__asm   {OS_CPU_PendSVHandler_00:  }


__asm   { CSEG    AT  PendSv_EntryAddress  }
__asm   { JMP     OS_CPU_PendSVHandler_00  }




附件是最新版本的源码:


uCOSII-STC32G-V1.02.zip

146.56 KB, 下载次数: 613

ucos2源码

回复 送花

使用道具 举报

该用户从未签到

11

主题

329

回帖

872

积分

荣誉版主

积分
872
 楼主| 发表于 2023-9-18 08:26:56 | 显示全部楼层
截图202309180818322309.jpg

需要设置全局可重入。昨天最后整理新建了工程,忘记设置了。
回复 支持 反对 送花

使用道具 举报

该用户从未签到

19

主题

519

回帖

1642

积分

荣誉版主

积分
1642
发表于 2023-9-18 09:06:00 | 显示全部楼层
熊哥威武! 真是行家一出手,就知有没有!

那个第一次切换任务用中断的方法, 有些烧脑啊, 哈哈, 牛B的, 我在脑海里转了好几圈才转出来, 就是第一次切换没有保存上下文呗, 厉害!
给熊哥几个建议:
1: 切换任务中有三个C语句, 直接全部用汇编替换, 一是便于理解, 二是你在文中有提到, C转汇编时"说明DR4的值已经是OSTCBCur" , 但这里有个隐含的条件是, C编绎一定会这么干! (个人认为编译权并不在我们手里, 万一它以后为DR8了呢,汇合编程还是小心为上).
2: 临界段模式2中 "#define OS_EXIT_CRITICAL() do{ _pop_ (ACC);IE |= ACC;}while(0) "  此处个人理解是有BUG的. 此处在将C代码文档中直接插入插入C代码, 访问ACC等同于直接访问内部寄存器A,会不会破坏原文的上下文.并且貌似251这编译也不支持 _pop_ ().
3:临界段模式4过于烦锁, 为了让读者少烧脑, 是不是可以却除

点评

问题1,之前想过,其实我都都弄好了,只保留钩子函数。后来想还是不要改动你太多,毕竟你的成果。 需要在前面把变量调用下才能通过编译。 if(OSPrioCur); if(OSPrioHighRdy); if(OSTCBCur); if(OSTCBHighRdy); 问题2  详情 回复 发表于 2023-9-18 09:18
回复 支持 反对 送花

使用道具 举报

该用户从未签到

11

主题

329

回帖

872

积分

荣誉版主

积分
872
 楼主| 发表于 2023-9-18 09:18:18 | 显示全部楼层
tzz1983 发表于 2023-9-18 09:06
熊哥威武! 真是行家一出手,就知有没有!

那个第一次切换任务用中断的方法, 有些烧脑啊, 哈哈, 牛B的, 我在 ...

问题1,之前想过,其实我都都弄好了,只保留钩子函数。后来想还是不要改动你太多,毕竟你的成果。
需要在前面把变量调用下才能通过编译。
if(OSPrioCur);
if(OSPrioHighRdy);
if(OSTCBCur);
if(OSTCBHighRdy);
问题2,忘记测试了,C251确实不支持_push_和_pop_,代码思路没有问题的,在STC8验证过的。251有堆栈寻址,貌似不适用
问题3,这个杨老师认为最好的方法,还是保留吧。喜欢的自己选。
回复 支持 反对 送花

使用道具 举报

该用户从未签到

19

主题

519

回帖

1642

积分

荣誉版主

积分
1642
发表于 2023-9-18 09:31:12 | 显示全部楼层
熊仔 发表于 2023-9-18 09:18
问题1,之前想过,其实我都都弄好了,只保留钩子函数。后来想还是不要改动你太多,毕竟你的成果。
需要在 ...

嗯 ,是的, 我移植时也遇到不能编绎, 用一个无效语句来调用一下, 后来想想直接C不影响结果, 就直接用C了, 但现在你用到了DR4.
另外138警告去处理一下, 这个更改只是为了迎和编绎器, 不算是对原代码的冒犯, 程序员肯定不喜欢warning, 屏蔽太多又不好, 不屏蔽又影响心情
回复 支持 反对 送花

使用道具 举报

该用户从未签到

11

主题

329

回帖

872

积分

荣誉版主

积分
872
 楼主| 发表于 2023-9-18 10:49:44 | 显示全部楼层

1,138警告,早上的更新的已经去掉了。
2,屏蔽方法2
3,void OS_CPU_PendSVHandler( void )除了OSTaskSwHook();其他使用汇编汇编


  1. void OS_CPU_PendSVHandler( void )
  2. {
  3.     //下面这样做为了能使用汇编访问变量
  4.     if(OSPrioCur);
  5.     if(OSPrioHighRdy);
  6.     if(OSTCBCur);
  7.     if(OSTCBHighRdy);
  8.     //函数入口标号,中断跳转到入口标号,解决huge和large存储模式不一样函数名字不一样的问题。
  9. __asm{
  10. OS_CPU_PendSVHandler_00:  
  11.         //寄存器入栈
  12.         PUSH  DR56
  13.         PUSH  DR28
  14.         PUSH  DR24
  15.         PUSH  DR20
  16.         PUSH  DR16
  17.         PUSH  DR12
  18.         PUSH  DR8
  19.         PUSH  DR4
  20.         PUSH  DR0
  21.         PUSH  PSW
  22.         //SP保存到任务控制块
  23.         MOV   DR0,DR60
  24.         MOV   DR4,OSTCBCur
  25.         MOV   @WR6+0x2,WR2
  26.         //保存并关EA  ,其实EA=0问题也不大,如果中断返回的时候EA=0,这个很明显是程序员的bug
  27.         SETB  C
  28.         JBC   EA,PendSvIsr_01  
  29.         CLR   C
  30. PendSvIsr_01:
  31.         PUSH  PSW
  32.     }
  33.         //这条用C方式就是解决huge和large存储模式不一样函数名字不一样的问题
  34.         OSTaskSwHook();
  35.    
  36. __asm{
  37.         //OSPrioCur = OSPrioHighRdy;
  38.         MOV      OSPrioCur,OSPrioHighRdy  ;使用data加速
  39.         //OSTCBCur  = OSTCBHighRdy;
  40.         MOV      DR4,OSTCBHighRdy
  41.         MOV      OSTCBCur,DR4
  42.         //恢复EA
  43.         POP   PSW
  44.         MOV   EA,C
  45.         //读取任务的SP
  46.         //DR4的值已经是OSTCBCur,下面这条可以屏蔽
  47.         // MOV   DR4,OSTCBCur
  48.         MOV   WR2,@WR6+0x2
  49.         MOV   DR60,DR0
  50.         //寄存器出栈
  51.         POP   PSW
  52.         POP   DR0
  53.         POP   DR4
  54.         POP   DR8
  55.         POP   DR12
  56.         POP   DR16
  57.         POP   DR20                  
  58.         POP   DR24                  
  59.         POP   DR28                  
  60.         POP   DR56                  
  61.         //中断返回
  62.         RETI            
  63.     }
  64. }
复制代码


源码先不更新。
回复 支持 反对 送花

使用道具 举报

该用户从未签到

61

主题

622

回帖

1万

积分

荣誉版主

积分
10816
发表于 2023-9-18 11:18:13 | 显示全部楼层
祝贺熊仔推出STC32G的移植版,这样“uCOSII-STC32G”、“C251-UCOSII”和“CosyOS”都采用了软中断作为任务切换的方法,可以互相借鉴和交流了

下面只等FreeRTOS软中断的移植版了,各位大侠加油!!
回复 支持 反对 送花

使用道具 举报

  • TA的每日心情
    奋斗
    昨天 15:35
  • 签到天数: 155 天

    [LV.7]常住居民III

    5

    主题

    475

    回帖

    2076

    积分

    荣誉版主

    积分
    2076
    发表于 2023-9-18 12:16:36 | 显示全部楼层
    本帖最后由 CosyOS 于 2023-9-18 12:26 编辑

    CosyOS允许用户自由选择一个未使用的硬件中断,来做为软中断使用。

    20230918_01.png

    由于CosyOS在进入任务临界区时是需要关闭系统滴答中断和这个“软中断”的,所以还需用户配置这个“软中断”的开启和关闭。



    点评

    最好选择能自动清零的中断。当然手动也行,多执行一条清零语句。 你的os代码太庞大了。之前看了一下,没理清,没坚持下去。以后有时间再拜读一下。  详情 回复 发表于 2023-9-18 13:05
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    11

    主题

    329

    回帖

    872

    积分

    荣誉版主

    积分
    872
     楼主| 发表于 2023-9-18 12:33:21 | 显示全部楼层
    *修改版本: V1.01
    *修改时间: 2023-09-18
    修改:  
            1.临界区保护方法2屏蔽
            2.void OS_CPU_PendSVHandler( void )除了OSTaskSwHook();其他使用汇编汇编
            3.解决void OSStartHighRdy(void) 函数里面的方法3,OSTaskSwHook();运行2次问题。
            4.增加putchar.c文件,char putchar(char c)重映射函数不能在全局可重入下使用。文件需要单独设置,才支持支持printf



    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    11

    主题

    329

    回帖

    872

    积分

    荣誉版主

    积分
    872
     楼主| 发表于 2023-9-18 13:05:10 来自手机 | 显示全部楼层
    CosyOS 发表于 2023-9-18 12:16
    CosyOS允许用户自由选择一个未使用的硬件中断,来做为软中断使用。



    最好选择能自动清零的中断。当然手动也行,多执行一条清零语句。

    你的os代码太庞大了。之前看了一下,没理清,没坚持下去。以后有时间再拜读一下。

    点评

    是的,能硬件自动清0的更好,然后中断清零的定义为空即可。  详情 回复 发表于 2023-9-18 13:33
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-4-30 08:32 , Processed in 0.093081 second(s), 74 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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