[单片机框架] [queue] 实现一个简易的消息队列

发布者:SparklingMelody最新更新时间:2022-09-19 来源: csdn关键字:queue  消息队列 手机看文章 扫描二维码
随时随地手机看文章

使用方法如下:


#define USB_RECV_Q_ITEM_CNT                             8

#define USB_RECV_Q_ITEM_SIZE                            (64 + 1)

 // 用于usb消息队列总缓存区

static uint8_t m_usb_recv_q_buff[USB_RECV_Q_ITEM_CNT * USB_RECV_Q_ITEM_SIZE] = {0};

queue_t m_usb_recv_q =

{

    .pbuff     = m_usb_recv_q_buff,

    .front     = 0,

    .rear      = 0,

    .item_cnt  = USB_RECV_Q_ITEM_CNT,

    .item_size = USB_RECV_Q_ITEM_SIZE

};

uint8_t g_usb_recv_data[USB_RECV_Q_ITEM_SIZE]    = {0}; // 用于usb消息临时缓存区


//函数使用:

/**

 * @brief  usb发送数据给usb自定义通道(消息入队,非实时发送)

 * @note   NULL

 * @param  *data: 欲发送内容

 * @param  len: 内容长度(字节大小)

 * @retval None

 */

void biz_usb_send_data(uint8_t *data, uint16_t len)

{

    queue_en(&m_usb_recv_q, data);

}


/**

 * @brief  处理消息队列中的消息,通过usb发送

 * @note   NULL

 * @retval None

 */

void biz_usb_data_dispose(void)

{

    if (!queue_de(&m_usb_recv_q, g_usb_recv_data))

        return;

    usb_send(g_usb_recv_data, MAX_USB_PACKET_SIZE);

    // LOG_D(" [usb_send] %02x %02x %02x %02x %02xrn", g_usb_recv_data[0], g_usb_recv_data[1], g_usb_recv_data[2], g_usb_recv_data[3], g_usb_recv_data[4]);

}


/********************************************************************************

* @file    queue.c

* @author  jianqiang.xue

* @Version V1.0.0

* @Date    2021-10-10

* @brief   消息队列 借鉴nrf

* @example 

#define RECV_Q_ITEM_CNT                             (8)

#define RECV_Q_ITEM_SIZE                            (20)

// 消息队列总缓存区

static uint8_t m_recv_q_buff[RECV_Q_ITEM_CNT * RECV_Q_ITEM_SIZE] = {0};

// 定义队列消息结构体

queue_t m_recv_q =

{

    .pbuff     = m_recv_q_buff,

    .front     = 0,

    .rear      = 0,

    .item_cnt  = RECV_Q_ITEM_CNT,

    .item_size = RECV_Q_ITEM_SIZE

};

// 消息队列项目临时缓存区

uint8_t g_recv_data[USB_RECV_Q_ITEM_SIZE] = {0};


// 数据入队(data长度为RECV_Q_ITEM_SIZE)

queue_en(&m_recv_q, data);


// 数据出队(如果队列为空,则返回)

if (!queue_de(&m_recv_q, g_recv_data))

    return;

********************************************************************************/

/* Includes ------------------------------------------------------------------*/

#include

#include

#include

#include


/* Private includes ----------------------------------------------------------*/

#include "queue.h"


/* Private function prototypes -----------------------------------------------*/

/**

 * @brief  [消息队列] 初始化

 * @note   NULL

 * @param  q: 队列信息指针

 * @param  data: 队列缓存区

 * @param  item_cnt: 队列总数量

 * @param  item_size: 队列总大小

 * @retval 1--成功 0--失败

 */

bool queue_init(queue_t *q, uint8_t *data, uint32_t item_cnt, uint32_t item_size)

{

    q->pbuff     = data;

    q->item_cnt  = item_cnt;

    q->item_size = item_size;

    q->front     = 0;

    q->rear      = 0;

    return true;

}


/**

 * @brief  [消息队列] 入队

 * @note   NULL

 * @param  q: 队列信息指针

 * @param  data: 数据头指针

 * @retval 1--成功 0--失败

 */

bool queue_en(queue_t *q, uint8_t *data)

{

    if (((q->rear+1)%q->item_cnt) == q->front)

        return false;

    

    memcpy(q->pbuff + (q->rear*q->item_size), data, q->item_size);

    q->rear = (q->rear+1)%q->item_cnt;


    return true;

}


/**

 * @brief  [消息队列] 出队

 * @note   NULL

 * @param  q: 队列信息指针

 * @param  data: 得到当前队列信息数据头指针

 * @retval 1--成功 0--失败

 */

bool queue_de(queue_t *q, uint8_t *data)

{

    if (q->front == q->rear)

        return false;


    if (data)

    {

        memcpy(data, q->pbuff + (q->front * q->item_size), q->item_size);

    }

    q->front = (q->front + 1) % q->item_cnt;

    return true;

}


/**

 * @brief  [消息队列] 读取当前第一个队列信息

 * @note   NULL

 * @param  q: 队列信息指针

 * @retval 第一个队列信息头指针

 */

uint8_t* queue_read(queue_t *q)

{

    if (q->front == q->rear)

        return NULL;


    return q->pbuff + (q->front * q->item_size);

}


/********************************************************************************

* @file    queue.h

* @author  jianqiang.xue

* @Version V1.0.0

* @Date    2021-10-10

* @brief   消息队列 借鉴nrf

********************************************************************************/


#ifndef __QUEUE_H__

#define __QUEUE_H__


/* Includes ------------------------------------------------------------------*/

#include

#include


/* Public Struct -----------------------------------------------*/


typedef struct 

{

uint8_t  *pbuff;

uint32_t front;

uint32_t rear;

    uint32_t item_cnt;

    uint32_t item_size;

} queue_t;


/* Public function prototypes -----------------------------------------------*/

bool queue_init(queue_t *q, uint8_t *data, uint32_t item_cnt, uint32_t item_size);

bool queue_en(queue_t *q, uint8_t *data);

bool queue_de(queue_t *q, uint8_t *data);

uint8_t* queue_read(queue_t *q);


#endif

关键字:queue  消息队列 引用地址:[单片机框架] [queue] 实现一个简易的消息队列

上一篇:[单片机框架][os层] RTX4 中间件 公共函数
下一篇:[keil5] 编译HEX文件,修改起始地址后,HEX文件地址不变

推荐阅读最新更新时间:2024-11-18 04:24

[单片机框架][bsp层][nrf51822][nrf51422][nrf51802][bsp_key] KEY配置和使用
按键的基本原理是设置单片机IO口(PB0-PB3)为输入状态,如DDRB = 0XF0(方向寄存器,“1”为输出,“0”为输入); 单片机一直检测按键端口(PB0-PB3)的状态,当端口为低电平时(即按键按下),实行相应的动作(比如控制LED灯)。 原理就是这么回事,但是正真实现时,按键会有抖动,要进行按键去抖,下图为按键按下时的抖动图。 按键实行一个动作过程是需要一定时间的,一般为100mS-1S左右,而一个单片机执行一个机器周期的时间很短,时钟为10MH的周期为0.1μs,这样按键每一次动作程序就会多次检测按键,出现误判(一次按下,多次动作)。 /********************************
[单片机]
[单片机框架][bsp层][cx32l003][bsp_key] KEY配置和使用
按键的基本原理是设置单片机IO口(PB0-PB3)为输入状态,如DDRB = 0XF0(方向寄存器,“1”为输出,“0”为输入); 单片机一直检测按键端口(PB0-PB3)的状态,当端口为低电平时(即按键按下),实行相应的动作(比如控制LED灯)。 原理就是这么回事,但是正真实现时,按键会有抖动,要进行按键去抖,下图为按键按下时的抖动图。 按键实行一个动作过程是需要一定时间的,一般为100mS-1S左右,而一个单片机执行一个机器周期的时间很短,时钟为10MH的周期为0.1μs,这样按键每一次动作程序就会多次检测按键,出现误判(一次按下,多次动作)。 /********************************
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved