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

uC/OS-II @ STC32G 移植

[复制链接]

该用户从未签到

61

主题

622

回帖

1万

积分

荣誉版主

积分
10818
发表于 2023-11-1 19:15:29 | 显示全部楼层
本帖最后由 杨为民 于 2023-11-1 19:26 编辑


哥们,我从教师的角度来解释一下,看看能不能解答你的疑问。
(1)手册上已经给出了中断响应的流程图:

中断响应.jpg

中断响应完成后就进入中断服务程序,没有其他的过程。
(2)而你的图中“第一条指令”就是属于“中断服务程序”。
(3)如果按你画的位置会响应高级中断,那么在手册上的流程图在“中断响应”与“中断服务过程”之间就必须要加上一系列的流程,比如检测有没有新的“中断申请”的过程和判断新的中断的与当前中断的优先级谁高的判断,然后还要有判断的流程分支。然而手册流程图中没有这些,这已经说明没有你画的那个问号过程了。这就是“已经在去响应中断,并且是在去中断向量入口地址的途中】,就不可能被打断”给你答复的意思
(4)然后进入中断服务程序,开始执行你图中的第一条指令。按照流程,执行指令的第一步是获取指令,然后的流程在手册上给出了:
第一条指令.jpg

“其中获取下一条指令”是指获取ISR的第二条指令,“解码当前指令”是指解码ISR的第一条指令,这两个过程的定语很清楚“当前指令”->第一条指令,“下一条指令”->第二条指令
(5)在解码当前指令的过程后,无论下面的流程分支走哪一路,都是“执行完成当前指令”->肯定执行你图中的“第一条指令”
至于走哪一条路,取决于你的第一条指令是你说的“关中断指令或 OSNesting++”。
(6)上面流程图中在“获取下一条指令”与“解码当前指令”之间表明了“产生了中断请求”(当然是一个优先级更高的满足响应条件的请求),说明STC单片机的中断响应机制在这里开始响应“新中断”,何时才能开始“新中断的中断响应”,请仔细地按照流程图走到底,可能是在执行完第二条ISR指令后(STC32G),也可能是在执行完多条ISR指令之后,具体的要看这些指令是不是特色指令。

(7)对于中断嵌套而言,响应新的高优先级中断请求,是发生在当前的中断服务程序ISR中,这就是“去到中断服务程序后,就是高中断优先级打断低中断优先级的事”给你答复的意思。
(8)因为在ISR中更高优先级的中断响应在不止一条指令之后,所以我才说“ISR的第一条指令”和特殊指令“RETI”之后的第一条指令在发生中断嵌套时也肯定会被执行,在此基础才给出我的“利用变量跟踪中断嵌套”进行中断嵌套保护的方案。



回复 支持 反对 送花

