📄 nqueue.c
字号:
#if !defined(__EBOS_H)
#include "ebos.h"
#endif
/*
*********************************************************************************************************
* Queue COMPOENTimplement FILE
*********************************************************************************************************
*/
static INT32U TotalQueues;
static VOID QueueCleanup(VOID *information);
/*
*********************************************************************************************************
* CREATE A Queue and then places it on the list of created Queuees.
Functions Called
CSC_Place_On_List
[HIC_Make_History_Entry]
[TCT_Check_Stack]
TCT_Protect
TCT_Unprotect
*********************************************************************************************************
*/
INT8U CreateQueue (QUEUE_QCB *queue_ptr,QUEUE_MSG *msg,UNSIGNED msg_num,INT8U suspend_type)
{
if (queue_ptr==NULL) return(ERR_INVALID_QUEUE);
if (queue_start==NULL ) return (ERR_INVALID_MEMORY);
if (queue_type!=FIX_TYPE && queue_type!=VAR_TYPE ) return (ERR_INVALID_MESSAGE);
if(message_size>queue_size ||message_size==0 || queue_size==0 ) return (ERR_INVALID_SIZE);
if (suspend_type!=FIFO && suspend_type !=PRIORITY) return(ERR_INVALID_SUSPEND);
if (queue_ptr->type_id==QUEUE) return (SUCCESS);
#ifdef OPTION_ENABLE_STACK_CHECK
Check_Stack();
#endif
#ifdef OPTION_ENABLE_HISTORY
MakeHistoryLog(CreateQueue,queue_ptr->id);//在日志中记录操作,时间等信息
#endif
queue_ptr->id=IDNumber++;
DoProtect(queue_ptr);
queue_ptr->type_id=QUEUE;
queue_ptr->suspend_type=suspend_type;
queue_ptr->queue_size=msg_num;
queue_ptr->available=0;
queue_ptr->queue_start=msg;
queue_ptr->queue_end=&msg[msg_num];
queue_ptr->read_pointer=msg;
queue_ptr->write_pointer=msg;
queue_ptr->task_wait_header=NULL;
DoUnProtect(queue_ptr);
// queue_ptr->urgent_list=NULL;
#ifdef CPU32
ProtectStruct(QUEUELIST_PROTECT);
Place_On_List(&(LIST_NODE *)(CreatedQueuesList),(LIST_NODE *)&(queue_ptr->linknode));
TotalQueues++; /* Increment the #Queues counter */
UnProtectStruct(QUEUELIST_PROTECT);
#endif
return( SUCCESS);
}
/*
*********************************************************************************************************
* DELETE A Queue
Functions Called
CSC_Remove_From_List
[HIC_Make_History_Entry]
TCC_Resume_Queue
[TCT_Check_Stack]
TCT__ControlToSystem
*********************************************************************************************************
*/
INT8U DeleteQueue(QUEUE_QCB *queue_ptr)
{
INT8U state,oldstate;
if (queue_ptr == NULL) { /* Not allowed to delete idle Queue */
return (ERR_INVALID_QUEUE);
}
#ifdef OPTION_ENABLE_STACK_CHECK
Check_Stack();
#endif
#ifdef INT8U_ENABLE_HISTORY
MakeHistoryLog(DELETE_TASK,task_ptr->TASK_name);//在日志中记录操作,时间等信息
#endif
DoProtect(queue_ptr);
while(queue_ptr->task_wait_header)
{
state=_ResumeTask(queue_ptr->task_wait_header->suspended_task,QUEUE_SUSPEND);
if(state==TRUE) oldstate =state;
Remove_From_List(&(LIST_NODE *)(queue_ptr->task_wait_header),(LIST_NODE *)(queue_ptr->task_wait_header));
}
queue_ptr->type_id=INIT;
DoUnProtect(queue_ptr);
ProtectStruct(QUEUELIST_PROTECT);
Remove_From_List(&(LIST_NODE *)CreatedQueuesList,&(queue_ptr->linknode));
TotalQueues--;
UnProtectStruct(QUEUELIST_PROTECT);
if(oldstate==TRUE) _ControlToSystem();
return (SUCCESS);
}
/*
*********************************************************************************************************
* SEND A MESSAGE TO A Queue
Functions Called
CSC_Place_On_List
CSC_Priority_Place_On_List
CSC_Remove_From_List
[HIC_Make_History_Entry]
TCC__ResumeTask
TCC_Suspend_task
*********************************************************************************************************
*/
INT8U SendToQueue(QUEUE_QCB *queue_ptr, QUEUE_MSG *message,INT32S suspend)
{
QUEUE_WAIT_QUEUE task_suspend;
TASK_TCB *task_ptr;
INT8U status;
if (queue_ptr == NULL) { /* Not allowed to delete idle Queue */
return (ERR_INVALID_QUEUE);
}
if (message == NULL) { /* Not allowed to delete idle Queue */
return (ERR_INVALID_POINTER);
}
if (queue_ptr->type_id!=QUEUE) return(ERR_INVALID_QUEUE);
#ifdef OPTION_ENABLE_STACK_CHECK
Check_Stack();
#endif
#ifdef OPTION_ENABLE_HISTORY
MakeHistoryLog(SendToQueue,queue_ptr->id);//在日志中记录操作,时间等信息
#endif
DoProtect(queue_ptr);
if(queue_ptr->available==NULL && queue_ptr->task_wait_header){//有任务在等待接收消息,恢复任务,消
queue_ptr->task_wait_header->message_area=message;
task_ptr=(queue_ptr->task_wait_header)->suspended_task;
DoUnProtect(queue_ptr);
status=_ResumeTask(task_ptr,QUEUE_SUSPEND);
if (status==TRUE) _ControlToSystem();
return (SUCCESS);
}
else if(queue_ptr->available==queue_ptr->queue_size){ ////若队列空间不够
if(suspend!=NO_SUSPEND){ //任务等待
if(((TASK_TCB *)CurrentThread)->type_id !=TASK) {
DoUnProtect(queue_ptr);
return(ERR_INVALID_SUSPEND);
}
task_suspend.suspended_task=(TASK_TCB *)CurrentThread;
if(queue_ptr->suspend_type==FIFO)
Place_On_List(&(LIST_NODE *)(queue_ptr->task_wait_header),(LIST_NODE *)&(task_suspend));
else{
task_suspend.priority=GetPriority((TASK_TCB *)(CurrentThread));
Priority_Place_On_List(&(LIST_NODE *)(queue_ptr->task_wait_header),(LIST_NODE *)&(task_suspend));
}
DoUnProtect(queue_ptr);
_SuspendTask(CurrentThread,QUEUE_SUSPEND,QueueCleanup,queue_ptr,suspend);
if(queue_ptr->type_id==0){
return(ERR_QUEUE_DELETED);
}
DoProtect(queue_ptr);
if (queue_ptr->available==queue_ptr->queue_size) {
DoUnProtect(queue_ptr);
return(ERR_TIMEOUT);
}
if(queue_ptr->task_wait_header==NULL){
DoUnProtect(queue_ptr);
return(ERR_QUEUE_RESET);
}
//队列消息被另一个任务接收导致队列有空间,则该任务放消息到队列
*(queue_ptr->write_pointer)=*message;
if(queue_ptr->write_pointer==queue_ptr->queue_end)
queue_ptr->write_pointer=queue_ptr->queue_start;
else (queue_ptr->write_pointer)++;
queue_ptr->available++;
Remove_From_List(&(LIST_NODE *)(queue_ptr->task_wait_header),(LIST_NODE *)&(task_suspend));
DoUnProtect(queue_ptr);
return (SUCCESS);
}
else{
DoUnProtect(queue_ptr);
return (ERR_QUEUE_FULL);
}
}
else{ //队列空且无任务在等待,消息放入队列,
*(queue_ptr->write_pointer)=*message;
if(queue_ptr->write_pointer==queue_ptr->queue_end)
queue_ptr->write_pointer=queue_ptr->queue_start;
else (queue_ptr->write_pointer)++;
queue_ptr->available++;
// Queue_ptr->message_present=TRUE;
DoUnProtect(queue_ptr);
return (SUCCESS);
}
}
INT8U SendToFrontOfQueue(QUEUE_QCB *queue_ptr, QUEUE_MSG *message, INT32S suspend)
{
QUEUE_WAIT_QUEUE task_suspend;
TASK_TCB *task_ptr;
INT8U status;
if (queue_ptr == NULL) { /* Not allowed to delete idle Queue */
return (ERR_INVALID_QUEUE);
}
if (message == NULL) { /* Not allowed to delete idle Queue */
return (ERR_INVALID_POINTER);
}
if (queue_ptr->type_id!=QUEUE) return(ERR_INVALID_QUEUE);
#ifdef OPTION_ENABLE_STACK_CHECK
Check_Stack();
#endif
#ifdef OPTION_ENABLE_HISTORY
MakeHistoryLog(SendToQueue,queue_ptr->id);//在日志中记录操作,时间等信息
#endif
DoProtect(queue_ptr);
if(queue_ptr->available==NULL && queue_ptr->task_wait_header){//有任务等待接收消息,恢复任务,消息放入队列队列中的任务的挂起结构的消息域
queue_ptr->task_wait_header->message_area=message;
task_ptr=(queue_ptr->task_wait_header)->suspended_task;
DoUnProtect(queue_ptr);
status=_ResumeTask(task_ptr,QUEUE_SUSPEND);
if (status==TRUE) _ControlToSystem();
return (SUCCESS);
}
else if(queue_ptr->available==queue_ptr->queue_size){ //若队列空间不够
if(suspend!=NO_SUSPEND){ //任务等待
if(((TASK_TCB *)CurrentThread)->type_id !=TASK)
{
DoUnProtect(queue_ptr);
return(ERR_INVALID_SUSPEND);
}
task_suspend.suspended_task=(TASK_TCB *)CurrentThread;
if(queue_ptr->suspend_type==FIFO)
Place_On_List(&(LIST_NODE *)(queue_ptr->task_wait_header),(LIST_NODE *)&(task_suspend));
else{
task_suspend.priority=GetPriority((TASK_TCB *)(CurrentThread));
Priority_Place_On_List(&(LIST_NODE *)(queue_ptr->task_wait_header),(LIST_NODE *)&(task_suspend));
}
DoUnProtect(queue_ptr);
_SuspendTask(CurrentThread,QUEUE_SUSPEND,QueueCleanup,queue_ptr,suspend);
if(queue_ptr->type_id==0){
return(ERR_QUEUE_DELETED);
}
DoProtect(queue_ptr);
if (queue_ptr->available==queue_ptr->queue_size)
{
DoUnProtect(queue_ptr);
return(ERR_TIMEOUT);
}
if(queue_ptr->task_wait_header==NULL){
DoUnProtect(queue_ptr);
return(ERR_QUEUE_RESET);
}
//队列消息被另一个任务接收导致队列为空,该任务放消息到队列
queue_ptr->available++;
if(queue_ptr->read_pointer==queue_ptr->queue_start)
queue_ptr->read_pointer=queue_ptr->queue_end;
else (queue_ptr->read_pointer)--;
*(queue_ptr->read_pointer)=*message;
Remove_From_List(&(LIST_NODE *)(queue_ptr->task_wait_header),(LIST_NODE *)&(task_suspend));
DoUnProtect(queue_ptr);
return (SUCCESS);
}
else{
DoUnProtect(queue_ptr);
return (ERR_QUEUE_FULL);
}
}
else{ //队列空间够,消息放入队列,
queue_ptr->available++;
if(queue_ptr->read_pointer==queue_ptr->queue_start)
queue_ptr->read_pointer=queue_ptr->queue_end;
else (queue_ptr->read_pointer)--;
*(queue_ptr->read_pointer)=*message;
DoUnProtect(queue_ptr);
return (SUCCESS);
}
}
/*
*********************************************************************************************************
* This function sends a message to all Queues currently waiting for a message from the Queue.
Functions Called
CSC_Place_On_List
CSC_Priority_Place_On_List
CSC_Remove_From_List
[HIC_Make_History_Entry]
TCC_Resume_Queue
TCC_Suspend_Queue
*********************************************************************************************************
*/
INT8U BroadcastToQueue(QUEUE_QCB *queue_ptr, QUEUE_MSG *message,INT32S suspend)
{
QUEUE_WAIT_QUEUE *linknode;
TASK_TCB *task_ptr;
QUEUE_WAIT_QUEUE task_suspend;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -