简单的消息队列(C语言实现)

#define ADV_DATA_DEPTH 10 //10帧数据深度
#define ADV_DATA_LENGTH_MAX 128 //每帧数据最大长度为128字节
//结构体声明
typedef struct{ 
    U8 ucHeadPtr; //头指针 
    U8 ucTailPtr; //尾指针 
    U8 ucAdvData[ADV_DATA_DEPTH][ADV_DATA_LENGTH_MAX];
}ADV_DATA_LIST;

ADV_DATA_LIST stAdvDataList;

//清消息队列
void Adv_Data_Clear(void)
{ 
    stAdvDataList.ucHeadPtr = stAdvDataList.ucTailPtr =0;
}

//获取队列长度
U8 Adv_Data_GetLength()
{ 
    U8 ucLen = 0; 
    if((stAdvDataList.ucHeadPtr >= ADV_DATA_DEPTH)||(stAdvDataList.ucTailPtr >= ADV_DATA_DEPTH)) //超过数组长度则清零
        Adv_Data_Clear(); 
    if( stAdvDataList.ucTailPtr >= stAdvDataList.ucHeadPtr)  //如果尾指针大于头指针 则长度正常取 (尾位置 - 头位置)
        ucLen = stAdvDataList.ucTailPtr - stAdvDataList.ucHeadPtr; 
    else  //否则若头位置大于尾位置 则表明数据二次写入 头指针靠近消息队列出口 尾指针靠近消息队列入口 长度取(尾位置 + 数组深度 - 头位置)
        ucLen = stAdvDataList.ucTailPtr + ADV_DATA_DEPTH - stAdvDataList.ucHeadPtr; 
        
    return ucLen;
}

//往队列里添加消息 返回0表示队列信息已满 无法再存储
U8 Adv_Data_Fill(U8 *buf,U8 length) //buf为消息内容 length为消息长度
{ 
    U8 ucLen = 0; 
    ucLen = Adv_Data_GetLength(); 
    if(ucLen >= ADV_DATA_DEPTH-1) //消息队列已满 
        return 0; 
    
    if(length>(ADV_DATA_LENGTH_MAX-1)) //存入数据过长 则只存入数组最大长度
        length=(ADV_DATA_LENGTH_MAX-1); 
    
    stAdvDataList.ucAdvData[stAdvDataList.ucTailPtr][0] = length; //转存时 每帧数据第一个字节用于存储数据长度信息
    
    for(ucLen=0;ucLen<length;ucLen++) 
        stAdvDataList.ucAdvData[stAdvDataList.ucTailPtr][1+ucLen] = buf[ucLen];

    stAdvDataList.ucTailPtr++; //尾指针位置下移 表示数据多了一帧
    
    if(stAdvDataList.ucTailPtr >= ADV_DATA_DEPTH)  //若尾指针位置超出队列长度 则重新置零
        stAdvDataList.ucTailPtr = 0;

    return 1;
}

//从队列获取消息 返回0表示队列信息已空 无法再读取
U8 Adv_Data_Get(U8 *buf,U8 *length)
{ 
    U8 ucLen = 0,temp8; 
    ucLen = Adv_Data_GetLength(); 
    if(ucLen == 0) //空 
        return 0; 
    
    *length = stAdvDataList.ucAdvData[stAdvDataList.ucHeadPtr][0]; //获取此帧数据的长度信息
    ucLen=*length; 
    
    for(temp8=0;temp8<ucLen;temp8++)
        buf[temp8]=stAdvDataList.ucAdvData[stAdvDataList.ucHeadPtr][1+temp8]; 
    
    stAdvDataList.ucHeadPtr++; //头指针位置下移 表示数据少了一帧
    
    if(stAdvDataList.ucHeadPtr >= ADV_DATA_DEPTH) //若头指针位置超出队列长度 则重新置零
        stAdvDataList.ucHeadPtr = 0; 
        
    return 1;
}

//使用方法
void main(void)
{ 
    Adv_Data_Clear(); 
    while(1) { 
        Adv_Data_Fill(…); 
        … 
        Adv_Data_Get(…); 
    }
}
posted @ 2020-06-04 13:23  苍月代表我  阅读(3805)  评论(0)    收藏  举报