关于-队列实现消息触发机制

C语言—队列处理消息机制

使用背景介绍

嵌入式开发中,经常使用触发flag标志位去处理很多事件,最典型的就是中断触发类型,flag置位。然后主程序轮询检查flag状态,如果检测flag置位条件满足,则进行下一步的操作,比如说中断读取串口数据操作。
在这里插入图片描述

通用处理情况

中断回调函数处理如下,将触发标志置1

rt_err_t rz_uart1_recv_callback(rt_device_t dev, rt_size_t size)
{

	.......

 	recv_flag = 1;

	.......

}


应用处理处理,判断触发标志是否满足,

if (recv_flag) {
   recv_flag = 0;
    .......
}

这种处理方式适合通用处理方法,优点是程序简单,缺点是程序接口不好,要注意标志位清除。
如果多种类型的触发标志,那么要定义很多的flag去识别,这样对程序开发很不友好!

采用队列方式存储事件消息

队列使用RT-Thread自带的数据接口 RingBuffer 其实就是先进先出(FIFO)的循环缓冲区。把一段线性的存储空间当作一个环形的存储空间使用,可以提高存储空间的利用率。

具体的使用说明,参考这位博友的文章,写的很清楚。
ringbuffer使用
在这里插入图片描述

设计思路

  1. 将所有触发的标志位类型作为事件消息,入队操作,保证每个触发事件类型有且唯一。

  2. 出队获取对应的事件消息,判断是否对应的触发类型。

这样设计的好处利于系统的耦合性及健壮性。

中断程序修改如下:

msg_put(MSG_TYPE_RECV_DATA); /* 相当于	recv_flag = 1; 入队操作*/

应用程序修改:

msg_put(&msg_code);    /* recv_flag = 0,出队操作 */
if (MSG_TYPE_RECV_DATA == msg_code ) {
	........
}

源文件程序

使用LW_OOPC框架,使用面向对象思想进行模块封装。

#ifndef __RZ_MSG_H
#define __RZ_MSG_H

#include <rtthread.h>
#include "lw_oopc.h"
#include <stdbool.h>
#include <rtdevice.h>

#define RING_BUFFER_LEN    10	   		/* 消息个数 */

typedef enum rz_msg_type_def {
      MSG_TYPE_NONE = 0x00,
      MSG_TYPE_RECV_RH172DATA,    
      MSG_TYPE_MAX,
}rz_msg_type_t;


typedef struct rz_msg_t rz_msg_t;

CLASS(rz_msg_t)
{
      struct rt_ringbuffer *rb ;
      bool (*msg_init)(rz_msg_t *t);                               
      bool (*msg_put)(rz_msg_t *t,uint8_t msg_code);  
      bool (*msg_get)(rz_msg_t *t,uint8_t *msg_code);          
};

bool rz_msg_init(void);
rz_msg_t * rz_msg_obj_get(void);

#endif 
#include "rz_msg.h"

static rz_msg_t   prz_msg_obj;
rz_msg_t * rz_msg_obj_get(void)
{
    return &prz_msg_obj;
}

static bool msg_init(rz_msg_t *t)
{     
    t->rb = rt_ringbuffer_create(RING_BUFFER_LEN);
    if (NULL ==  t->rb) {
       rt_kprintf("can't create ringbffer");
       return false;
    }    
    return true;    

}

static bool msg_put(rz_msg_t *t,uint8_t msg_code)
{     
    if(0 == rt_ringbuffer_put(t->rb,&msg_code,1)){
        return false;
    }
    return true;    

}

static bool msg_get(rz_msg_t *t,uint8_t* msg_code)
{     
   if(0 == rt_ringbuffer_get(t->rb,msg_code,1)){
        return false;
    }
    return true;    

}
CTOR(rz_msg_t)
FUNCTION_SETTING(msg_get, msg_get);
FUNCTION_SETTING(msg_put, msg_put);
FUNCTION_SETTING(msg_init, msg_init);
END_CTOR


bool rz_msg_init(void)
{
        rz_msg_t * t = rz_msg_obj_get();
        rz_msg_t_ctor(t);
        return t->msg_init(t);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值