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 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()一定会发生任务切换
你觉得的不对。
你觉得的不对。
你觉得的不对。
这可是通过了FAA安全认证的代码,
可以用在航空航天、医疗器械等性命攸关的领域。
即使代码有问题也不会就这样被你发现了
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--;
}
}
}
}
hsrzq 发表于 2024-7-13 10:38
你觉得的不对。
你觉得的不对。
你觉得的不对。
您说的对,我也总感觉自己感觉的不对,但是,各种测试后,发现,优先级高的任务就是不能及时切换过来,还是我不熟悉这个系统的,也可能哪里设置不对。 380091044 发表于 2024-7-15 09:04
您说的对,我也总感觉自己感觉的不对,但是,各种测试后,发现,优先级高的任务就是不能及时切换过来,还 ...
你是怎么测试的? 380091044 发表于 2024-7-15 09:02
我的代码如下:
在Free RTOS 中是可以的,在UCOSII中,当语音播报时,按键按下,没有什么反应,等语音播 ...
为什么你手动调了OSCtxSw()? hsrzq 发表于 2024-7-15 09:47
为什么你手动调了OSCtxSw()?
没有手动调呀,我看例程里面加这句,我也试着测试加不加,是否有区别,结果,加不加没有啥区别,可能是没有用到; hsrzq 发表于 2024-7-15 09:39
你是怎么测试的?
就是按照加入系统后,3个任务后优先级测试,语音播报延时采用delay_ms(300)延时与OSTimeDly(300)延时,各个任务的动作顺序测试,包括任务3为何内部修改测试等,测试了很多,都没效果,是不是我测试方法有问题?应该如何测试呢? 380091044 发表于 2024-7-15 13:23
就是按照加入系统后,3个任务后优先级测试,语音播报延时采用delay_ms(300)延时与OSTimeDly(300)延时,各 ...
1. 你参考的哪个例子?我感觉你参考的例子就有问题……或者是你理解错了参考的不对。
2. 一般不需要在我们的业务代码中调用OSCtxSw(),这个一般是由系统来自动调用的。
3. 不能使用delay_ms,这会把系统也卡住;正常都应该是使用OSTimeDly。
4. 我读你这段代码除了对OSCtxSw()有疑问,其它也没发现问题;你自己死磕这段代码也没测出毛病在哪。我高度怀疑问题其实不在这一段,而是在其它地方。