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

📄 ar_semaphore.c

📁 Keil开发环境下ARM7内核单片机的ARTX RTOS内核源代码
💻 C
字号:
/*----------------------------------------------------------------------------
 *      A R T X  -  K e r n e l
 *----------------------------------------------------------------------------
 *      Name:    AR_SEMAPHORE.C
 *      Purpose: Implements binary and counting semaphores
 *      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_List.h"
#include "Kernel\AR_Task.h"
#include "Kernel\AR_Lib.h"

/* Ptr to TCB of running task */
extern P_TCB  os_runtask;

/* Mapping of API-type to internal type */
#define p_SCB   ((struct OS_SCB *)semaphore)


/*----------------------------------------------------------------------------
 *      Functions
 *---------------------------------------------------------------------------*/


/*--------------------------- os_sem_init -----------------------------------*/

void os_sem_init (OS_ID semaphore, U16 token_count) {
   /* Initialize a semaphore */
   tsk_lock();
   p_SCB->cb_type = SCB;
   p_SCB->p_lnk  = NULL;
   p_SCB->tokens = token_count;
   tsk_unlock();
} /* end of os_sem_init */


/*--------------------------- os_sem_send -----------------------------------*/

OS_RESULT os_sem_send (OS_ID semaphore) {
   /* Return a token to semaphore */
   P_TCB p_TCB;

   tsk_lock();
   if (p_SCB->p_lnk != NULL) {
      /* A task is waiting for token */
      p_TCB = os_get_first ((P_XCB)p_SCB);
      p_TCB->ret_val = OS_R_SEM;
      os_rmv_dly (p_TCB);
      os_dispatch (p_TCB);
      }
   else {
      /* Store token. */
      _incw (&p_SCB->tokens);
      };
   tsk_unlock();
   return (OS_R_OK);
} /* end of os_sem_send */


/*--------------------------- os_sem_wait -----------------------------------*/

OS_RESULT os_sem_wait (OS_ID semaphore, U16 timeout) {
   /* Obtain a token; possibly wait for it */
   tsk_lock();
   if (p_SCB->tokens) {
      _decw (&p_SCB->tokens);
      tsk_unlock();
      return (OS_R_OK);
      };
   /* No token available: wait for one */
   if (timeout == 0) {
      goto rtmo;
   }
   if (p_SCB->p_lnk != NULL) {
      os_put_prio ((P_XCB)p_SCB, os_runtask);
      }
   else {
      p_SCB->p_lnk = os_runtask;
      os_runtask->p_lnk = NULL;
      os_runtask->p_rlnk = (P_TCB)p_SCB;
      };
   if (os_block(timeout, WAIT_SEM) == OS_R_TMO) {
rtmo: tsk_unlock();
      return (OS_R_TMO);
      }
   else {
      tsk_unlock();
      return (OS_R_SEM);
      }
} /* end of os_sem_wait */


/*--------------------------- isr_sem_send ----------------------------------*/

void isr_sem_send (OS_ID semaphore) {
   /* Same function as "os_sem"send", but to be called by ISRs */
   /* Store token */
   _incw (&p_SCB->tokens);
   os_psq_enq (p_SCB, NULL);
   os_psh_req ();
} /* end of isr_sem_send */


/*--------------------------- os_sem_psh ------------------------------------*/

void os_sem_psh (P_SCB p_CB) {
   /* Check if task has to be waken up */
   P_TCB p_TCB;

   if (p_CB->p_lnk != NULL) {
      /* A task is waiting for token */
      _decw (&p_CB->tokens);
      p_TCB = os_get_first ((P_XCB)p_CB);
      os_rmv_dly (p_TCB);
      p_TCB->ret_val = OS_R_SEM;
      p_TCB->state   = READY;
      os_put_prio (&os_rdy, p_TCB);
   }
} /* end of os_sem_psh */

/*----------------------------------------------------------------------------
 * end of file
 *---------------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -