#define __DTU_INNER_FUNC__ #ifdef __DTU_INNER_FUNC__ #define MAX_UART_SIZE (32*1024) // 用户共享内存 kal_mutexid dtu_mutex; #define MUTEX_BEGIN kal_take_mutex(dtu_mutex) #define MUTEX_END kal_give_mutex(dtu_mutex) #define MAX_SIZE (1024*1024-1024*1024/56 -2*MAX_UART_SIZE) // 1MB-MAX_L_SIZE struct arrQueue // 声明队列的头和尾节点,数据存储元素 { unsigned char data[MAX_SIZE+1]; // 定义数组队列元素,能容纳MAX_SIZE字节 unsigned int front; // 含有数据的第一个下标 unsigned int rear; // 含有数据的最后一个元素下标,rear所在的元素不存数据 }queue; void initQueue() { memset(queue.data, '\0', sizeof(queue.data)); queue.front = 0; queue.rear = 0; } void enQueue(unsigned char *pElement, unsigned int *len)//向queue中存入长度为len字节数据,len返回长度实际存入的长度 { // 如果rear在front前面一位,则表明缓冲区已经满,无法存入数据 // 当rear在最后一位,front在最前一位,也是没有空间 if ((queue.rear+1)%(MAX_SIZE+1) == queue.front) { *len = 0; return; } // 如果rear在front前面一位以上,则rear与front之间就是空闲区域,长度为front-rear-1 if (queue.rear+1<queue.front) { // 存入数据位len与剩余空间较小者 *len = *len <= (queue.front-queue.rear-1) ? *len : queue.front-queue.rear-1; memcpy(&queue.data[queue.rear], pElement, *len); queue.rear += *len; } else // 如果 rear在front后面,或者相等时,并且有空间 { // 剩余空间大小为 MAX_SIZE-(rear-front), 可写入的数据位长度与剩余空间较小者 *len = *len <= (MAX_SIZE-(queue.rear-queue.front)) ? *len : MAX_SIZE-(queue.rear-queue.front); // 如果front为0,则rear就在小于等于MAX_SIZE的位置,只需要队列尾部保存数据 if (queue.front==0) { memcpy(&queue.data[queue.rear], pElement, *len); queue.rear += *len; } else // 如果front不为0,则 队列尾保存了数据,队列头部有可能需要保存数据 { // 如果尾部可以保存数据,则直接保存数据 if ((MAX_SIZE+1-queue.rear) >= *len) { memcpy(&queue.data[queue.rear], pElement, *len); queue.rear = (queue.rear + *len)%(MAX_SIZE+1); } else // 如果尾部保存不了数据,头部还需要保存数据,尾部保存的数据长度为:MAX_SIZE+1-queue.rear { memcpy(&queue.data[queue.rear], pElement, MAX_SIZE+1-queue.rear); queue.rear = *len-(MAX_SIZE+1-queue.rear); memcpy(&queue.data[0], pElement+(*len-queue.rear), queue.rear); } } } } void deQueue(unsigned char *pElement, unsigned int *len)//向queue中取出长度为len字节数据,len返回长度实际取出的长度 { // 如果为空数据 if ((*len==0) || (queue.rear==queue.front)) { *len = 0; return; } // 如果 rear在front后面,则直接取出数据 if (queue.rear > queue.front) { *len = *len <= (queue.rear-queue.front) ? *len : (queue.rear-queue.front); memcpy(pElement, &queue.data[queue.front], *len); queue.front += *len; } else // 如果rear在front前面 { // 队列中数据长度为 rear+(MAX_SIZE+1-front) *len = *len <= queue.rear+(MAX_SIZE+1-queue.front) ? *len : queue.rear+(MAX_SIZE+1-queue.front); // 如果尾部可以取出*len的数据则直接取,尾部数据大小为MAX_SIZE+1-queue.front if (*len <= MAX_SIZE+1-queue.front) { memcpy(pElement, &queue.data[queue.front], *len); queue.front = (queue.front + *len) % (MAX_SIZE+1); } else // 如果尾部取完,还需要取数据,则取头部数据 { memcpy(pElement, &queue.data[queue.front], (MAX_SIZE+1-queue.front)); queue.front = *len-(MAX_SIZE+1-queue.front); memcpy(&pElement[*len-queue.front], &queue.data[0], queue.front); } } } unsigned int lenQueue() // 队列存了多少数据 { return (queue.rear+MAX_SIZE+1-queue.front)%(MAX_SIZE+1); } /////////////////////////////////长度数组队列/////////////////////////////////// #define MAX_L_SIZE 1024*1024/56 //1024*1024/56+1 struct LQueue { unsigned int data[MAX_L_SIZE]; unsigned int front; unsigned int rear; }lqueue; void initLQueue() { memset(lqueue.data, '\0', sizeof(lqueue.data)); lqueue.front = 0; lqueue.rear = 0; } void enLQueue(unsigned int *len) // 插入长度len, len不能为0,插入正确len不改变,插入错误len为0 { if ((lqueue.rear+1)%MAX_L_SIZE == lqueue.front) // 队列已满 { *len = 0; } else { lqueue.data[lqueue.rear] = *len; lqueue.rear = (lqueue.rear+1)%MAX_L_SIZE; } } void deLQueue(unsigned int *len) // 返回一个长度len数值,len为0则队列为空 { if (lqueue.rear == lqueue.front) // 队列为空 { *len = 0; } else { *len = lqueue.data[lqueue.front]; lqueue.data[lqueue.front] = 0; // 还原数据为0 lqueue.front = (lqueue.front+1)%MAX_L_SIZE; } } unsigned int lenLQueue() // 获取队列存入多少len数值 { return (lqueue.rear+MAX_L_SIZE-lqueue.front)%MAX_L_SIZE; } /////////////////////////////////长度队列/////////////////////////////////// #endif #undef __DTU_INNER_FUNC__ // 缓冲区对外两个接口函数 ////////////////////////////////////////////////////////////////////// // 写入数据到缓冲区,若缓冲区存不下需要放入的数据,则删除前面存入的数据 unsigned char dtu_buffer_add_data(const unsigned char *pbuf, unsigned int len) { unsigned int len_t = 0; int i = 0; if ((pbuf==NULL) || (len==0)) { return 0; } MUTEX_BEGIN; while (MAX_SIZE-lenQueue() < len) // 如果缓冲区满了,则删除以前的的数据 { deLQueue(&len_t); deQueue((unsigned char*)g_dtu_buffer, &len_t); trace_print("add_data deQueue【%d-%s】\r\n", len_t, g_dtu_buffer); } if (MAX_L_SIZE==lenLQueue()+1) // 如果长度队列满了,则删除一个长度队列 { deLQueue(&len_t); deQueue((unsigned char*)g_dtu_buffer, &len_t); trace_print("add_data deQueue【%d-%s】\r\n", len_t, g_dtu_buffer); } for (i=len-DTU_DATA_LEN; i>=0; i-=DTU_DATA_LEN) // i为剩余存储一组数据的剩余长度,如果小于0,表示不足一组数据,等于0表示刚好一组数据 { len_t = DTU_DATA_LEN; trace_print("lenQueue=%d,%d,%d\r\n", lenQueue(), len_t, len-i-DTU_DATA_LEN); enLQueue(&len_t); enQueue((unsigned char*)&pbuf[len-i-DTU_DATA_LEN], &len_t); } // 存储不足一组数据的数据 len_t = len%DTU_DATA_LEN; if (len_t) { enLQueue(&len_t); enQueue((unsigned char*)&pbuf[len-len_t], &len_t); trace_print("lenQueue=%d,%d\r\n", lenQueue(), len_t); } MUTEX_END; return 1; } // 从缓冲区获取内容 unsigned char dtu_buffer_get_data(unsigned char* pbuf, unsigned int* len) { unsigned char result = 0; if (pbuf==NULL) return result; MUTEX_BEGIN; deLQueue((unsigned int*)len); deQueue((unsigned char*)pbuf, (unsigned int*)len); if (*len) // 如果有数据,返回1 { result = 1; } MUTEX_END; return result; } /////////////////////////////////////////////////////////////////////////
// 使用时需要先初始化
///////////////////////////// 初始化队列 initQueue(); initLQueue(); ///////////////////////////// 初始化队列完毕
// 然后调用两个函数进行存取数据,上面数组队列对外接口只有两个函数和初始化函数而已
// 存入数据 dtu_buffer_add_data((unsigned char*)uart_buffer2, len); // 添加数据到发送队列 // 取出数据 if (KAL_TRUE==dtu_buffer_get_data((unsigned char*)g_send_data_buffer, (unsigned int*)&len)) // 取数据 { g_send_data_buffer[len] = '\0'; u8_heartbeat_times = 0; }
数据队列测试原型见http://blog.csdn.net/zeroboundary/article/details/9295979