📄 event.c
字号:
#if !defined(__EBOS_H)
#include "ebos.h"
#endif
/*
*********************************************************************************************************
* event module implement FILE
*********************************************************************************************************
*/
static EVENT_ECB *EventTable[MAX_EVENT_NUM];//事件向量表
static void CleanupEvent(void *information); //事件组清除函数
static EVENT_ECB * EventFreeList; //可用事件组列表
/*
*********************************************************************************************************
* 获得一个可用的ID号
*********************************************************************************************************
*/
static SIGNED _NewEventId()
{
static UNSIGNED Next_ID;
UNSIGNED id; /* process id to return */
EnLock();
if ((id=Next_ID++) < MAX_EVENT_NUM){
if (EventTable[id] == NULL){
UnLock();
return(id);
}
}
else if(EventFreeList){
id=EventFreeList->id;
#if ENABLE_MEM
FreeBuff(EventFreeList);
#endif
EventFreeList=EventFreeList->next;
UnLock();
return(id);
}
UnLock();
return(NO_EVENT_SPACE);
}
/*
*********************************************************************************************************
* CREATE A event Group
*********************************************************************************************************
*/
#if ENABLE_MEM
SIGNED CreateEventGroup()
#else
SIGNED CreateEventGroup(EVENT_ECB *event_ptr)
#endif
{
SIGNED event_id;
SIGNED err;
#if ENABLE_MEM
EVENT_ECB *event_ptr;
err=AllocBuff(KERNAL.event_pool,&(void *)event_ptr,-1);
if(err!=OK)
return (ERR_NO_MEMORY);
#else
if(!event_ptr) return ERR_INVALID_GROUP;
else if(EventTable[event_ptr->id]==event_ptr)
return (event_ptr->id);
#endif
event_id=_NewEventId();
if(event_id<0)
return (event_id);
#if DEBUG
DebugLog(CREATE_EVENT_GROUP,event_ptr->event_id);//在日志中记录操作,时间等信息
#endif
EventTable[event_id]=event_ptr;
event_ptr->id=event_id;
event_ptr->current_protect=NULL;
event_ptr->current_events=0;
event_ptr->task_wait_header=NULL;
return(event_id);
}
/*
*********************************************************************************************************
* 删除一个事件组
*********************************************************************************************************
*/
STATUS DelEventGroup(SIGNED event_id)
{
STATUS state,oldstate;
EVENT_ECB *event_ptr;
if (event_id<0 || event_id >MAX_EVENT_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_EVENT);
}
event_ptr=EventTable[event_id];
#if DEBUG
DebugLog(DELETE_EVENT_GROUP,event_id);//在日志中记录操作,时间等信息
#endif
DoProtect(event_ptr);
if (event_ptr == NULL) /* Not allowed to Del idle event */
return (ERR_INVALID_GROUP);
while(event_ptr->task_wait_header){
state=_ResumeTask(event_ptr->task_wait_header->task_ptr,EVENT_SUSPEND);
if(state==TRUE) oldstate =state;
DelHead(&(void *)(event_ptr->task_wait_header));
}
UnProtect(event_ptr);
EnLock();
event_ptr->next=EventFreeList;
EventFreeList=event_ptr;
EventTable[event_id]=NULL;
UnLock();
if(oldstate==TRUE)
_ControlToSystem();
return (OK);
}
/*
*********************************************************************************************************
* 设置事件,事件是一组事件标志(一个事件标志对应一位)的与或组合
*********************************************************************************************************
*/
STATUS SetEvents(SIGNED event_id,UNSIGNED events, INT8U operation)
{
WAIT_QUEUE *linknode;
TASK_TCB * task_ptr;
STATUS status,oldstate;
UNSIGNED flags;
EVENT_ECB *event_ptr;
flags=FALSE;
if (event_id<0 || event_id >MAX_EVENT_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_EVENT);
}
event_ptr=EventTable[event_id];
if (operation!=AND && operation!=OR){
return (ERR_INVALID_OPERATION);
}
#if DEBUG
DebugLog(SET_EVENTS,event_id);//在日志中记录操作,时间等信息
#endif
DoProtect(event_ptr);
if (event_ptr == NULL) /* Not allowed to Del idle event */
return (ERR_INVALID_GROUP);
if (operation==AND)
(event_ptr->current_events) &= events;
else if (operation==OR)
(event_ptr->current_events) |= events;
if(event_ptr->task_wait_header){//有任务等待信号灯释放,恢复任务
linknode=event_ptr->task_wait_header;
do{
task_ptr=linknode->task_ptr;
if (linknode->event_operation==AND) {
if(linknode->event_requested_events==event_ptr->current_events)
flags=TRUE;
}
else if (linknode->event_operation==OR)
flags=(linknode->event_requested_events) & (event_ptr->current_events);
if (flags){
linknode->event_return_status=FINISHED;
status=_ResumeTask(task_ptr,EVENT_SUSPEND);
if (status==TRUE) oldstate =status;
}
linknode=(WAIT_QUEUE *)(linknode->next);
}while(linknode!=event_ptr->task_wait_header);
UnProtect(event_ptr);
if (oldstate==TRUE) _ControlToSystem();
}
else
UnProtect(event_ptr);
return (OK);
}
/*
*********************************************************************************************************
* 看一个事件组上是否发生请求的事件和获得当前的事件,不能满足时,任务可以挂起等待
*********************************************************************************************************
*/
STATUS RecvEvents(SIGNED event_id, UNSIGNED *requested_events,INT8U operation,SIGNED suspend)
{
WAIT_QUEUE *task_suspend;
TASK_TCB *task_ptr;
STATUS status;
UNSIGNED flags;
EVENT_ECB *event_ptr;
#if WAIT_QUEUE_ALLOC_MODE
task_suspend=WaitQueueFreeList;
WaitQueueFreeList=WaitQueueFreeList->queue_ptr;
#else
WAIT_QUEUE event_wait_queue;
task_suspend=&event_wait_queue;
#endif
if (event_id<0 || event_id >MAX_EVENT_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_EVENT);
}
event_ptr=EventTable[event_id];
flags=FALSE;
if (requested_events==NULL)
return (ERR_INVALID_POINTER);
if (operation!=AND && operation!=OR){
return (ERR_INVALID_OPERATION);
}
#if DEBUG
DebugLog(RECV_EVENTS,event_id);//在日志中记录操作,时间等信息
#endif
DoProtect(event_ptr);
if (event_ptr == NULL)
return (ERR_INVALID_GROUP);
if (operation==AND){
if (*requested_events==event_ptr->current_events)
flags=TRUE;
}
else if (operation==OR)
flags=*requested_events & (event_ptr->current_events);
if(!flags){ //事件请求不能满足
if(suspend!=NO_SUSPEND){//任务挂起
if (((TASK_TCB *)KERNAL.current_thread)->type!=TASK){
UnProtect(event_ptr);
return(ERR_INVALID_SUSPEND);
}
event_ptr->tasks_waiting++;
task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
task_suspend->event_requested_events=*requested_events;
task_suspend->event_operation=operation;
task_suspend->event_return_status=EVENT_SUSPEND;
AddList(&(void *)(event_ptr->task_wait_header),task_suspend,0);
UnProtect(event_ptr);
_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,CleanupEvent,event_ptr,suspend);
_ControlToSystem();
Enlock();
#if WAIT_QUEUE_ALLOC_MODE
task_suspend->queue_ptr=WaitQueueFreeList;
WaitQueueFreeList=task_suspend;
#endif
if(event_ptr==NULL){
Unlock();
return(ERR_GROUP_DELETED);
}
if (task_suspend->event_return_status!=FINISHED){
*requested_events=event_ptr->current_events;
Unlock();
return(ERR_TIMEOUT);
}
event_ptr->tasks_waiting--;
DelList(&(void *)(event_ptr->task_wait_header),task_suspend);
(event_ptr->current_events) &= ~ (*requested_events);
Unlock();
return (OK);
}// if(suspend!=NO_SUSPEND){//任务挂起
else{
UnProtect(event_ptr);
return (ERR_NOT_PRESENT);
}
}
else{
(event_ptr->current_events) &= ~ (*requested_events);
UnProtect(event_ptr);
return (OK);
}
}
/*
*********************************************************************************************************
* 在一个事件组上的挂起结构上的某个任务恢复或删除时,清除相应等待列表上的项
*********************************************************************************************************
*/
static void CleanupEvent(void *information)
{
EVENT_ECB *event_ptr;
TASK_TCB *task_ptr;
WAIT_QUEUE *linknode;
event_ptr=(EVENT_ECB *)information;
UnProtect(event_ptr);
EnLock();
linknode=event_ptr->task_wait_header;
do{
task_ptr=linknode->task_ptr;
if (task_ptr==((TASK_TCB *)KERNAL.current_thread)){
event_ptr->tasks_waiting--;
DelList(&(void *)(event_ptr->task_wait_header),linknode);
#if WAIT_QUEUE_ALLOC_MODE
linknode->queue_ptr=WaitQueueFreeList;
WaitQueueFreeList=linknode;
#endif
}
linknode=(WAIT_QUEUE *)(linknode->next);
if (linknode==NULL) break;
}while(linknode!=event_ptr->task_wait_header);
UnLock();
}
/*
*********************************************************************************************************
* 列出系统中存在的事件组信息
*********************************************************************************************************
*/
STATUS ListEventGroups(SIGNED event_id,EVENT_DATA **event_lst)
{
EVENT_ECB *event_ptr;
UNSIGNED i;
if (event_id+1<0 || event_id >MAX_EVENT_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_EVENT);
}
if(event_id>=0){
event_ptr=EventTable[event_id];
DoProtect(event_ptr);
if (event_ptr == NULL) /* Not allowed to Del idle task */
return (ERR_INVALID_GROUP);
(*event_lst)->tasks_waiting=event_ptr->tasks_waiting;
(*event_lst)->current_events= event_ptr->current_events;
(*event_lst)->task_id=(event_ptr->task_wait_header)->task_ptr->id;
UnProtect(event_ptr);
return (OK);
}
else{
for(i=0;i<MAX_EVENT_NUM;i++){
event_ptr=EventTable[i];
DoProtect(event_ptr);
if (event_ptr){ /* Not allowed to Del idle task */
(*event_lst)->tasks_waiting=event_ptr->tasks_waiting;
(*event_lst)->current_events= event_ptr->current_events;
(*event_lst)->task_id=(event_ptr->task_wait_header)->task_ptr->id;
(event_lst)++;
}
UnProtect(event_ptr);
}
return (OK);
}
}
/*
*********************************************************************************************************
* 事件模块的初始化
*********************************************************************************************************
*/
void EventInit(void)
{
UNSIGNED i;
for(i=0;i<MAX_EVENT_NUM;i++)
EventTable[i]=NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -