ucos之信号量集问题求解
问题描述:小弟最近在学习信号同步,使用的是信号量集,通过LED1_Task任务释放一个信号量,通过按键中断释放另一个信号量,在Disp_Task任务中用串口打印出来~~~问题求解:
问题1:如下是我写的程序,它一直在打印,根本停不下来(我想达到的效果是按键每按一次,在串口上打印一次,),恳请大神指教
问题2:假设我有Task1(prio=1),Task2(prio=2),Task3(prio=3),那ucos在执行任务调度之后,
ucos是一直在执行Task1,还是执行完Task1 一次之后,转而去执行其他任务(Task1一直保持最高优先级)?
int main(void)
{
INT8U err;
USART1_Config(115200);
OSInit();
err = OSTaskCreate(Start_Task, (void *)0,&Start_Task_Stk,3);/*在main()函数中创建一个Start_Task任务 */
OSStart();
return (0);
}
static void Start_Task(void* p_arg)
{
OS_CPU_SysTickInit();/*初始化SysTick,LED,EXTI*/
LED1_Init();
EXTI_PA0_Config();
OSTaskCreate(Disp_Task,(void *)0,&Disp_Task_Stk,5);/*创建Disp_Task任务*/
OSTaskCreate(LED1_Task,(void *)0,&LED1_Task_Stk,7);/*创建LED1_Task任务*/
OSTaskDel(OS_PRIO_SELF);/*删除Start_Task任务*/
}
static void Disp_Task(void *p_arg)
{
INT8U err;
p_arg=p_arg;
FLAGW=OSFlagCreate(0,&err);/*创建信号量集*/
while(1)
{
OSFlagPend(FLAGW,0x03,OS_FLAG_WAIT_SET_ALL,0,&err);
printf("已经接收到信号量集");
OSTimeDly(OS_TICKS_PER_SEC);
}
}
static void LED1_Task(void *p_arg)
{
INT8U err;
p_arg=p_arg;
printf("Ö´ÐÐLED_TaskÈÎÎñ\n");
while(1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_0);
OSFlagPost(FLAGW,0x01,OS_FLAG_SET,&err);/*释放信号量集*/
}
}
void EXTI0_IRQHandler(void)
{
INT8U err;
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL();
OSIntEnter();
OS_EXIT_CRITICAL();
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
printf("按键被按下");
OSFlagPost(FLAGW,0x02,OS_FLAG_SET,&err);/*发送信号量*/
EXTI_ClearITPendingBit(EXTI_Line0);
}
OSIntExit();
}
2)ucos任务调度契机只有两次(至少ucosII如此,据说ucosIII已经增加了时间片激活任务):中断,任务交出控制权
任务交出控制权一般的形式为dly,如果任务不交出控制权,中断后还是会执行任务
1)Disp的任务高,LED1的任务低,中断和LED1任务都会post信号量,
中断调用后,Disp可能获得控制权,执行打印后,会交出控制权,
在中断来之前LED1会一直获得控制权,导致pos大量的信号量,这样会导致信号量积压,
所以Disp任务dly后,获得控制权就会打印,消耗信号量,但是消耗的速度远低于LED1任务抛出的信号量
因此你的感受就是一直在打印 zhusizhan 发表于 2015-8-5 14:25
2)ucos任务调度契机只有两次(至少ucosII如此,据说ucosIII已经增加了时间片激活任务):中断,任务交出控制 ...
大神:首先非常感谢您的指导~小弟还有点疑问,还想聆听大神的指点~~~
问题1:因为我这里使用的是信号量集,采用的是"与",虽然我的LED1_Task任务里面会一直产生信号量(暂称为信号量1吧),
那我的中断中的信号量2一次中断只会产生一个,也就是说:信号量1的数量远远大于信号量2的数量,那此时Disp_Task中
调用串口打印的数目不是应该=信号量2的数目吗?恳请大神指教~~~
问题2:我看网上有人说:一个任务就相当于一个while(1),请教大神:这样说有道理吗?
for example:Task1(prio=1),Task2(prio=2),Task3(prio=3),3个任务都处于就绪态.
如果我同时建立了这3个任务,并且我在这3个任务中都没有使用while(1),
那么:ucos在处理完1次Task1之后,它是会继续处理Task1,还是会转向Task2?还是其它?
大神:我的积分不多,原谅我放在一个帖子里吧:'(:'(:'( liuchang890811 发表于 2015-8-5 17:11
大神:我的积分不多,原谅我放在一个帖子里吧
每个任务都需要无限循环的,你不用可以删除任务或者挂载任务,没有无限循环,任务交出CPU就不会再就绪了,如果你的每个任务都不是无限循环,做完了任务,CPU还干嘛?卡死还是进入空闲任务? 看来你还不知道什么叫任务调度,估计你连压栈和出栈都不清楚,每个任务都是独立的模块,可以相互通信,高优先级任务需要释放cpu给低任务 说一下我的看法
1. 关于程序问题,flag使用没看出什么问题来,可以关注一下是不是一直在进中断,在中断里最好不用printf,点个灯看是不是只有按键灯才亮
2. 关于任务调度,看Task1有没有被阻塞或主动释放CPU了,如果没有,且Task1又是一个死循环,那Task2和Task3将一直得不到调度。
你提到的3个任务都没有使用while(1)的情况,可以看一下你的代码里OSTaskStkInit的实现,把LR设成了哪个函数,它就是没有while(1)的任务执行完后要执行的函数,一般来说是OS_TaskReturn。里面取决于你编译时的配置,如果OS_TASK_DEL_EN使能,则Task1会被删除,如果OS_TASK_DEL_EN未使能,则Task1会死循环delay。
voidOS_TaskReturn (void)
{
OSTaskReturnHook(OSTCBCur); /* Call hook to let user decide on what to do */
#if OS_TASK_DEL_EN > 0u
(void)OSTaskDel(OS_PRIO_SELF); /* Delete task if it accidentally returns! */
#else
for (;;) {
OSTimeDly(OS_TICKS_PER_SEC);
}
#endif
} 楼主 楼主1每个任务本身就会被快速不停执行,2建议先看看任哲的书
页:
[1]