嵌入式学习小组
直播中

胡楚翘

7年用户 218经验值
私信 关注

请求并且获得信号量后执行信号量删除那当再次请求信号量时还会成功吗?

在请求并且获得信号量后执行 信号量删除,那么当我再次请求信号量的时候,还会成功吗?
其他任务 OSSemPost(LED1_SEM);
然后新任务执行
     OSSemPend(LED1_SEM,0,&err);
     GPIOA->ODR ^= GPIO_Pin_8;
     OSSemDel(LED1_SEM,OS_DEL_ALWAYS,&err);
删除信号量后 再次进入任务时
    OSSemPend(LED1_SEM,0,&err);
还能执行到
     GPIOA->ODR ^= GPIO_Pin_8;吗?

回帖(7)

贺楠

2019-4-25 09:41:15
uC/OS-II 2.52 OS_SEM.c的OSSemDel()中是这样处理你的请求的:
caseOS_DEL_ALWAYS: 
   while (pevent->OSEventGrp != 0x00) {
          OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); 

 pevent->OSEventType = OS_EVENT_TYPE_UNUSED; 
 pevent->OSEventPtr = OSEventFreeList;  //信号量对应的指针=空余块链接表----------1
 OSEventFreeList  = pevent;  //空余块链接表=当前事件指针----------------------------2
。。。
return ((OS_EVENT *)0);---------------------------------------------------------------3
看后面标注的三句代码知道:
1、信号量的事件控制块被回收
2、你声明的LED1_SEM被函数重新赋值成(OS_EVENT *)0了
3、删除信号量后 再次进入任务时    OSSemPend(LED1_SEM,0,&err);请求信号量,
这时,进入 OSSemPend(){
                        .........
                      #ifOS_ARG_CHK_EN > 0 
                        if (pevent == (OS_EVENT *)0) 
                        *err = OS_ERR_PEVENT_NULL;  //pevent是空指针
                        return;  //返回空,啥也没做,往下执行了
  }
4、因为 return;     所以是可以往下执行GPIOA->ODR ^= GPIO_Pin_8;的
举报

周悠悠

2019-4-25 09:49:17
自己测试下就知道了。
举报

高颖

2019-4-25 09:58:16
正确使用OSSemDel(),那么OSSemPend()会返回失败。
从举例的代码看,你没有。
详见OSSemDel()函数说明。
举报

张秀芳

2019-4-25 10:09:30
补充:上面是以uC/OS-II出发的,如果是其他版本不一定成立。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分