[FreeRTOS] 调用vTaskSuspend后,通过vTaskResume恢复任务无法响应

本文描述了在调试过程中遇到的问题,即串口任务在被vTaskSuspend挂起并vTaskResume恢复后无法响应。问题在于中断回调机制导致的死锁,解决方法是给信号量加保护或在恢复任务后重新设置信号量。
摘要由CSDN通过智能技术生成

1、今天在调试串口任务时,碰到了一个问题:

        调用vTaskSuspend挂起任务后,通过vTaskResume恢复任务,恢复的任务无法响应

2、具体如下:

        1> 串口接收读取中断函数:

                

        串口接收中断函数:通过设置(give)一个信号量标记,告诉串口接收主任务函数,可以进行接收串口数据了

        串口接收主任务函数:等待信号量,接收数据,将数据送入队列

        

3、所做的测试如下:

在其他任务重,通过指令调试代码:

        Print("test uart :\r\n");
        Dis_TaskCmsdkISR_uart();            //挂起TaskCmsdkISR_uart任务
        for(i=0;i<=9;i++)
        {
            //rxByte=uart0_read(DP_WaitForever);
            rxByte=uart0_read_POLL(5000);    //在这里接收和使用串口数据
            Print("%02x ",rxByte);
        }
        EN_TaskCmsdkISR_uart();                //恢复TaskCmsdkISR_uart任务
        DP_TaskSleep(1);
        taskYIELD();
        Print("rev uart 10bytes ok\r\n");

在运行EN_TaskCmsdkISR_uart()之后,发送其他调试指令,不能响应,如下:

按道理已经恢复任务了,应该可以响应正常的指令才对。

观察led任务,发现灯还可以闪烁,说明RTOS任务能正常切换,操作系统未被挂死。

4、分析:

        1>查看挂起的任务Task_cmsdkISR_uart代码

                代码长期都会处于等待信号量状态,所以在挂起任务时,肯定是出于等待信号量函数的那行;所以恢复任务时,会恢复到等待信号量的那行

        2>挂起和恢复任务间的操作

                我们可以看到,挂起任务后,我们会操作信号量去读取数据,这里会不会和挂起任务所使用的信号量冲突呢?那肯定会是冲突的,在不同任务调用同一资源,需要保护。

                所以在任务恢复后,那个信号量的状态可能已经发生了变化,可能会导致Task_cmsdkISR_uart任务移植在那里等待,所以解决办法是:

        a>给信号量加保护?

        b>将信号量重新复位一下:

                这里是这样做:

恢复任务后,重新give信号量,让他可以跳出当前foever等待的那个状态。

然后就可以正常接收数据了。

-----主要还是,这里中断使用问题:

        这个提供的库,中断函数采用回调方式,当调用uart_read时,才会调用中断回调函数。

        这里非阻塞方式读数据,当没数据时,会等待回调的那个中断函数响应,如果一直没,会一直等那里,跳不过那个forever;

而只有调用uart_read函数,才会有中断回调函数响应,在挂起/恢复后,那个中断give的信号量被使用后,形成了个死循环。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值