OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5136|回复: 3

ucos信号量访问共享资源问题

[复制链接]

14

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2020-9-2
在线时间
41 小时
发表于 2021-1-8 08:56:03 | 显示全部楼层 |阅读模式
1金钱
这个是正点原子的项目模板,两个任务访问一个共享资源,并且两个任务都是先等待一个信号量,然后再释放信号量,怎么不会产生死锁问题?
//任务1的任务函数
void task1_task(void *p_arg)
{
        OS_ERR err;
        u8 task1_str[]="First task Running!";
        while(1)
        {
                printf("\r\n任务1:\r\n");
               
                OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err);         //请求信号量
                memcpy(share_resource,task1_str,sizeof(task1_str)); //向共享资源区拷贝数据
                delay_ms(300);
                printf("%s\r\n",share_resource);        //串口输出共享资源区数据       
                OSSemPost (&MY_SEM,OS_OPT_POST_1,&err);                                //发送信号量
                LED0 = ~LED0;
                OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);   //延时1s
        }
}

//任务2的任务函数
void task2_task(void *p_arg)
{       
        OS_ERR err;
        u8 task2_str[]="Second task Running!";
        while(1)
        {
                printf("\r\n任务2:\r\n");
               
                OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err);         //请求信号量
                memcpy(share_resource,task2_str,sizeof(task2_str));        //向共享资源区拷贝数据
                delay_ms(300);
                printf("%s\r\n",share_resource);        //串口输出共享资源区数据               
                OSSemPost (&MY_SEM,OS_OPT_POST_1,&err);                                //发送信号量
                LED1 = ~LED1;
                OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);   //延时1s
        }
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165353
金钱
165353
注册时间
2010-12-1
在线时间
2108 小时
发表于 2021-1-9 02:28:40 | 显示全部楼层
回复

使用道具 举报

14

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2020-9-2
在线时间
41 小时
 楼主| 发表于 2021-1-9 09:21:38 | 显示全部楼层

这个原因我已经知道了,是因为创建信号量时信号量数设置的是1,不会出现自锁
回复

使用道具 举报

14

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2020-9-2
在线时间
41 小时
 楼主| 发表于 2021-1-9 09:26:27 | 显示全部楼层
本帖最后由 binzhang 于 2021-1-9 09:40 编辑

你好,我用原子的串口接收数据的例程,利用串口1接收到的数据然后这做校验通过串口2 发送出去,串口1接收到数据的频率是100ms一次,但是串口2 发送数据时数据更新很慢!//串口1接收数据校验,优先级是4
void Analy_task(void *p_arg)
{
        unsigned char check_sum;
        u8 i=0;
        OS_ERR err;
        CPU_TS         ts;
        CPU_SR_ALLOC();
        p_arg = p_arg;
       
        while(1)
        {
         
                OSTaskSemPend ((OS_TICK   )0,                     //无期限等待
                                                (OS_OPT    )OS_OPT_PEND_BLOCKING,  //如果信号量不可用就等待
                                                (CPU_TS   *)&ts,                   //获取信号量被发布的时间戳
                                                (OS_ERR   *)&err);                 //返回错误类型       
                for(i=0;i<USART1_REC_LEN;i++)
                {
                        printf("USART1_RX_BUF[%d] = 0x%02hhx\r",i,USART1_RX_BUF);
                }
                printf("Analy wait signal sucess\r\n");
                if((USART1_RX_BUF[0]==0xff)&&(USART1_RX_BUF[1]==0xff))
                {
                        check_sum=USART1_RX_BUF[2]+USART1_RX_BUF[3]+USART1_RX_BUF[4]+USART1_RX_BUF[5]+USART1_RX_BUF[6]+USART1_RX_BUF[7]+USART1_RX_BUF[8]+USART1_RX_BUF[9]+USART1_RX_BUF[10]+USART1_RX_BUF[11]+USART1_RX_BUF[12]+0xff+0xff;
                        check_sum=~check_sum;
                        check_sum=check_sum&0xff;
                        printf("check_Sum=0x%hx",check_sum);
                        printf("buff[%d] = 0x%02hhx",13, USART1_RX_BUF[13]);
                        if(check_sum==USART1_RX_BUF[13])
                        {
                                RecToUsart2();        
                                OSSemPost(&SYNC_SEM,OS_OPT_POST_1,&err);//发送信号量       
                        }
                        else
                        {
                                clearUsart1Buff();printf("usart1 del");
                        }
                }
                else
                {
                        clearUsart1Buff();
                }
            OSTimeDlyHMSM(0,0,0,5,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s
        }
}
//串口2发送任务数据校验优先级是6
void check_task(void *p_arg)
{
        unsigned char check_sum;
        OS_ERR err;
        CPU_SR_ALLOC();
        p_arg = p_arg;
       
        while(1)
        {               
                       
                       
                        OSSemPend(&SYNC_SEM,0,OS_OPT_PEND_BLOCKING,0,&err);         //请求信号量
                        printf("check wait signal success\r\n");
                        check_sum=USART2_BUFF[2]+USART2_BUFF[3]+USART2_BUFF[4]+USART2_BUFF[5]+USART2_BUFF[6]+USART2_BUFF[7]+USART2_BUFF[8]+USART2_BUFF[9]+USART2_BUFF[10]+USART2_BUFF[11]+USART2_BUFF[12]+USART2_BUFF[13]+USART2_BUFF[14]+USART2_BUFF[15]+USART2_BUFF[16]+USART2_BUFF[17]+USART2_BUFF[18]+0xff+0xff;
                        check_sum=~check_sum;
                        check_sum=check_sum&0xff;
                        printf("check_Sum2=0x%hx\r",check_sum);
                       
                        if(USART2_BUFF[0]==0xff&&USART2_BUFF[1]==0xff&&USART2_BUFF[2]!=0x00&&USART2_BUFF[3]!=0x00)
                        {
                                USART2_BUFF[18]=check_sum;  printf("USART2_BUFF[%d] = 0x%02hhx\r\n",18, USART2_BUFF[18]);
                                OSTaskSemPost((OS_TCB  *)&USART2_SendData_TaskTCB,           //目标任务
                                                 (OS_OPT   )OS_OPT_POST_NONE,        //没选项要求
                                                 (OS_ERR  *)&err);
                        }
                        else
                        {
                                clearUsart2Buff();
                        }
                        //OSSemPost(&SYNC_SEM,OS_OPT_POST_1,&err);//发送信号量
                        OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s
        }
}
//串口2发送数据任务函数,优先级是7
void USART2_SendData_task(void *p_arg)
{
       u8 i=0;        OS_ERR err;
      CPU_TS         ts;        CPU_SR_ALLOC();
      p_arg = p_arg;
     while(1)
    {
         OSTaskSemPend ((OS_TICK   )0,                     //无期限等待                                                (OS_OPT    )OS_OPT_PEND_BLOCKING,  //如果信号量不可用就等待                                                (CPU_TS   *)&ts,                   //获取信号量被发布的时间戳                                                (OS_ERR   *)&err);                 //返回错误类型       
         printf("usart2 wait signal\r\n");
        for(i=0;i<USART2_LEN;i++)
       {
            while( RESET == USART_GetFlagStatus( USART2, USART_FLAG_TXE ));
            USART_SendData(USART2,USART2_BUFF);
        }
             OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s
        }
}       


void USART1_IRQHandler(void)         
{
        unsigned char r;
        OS_ERR err;
        OSIntEnter();
        
        if(USART_GetFlagStatus(USART1,USART_IT_RXNE)!=RESET)
        {
                r=USART_ReceiveData(USART1);
                USART1_RX_BUF[USART1_REC_CNT]=r;
                USART1_REC_CNT++;
        
                if(USART1_REC_CNT>(USART1_REC_LEN-1))
                {
                        printf("数据接收完成,释放一个任务信号量到数据分析任务\r\n");
                        OSTaskSemPost((OS_TCB  *)&Analy_TaskTCB,           //目标任务
                                                        (OS_OPT   )OS_OPT_POST_NONE,        //没选项要求
                                                        (OS_ERR  *)&err);        
                }
               
        }        
        OSIntExit();               
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 11:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表