⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ar_event.c

📁 Keil开发环境下ARM7内核单片机的ARTX RTOS内核源代码
💻 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 + -