杨为民 发表于 2024-5-11 16:29:08

tzz1983 发表于 2024-5-11 15:37
可以这样认为,其实大家都知道怎么回事。
如果说,在高优中断里不调用OS服务,基本上都是零改就能实现的 ...

(1)回答正确,你最近给出的作品 uC/OS-II@STC8H确实是一个“能在高优先级零延迟中断”中调用系统服务的RTOS。祝贺你的这个作品成为本论坛“零中断延迟”RTOS的第二匹黑马。
(2)这是你的测试程序中的测试中断ISR:
void Timer3_ISR_Handler (void) interrupt 19{
        T4T3M &= ~0x08;   //定时器3停止计数
    IE2 &= ~0X20;       //关闭定时器3中断   
    P00 = ~P00;   
    P01 = 1;            //开始唤醒任务
    OSTaskResume_FROM_ISR(APP_CFG_START_TASK_PRIO);
}
其中这个在中断里的语句“OSTaskResume_FROM_ISR(APP_CFG_START_TASK_PRIO);”就是调用系统服务功能实现唤醒最高优先级的任务的,这就是赤裸裸的“中断里”调用呀。

(3)为了实现功能,你特地在uC/OS-II的系统内核文件“os_task.c”里新增加了这个在中断内使用的系统服务
INT8UOSTaskResume_FROM_ISR (INT8U prio)FunctionProperties
{
    OS_TCB    *ptcb;
#if OS_CRITICAL_METHOD == 3u                                  /* Storage for CPU status register       */
    OS_CPU_SRcpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0u
    if (prio >= OS_LOWEST_PRIO) {                           /* Make sure task priority is valid      */
      return (OS_ERR_PRIO_INVALID);
    }
#endif
    OS_ENTER_CRITICAL();
    ptcb = OSTCBPrioTbl;
    if (ptcb == (OS_TCB *)0) {                              /* Task to suspend must exist            */
      OS_EXIT_CRITICAL();
      return (OS_ERR_TASK_RESUME_PRIO);
    }
    if (ptcb == OS_TCB_RESERVED) {                            /* See if assigned to Mutex            */
      OS_EXIT_CRITICAL();
      return (OS_ERR_TASK_NOT_EXIST);
    }
    if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) { /* Task must be suspended                */
      ptcb->OSTCBStat &= (INT8U)~(INT8U)OS_STAT_SUSPEND;    /* Remove suspension                     */
      if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) == OS_STAT_RDY) { /* See if task is now ready         */
            if (ptcb->OSTCBDly == 0u) {
                OSRdyGrp               |= ptcb->OSTCBBitY;    /* Yes, Make task ready to run         */
                OSRdyTbl |= ptcb->OSTCBBitX;
                OS_TRACE_TASK_READY(ptcb);
                OS_EXIT_CRITICAL();
                if (OSRunning == OS_TRUE) {
                  OS_TRACE_TASK_RESUME(ptcb);
                  OS_Sched_FROM_ISR();                      /* Find new highest priority task      */
                }
            } else {
                OS_EXIT_CRITICAL();
            }
      } else {                                              /* Must be pending on event            */
            OS_EXIT_CRITICAL();
      }
      return (OS_ERR_NONE);
    }
    OS_EXIT_CRITICAL();
    return (OS_ERR_TASK_NOT_SUSPENDED);
}
其中调用的是中断内的任务切换函数“OS_Sched_FROM_ISR(); ”,这就是赤裸裸的从内核开始了“在中断内进行系统功能的调用”的设计。

