嵌入式DTU实际用到的数组队列形式共享内存实现结果

来源:互联网 发布:ajax提交json格式数据 编辑:程序博客网 时间:2024/06/03 22:39
#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_SIZEstruct 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+1struct 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

0 0