打印
[uCOS/RTOS]

ucos之信号量集问题求解

[复制链接]
1008|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liuchang890811|  楼主 | 2015-8-5 11:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
问题描述:小弟最近在学习信号同步,使用的是信号量集,通过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[START_TASK_STK_SIZE - 1],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[DISP_TASK_STK_SIZE-1],5);/*创建Disp_Task任务*/
        OSTaskCreate(LED1_Task,(void *)0,&LED1_Task_Stk[LED1_TASK_STK_SIZE-1],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();
}

相关帖子

沙发
zhusizhan| | 2015-8-5 14:25 | 只看该作者
2)ucos任务调度契机只有两次(至少ucosII如此,据说ucosIII已经增加了时间片激活任务):中断,任务交出控制权
任务交出控制权一般的形式为dly,如果任务不交出控制权,中断后还是会执行任务

1)Disp的任务高,LED1的任务低,中断和LED1任务都会post信号量,
    中断调用后,Disp可能获得控制权,执行打印后,会交出控制权,
    在中断来之前LED1会一直获得控制权,导致pos大量的信号量,这样会导致信号量积压,
    所以Disp任务dly后,获得控制权就会打印,消耗信号量,但是消耗的速度远低于LED1任务抛出的信号量
    因此你的感受就是一直在打印

使用特权

评论回复
板凳
liuchang890811|  楼主 | 2015-8-5 17:09 | 只看该作者
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 | 只看该作者
大神:我的积分不多,原谅我放在一个帖子里吧:'(:'(:'(

使用特权

评论回复
5
ywlzh| | 2015-10-23 18:47 | 只看该作者
liuchang890811 发表于 2015-8-5 17:11
大神:我的积分不多,原谅我放在一个帖子里吧

每个任务都需要无限循环的,你不用可以删除任务或者挂载任务,没有无限循环,任务交出CPU就不会再就绪了,如果你的每个任务都不是无限循环,做完了任务,CPU还干嘛?卡死还是进入空闲任务?

使用特权

评论回复
6
ywlzh| | 2015-12-11 15:24 | 只看该作者
看来你还不知道什么叫任务调度,估计你连压栈和出栈都不清楚,每个任务都是独立的模块,可以相互通信,高优先级任务需要释放cpu给低任务

使用特权

评论回复
7
JasonWangSE| | 2015-12-11 16:49 | 只看该作者
说一下我的看法
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。
void  OS_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
}

使用特权

评论回复
8
2hawer| | 2015-12-14 00:07 | 只看该作者
楼主

使用特权

评论回复
9
2hawer| | 2015-12-14 00:09 | 只看该作者
楼主1每个任务本身就会被快速不停执行,2建议先看看任哲的书

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

87

帖子

0

粉丝