380091044 发表于 2024-7-12 17:31:49

UCOSII中使用OSTimeDly (INT32U ticks)延时,不进行任务切换?



UCOSII中使用OSTimeDly (INT32U ticks)延时,不进行任务切换?延时效果和delay效果一样,其代码,我也看不太懂

我感觉是这个延时函数有问题,代码如下:




voidOSTimeDly (INT32U ticks)
{

    INT8U      y;
#if OS_CRITICAL_METHOD == 3u
    OS_CPU_SRcpu_sr = 0u;
#endif


    if (OSIntNesting > 0u)
                {                  
      return;
    }

    if (OSLockNesting > 0u)
                {                  
      return;
    }
               
    if (ticks > 0u)
                {                           
      OS_ENTER_CRITICAL();
      y =OSTCBCur->OSTCBY;
      OSRdyTbl &= (OS_PRIO)~OSTCBCur->OSTCBBitX;

      OS_TRACE_TASK_SUSPENDED(OSTCBCur);
      if (OSRdyTbl == 0u)
                                {
            OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;
      }
      OSTCBCur->OSTCBDly = ticks;
      OS_TRACE_TASK_DLY(ticks);
      OS_EXIT_CRITICAL();
      OS_Sched();
    }
}

tzz1983 发表于 2024-7-12 20:33:22

本帖最后由 tzz1983 于 2024-7-12 22:52 编辑

voidOSTimeDly (INT32U ticks)
{
    INT8U      y;

#if OS_CRITICAL_METHOD == 3u   
    OS_CPU_SRcpu_sr = 0u;      //如果定义了临界模式3,则申明变量 cpu_sr
#endif


    if (OSIntNesting > 0u)   // 中断里不允许调用, 如果检测到中断调用, 直接退出
    {                  
      return;
    }

    if (OSLockNesting > 0u) //如果调度器已被锁定,( ==不允许切换任务),直接退出.
    {                  
      return;
    }

    if (ticks > 0u)   // ticks 大于 0时才有意义
         {          //以下8行, 将当前任务从就绪表中移除            
      OS_ENTER_CRITICAL();               
      y =OSTCBCur->OSTCBY;            
      OSRdyTbl &= (OS_PRIO)~OSTCBCur->OSTCBBitX;
      OS_TRACE_TASK_SUSPENDED(OSTCBCur);

      if (OSRdyTbl == 0u)
      {
            OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;
      }

      OSTCBCur->OSTCBDly = ticks;    // 延时时长保存在任务控制块
      OS_TRACE_TASK_DLY(ticks);
      OS_EXIT_CRITICAL();
      OS_Sched();               // 此句 任务切换,   
    }
}


// 谁说不进行任务切换了?
// 有3 种情况不会进行任务切切换,1:中断调用, 2. 任务锁定时调用, 3. 延时为0 .
// 以上3种情况, 皆为使用者自己的错误用法, 就是说自己的BUG, 与OS无关
// 正常情况下, 调用OSTimeDly()一定会发生任务切换


hsrzq 发表于 2024-7-13 10:38:04

你觉得的不对。
你觉得的不对。
你觉得的不对。
这可是通过了FAA安全认证的代码,
可以用在航空航天、医疗器械等性命攸关的领域。
即使代码有问题也不会就这样被你发现了

380091044 发表于 2024-7-15 09:02:17

