📄 ar_semaphore.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 + -