使用道具 举报

  • TA的每日心情
    奋斗
    3 小时前
  • 签到天数: 154 天

    [LV.7]常住居民III

    1

    主题

    96

    回帖

    453

    积分

    中级会员

    积分
    453
    发表于 2023-11-1 22:00:06 | 显示全部楼层
    本帖最后由 fanxsp 于 2023-11-1 22:02 编辑
    杨为民 发表于 2023-11-1 19:15
    哥们,我从教师的角度来解释一下,看看能不能解答你的疑问。
    (1)手册上已经给出了中断响应的流程图:

    论坛里关于这个问题的各种论讨、分析我也看了,我是希望厂家的芯片设计人员给出明确答复,这样就可以一锤定音了。
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    19

    主题

    519

    回帖

    1642

    积分

    荣誉版主

    积分
    1642
     楼主| 发表于 2023-11-2 09:18:09 | 显示全部楼层
    本帖最后由 tzz1983 于 2023-11-2 09:21 编辑

    更新通告:

    自2023/10/20发布后有两次更新,之前没有通告,现在补告

    更新内容如下:

    定稿:                 V1.00    2023/10/20

    优化版本:        V1.01        2023/10/23
    修改内容:文档os_cpu.h
    原:
    53  #define  OS_ENTER_CRITICAL()  {cpu_sr=EA;EA=0;}     /* 直接用宏插入C语言, 省去调用过程. 无需使用JBC指令,避免跳转,可加速. 不支持也没必要在同一函数内嵌套进入临界区*/
    54  #define  OS_EXIT_CRITICAL()   {EA=cpu_sr;}          /* 直接用宏插入C语言, 省去调用过程*/
    修改后:
    53        #define  OS_ENTER_CRITICAL()  {cpu_sr=IE;EA=0;}     /* 直接用宏插入C语言, 省去调用过程. 无需使用JBC指令,避免跳转,可加速. 不支持也没必要在同一函数内嵌套进入临界区*/
    54        #define  OS_EXIT_CRITICAL()   {EA=cpu_sr&0X80;}     /* 直接用宏插入C语言, 省去调用过程*/


    代码补全:        V1.02        2023/11/2
    修改内容:文档os_cpu_a.c
    第118行新增:
    118                PendSv_ClearFlag(); //在读取OS核心参数前 清除PendSv中断标志。

    工程项目内新增版本 更新记录 和 使用说明 TXT文档

    压缩包内新增两个比较实用的UCOSII网络PDF教程,分别为 《UCOS-ii学习教程(邵贝贝)》  《uCOS_II_2.52源码中文译注(钟常慰).pdf》 方便初学者学习UCOS原理。

    回复 支持 反对 送花

    使用道具 举报

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

    [LV.7]常住居民III

    5

    主题

    475

    回帖

    2076

    积分

    荣誉版主

    积分
    2076
    发表于 2023-11-2 11:12:53 | 显示全部楼层
    杨为民 发表于 2023-11-1 06:45
    送佛送到底,你的队列都已经研究过FIFO和LIFO了,建议在单片机RTOS中你再采用标准操作系统理论中的“高优 ...

    首先,感谢杨老师的建议和讲解,我会进一步思考相关问题。
    我现在的考虑是,中断挂起服务缓存队列,缓存的是用户在中断中调用的服务,也就是说提出服务的主体是“中断”,而不是“任务”,

    如果按优先级排队处理的话,也应该按中断优先级排队处理。
    1、如果按中断优先级排队处理的话,势必会造成很多额外的麻烦。
         如需要在API中输入中断优先级号,当中断优先级调整后,还需要再次修改API参数,如果用户忘记了修改呢?。
    2、即使按服务的操作对象(任务)的优先级排队处理,但对于大量的服务应用,其操作对象也并非是任务,
         如Give信号量、全局变量写访问、自运算,发送飞信、邮件、消息等皆是如此。
    所以,当前 CosyOS-II 采用了 FIFO,以确保服务执行时序的正确。


    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    19

    主题

    519

    回帖

    1642

    积分

    荣誉版主

    积分
    1642
     楼主| 发表于 2023-11-2 13:33:52 | 显示全部楼层
    本帖最后由 tzz1983 于 2023-11-2 13:45 编辑

    又发现一个BUG,好尴尬呀,今天要更新两次代码了。。这是一个真BUG,不是优化,必须第一时间公布

    BUG描述:
    1.由于本人为防范RETI强迫指令往后执行破坏等待事件,之前在任务切换函数OS_Sched()内加了一条语句:while(PendSv_flag());
    2.深度中断嵌套时,OSIntNesting来不及加,可导至OSIntNesting值可能会和实际嵌套层数不符,正常情况下用中断切换任务的UCOS不会因此发生BUG.
    3.UCOS有许多OS服务不分中断级和任务级,比如: OSSemPost(), 这个服务可以任务级调用,也可以中断级调用,OS是通过OSIntNesting值来判断是否为中断调用,然后做相应的处理.

    以上3点分开来看任何一点都是没有问题的。但是:
    组合以上3点,比如在ISR中调用OSSemPost(), OSSemPost()又间接调用了OS_Sched(), 正常情况时,OS_Sched()通过OSIntNesting值判断出此时为中断例程,不会做任何动作,不会出错。
    但是深度中断嵌套时, OSIntNesting值可能会和实际嵌套层数不符,OSIntNesting值可被OSIntExit削减为0,同时置位PendSv_flag,发布RETI时却没有彻底退出中断,只是返回到了下一级中断里。
    这造成另一种可能,下一级中断在调用OS服务并间接调用OS_Sched()时,PendSv_flag已经被设置,如此一来则 while(PendSv_flag())陷入死循环,因为此时无法响应最低级的PendSv。

    尴尬啊,实际证明上一次BUG修复的不彻底! 不过大家请放心,移植版如果出问题一般都出在移植代码上。但是移植部分代码量小,吃透以后还是可以放心用的。
    作为这个移植版本的先行试验田,我现在已用于实际产品。有问题一定会提前通知大家。

    修复公告:

    BUG修复:        V1.03        2023/11/2
    修改内容:文档 os_core.c
    新增代码:
    1709    INT8U sw = 0u;  //声明变量
    1729    sw = 1u;        //可以确认此时不在中断例程中,PendSv中断标志是任务切换需求设置的
    原:
    1734    while(PendSv_flag());                //等待任务切换,切换前不会继续执行代码
    修改后:
    1734    if(sw)while(PendSv_flag());   //等待任务切换,切换前不会继续执行代码

    修复结果截图:
    捕获.JPG

    代码已更新

    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    19

    主题

    519

    回帖

    1642

    积分

    荣誉版主

    积分
    1642
     楼主| 发表于 2023-11-3 08:40:36 | 显示全部楼层
    本帖最后由 tzz1983 于 2023-11-3 08:48 编辑

    昨天发现BUG之后,更新比较仓促,还是没有彻底解决问题(并发中断时OS_Sched()函数仍可能陷入死循环),今天再次修复,都不好意思贴代码了,详情见项目代码,代码已更新
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    3 小时前
  • 签到天数: 154 天

    [LV.7]常住居民III

    1

    主题

    96

    回帖

    453

    积分

    中级会员

    积分
    453
    发表于 2023-11-3 10:09:47 | 显示全部楼层
    本帖最后由 fanxsp 于 2023-11-3 10:54 编辑
    tzz1983 发表于 2023-11-3 08:40
    昨天发现BUG之后,更新比较仓促,还是没有彻底解决问题(并发中断时OS_Sched()函数仍可能陷入死循环),今 ...

      不用不好意思,很正常,很多问题只能在实际的项目中才会发现,设计几个简单例子进行测试,只能证明系统能跑起来,很多问题还是发现不了的。我的系统,现在是这样处理:1. 在中断中触发的任务切换,改在PendSV中断进行.  2. 在任务中调用系统服务进行任务切换,用一个单独函数进行切换,不是触发PendSV中断。3. 这两种切换方式的公共部份做成一个函数,供两边调用。 4. 完全取消中断嵌套跟踪。5. 同一个系统服务,都有任务级和中断级两个版本,中断中调用中断级的版本,任务中调用任务级的版本.
        我手头只有一块赛元8547的开发板,现在是在这块板上调试的。 我准备改用STC的板来调试。这样也可以测试一下你们移植的版本。


    回复 支持 1 反对 0 送花

    使用道具 举报

    该用户从未签到

    19

    主题

    519

    回帖

    1642

    积分

    荣誉版主

    积分
    1642
     楼主| 发表于 2023-11-3 10:50:32 | 显示全部楼层
    本帖最后由 tzz1983 于 2023-11-3 10:52 编辑
    fanxsp 发表于 2023-11-3 10:09
    不用不好意思,很正常,很多问题只能在实际的项目中才会发现,设计几个简单例子进行测试,只能证明系统能 ...

    我昨天也想到任务级切换用代码实现,这个想法是好的。
    但是我做的是移植,改动太大不合适的,也怕一不留神出新问题,暂时做到这样吧。
    期盼早点看到你的代码
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    19

    主题

    519

    回帖

    1642

    积分

    荣誉版主

    积分
    1642
     楼主| 发表于 2023-11-3 11:19:53 | 显示全部楼层
    fanxsp 发表于 2023-11-3 10:09
    不用不好意思,很正常,很多问题只能在实际的项目中才会发现,设计几个简单例子进行测试,只能证明系统 ...

    是51内核吧,你做的OS能避开“搬栈”吗? 有没有办法 避开“搬栈”? 这个点我想了好久都没想到办法避开。 另外就是编绎器重入处理套路用着不顺手,大模式下默认XDATA局部变量,生成的代码,效率低,代码长,这些也是不小的障碍。
    对于51内核,我一直都是放弃OS的,不知道你现在是不是有了好的办法.
    过些天也去看看CosyOS的作品,看看他是怎么操作的,大家互相借鉴一下。

    点评

    对于一个用51做的大型项目来说,我认为内存model采用大模式是人性化的、同时也完全兼顾性能的方法。 因为一个稍大型的项目,往往要定义很多的全局变量、很多的函数(局部变量), 当采用大模式时,只需把少量需要高  详情 回复 发表于 2023-11-6 14:48
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    3 小时前
  • 签到天数: 154 天

    [LV.7]常住居民III

    1

    主题

    96

    回帖

    453

    积分

    中级会员

    积分
    453
    发表于 2023-11-3 11:28:32 | 显示全部楼层
    本帖最后由 fanxsp 于 2023-11-3 11:33 编辑
    tzz1983 发表于 2023-11-3 11:19
    赛元8547 是51内核吧,你做的OS能避开“搬栈”吗? 有没有办法 避开“搬栈”? 这个点我想了好久都没想到 ...

    “搬栈” ,这个肯定要,51核免不了的,但没有使用Keil  c51  的重入函数. 首先OS内核的代码和占用的RAM,要比较小,才有实用价值,性能和功能方面只能进行折中,尽量做到最好。

    点评

    越期待了,哈哈  发表于 2023-11-3 11:32
    回复 支持 1 反对 0 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-4-30 11:19 , Processed in 0.071368 second(s), 67 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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