(4)并且,你增加的不是一个,而是新增加了一组供中断内调用的常用的系统功能服务:
* 针对所有需要中断调用并且会引起任务切换的OS服务,移植版本提供了额外的中断调用版本,以下是新增中断服务的函数.
INT8UOSTaskSuspend_FROM_ISR (INT8U prio)FunctionProperties;
INT8UOSTaskResume_FROM_ISR (INT8U prio)FunctionProperties;
INT8UOSTaskChangePrio_FROM_ISR (INT8Uoldprio,INT8Unewprio)FunctionProperties;
INT8UOSTimeDlyResume_FROM_ISR (INT8U prio)FunctionProperties;
INT8UOSSemPendAbort_FROM_ISR (OS_EVENT *pevent, INT8U opt, INT8U *perr)FunctionProperties;
INT8UOSSemPost_FROM_ISR (OS_EVENT *pevent)FunctionProperties;
OS_FLAGSOSFlagPost_FROM_ISR (OS_FLAG_GRP*pgrp, OS_FLAGS flags, INT8U opt, INT8U *perr)FunctionProperties;
INT8UOSMboxPostOpt_FROM_ISR (OS_EVENT*pevent, void *pmsg, INT8U opt)FunctionProperties;
INT8UOSMboxPost_FROM_ISR (OS_EVENT*pevent, void *pmsg)FunctionProperties;
INT8UOSMboxPendAbort_FROM_ISR (OS_EVENT*pevent, INT8U opt, INT8U *perr)FunctionProperties;
INT8UOSQPendAbort_FROM_ISR (OS_EVENT*pevent, INT8U opt, INT8U *perr)FunctionProperties;
INT8UOSQPost_FROM_ISR (OS_EVENT*pevent, void *pmsg)FunctionProperties;
INT8UOSQPostFront_FROM_ISR (OS_EVENT*pevent, void *pmsg)FunctionProperties;
INT8UOSQPostOpt_FROM_ISR (OS_EVENT*pevent, void *pmsg, INT8U opt)FunctionProperties;

见你的主贴的19楼介绍:《自己用的 uC/OS-II@STC8H, 51核移植版本》
(https://www.stcaimcu.com/forum.php?mod=viewthread&tid=8195&extra=page%3D1&page=1)


(5)经过这些操作,你已经成功地将uC/OS-II移植到STC8H单片机上(本不具备RTX4/5需要的片上中断条件),必将会成为一个比CosyOS-II还强的“零中断延迟”的STC单片机RTOS。
强就强在uC/OS-II是一个主流的单片机RTOS,可以移植很多开源库在上面,比如本尊在本论坛已经移植的“uGFX”图形接口和“znFAT”文件系统,这些是CosyOS-II一时半会难以做到的。


tzz1983 发表于 2024-5-11 16:37:11

杨为民 发表于 2024-5-11 16:29
(1)回答正确,你最近给出的作品 uC/OS-II@STC8H确实是一个“能在高优先级零延迟中断”中调用系统服务的 ...

杨老师,我补充一下,不是 “新增加了一组供中断内调用的常用的系统功能服务”,

是 所有需要中断调用并且会引起任务切换的OS服务.

这个移植版本不存在功能裁剪,所有uC/OS-II的功能都可用,并且针对51核IDATA的栈还增加了一个检查功能。



fanxsp 发表于 2024-5-11 16:49:51

本帖最后由 fanxsp 于 2024-5-11 16:55 编辑

tzz1983 发表于 2024-5-11 16:37
杨老师,我补充一下,不是 “新增加了一组供中断内调用的常用的系统功能服务”,

是 所有需要中断调用 ...
你的堆栈检查,是用什么方法?我采用最简单的,就是把堆栈数据通过回调函数处理,回调函数可以直接把堆栈数据发往串口,我们自己直接分析堆栈数据,连续为0的区域,就是空余的堆栈空间。
如果是仿真运行,就停止运行,然后直接查看堆栈数据。

tzz1983 发表于 2024-5-11 16:54:39

fanxsp 发表于 2024-5-11 16:49
你的堆栈检查,是用什么方法?我采用最简单的,就是把堆栈数据通过回调函数处理,回调函数可以直接把堆栈 ...

我把代码贴出来吧,省得你下载了{:smile:}

/*-----------------------------------------------------------*
* idata公共运行栈检查, 检查方法是查找栈中连续0最大的块
* 此函数在统计任务中自动调用,也可主动调用. 没有返回值,通过全局变量回传数据.
* 使用此功能时,必须在STARTUP.A51中清零所有的IDATA.
* 有多种可能导致检查的结果不准确
* 当剩余的栈容量小余栈正常数据中连续的0时,将得到错误的结果.
* 极端的可能是正常的栈数据中含有大量的连续0
* 所以,只有在栈剩余量较大时才有参考意义
* 虽然结果可能不准确,但是,当栈剩余量较大时仍有参考意义.
*-----------------------------------------------------------*/
void IDStkChk(void)FunctionProperties
{
    INT8U addr=ID_CH_Start+1,maxFree=0,cnt=0;
   
    for(;addr;addr++){
      if( ((u8 idata *)0) == 0){
            cnt++;
      }else{
            maxFree = (cnt>maxFree)? cnt:maxFree;
            cnt=0;
      }
    }
    maxFree = (cnt>maxFree)? cnt:maxFree;
   
    if(maxFree<ID_STK_Free){
      ID_STK_Free = maxFree;
      ID_STK_Used = ID_STK_Size-ID_STK_Free;
    }
}

tzz1983 发表于 2024-5-11 16:55:21

本帖最后由 tzz1983 于 2024-5-11 17:01 编辑

fanxsp 发表于 2024-5-11 16:49
你的堆栈检查,是用什么方法?我采用最简单的,就是把堆栈数据通过回调函数处理,回调函数可以直接把堆栈 ...
我的方法和你的方法基本一致, 我只是检查一个大概,作为参考。并不是很准确, 但也无伤大雅。
这个功能只会在调试代码时用到,基本上是为了方便程序员查看,而不是要一个准确的结果

fanxsp 发表于 2024-5-11 17:02:13

tzz1983 发表于 2024-5-11 16:54
我把代码贴出来吧,省得你下载了

/*-----------------------------------------------------------*


ucos 本身好象也是这个办法,我的情况是有多个堆栈区,想来想去,没有什么好办法,就采用最简单的,把堆栈数据上传,人工判断。

CosyOS 发表于 2024-5-12 13:33:24

本帖最后由 CosyOS 于 2024-5-12 14:17 编辑

首先,我从未说过只有 CosyOS 才能实现 “零中断延迟” 。
而且,我相信,只要进行适当调整,很多 RTOS 都可以实现 “零中断延迟”。
只是 实现 “零中断延迟” 的技术手段不同,效果也不尽相同。

对于 坛友 tzz1983 的作品 我不慎了解,不敢妄加评论,
但只想 问问他本尊,他的这个测试程序中,定时器3中断,
void Timer3_ISR_Handler (void) interrupt 19{
    T4T3M &= ~0x08;   //定时器3停止计数
    IE2 &= ~0X20;       //关闭定时器3中断   
    P00 = ~P00;   
    P01 = 1;            //开始唤醒任务
    OSTaskResume_FROM_ISR(APP_CFG_START_TASK_PRIO);
}
是否真的实现了 “零中断延迟” ?

如果确实实现了 “零中断延迟”,那么,
INT8UOSTaskResume_FROM_ISR (INT8U prio)FunctionProperties
中的 “OS_ENTER_CRITICAL();”,
是否会影响其它高优先级中断的实时响应 ?
进而导致其它高优先级中断无法实现 “零中断延迟” ?

如果该定时器3中断未能实现 “零中断延迟”,
那么 其它高优先级中断 是否可以实现 “零中断延迟” ?是否支持随意调用服务?

请 坛友 tzz1983 把你的先进技术也简单介绍一下,
也让 大家 都能从中受益 !




CosyOS 发表于 2024-5-12 14:20:55

本帖最后由 CosyOS 于 2024-5-12 14:25 编辑

CosyOS 发表于 2024-5-12 13:33
首先,我从未说过只有 CosyOS 才能实现 “零中断延迟” 。
而且,我相信,只要进行适当调整,很多 RTOS 都 ...
没人和你较真,但需要通过你,没你不行啊!
我也不想和任何人较真。

tzz1983 发表于 2024-5-12 14:24:08

CosyOS 发表于 2024-5-12 14:20
没人和你较真,但需要通过你,没你不行啊!

那你自己知道就行了,我相信不只你知道. 你自己的问题都不正面解决,
我这里没有问题, 我也没有乱说话


tzz1983 发表于 2024-5-12 14:36:35

本帖最后由 tzz1983 于 2024-5-12 14:39 编辑

CosyOS 发表于 2024-5-12 14:20
没人和你较真,但需要通过你,没你不行啊!
我也不想和任何人较真。


好吧, 正面回答你,要实现0延时, 需要改一下进入临界区的宏,
把关闭总中断改为只关闭一部分中断, 未被临界区关闭的中断才可以实现零中断延迟,
作为代价, 不可以调用OS服务, 并且进入临界区的宏也会变得复杂一点.

虽然最终可以实现这个功能, 但我个人认为使用uC/OS-II 时是没有必要这样做的
页: 3 4 5 6 7 8 9 10 11 12 [13] 14 15
查看完整版本: 单片机RTOS实时响应时间排行榜重大宣布:STC32G12K128单片机 全面碾压 STM32F103C