📄 queue.c
字号:
#if !defined(__EBOS_H)
#include "ebos.h"
#endif
/*
*********************************************************************************************************
* Queue module implement FILE
*********************************************************************************************************
*/
static QUEUE_QCB *QueueTable[MAX_QUEUE_NUM];//队列向量表
static void CleanupQueue(void *information);//队列清除函数
static QUEUE_QCB * QueueFreeList; //可用队列列表
/*
*********************************************************************************************************
* 获得一个可用的ID号
*********************************************************************************************************
*/
static SIGNED _NewQueueId()
{
static UNSIGNED Next_ID;
UNSIGNED id; /* process id to return */
EnLock();
if ( (id=Next_ID++) <MAX_QUEUE_NUM){
if (QueueTable[id] == NULL){
UnLock();
return(id);
}
}
else if(QueueFreeList){
id=QueueFreeList->id;
#if ENABLE_MEM
FreeBuff(QueueFreeList);
#endif
QueueFreeList=QueueFreeList->next;
UnLock();
return(id);
}
UnLock();
return(ERR_QUEUE_FULL);
}
/*
*********************************************************************************************************
* 创建一个队列
*********************************************************************************************************
*/
#if ENABLE_MEM
SIGNED CreateQueue (UNSIGNED queue_size)
#else
SIGNED CreateQueue (QUEUE_QCB *queue_ptr,void **queue_start, UNSIGNED queue_size)
#endif
{
SIGNED queue_id,err;
#if ENABLE_MEM
void *queue_start;
QUEUE_QCB *queue_ptr;
#endif
if (queue_start==NULL ) return (ERR_INVALID_MEMORY);
if (queue_size==0 ) return (ERR_INVALID_SIZE);
queue_id=_NewQueueId();
if(queue_id<0)
return(queue_id);
#if ENABLE_MEM
err=AllocBuff(KERNAL.event_pool,&(void *)queue_ptr,-1);
if(err!=OK)
return (ERR_NO_MEMORY);
err=AllocMem(KERNAL.mem_pool,&queue_start,queue_size*sizeof(void *),-1);
if(err!=OK)
return (ERR_NO_MEMORY);
#else
if (queue_ptr==NULL) return(ERR_INVALID_QUEUE);
else if(QueueTable[queue_ptr->id]==queue_ptr) return (queue_ptr->id);
#endif
#if DEBUG
DebugLog(CREATE_QUEUE,queue_ptr->id);//在日志中记录操作,时间等信息
#endif
QueueTable[queue_id]=queue_ptr;
queue_ptr->id=queue_id;
queue_ptr->current_protect=NULL;
queue_ptr->suspend_type=FIFO;
queue_ptr->queue_size=queue_size;
queue_ptr->available=0;
queue_ptr->queue_start=queue_start;
queue_ptr->queue_end=(void *)((INT8 *)queue_start+queue_size*sizeof(void *));
queue_ptr->read_pointer=queue_start;
queue_ptr->write_pointer=queue_start;
queue_ptr->task_wait_header=NULL;
return(queue_id);
}
/*
*********************************************************************************************************
* Del A Queue
*********************************************************************************************************
*/
STATUS DelQueue(SIGNED queue_id)
{
STATUS state,oldstate;
QUEUE_QCB *queue_ptr;
if (queue_id<0 || queue_id >=MAX_QUEUE_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_QUEUE);
}
queue_ptr=QueueTable[queue_id];
#if DEBUG
DebugLog(DELETE_QUEUE,queue_id);//在日志中记录操作,时间等信息
#endif
DoProtect(queue_ptr);
if (queue_ptr == NULL) /* Not allowed to Del idle QUEUE */
return (ERR_INVALID_QUEUE);
while(queue_ptr->task_wait_header){
state=_ResumeTask(queue_ptr->task_wait_header->task_ptr,EVENT_SUSPEND);
if(state==TRUE)
oldstate =state;
DelHead(&(void *)(queue_ptr->task_wait_header));
}
#if ENABLE_MEM
FreeBuff(queue_ptr);
FreeMem(queue_ptr->queue_start,(queue_ptr->queue_size)*sizeof(void *));
#endif
UnProtect(queue_ptr);
EnLock();
queue_ptr->next=QueueFreeList;
QueueFreeList=queue_ptr;
QueueTable[queue_id]=NULL;
UnLock();
if(oldstate==TRUE)
_ControlToSystem();
return (OK);
}
/*
*********************************************************************************************************
* 队列参数设置函数
*********************************************************************************************************
*/
STATUS SysQueueCtl(SIGNED queue_id,INT8U cmd,INT8U param)
{
STATUS ret;
QUEUE_QCB *queue_ptr;
if (queue_id<0 || queue_id >=MAX_QUEUE_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_QUEUE);
}
queue_ptr=QueueTable[queue_id];
#if DEBUG
DebugLog(SYS_QUEUE_CTL,queue_id);//在日志中记录操作,时间等信息
#endif
DoProtect(queue_ptr);
if (queue_ptr == NULL) {
return (ERR_INVALID_QUEUE); /* Not allowed is idle task */
}
switch(cmd){
case SUSPEND_TYPE:
queue_ptr->suspend_type=param;
ret=OK;
break;
case QUEUE_SIZE:
#if ENABLE_MEM
ret=DelQueue(queue_id);
if(ret!=OK)
break;
ret=CreateQueue(param);
#endif
break;
default:
ret=ERR_INVALID_CMD;
break;
}
UnProtect(queue_ptr);
return(ret);
}
/*
*********************************************************************************************************
* SEND A MESSAGE TO A Queue
*********************************************************************************************************
*/
INT8 _AddWaitQueue(QUEUE_QCB *queue_ptr,SIGNED suspend)
{
WAIT_QUEUE *task_suspend;
#if WAIT_QUEUE_ALLOC_MODE
task_suspend=WaitQueueFreeList;
WaitQueueFreeList=WaitQueueFreeList->queue_ptr;
#else
WAIT_QUEUE queue_wait_queue;
task_suspend=&queue_wait_queue;
#endif
if(queue_ptr->available>=queue_ptr->queue_size){ //队列满
if(suspend!=NO_SUSPEND){//任务挂起
if(((TASK_TCB *)KERNAL.current_thread)->type!=TASK){
UnProtect(queue_ptr);
return(ERR_INVALID_SUSPEND);
}
queue_ptr->tasks_waiting++;
task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
task_suspend->priority=GetPriority(((TASK_TCB *)KERNAL.current_thread)->id);
AddList(&(void *)(queue_ptr->task_wait_header),task_suspend,queue_ptr->suspend_type);
UnProtect(queue_ptr);
_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,CleanupQueue,queue_ptr,suspend);
_ControlToSystem();
Enlock();
#if WAIT_QUEUE_ALLOC_MODE
task_suspend->queue_ptr=WaitQueueFreeList;
WaitQueueFreeList=task_suspend;
#endif
if(queue_ptr==NULL){
Unlock();
return(ERR_QUEUE_DELETED);
}
if (queue_ptr->available>=queue_ptr->queue_size){
Unlock();
return(ERR_TIMEOUT);
}
if(queue_ptr->task_wait_header==NULL){
Unlock();
return(ERR_QUEUE_RESET);
}
//队列消息被另一个任务接收导致队列为空,该任务放消息到队列
queue_ptr->tasks_waiting--;
DelList(&(void *)(queue_ptr->task_wait_header),task_suspend);
Unlock();
return (OK);
}
else{
UnProtect(queue_ptr);
return (ERR_QUEUE_FULL);
}
}
else{//队列不满,消息放入队列
UnProtect(queue_ptr);
return (OK);
}
}
STATUS SendToQueue(SIGNED queue_id, void *message, SIGNED suspend)
{
TASK_TCB *task_ptr;
STATUS status,ret;
QUEUE_QCB *queue_ptr;
if (message == NULL) /* Not allowed to Del idle Queue */
return (ERR_INVALID_POINTER);
if (queue_id<0 || queue_id >=MAX_QUEUE_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_QUEUE);
}
queue_ptr=QueueTable[queue_id];
#if DEBUG
DebugLog(SENDTO_QUEUE,queue_id);//在日志中记录操作,时间等信息
#endif
DoProtect(queue_ptr);
if (queue_ptr == NULL) /* Not allowed to Del idle QUEUE */
return (ERR_INVALID_QUEUE);
if(queue_ptr->available==NULL && queue_ptr->task_wait_header){//有任务在等待接收消息,恢复任务,消
queue_ptr->task_wait_header->queue_message=message;
task_ptr=(queue_ptr->task_wait_header)->task_ptr;
UnProtect(queue_ptr);
status=_ResumeTask(task_ptr,EVENT_SUSPEND);
if (status==TRUE)
_ControlToSystem();
return (OK);
}
ret=_AddWaitQueue(queue_ptr,suspend);
if(ret==OK){
DoProtect(queue_ptr);
queue_ptr->available++;
*(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)++;
UnProtect(queue_ptr);
}
return ret;
}
/*
*********************************************************************************************************
* SEND A MESSAGE TO Front Of A Queue
*********************************************************************************************************
*/
STATUS SendToFrontOfQueue(SIGNED queue_id, void *message, SIGNED suspend)
{
TASK_TCB *task_ptr;
STATUS status,ret;
QUEUE_QCB *queue_ptr;
if (message == NULL) { /* Not allowed to Del idle Queue */
return (ERR_INVALID_POINTER);
}
if (queue_id<0 || queue_id >=MAX_QUEUE_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_QUEUE);
}
queue_ptr=QueueTable[queue_id];
#if DEBUG
DebugLog(SENDTO_FRONTOFQUEUE,queue_id);//在日志中记录操作,时间等信息
#endif
DoProtect(queue_ptr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -