×
嵌入式 > 技术百科 > 详情

FIFO程序设计解析(队列指针)

发布时间:2020-09-23 发布时间:
|
typedef struct {
    QUEUE_DATA_TYPE     *Out;                  
    QUEUE_DATA_TYPE     *In;                    
    QUEUE_DATA_TYPE     *End;                  
    u16              NData;                  
    u16              MaxData;                
    
    u8               (* ReadEmpty)();        
    u8               (* WriteFull)();        
    QUEUE_DATA_TYPE     Buf[1];                
} DataQueue;
u8 QueueCreate(void *Buf,
                          u32 SizeOfBuf,
                          u8 (* ReadEmpty)(),
                          u8 (* WriteFull)()
                          )
{
    DataQueue *Queue;
    
    if (Buf != NULL && SizeOfBuf >= (sizeof(DataQueue)))        
    {
        Queue = (DataQueue *)Buf;//强制转换成数据队列类型
        
        NVIC_SETPRIMASK(); //disable all system interrupts 
                                                               
        Queue->MaxData = (SizeOfBuf - (u32)(((DataQueue *)0)->Buf)) / 
                         sizeof(QUEUE_DATA_TYPE);              
        Queue->End = Queue->Buf + Queue->MaxData;              
        Queue->Out = Queue->Buf;
        Queue->In = Queue->Buf;
        Queue->NData = 0;
        Queue->ReadEmpty = ReadEmpty;
        Queue->WriteFull = WriteFull;
 
        NVIC_RESETPRIMASK(); //enable all system interrupts
        
        return QUEUE_OK;
    }
    else
    {
        return NOT_OK;
    }
}
 
 
u8 QueueRead(QUEUE_DATA_TYPE *Ret, void *Buf)
{
    u8 err;
    DataQueue *Queue;
 
    err = NOT_OK;
    if (Buf != NULL)                                            
    {                                                          
        Queue = (DataQueue *)Buf;
        
        NVIC_SETPRIMASK(); //disable all system interrupts 
        
        if (Queue->NData > 0)                                  
        {                                                      
            *Ret = Queue->Out[0];   
                      
 
Queue->Out++;                                      
            if (Queue->Out >= Queue->End)
            {
           
                Queue->Out = Queue->Buf;
            }
            Queue->NData--;                                    
            err = QUEUE_OK;
        }
        else
        {                                                      
            err = QUEUE_EMPTY;
            if (Queue->ReadEmpty != NULL)                      
            {
                err = Queue->ReadEmpty(Ret, Queue);
            }
        }
        
        NVIC_RESETPRIMASK(); //enable all system interrupts
        
    }
    return err;
}
 
#ifndef EN_QUEUE_WRITE
#define EN_QUEUE_WRITE      1
#endif
 
#if EN_QUEUE_WRITE > 0
 
u8 QueueWrite(void *Buf, QUEUE_DATA_TYPE Data)
{
    u8 err;
    DataQueue *Queue;
 
    err = NOT_OK;
    if (Buf != NULL)                                                    
    {
        Queue = (DataQueue *)Buf;
        
        NVIC_SETPRIMASK(); //disable all system interrupts 
        
        if (Queue->NData < Queue->MaxData)                              
        {   
             
            Queue->In[0] = Data;                                        
            Queue->In++;                                                
            if (Queue->In >= Queue->End)
            {
                Queue->In = Queue->Buf;
            }
            Queue->NData++;                                            
            err = QUEUE_OK;
        }
        else
        {                                                              
            err = QUEUE_FULL;
            if (Queue->WriteFull != NULL)                              
            {
                err = Queue->WriteFull(Queue, Data, Q_WRITE_MODE);
            }
        }
        
        NVIC_RESETPRIMASK(); //enable all system interrupts
        
    }
    return err;
}
#endif
 
#ifndef EN_QUEUE_WRITE_FRONT
#define EN_QUEUE_WRITE_FRONT    0
#endif
 
#if EN_QUEUE_WRITE_FRONT > 0
 
u8 QueueWriteFront(void *Buf, QUEUE_DATA_TYPE Data)
{
    u8 err;
    DataQueue *Queue;
 
    err = NOT_OK;
    if (Buf != NULL)                                                    
    {
        Queue = (DataQueue *)Buf;
        
        if (Queue->NData < Queue->MaxData)                              
        {                                                              
            Queue->Out--;                                              
            if (Queue->Out < Queue->Buf)
            {
                Queue->Out = Queue->End - 1;
            }
            Queue->Out[0] = Data;                                      
            Queue->NData++;                                            
            err = QUEUE_OK;
        }
        else
        {                                                              
            err = QUEUE_FULL;
            if (Queue->WriteFull != NULL)                              
            {
                err = Queue->WriteFull(Queue, Data, Q_WRITE_FRONT_MODE);
            }
        }
    }
    return err;
}
 
#endif
 
#ifndef EN_QUEUE_NDATA
#define EN_QUEUE_NDATA    1
#endif
 
#if EN_QUEUE_NDATA > 0
 
u16 QueueNData(void *Buf)
{
    u16 temp;
    
    temp = 0;    
    
    NVIC_SETPRIMASK(); //disable all system interrupts 
    
    if (Buf != NULL)
    {
        temp = ((DataQueue *)Buf)->NData;
    }
    
    NVIC_RESETPRIMASK(); //enable all system interrupts
    
    return temp;
}
 
#endif
 
#ifndef EN_QUEUE_SIZE
#define EN_QUEUE_SIZE    1
#endif
 
#if EN_QUEUE_SIZE > 0
 
u16 QueueSize(void *Buf)
{
    u16 temp;
    
    temp = 0;
    if (Buf != NULL)
    {
        temp = ((DataQueue *)Buf)->MaxData;
    }
    return temp;
}
 
#endif
 
#ifndef EN_QUEUE_FLUSH
#define EN_QUEUE_FLUSH    1
#endif
 
#if EN_QUEUE_FLUSH > 0
 
void QueueFlush(void *Buf)
{
    DataQueue *Queue;
    
    if (Buf != NULL)
    {                
        Queue = (DataQueue *)Buf;
        Queue->Out = Queue->Buf;
        Queue->In = Queue->Buf;
        Queue->NData = 0;  
    }
}
 
#endif
 
/*********************************************************************************************************
**      
 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
VR十大误区:眼睛离屏幕太近真的会瞎吗?