LL01/code_boot_out/qm/common/queue_entity.c
2025-04-26 16:03:23 +08:00

796 lines
18 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** ##########################################################################
** Filename : queue_entity.c
** Project :
** Module :
** Processor :
** Version : 1.2
** Compiler :
** Date/Time :
** Abstract :
** Contents :
** Note : 消息隊列
順序循環消息隊列 ---- 溢出丟棄
約定:1.隊列尾指針為實際末尾無素的下一位置. 2.浪費一個元素空間,以"隊列頭指
針在隊列尾指針的下一位置(指環狀的下一位置)上作為隊列呈"滿"狀態的標誌.
seq為空循環隊列的判定條件為:頭尾重合 seq.front==seq.rear
seq為滿循環隊列的判定條件為:隊尾趕上隊頭 (seq.rear+1)%MAXSIZE==seq.front
注: 申請的隊列空間,buf至少2個.
注: 定義隊列緩存時;可以多加一個地址緩存;但是記住在調用queue_init函數時;參數length的值就是隊列緩存大小值;
**
** (c) Copyright dmdz Co.,Ltd
** --------------------------------------------------------------------------
** R E V I S I O N H I S T O R Y
** --------------------------------------------------------------------------
** Date Ver Author Description
** -20230602- --V1.2-- --mingyea--- --修改--
** #########################################################################*/
/*---------------------------------------------------------------------------
- I N C L U D E F I L E S
----------------------------------------------------------------------------*/
#include "common_types.h"
#include "queue_entity.h"
/*---------------------------------------------------------------------------
- D E F I N E S / M A C R O S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- T Y P E D E F I N I T I O N S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- S T A T I C V A R I A B L E S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- G L O B A L V A R I A B L E S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- C O N S T A N T S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- F U N C T I O N P R O T O T Y P E
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
|Prototype : void queue_init(sequential_queue_s *seq, sequential_queue_elem *pdata, u8 length , u8 unit_sizes)
|Called by :
|Preconditions :
|Input parameters : seq : 順序隊列pdata 隊列元素的數據; length隊列長度,unit_sizes 元素的字節長度;
|Output parameters :
|Return value :
|Description : 初始化一個空順序隊列
----------------------------------------------------------------------------*/
void queue_init(sequential_queue_s *seq, sequential_queue_elem *pdata, u8 length , u8 unit_sizes)
{
seq->front = 0u;
seq->rear=0u;
seq->base = pdata;
seq->length = length;
seq->unit_sizes = unit_sizes;
} /* End of function queue_init*/
/*---------------------------------------------------------------------------
|Prototype : void queue_clear(sequential_queue_s *seq)
|Called by :
|Preconditions :
|Input parameters : seq : 順序隊列;
|Output parameters :
|Return value :
|Description : 清空隊列
----------------------------------------------------------------------------*/
void queue_clear(sequential_queue_s *seq)
{
QUEUE_CPU_SR_ALLOC(); /*PRQA S 2981*/
QUEUE_CPU_CRITICAL_ENTER();
seq->front = 0u;
seq->rear=0u;
QUEUE_CPU_CRITICAL_EXIT();
} /* End of function queue_clear*/
/*---------------------------------------------------------------------------
|Prototype : QUEUE_RIGHT_FLAG_E queue_get_empty(sequential_queue_s seq)
|Called by :
|Preconditions :
|Input parameters : seq : 順序隊列;
|Output parameters :
|Return value : QUEUE_RIGHT_FLAG_E: 若隊列seq為空隊列則返回ture 否則返回false
|Description : 判斷隊列是否為空;
----------------------------------------------------------------------------*/
QUEUE_RIGHT_FLAG_E queue_get_empty(sequential_queue_s seq)
{
QUEUE_RIGHT_FLAG_E l_resutl;
QUEUE_CPU_SR_ALLOC(); /*PRQA S 2981*/
QUEUE_CPU_CRITICAL_ENTER();
/*隊列空的標誌*/
if(seq.front==seq.rear)
{
l_resutl = QUEUE_TRUE;
}
else
{
l_resutl = QUEUE_FALSE;
}
QUEUE_CPU_CRITICAL_EXIT();
return l_resutl;
} /* End of function queue_get_empty*/
/*---------------------------------------------------------------------------
|Prototype : u16 queue_get_length(sequential_queue_s seq)
|Called by :
|Preconditions :
|Input parameters : seq : 順序隊列;
|Output parameters :
|Return value : 長度數目
|Description : 求出隊列不為空元素的數目;
----------------------------------------------------------------------------*/
u16 queue_get_length(sequential_queue_s seq)
{
#ifdef QUEUE_MOD_ENABLE
u16 length = (seq.length + seq.rear) - seq.front ;
QUEUE_CPU_SR_ALLOC(); /*PRQA S 2981*/
QUEUE_CPU_CRITICAL_ENTER();
length %= seq.length;
#else
u16 length ;
QUEUE_CPU_SR_ALLOC(); /*PRQA S 2981*/
QUEUE_CPU_CRITICAL_ENTER();
if( seq.rear >= seq.front)
{
length = seq.rear - seq.front;
}
else
{
#if 0
length = seq.length + seq.rear - seq.front;
#else
length = seq.length + seq.rear;
length -= seq.front;
#endif
}
#endif
QUEUE_CPU_CRITICAL_EXIT();
return length;
} /* End of function queue_get_length*/
/*---------------------------------------------------------------------------
|Prototype : QUEUE_OPERATE_FLAG_E queue_get_head(sequential_queue_s *seq,sequential_queue_elem *element)
|Called by :
|Preconditions :
|Input parameters : seq : 順序隊列;
|Output parameters : element: 將頭元素數據傳給外部的變量;
|Return value : 是否操作成功
|Description : 若隊列不為空則用e返回seq的隊頭元素
----------------------------------------------------------------------------*/
QUEUE_OPERATE_FLAG_E queue_get_head(sequential_queue_s *seq,sequential_queue_elem *element)
{
sequential_queue_elem *pdata;
u8 j;
QUEUE_OPERATE_FLAG_E l_resutl = QUEUE_OK;
QUEUE_CPU_SR_ALLOC(); /*PRQA S 2981*/
QUEUE_CPU_CRITICAL_ENTER();
if(seq->front == seq->rear)
{
l_resutl = QUEUE_ERRO;
}
if( l_resutl == QUEUE_OK)
{
/* 將隊頭元素賦值給e */
#ifdef QUEUE_MOD_ENABLE
pdata = seq->base + ( (seq->front%seq->length) * seq->unit_sizes) ;
#else
pdata = seq->base + ((seq->front) * seq->unit_sizes) ;
#endif
for(j=0u;j<seq->unit_sizes;j++)
{
element[j] = *pdata;
/* 該語句刪除隊列元素; */
/* *pdata = 0;*/
pdata += sizeof(sequential_queue_elem);
}
}
QUEUE_CPU_CRITICAL_EXIT();
return l_resutl;
} /* End of function queue_get_head*/
/*---------------------------------------------------------------------------
|Prototype : QUEUE_OPERATE_FLAG_E queue_add_element(sequential_queue_s *seq,const sequential_queue_elem *element)
|Called by :
|Preconditions :
|Input parameters : seq : 順序隊列;
|Output parameters : element: 將頭元素數據傳給外部的變量;
|Return value : 是否操作成功
|Description : 若隊列未滿則插入元素e為seq新的隊尾元素
----------------------------------------------------------------------------*/
/*lint -efunc(818,queue_add_element) */ /*建議16.7 函數的指針參數 如果不是用來修改的話,建議聲明指向 const 類型*/
QUEUE_OPERATE_FLAG_E queue_add_element(sequential_queue_s *seq,const sequential_queue_elem *element)
{
sequential_queue_elem *pdata;
u8 i;
QUEUE_OPERATE_FLAG_E l_resutl= QUEUE_OK;
#ifdef QUEUE_MOD_ENABLE
#else
u16 tmp_rear ;
#endif
QUEUE_CPU_SR_ALLOC(); /*PRQA S 2981*/
QUEUE_CPU_CRITICAL_ENTER();
#ifdef QUEUE_MOD_ENABLE
/* 隊列滿的標誌 */
if( ((seq->rear+1u)%seq->length) == seq->front)
#else
tmp_rear = seq->rear + 1u;
if( tmp_rear >= seq->length)
{
tmp_rear = 0u;
}
if(tmp_rear == seq->front)
#endif
{
l_resutl = QUEUE_ERRO;
}
if( l_resutl == QUEUE_OK)
{
/*將元素e賦值給隊尾*/
#ifdef QUEUE_MOD_ENABLE
pdata = seq->base + ( (seq->rear%seq->length) * seq->unit_sizes) ;
#else
pdata = seq->base + ((seq->rear) * seq->unit_sizes) ;
#endif
for(i=0u;i<seq->unit_sizes;i++)
{
*pdata = element[i];
pdata += sizeof(sequential_queue_elem);
}
/*seq->base[seq->rear%seq->length]=element;*/
/* rear指針向後移一位若到最後就轉到 數組頭部*/
#ifdef QUEUE_MOD_ENABLE
seq->rear=(seq->rear+1u)%seq->length;
#else
seq->rear++;
if( seq->rear >= seq->length)
{
seq->rear = 0u;
}
#endif
}
QUEUE_CPU_CRITICAL_EXIT();
return l_resutl;
} /* End of function queue_add_element*/
/*---------------------------------------------------------------------------
|Prototype : QUEUE_OPERATE_FLAG_E queue_del_element(sequential_queue_s *seq,sequential_queue_elem *element)
|Called by :
|Preconditions :
|Input parameters : seq : 順序隊列;
|Output parameters : element: 將頭元素數據傳給外部的變量;
|Return value : 是否操作成功
|Description : 若隊列未滿則刪除元素e為seq新的隊尾元素
----------------------------------------------------------------------------*/
QUEUE_OPERATE_FLAG_E queue_del_element(sequential_queue_s *seq,sequential_queue_elem *element)
{
QUEUE_OPERATE_FLAG_E l_resutl= QUEUE_OK;
sequential_queue_elem *pdata;
u8 i;
QUEUE_CPU_SR_ALLOC(); /*PRQA S 2981*/
QUEUE_CPU_CRITICAL_ENTER();
/* 隊列空的判斷 */
if( seq->rear == seq->front)
{
l_resutl = QUEUE_ERRO;
}
if( l_resutl == QUEUE_OK)
{
/* 將隊頭元素賦值給e */
#ifdef QUEUE_MOD_ENABLE
pdata = seq->base + ( (seq->front%seq->length) * seq->unit_sizes) ;
#else
pdata = seq->base + ((seq->front) * seq->unit_sizes );
#endif
for(i=0u;i<seq->unit_sizes;i++)
{
element[i] = *pdata;
/* 該語句刪除隊列元素; */
*pdata = 0u;
pdata += sizeof(sequential_queue_elem);
}
/* *element = seq->base[seq->front]; */
/* 該語句刪除隊列元素; */
/*seq->base[seq->front] = 0; */
#ifdef QUEUE_MOD_ENABLE
/* front 指針向後移一位置 */
seq->front=(seq->front+1u)%seq->length;
#else
seq->front++;
if( seq->front >= seq->length)
{
seq->front = 0u;
}
#endif
}
QUEUE_CPU_CRITICAL_EXIT();
return l_resutl;
} /* End of function queue_del_element*/
#if 0
/*---------------------------------------------------------------------------
|Prototype : QUEUE_OPERATE_FLAG_E queue_del_one_element(sequential_queue_s *seq,u16 i,sequential_queue_elem *element)
|Called by :
|Preconditions :
|Input parameters : seq : 順序隊列;
|Output parameters : element: 將頭元素數據傳給外部的變量;
|Return value : 是否操作成功
|Description : 若隊列不空則刪除Q中的某一個元素
----------------------------------------------------------------------------*/
QUEUE_OPERATE_FLAG_E queue_del_one_element(sequential_queue_s *seq,u16 i,sequential_queue_elem *element)
{
QUEUE_OPERATE_FLAG_E l_resutl= QUEUE_OK;
sequential_queue_elem *pdata;
u8 j;
#ifdef QUEUE_MOD_ENABLE
#else
u16 tmp_i;
#endif
QUEUE_CPU_SR_ALLOC(); /*PRQA S 2981*/
QUEUE_CPU_CRITICAL_ENTER();
/* 隊列空的判斷 */
if( seq->rear == seq->front)
{
l_resutl = QUEUE_ERRO;
}
if( l_resutl == QUEUE_OK)
{
l_resutl = QUEUE_ERRO;
#if 0
/* 將隊頭元素賦值給e */
*element = seq->base[i%seq->length];
/* 該語句刪除隊列元素; */
seq->base[i%seq->length] = 0;
#else
/* 將隊頭元素賦值給e */
#ifdef QUEUE_MOD_ENABLE
pdata = seq->base + ( (i%seq->length) * seq->unit_sizes ) ;
#else
if( i < seq->length)
{
tmp_i = i;
}
else
{
tmp_i = i - seq->length ;
}
pdata = seq->base + (tmp_i * seq->unit_sizes );
#endif
for(j=0u;j<seq->unit_sizes;j++)
{
element[j] = *pdata;
/* 該語句刪除隊列元素; */
*pdata = 0u;
pdata += sizeof(sequential_queue_elem);
}
#endif
#ifdef QUEUE_MOD_ENABLE
if( (seq->front%seq->length) == (i%seq->length) )
#else
/* 如果要刪除的是隊頭 */
if( seq->front == tmp_i )
#endif
{
#ifdef QUEUE_MOD_ENABLE
seq->front = ( seq->front + 1u)%seq->length;
#else
/* front 指針向後移一位置 */
seq->front++;
if( seq->front >= seq->length)
{
seq->front = 0u;
}
#endif
l_resutl = QUEUE_OK;
}
if( l_resutl == QUEUE_ERRO)
{
/* 如果要刪除的是隊尾 */
#ifdef QUEUE_MOD_ENABLE
if( ( ( (seq->rear + seq->length) -1u) %seq->length) == (i%seq->length) )
#else
tmp_i++;
if( tmp_i >= seq->length)
{
tmp_i = 0u;
}
if( seq->rear == tmp_i )
#endif
{
#ifdef QUEUE_MOD_ENABLE
/* rear 指針向前移一位置 */
seq->rear = ( (seq->rear + seq->length) -1u) %seq->length;
#else
if( seq->rear >0u )
{
seq->rear--;
}
else
{
seq->rear = seq->length -1u;
}
#endif
l_resutl = QUEUE_OK;
}
}
/*lint -e(838) */ /*局部變量只作臨界交換用;所以提示沒作用*/
/* l_resutl = QUEUE_OK; */
}
QUEUE_CPU_CRITICAL_EXIT();
return l_resutl;
} /* End of function queue_del_one_element*/
/*---------------------------------------------------------------------------
|Prototype : QUEUE_OPERATE_FLAG_E queue_del_one_element_by_flag(sequential_queue_s *seq,u16 i,sequential_queue_elem *element,QUEUE_DEL_FLAG_E fdo)
|Called by :
|Preconditions :
|Input parameters : seq : 順序隊列i表示元素地址; fdo 刪除的方法
|Output parameters : element: 將頭元素數據傳給外部的變量;
|Return value : 是否操作成功
|Description : 若隊列不空則刪除Q中的某一個元素
----------------------------------------------------------------------------*/
QUEUE_OPERATE_FLAG_E queue_del_one_element_by_flag(sequential_queue_s *seq,u16 i,sequential_queue_elem *element,QUEUE_DEL_FLAG_E fdo)
{
QUEUE_OPERATE_FLAG_E l_resutl= QUEUE_OK;
sequential_queue_elem *pdata;
u8 j;
u8 flag_del = 0u;
#ifdef QUEUE_MOD_ENABLE
#else
u16 tmp_i;
#endif
QUEUE_CPU_SR_ALLOC(); /*PRQA S 2981*/
QUEUE_CPU_CRITICAL_ENTER();
/* 隊列空的判斷 */
if( seq->rear == seq->front)
{
*element = 0u;
/* 開啟總中斷 */
l_resutl = QUEUE_ERRO;
}
if( l_resutl ==QUEUE_OK)
{
/* 複製元素*/
#ifdef QUEUE_MOD_ENABLE
pdata = seq->base + ( (i%seq->length) * seq->unit_sizes );
#else
if( i < seq->length)
{
tmp_i = i;
}
else
{
tmp_i = i - seq->length ;
}
pdata = seq->base + (tmp_i * seq->unit_sizes) ;
#endif
for(j=0u;j<seq->unit_sizes;j++)
{
element[j] = *pdata;
/* 該語句刪除隊列元素; */
if(fdo == QUEUE_DEL)
{
*pdata = 0u;
}
else if((fdo == QUEUE_MINUS)&& (j==0u))
{
if(*pdata != 0u)
{
*pdata = *pdata - 1u;
/*重新運行的次數被清為0時將隊列元素刪除*/
if( *pdata == 0u)
{
flag_del = 1u;
}
}
}
else /*PRQA S 2013*/
{
}
pdata += sizeof(sequential_queue_elem);
}
l_resutl = QUEUE_ERRO;
/*滿足刪除隊列的標誌*/
if( (fdo == QUEUE_DEL) || (flag_del ==1u) )
{
#ifdef QUEUE_MOD_ENABLE
/* 如果要刪除的是隊頭 */
if( (seq->front%seq->length) == (i%seq->length) )
#else
if( seq->front == tmp_i )
#endif
{
/* front 指針向後移一位置 */
#ifdef QUEUE_MOD_ENABLE
seq->front = ( seq->front + 1u)%seq->length;
#else
/* front 指針向後移一位置 */
seq->front++;
if( seq->front >= seq->length)
{
seq->front = 0u;
}
#endif
l_resutl = QUEUE_OK;
}
if ( l_resutl == QUEUE_ERRO)
{
/* 如果要刪除的是隊尾 */
#ifdef QUEUE_MOD_ENABLE
if( ( ( (seq->rear + seq->length) -1u) %seq->length) == (i%seq->length) )
#else
tmp_i++;
if( tmp_i >= seq->length)
{
tmp_i = 0u;
}
if( seq->rear == tmp_i )
#endif
{
#ifdef QUEUE_MOD_ENABLE
/* rear 指針向前移一位置 */
seq->rear = ( (seq->rear + seq->length) -1u) %seq->length;
#else
if( seq->rear >0u )
{
seq->rear--;
}
else
{
seq->rear = seq->length -1u;
}
#endif
l_resutl = QUEUE_OK;
}
}
}
}
QUEUE_CPU_CRITICAL_EXIT();
return l_resutl;
} /* End of function queue_del_one_element_by_flag*/
/*---------------------------------------------------------------------------
|Prototype : QUEUE_OPERATE_FLAG_E queue_get_element(sequential_queue_s seq,u8 i ,sequential_queue_elem *element)
|Called by :
|Preconditions :
|Input parameters : seq : 順序隊列;
|Output parameters : element: 將頭元素數據傳給外部的變量;
|Return value : 是否操作成功
|Description : 若隊列不為空則用e返回seq的某一个元素该函数不建议调用
----------------------------------------------------------------------------*/
QUEUE_OPERATE_FLAG_E queue_get_element(sequential_queue_s seq,u8 i ,sequential_queue_elem *element)
{
sequential_queue_elem *pdata;
u8 j;
QUEUE_OPERATE_FLAG_E l_resutl= QUEUE_OK;
#ifdef QUEUE_MOD_ENABLE
#else
u16 tmp_i ;
#endif
QUEUE_CPU_SR_ALLOC(); /*PRQA S 2981*/
QUEUE_CPU_CRITICAL_ENTER();
if(seq.front == seq.rear)
{
l_resutl = QUEUE_ERRO;
}
if( l_resutl == QUEUE_OK)
{
#ifdef QUEUE_MOD_ENABLE
/* 將隊頭元素賦值給e */
pdata = seq.base + ( (i%seq.length) * seq.unit_sizes) ;
#else
if( i < seq.length)
{
tmp_i = i;
}
else
{
tmp_i = i - seq.length ;
}
pdata = seq.base + (tmp_i * seq.unit_sizes) ;
#endif
for(j=0u;j<seq.unit_sizes;j++)
{
element[j] = *pdata;
/* 該語句刪除隊列元素; */
/* *pdata = 0; */
pdata += sizeof(sequential_queue_elem);
}
}
else
{
}
QUEUE_CPU_CRITICAL_EXIT();
return l_resutl;
} /* End of function queue_get_element*/
#endif
/* [] END OF FILE */