裸机消息队列的实现

一.背景

在嵌入式开发的时候,如果我们移植了操作系统,那么操作系统会带有消息队列的功能。但如果我们使用的是裸机,然后又需要到消息缓存的功能时,那么就需要自己去实现消息队列的功能了。本文章就给出了一种简便地实现消息队列的方法。

那么为什么会需要消息队列呢?

我认为主要原因是为了应对接收端接收数据快,而处理端处理数据慢而设置的缓冲吧。如果没有缓冲处理,那么很容易出现数据丢失没有处理到的情况。举个生活中的例子,现在大家的电视基本上都是网络电视了吧。有时候我们使用遥控器按的速度过快时,比如调节音量吧,我们快速连续按几次,会发现当我们停止按按键的时候,电视显示音量调节变化的动作还未结束,需要过一会才执行完我们刚才的动作,这就是电视处理器,先把我们按键的消息放到缓存队列里面,然后再一条一条慢慢取出来执行的。如果没有缓存队列,那么可能会出现我们快速按3到4次,最后只执行了一次的情况。

当然对于使用操作系统的话,消息队列的作用还可以用于各个任务之间的同步。

二.源码

上述讲了消息队列的作用,接下来给上源码。实现原理非常简单,应该没必要做过多的解释,代码量也很精简,直接阅读代码即可,大家可以根据自己的项目实际需求进行调整。

#include<stdio.h>
#include <string.h>
//消息队列数据类型
#define MAX_LEN  20
typedef struct{
    unsigned *addr;     //可接受数据缓存地址
    unsigned buff[10];  //可接受实际数据
}message_type;
static struct
{
    message_type data_buffer[MAX_LEN];
    unsigned read_index;                    //记录接收到消息的序号(例程中未运用到)
    unsigned write_index;                   //记录读取完消息的序号(例程中未运用到)
    unsigned data_num;                      //记录当前队列缓存消息的数量
}g_recv_queue_t;

//消息接收(缓存入队)列函数
static void on_message_recv(message_type *rx_msg)
{
    if(g_recv_queue_t.data_num < MAX_LEN){
        memcpy(&g_recv_queue_t.data_buffer[g_recv_queue_t.write_index], rx_msg, sizeof(message_type));
        g_recv_queue_t.data_num++;
        g_recv_queue_t.write_index = (g_recv_queue_t.write_index + 1) % MAX_LEN;
    }
}
//消息读取(出队列)函数
static unsigned get_msg(message_type *rx_msg)    
{
    if (g_recv_queue_t.data_num){
        memcpy(rx_msg, &g_recv_queue_t.data_buffer[g_recv_queue_t.read_index], sizeof(message_type));
        g_recv_queue_t.read_index = (g_recv_queue_t.read_index + 1) % MAX_LEN;
        g_recv_queue_t.data_num--;
        return 1;
    }
    return 0;
}

message_type message;
//指向上层接收函数的指针
void (*g_precv_func2)(message_type *rx_msg) = NULL;
//初始化消息接收函数
void copy_func2_init(void (*p_recv_data)(message_type *rx_msg))
{
    g_precv_func2 = p_recv_data;
}
//某个中断里面消息接收
void XXX_IRQHandler(void)
{
    //将数据存储到message消息类型变量中
    //message.addr = xxx;
    //...
    //放入到消息队列中
    g_precv_func2(&message);
}

void main(void)
{
    message_type my_message;
    copy_func2_init(on_message_recv);//初始化消息队列接收函数
    while(1){
        if(get_msg(&my_message)){//查询消息队列
            //处理消息数据
        }
    }
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值