数据通信队列的操作
modbus_data_queue.h头文件
/**************************************************************************
** 名称: modbus_data_queue.h头文件
* 日期:
* 作者:
* 描述: modbus处理数据队列
* 修改记录:
* 日期 修改人 修改问题
* XX XX XXX
***************************************************************************/
#ifndef __MODBUS_DATA_QUEUE_H__
#define __MODBUS_DATA_QUEUE_H__
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* __cplusplus */
#include "modbus_common.h"
#include <pthread.h>
#include <semaphore.h>
/**************************************************************************
** 宏定义
**************************************************************************/
#define M_MODBUS_MAX_QUEUE_CNT (50) /* 支持最大50个数据 */
#define M_MODBUS_MAX_DATA_LEN (64) /* 最大支持64字节的数据长度 */
/**************************************************************************
** 结构体声明
**************************************************************************/
/* 每一项的数据信息 */
typedef struct _modbus_node_data_st
{
uint32_t datalen; /* 数据长度 */
uint8_t *data; /* 数据内容 */
bool send_flag; /* 数据发送标志 */
struct _modbus_node_data_st *next;
} modbus_node_data_st;
/* 数据队列信息 */
typedef struct _modbus_queue_data_st
{
sem_t data_sem; /* 信号值 */
pthread_mutex_t lock; /* 队列锁,原子操作 */
uint16_t data_cnt; /* 实际队列数据个数 */
uint16_t max_data_cnt; /* 最大的数据个数 */
modbus_node_data_st *header; /* 数据队列链表 */
} modbus_queue_data_st;
/**************************************************************************
** 函数声明
**************************************************************************/
/**************************************************************************
* 函 数: int32_t modbus_queue_add_tail(modbus_queue_data_st *queue, uint8_t *data, uint32_t datalen);
* 描 述: 从尾部加入队列
* 入 参: modbus_queue_data_st *queue: 数据队列
uint8_t *data: 数据信息
uint32_t datalen: 队列数据信息
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_add_tail(modbus_queue_data_st *queue, uint8_t *data, uint32_t datalen);
/**************************************************************************
* 函 数: int32_t modbus_queue_add_head(modbus_queue_data_st *queue, uint8_t *data, uint32_t datalen);
* 描 述: 从首部加入队列
* 入 参: modbus_queue_data_st *queue: 数据队列
uint8_t *data: 数据信息
uint32_t datalen: 队列数据信息
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_add_head(modbus_queue_data_st *queue, uint8_t *data, uint32_t datalen);
/**************************************************************************
* 函 数: int32_t modbus_queue_remove_tail(modbus_queue_data_st *queue);
* 描 述: 从队列尾中删除一个数据
* 入 参: modbus_queue_data_st *queue: 数据队列
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_remove_tail(modbus_queue_data_st *queue);
/**************************************************************************
* 函 数: int32_t modbus_queue_remove_head(modbus_queue_data_st *queue);
* 描 述: 从队列头中删除一个数据
* 入 参: modbus_queue_data_st *queue: 数据队列
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_remove_head(modbus_queue_data_st *queue);
/**************************************************************************
* 函 数: int32_t modbus_queue_clear(modbus_queue_data_st *queue);
* 描 述: 清空队列数据
* 入 参: modbus_queue_data_st *queue: 队列数据
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_clear(modbus_queue_data_st *queue);
/**************************************************************************
* 函 数: int32_t modbus_queue_show(modbus_queue_data_st *queue)
* 描 述: 显示所有的队列数据
* 入 参: modbus_queue_data_st *queue: 队列数据
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_show(modbus_queue_data_st *queue);
/**************************************************************************
* 函 数: int32_t modbus_queue_create(modbus_queue_data_st *queue, uint16_t queue_cnt)
* 描 述: 创建一个数据队列
* 入 参: uint16_t queue_cnt : 队列数,最大限制是数量是50,至少数量是1
* 出 参: modbus_queue_data_st *queue: 队列数据
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_create(modbus_queue_data_st *queue, uint16_t queue_cnt);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif
modbus_data_queue.c源文件
/**************************************************************************
** 名称: modbus_data_queue.c文件
* 日期:
* 作者:
* 描述: modbus处理数据队列
* 修改记录:
* 日期 修改人 修改问题
* XX XX XX
***************************************************************************/
#include "modbus_data_queue.h"
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
/**************************************************************************
* 函 数: int32_t modbus_queue_add_tail(modbus_queue_data_st *queue, uint8_t *data, uint32_t datalen);
* 描 述: 从尾部加入队列
* 入 参: modbus_queue_data_st *queue: 数据队列
uint8_t *data: 数据信息
uint32_t datalen: 队列数据信息
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_add_tail
(
modbus_queue_data_st *queue,
uint8_t *data,
uint32_t datalen
)
{
int32_t ret = M_MODBUS_ERR;
modbus_node_data_st *node_data = NULL;
modbus_node_data_st *tmp_data = NULL;
M_MODBUS_TRACE_IN();
do
{
if ((NULL == queue) || (NULL == data)
|| (0 == datalen) || (M_MODBUS_MAX_DATA_LEN < datalen))
{
M_MODBUS_LOG_ERROR("input param null point.");
break;
}
modbus_log_hex_print(data, datalen);
(void)pthread_mute_lock(&queue->lock);
if (queue->max_data_cnt <= queue->data_cnt)
{
/* 队列已经满了,不能向队列中添加数据 */
(void)pthread_mute_unlock(&queue->lock);
M_MODBUS_LOG_WARN("modbus queue add tail, data count[%d] is over max queue count[%d], exit",
queue->data_cnt, queue->max_data_cnt);
ret = M_MODBUS_OK;
break;
}
/* 申请新的节点空间 */
node_data = (modbus_node_data_st *)malloc(sizeof(modbus_node_data_st));
if (NULL == node_data)
{
(void)pthread_mute_unlock(&queue->lock);
M_MODBUS_LOG_ERROR("modbus queue malloc new node space[%d] failed",
sizeof(modbus_node_data_st));
break;
}
(void)memset(node_data, 0, sizeof(modbus_node_data_st));
node_data->datalen = datalen;
node_data->send_flag = false;
/* 申请数据空间 */
node_data->data = (uint8_t *)malloc(datalen);
if (NULL == node_data->data)
{
(void)pthread_mute_unlock(&queue->lock);
M_MODBUS_LOG_ERROR("modbus queue malloc new node data space[%d] failed", datalen);
break;
}
(void)memset(node_data->data, 0, datalen);
(void)memcpy(node_data->data, data, datalen);
node_data->next = NULL;
tmp_data = queue->header->next;
if (NULL == tmp_data)
{
/* 队列为空 */
queue->header->next = node_data;
}
else
{
/* 查找到队列尾部 */
while (tmp_data->next)
{
tmp_data = tmp_data->next;
}
tmp_data->next = node_data;
}
queue->data_cnt++;
(void)pthread_mute_unlock(&queue->lock);
ret = M_MODBUS_OK;
/* 告诉发送任务信号,队列中有数据需要发送 */
//---
M_MODBUS_LOG_INFO("modbus queue to add new node of tail ok.");
}
while (0);
M_MODBUS_TRACE_OUT();
return ret;
}
/**************************************************************************
* 函 数: int32_t modbus_queue_add_head(modbus_queue_data_st *queue, uint8_t *data, uint32_t datalen);
* 描 述: 从首部加入队列
* 入 参: modbus_queue_data_st *queue: 数据队列
uint8_t *data: 数据信息
uint32_t datalen: 队列数据信息
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_add_head
(
modbus_queue_data_st *queue,
uint8_t *data,
uint32_t datalen
)
{
int32_t ret = M_MODBUS_ERR;
modbus_node_data_st *node_data = NULL;
modbus_node_data_st *tmp_data = NULL;
M_MODBUS_TRACE_IN();
do
{
if ((NULL == queue) || (NULL == data)
|| (0 == datalen) || (M_MODBUS_MAX_DATA_LEN < datalen))
{
M_MODBUS_LOG_ERROR("input param null point.");
break;
}
modbus_log_hex_print(data, datalen);
(void)pthread_mute_lock(&queue->lock);
if (queue->max_data_cnt <= queue->data_cnt)
{
/* 队列已经满了,不能向队列中添加数据 */
(void)pthread_mute_unlock(&queue->lock);
M_MODBUS_LOG_WARN("modbus queue add head, data count[%d] is over max queue count[%d], exit",
queue->data_cnt, queue->max_data_cnt);
ret = M_MODBUS_OK;
break;
}
/* 申请新的节点空间 */
node_data = (modbus_node_data_st *)malloc(sizeof(modbus_node_data_st));
if (NULL == node_data)
{
(void)pthread_mute_unlock(&queue->lock);
M_MODBUS_LOG_ERROR("modbus queue malloc new node space[%d] failed",
sizeof(modbus_node_data_st));
break;
}
(void)memset(node_data, 0, sizeof(modbus_node_data_st));
node_data->datalen = datalen;
node_data->send_flag = false;
/* 申请数据空间 */
node_data->data = (uint8_t *)malloc(datalen);
if (NULL == node_data->data)
{
(void)pthread_mute_unlock(&queue->lock);
M_MODBUS_LOG_ERROR("modbus queue malloc new node data space[%d] failed", datalen);
break;
}
(void)memset(node_data->data, 0, datalen);
(void)memcpy(node_data->data, data, datalen);
/* 添加到队列头部 */
tmp_data = queue->header->next;
node_data->next = tmp_data;
queue->header->next = node_data;
queue->data_cnt++;
(void)pthread_mute_unlock(&queue->lock);
ret = M_MODBUS_OK;
/* 告诉发送任务信号,队列中有数据需要发送 */
//---
M_MODBUS_LOG_INFO("modbus queue to add new node of head ok.");
}
while (0);
M_MODBUS_TRACE_OUT();
return ret;
}
/**************************************************************************
* 函 数: int32_t modbus_queue_clear(modbus_queue_data_st *queue);
* 描 述: 清空队列数据
* 入 参: modbus_queue_data_st *queue: 队列数据
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_clear(modbus_queue_data_st *queue)
{
int32_t ret = M_MODBUS_ERR;
modbus_node_data_st *node_data = NULL;
modbus_node_data_st *tmp_data = NULL;
M_MODBUS_TRACE_IN();
do
{
if (NULL == queue)
{
M_MODBUS_LOG_ERROR("input param null point.");
break;
}
/* 清空队列数据 */
(void)pthread_mute_lock(&queue->lock);
queue->data_cnt = 0;
tmp_data = queue->header;
while (tmp_data->next)
{
node_data = tmp_data->next;
tmp_data->next = tmp_data->next->next;
/* 先释放队列中的数据 */
if (NULL != node_data->data)
{
free(node_data->data);
node_data->data = NULL;
}
/* 再释放队列中节点数据 */
if (NULL != node_data)
{
free(node_data);
node_data = NULL;
}
}
(void)pthread_mute_unlock(&queue->lock);
ret = M_MODBUS_OK;
M_MODBUS_LOG_INFO("modbus queue clear ok.");
}
while (0);
M_MODBUS_TRACE_OUT();
return ret;
}
/**************************************************************************
* 函 数: int32_t modbus_queue_remove_tail(modbus_queue_data_st *queue);
* 描 述: 从队列尾中删除一个数据
* 入 参: modbus_queue_data_st *queue: 数据队列
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_remove_tail(modbus_queue_data_st *queue)
{
int32_t ret = M_MODBUS_ERR;
modbus_node_data_st *node_data = NULL;
modbus_node_data_st *tmp_data = NULL;
M_MODBUS_TRACE_IN();
do
{
if (NULL == queue)
{
M_MODBUS_LOG_ERROR("input param null point.");
break;
}
(void)pthread_mute_lock(&queue->lock);
/* 判断是否是空队列 */
if (0 == queue->data_cnt)
{
(void)pthread_mute_unlock(&queue->lock);
M_MODBUS_LOG_WARN("modbus queue count is 0.");
/* 如果不为空,直接删除队列 */
if (NULL != queue->header->next)
{
modbus_queue_clear(queue);
}
ret = M_MODBUS_OK;
break;
}
/* 队列数不为0,而队列是空,出错 */
if (NULL == queue->header->next)
{
/* 强制把队列数至成0 */
M_MODBUS_LOG_ERROR("modbus queue count is %d, queue header is not null.", queue->data_cnt);
queue->data_cnt = 0;
(void)pthread_mute_unlock(&queue->lock);
break;
}
/* 查找最后一个节点 */
tmp_data = queue->header;
node_data = tmp_data->next;
while (node_data->next)
{
tmp_data = node_data;
node_data = node_data->next;
}
tmp_data->next = NULL;
/* 释放数据 */
if (NULL != node_data->data)
{
free(node_data->data);
node_data->data = NULL;
}
/* 释放节点 */
free(node_data);
node_data = NULL;
queue->data_cnt--;
(void)pthread_mute_unlock(&queue->lock);
ret = M_MODBUS_OK;
M_MODBUS_LOG_INFO("modbus queue remove tail ok.");
}
while (0);
M_MODBUS_TRACE_OUT();
return ret;
}
/**************************************************************************
* 函 数: int32_t modbus_queue_remove_head(modbus_queue_data_st *queue);
* 描 述: 从队列头中删除一个数据
* 入 参: modbus_queue_data_st *queue: 数据队列
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_remove_head(modbus_queue_data_st *queue)
{
int32_t ret = M_MODBUS_ERR;
modbus_node_data_st *node_data = NULL;
M_MODBUS_TRACE_IN();
do
{
if (NULL == queue)
{
M_MODBUS_LOG_ERROR("input param null point.");
break;
}
(void)pthread_mute_lock(&queue->lock);
/* 判断是否是空队列 */
if (0 == queue->data_cnt)
{
(void)pthread_mute_unlock(&queue->lock);
M_MODBUS_LOG_WARN("modbus queue count is 0.");
/* 如果不为空,直接删除队列 */
if (NULL != queue->header->next)
{
modbus_queue_clear(queue);
}
ret = M_MODBUS_OK;
break;
}
/* 队列数不为0,而队列是空,出错 */
node_data = queue->header->next;
if (NULL == node_data)
{
/* 强制把队列数至成0 */
M_MODBUS_LOG_ERROR("modbus queue count is %d, queue header is not null.", queue->data_cnt);
queue->data_cnt = 0;
(void)pthread_mute_unlock(&queue->lock);
break;
}
queue->header->next = node_data->next;
/* 释放数据 */
if (NULL != node_data->data)
{
free(node_data->data);
node_data->data = NULL;
}
/* 释放节点 */
free(node_data);
node_data = NULL;
queue->data_cnt--;
(void)pthread_mute_unlock(&queue->lock);
ret = M_MODBUS_OK;
M_MODBUS_LOG_INFO("modbus queue remove head ok.");
}
while (0);
M_MODBUS_TRACE_OUT();
return ret;
}
/**************************************************************************
* 函 数: int32_t modbus_queue_show(modbus_queue_data_st *queue)
* 描 述: 显示所有的队列数据
* 入 参: modbus_queue_data_st *queue: 队列数据
* 出 参: void
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_show(modbus_queue_data_st *queue)
{
int32_t ret = M_MODBUS_ERR;
modbus_node_data_st *tmp_data = NULL;
M_MODBUS_TRACE_IN();
do
{
if (NULL == queue)
{
M_MODBUS_LOG_ERROR("input param null point.");
break;
}
/* 清空队列数据 */
(void)pthread_mute_lock(&queue->lock);
M_MODBUS_LOG_DEBUG("modbus queue count[%d]", queue->data_cnt);
tmp_data = queue->header->next;
while (tmp_data)
{
modbus_log_hex_print(tmp_data->data, tmp_data->datalen);
tmp_data = tmp_data->next;
}
(void)pthread_mute_unlock(&queue->lock);
ret = M_MODBUS_OK;
M_MODBUS_LOG_INFO("modbus queue show ok.");
}
while (0);
M_MODBUS_TRACE_OUT();
return ret;
}
/**************************************************************************
* 函 数: int32_t modbus_queue_create(modbus_queue_data_st *queue, uint16_t queue_cnt)
* 描 述: 创建一个数据队列
* 入 参: uint16_t queue_cnt : 队列数,最大限制是数量是50。
如果取值是0,则默认是50
* 出 参: modbus_queue_data_st *queue: 队列数据
* 返回值: int32_t M_MODBUS_OK - 成功
M_MODBUS_ERR - 失败
**************************************************************************/
int32_t modbus_queue_create(modbus_queue_data_st *queue, uint16_t queue_cnt)
{
int32_t ret = M_MODBUS_ERR;
M_MODBUS_TRACE_IN();
do
{
if ((NULL == queue) || (M_MODBUS_MAX_QUEUE_CNT < queue_cnt))
{
M_MODBUS_LOG_ERROR("input param null point.");
break;
}
/* 创建队列互斥锁 */
if (0 != pthread_mutex_init(&queue->lock, NULL))
{
M_MODBUS_LOG_ERROR("create queue mutex lock failed");
break;
}
/* 创建队列信号量 */
if (0 != sem_init(&queue->data_sem, 0, 0))
{
M_MODBUS_LOG_ERROR("create queue sem init failed");
break;
}
/* 初始化队列信息 */
if (0 == queue_cnt)
{
queue_cnt = M_MODBUS_MAX_QUEUE_CNT;
}
queue->max_data_cnt = queue_cnt; /* 最大队列个数 */
queue->data_cnt = 0;
queue->header = (modbus_node_data_st *)malloc(sizeof(modbus_node_data_st));
if (NULL == queue->header)
{
M_MODBUS_LOG_ERROR("create queue header node failed");
break;
}
(void)memset(queue->header, 0, sizeof(modbus_node_data_st));
ret = M_MODBUS_OK;
M_MODBUS_LOG_INFO("modbus queue create ok.");
}
while (0);
M_MODBUS_TRACE_OUT();
return ret;
}