tzz1983 发表于 2024-7-12 20:33
voidOSTimeDly (INT32U ticks)
{
    INT8U      y;


我的代码如下:
在Free RTOS 中是可以的,在UCOSII中,当语音播报时,按键按下,没有什么反应,等语音播报完成后,电磁阀动作,状态指示切换,语音切换都可以,就是电磁阀和状态不能及时打断语音播报切换,

        OSTaskCreate(Key_Server,            (void *)0,      &Task_STK_K,      1);//按键处理       
        OSTaskCreate(State_Inspect,         (void *)0,      &Task_STK_S,      2);//状态检测
        OSTaskCreate(Voice_Announcements,   (void *)0,      &Task_STK_V,      3);//语音播报

/*****任务3语音播报******/
void Voice_Announcements(void *p_arg)
{
        if(p_arg);
        while (1)
        {               
                        static U8 j=3;       
                        static U8 i=3;       
                  OSTaskResume(1);//恢复按键检测,就绪等待;
                        if(key_lock3==0 && key_lock4==1 && Flag_work==0)//拐弯;
                        {       

                               j=3;
                        if(i!=0)//拐弯检测
                                {
                                        led_L=0;//开启拐弯指示灯
                                        YY_OUT_2=0;//开启语音播报
                      OSCtxSw();//加不加都行
                      OSTimeDly(1000);//为何常亮?加了关中断导致常亮不工作;
                                        YY_OUT_2=1;//关闭语音播报
                                        OSCtxSw();//加不加都行
                      OSTimeDly(3500);//3500
                                        i--;
                                }
                  }
                        if(key_lock3==1 && key_lock4==0&& Flag_work==0)//Flag_position==0;直行;
                        {
                                        i=3;
                                        if(j!=0)//直行检测
                                        {
                                                led_U=0;//开启直行指示灯
                                                YY_OUT_2=0;//开启语音播报
                                          OSCtxSw();//加不加都行
                        OSTimeDly(300);//       
                                                YY_OUT_2=1;//关闭语音播报
                                                OSCtxSw();//加不加都行
                        OSTimeDly(4500);//
                                                j--;                                       
                                        }
                        }
          

        }
}

380091044 发表于 2024-7-15 09:04:22

hsrzq 发表于 2024-7-13 10:38
你觉得的不对。
你觉得的不对。
你觉得的不对。


您说的对,我也总感觉自己感觉的不对,但是,各种测试后,发现,优先级高的任务就是不能及时切换过来,还是我不熟悉这个系统的,也可能哪里设置不对。

hsrzq 发表于 2024-7-15 09:39:06

380091044 发表于 2024-7-15 09:04
您说的对,我也总感觉自己感觉的不对,但是,各种测试后,发现,优先级高的任务就是不能及时切换过来,还 ...
你是怎么测试的?

hsrzq 发表于 2024-7-15 09:47:55

380091044 发表于 2024-7-15 09:02
我的代码如下:
在Free RTOS 中是可以的,在UCOSII中,当语音播报时,按键按下,没有什么反应,等语音播 ...

为什么你手动调了OSCtxSw()?

380091044 发表于 2024-7-15 13:17:50

hsrzq 发表于 2024-7-15 09:47
为什么你手动调了OSCtxSw()?

没有手动调呀,我看例程里面加这句,我也试着测试加不加,是否有区别,结果,加不加没有啥区别,可能是没有用到;

380091044 发表于 2024-7-15 13:23:13

hsrzq 发表于 2024-7-15 09:39
你是怎么测试的?

就是按照加入系统后,3个任务后优先级测试,语音播报延时采用delay_ms(300)延时与OSTimeDly(300)延时,各个任务的动作顺序测试,包括任务3为何内部修改测试等,测试了很多,都没效果,是不是我测试方法有问题?应该如何测试呢?

hsrzq 发表于 2024-7-15 15:11:41

380091044 发表于 2024-7-15 13:23
就是按照加入系统后,3个任务后优先级测试,语音播报延时采用delay_ms(300)延时与OSTimeDly(300)延时,各 ...

1. 你参考的哪个例子?我感觉你参考的例子就有问题……或者是你理解错了参考的不对。
2. 一般不需要在我们的业务代码中调用OSCtxSw(),这个一般是由系统来自动调用的。
3. 不能使用delay_ms,这会把系统也卡住;正常都应该是使用OSTimeDly。
4. 我读你这段代码除了对OSCtxSw()有疑问,其它也没发现问题;你自己死磕这段代码也没测出毛病在哪。我高度怀疑问题其实不在这一段,而是在其它地方。
页: [1] 2 3 4
查看完整版本: UCOSII中使用OSTimeDly (INT32U ticks)延时,不进行任务切换?