嵌入式技术论坛
直播中

贾埃罗

7年用户 1649经验值
私信 关注
[问答]

RT_thread的datacomm_thread_entry中接收任务通知或者消息队列时的冲突问题如何解决?

/***************************************************
****系统数据处理线程
*/
static    void    dataproc_thread_entry(void* parameter)
{
    uint8_t i;
    uint8_t Sys_Mode = 0;   
    rt_uint32_t recved;
    rt_err_t    wret;
    while(1)
    {
        //等待AD转换完成事件通知,超时时间1S
        wret = rt_event_recv(get_addata_event,AD_DATA_EVENT,RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR,1000,&recved);
        if(wret == RT_EOK)                                                //-------AD转换完成事件正确接收
        {
            dataproc_tick++;
            //翻转AD转换指示灯
            if((dataproc_tick % 100) == 0)
            {
                DEV_LED_TOGGLE(AD_LED);
            }
        }
        else if(wret == (-RT_ETIMEOUT))                    //-------等待AD转换完成事件超时
        {
            PRINT_ERR("Dataproc Timeout - recved:  %d rn",recved);
        }
        else                                                                        //-------AD转换完成事件接收错误
        {
            PRINT_ERR("Dataproc ThreadERR - sta: %d  recved:  %d rn",(uint8_t)wret,recved);;
        }
    }
}
/***************************************************
****系统数据通信线程
*/
static    void    datacomm_thread_entry(void* parameter)
{
    uint8_t i;
    rt_err_t    qret;   
    rt_uint32_t recved;   
    rt_uint8_t    mqdata_buff[256];                                                                                                        //接收缓存区,比预定义的消息大小大一些
    while(1)
    {
//        qret = rt_mq_recv(data_comm_mq,mqdata_buff,sizeof(mqdata_buff),1);                    //2秒超时等待,消息队列
        qret = rt_event_recv(test_event,AD_DATA_EVENT,RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR,2000,&recved);
        if(qret == RT_EOK)                                                    //接收到消息
        {
            //PRINT_RUN("接收到消息:%s",mqdata_buff);
        }
        else if(qret == (-RT_ETIMEOUT))                            //接收超时
        {
//            PRINT_RUN("接收队列超时,发送实时数据!rn");
//            RealtimeData_Pack(&SysSTA_Data,&SysReal_Data,mqdata_buff);
//            Data_Uart_SendBuff(mqdata_buff,(mqdata_buff[3]<<8)|mqdata_buff[4]);
        }
        else                                                                                //接收错误
        {
            PRINT_ERR("MQ队列接收错误: 0x%2x rn",(uint8_t)qret);
        }   
    }
}
初次使用RT_thread。。版本是nano最新版本,dataproc_thread_entry任务优先级是1,datacomm_thread_entry任务优先级是3. 现象是,假如datacomm_thread_entry任务不接收任何事件通知或者消息队列,直接延迟100ms,dataproc_thread_entry任务可以每秒响应10000次AD转换完成的任务通知。但是datacomm_thread_entry中接收任务通知或者消息队列时,dataproc_thread_entry就会受到极大的影响。不知是何原因。。

回帖(1)

王飞云

2022-5-24 15:19:39
找到问题所在了。。因为之前参考的代码是动态申请内存的
rt_event_t get_addata_event;//只是初始化了指针
rt_event_init();//这个函数是静态初始化事件组的,不开启内核调试的时候,是不报错的,但是指向的内存区就是有问题的。而且简单测试时,因为内存被修改的可能性不大,还是可以工作的。

//正常的静态创建事件组结构体,应该使用下面的方式。
struct rt_event get_addata_event;

由于不太了解RT_THREAD,且自身不够细心,基础不扎实的原因,导致了这个情况的发生!希望大家引以为戒!
再者就是,前期搭建框架时,最好打开内核调试,等相关流程跑通了,再关掉也不迟!
举报

更多回帖

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