📄 ar_event.c
字号:
/*----------------------------------------------------------------------------
* A R T X - K e r n e l
*----------------------------------------------------------------------------
* Name: AR_EVENT.C
* Purpose: Implements waits and wake-ups for event flags
* Rev.: V2.00 / 19-oct-2005
*----------------------------------------------------------------------------
* This code is part of the ARTX-ARM kernel package of Keil Software.
* Copyright (c) 2004-2005 Keil Software. All rights reserved.
*---------------------------------------------------------------------------*/
#include "Kernel\ARTX_Config.h"
#include "Kernel\AR_Task.h"
#include "Kernel\AR_List.h"
#include "Kernel\AR_Event.h"
#include "Kernel\AR_Lib.h"
/* ARTX_Config.c */
extern P_TCB os_active_TCB[];
/* Ptr to TCB of running task */
extern P_TCB os_runtask;
/* Mapping of API-type to internal type */
#define p_TCB ((struct OS_TCB *)task)
/*----------------------------------------------------------------------------
* Functions
*---------------------------------------------------------------------------*/
/*--------------------------- os_evt_wait -----------------------------------*/
OS_RESULT os_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) {
/* Wait for one or more event flags with optional time-out. */
/* "wait_flags" identifies the flags to wait for. */
/* "timeout" is the time-out limit in system ticks (0xffff if no time-out)*/
/* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met*/
/* to complete the wait. (OR-ing if set to 0). */
U32 block_state;
tsk_lock();
if (and_wait) {
/* Check for AND-connected events */
if ((os_runtask->events & wait_flags) == wait_flags) {
_andw (&os_runtask->events, ~wait_flags);
tsk_unlock();
return (OS_R_EVT);
}
else {
block_state = WAIT_AND;
}
}
else {
/* Check for OR-connected events */
if (os_runtask->events & wait_flags) {
os_runtask->waits = os_runtask->events & wait_flags;
_andw (&os_runtask->events, ~wait_flags);
tsk_unlock();
return (OS_R_EVT);
}
else {
block_state = WAIT_OR;
}
};
/* Task has to wait */
os_runtask->waits = wait_flags;
if (os_block(timeout, (U8)block_state) == OS_R_TMO) {
tsk_unlock();
return (OS_R_TMO);
}
else {
tsk_unlock();
return (OS_R_EVT);
}
} /* end of os_wait */
/*--------------------------- os_evt_set ------------------------------------*/
void os_evt_set (U16 event_flags, OS_TID task_id) {
/* Set one or more event flags (identified by "event_flags") of a */
/* selectable task (identified by "task").*/
OS_ID task;
BOOL wake_up;
task = os_active_TCB[task_id-1];
if (task == NULL) {
return;
}
wake_up = __FALSE;
tsk_lock();
_orw (&p_TCB->events, event_flags);
/* If the task is not waiting for an event, it should not be put */
/* to ready state. */
if (p_TCB->state == WAIT_AND) {
if ((p_TCB->waits & p_TCB->events) == p_TCB->waits) {
wake_up = __TRUE;
}
}
if (p_TCB->state == WAIT_OR) {
if (p_TCB->waits & p_TCB->events) {
p_TCB->waits &= p_TCB->events;
wake_up = __TRUE;
}
};
if (wake_up) {
os_rmv_dly (p_TCB);
_andw (&p_TCB->events, ~event_flags);
p_TCB->state = READY;
p_TCB->ret_val = OS_R_EVT;
os_dispatch (p_TCB);
};
tsk_unlock();
} /* end of os_evt_set */
/*--------------------------- os_evt_clr ------------------------------------*/
void os_evt_clr (U16 clear_flags, OS_TID task_id) {
/* Clear one or more event flags (identified by "clear_flags") of a */
/* selectable task (identified by "task"). */
P_TCB task = os_active_TCB[task_id-1];
if (task == NULL) {
return;
}
_andw (&task->events, ~clear_flags);
} /* end of os_evt_clr */
/*--------------------------- isr_evt_set -----------------------------------*/
void isr_evt_set (U16 event_flags, OS_TID task_id) {
/* Same function as "os_evt_set", but to be called by ISRs. */
P_TCB task = os_active_TCB[task_id-1];
if (task == NULL) {
return;
}
_orw (&p_TCB->events, event_flags);
os_psq_enq (p_TCB, NULL);
os_psh_req ();
} /* end of isr_evt_set */
/*--------------------------- os_evt_get ------------------------------------*/
U16 os_evt_get (void) {
/* Get events of a running task after waiting for OR connected events. */
return (os_runtask->waits);
} /* end of os_evt_get */
/*--------------------------- os_evt_psh ------------------------------------*/
void os_evt_psh (P_TCB p_CB) {
/* Check if task has to be waken up */
U16 event_flags;
event_flags = p_CB->waits;
if (p_CB->state == WAIT_AND) {
/* Check for AND-connected events */
if ((p_CB->events & event_flags) == event_flags) {
goto rdy;
}
}
if (p_CB->state == WAIT_OR) {
/* Check for OR-connected events */
if (p_CB->events & event_flags) {
p_CB->waits &= p_CB->events;
rdy: _andw (&p_CB->events, ~event_flags);
os_rmv_dly (p_CB);
p_CB->ret_val = OS_R_EVT;
p_CB->state = READY;
os_put_prio (&os_rdy, p_CB);
}
}
} /* end of os_evt_psh */
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -