通信队列的操作

数据通信队列的操作

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;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值