创建信号量,挂起信号量和发布信号量
创建信号量
void OSSemCreate (OS_SEM *p_sem,CPU_CHAR *p_name,OS_SEM_CTR cnt,OS_ERR *p_err)
{
CPU_SR_ALLOC();//分配CPU状态寄存器,字节为单位;cpu.h中#define CPU_SR cpu_sr = (CPU_SR)0
CPU_CRITICAL_ENTER();//CPU_INT_DIS(); cpu_sr = CPU_SR_Save(); //CPU_SR_Save 是汇编语言,见note1
//CPU_IntDisMeasStart(); //见Note2
p_sem->Type = OS_OBJ_TYPE_SEM;
p_sem->Ctr = cnt; /* Set semaphore value */ //信号量被发起的次数
p_sem->TS = (CPU_TS)0;
p_sem->NamePtr = p_name;
OS_PendListInit(&p_sem->PendList); //初始化任务挂起表
OSSemQty++; //信号量个数
OS_CRITICAL_EXIT_NO_SCHED(); //CPU_IntDisMeasStop(); //见Note3
// CPU_INT_EN(); //CPU_SR_Restore(cpu_sr); //汇编语言,见Note4
}
挂起信号量
OS_SEM_CTR OSSemPend (OS_SEM *p_sem,OS_TICK timeout,OS_OPT opt,CPU_TS *p_ts,OS_ERR *p_err)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
if (p_sem->Ctr > (OS_SEM_CTR)0) { /* Resource available? */ //信号量post过?
p_sem->Ctr--; /* Yes, caller may proceed */
*p_ts = p_sem->TS; /* get timestamp of last post */
ctr = p_sem->Ctr;
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return (ctr);
}
//信号量没有post过,执行以下
OS_Pend(&pend_data,(OS_PEND_OBJ *)((void *)p_sem),OS_TASK_PEND_ON_SEM,timeout); /* Block task pending on Semaphore */ //pend类型是信号量,去掉就绪状态,可以设定timeout(插入定时列表),见NOTE5
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); //任务调度,包括切换
CPU_CRITICAL_ENTER(); //重新进入任务的该函数?
switch (OSTCBCurPtr->PendStatus) {
case OS_STATUS_PEND_OK:
break;
case OS_STATUS_PEND_ABORT:
break;
}
ctr = p_sem->Ctr;
CPU_CRITICAL_EXIT();
return (ctr);
}
发布信号量
OS_SEM_CTR OSSemPost (OS_SEM *p_sem,OS_OPT opt,OS_ERR *p_err)
{
OS_Post((OS_PEND_OBJ *)((void *)p_sem),p_tcb,(void *)0,(OS_MSG_SIZE)0,ts);
}
NOTE1
CPU_SR_Save
MRS R0, PRIMASK ; Set prio int mask to mask all (except faults)
CPSID I
BX LR
NOTE2
void CPU_IntDisMeasStart (void)
{
CPU_IntDisMeasCtr++;
if (CPU_IntDisNestCtr == 0u) { /* If ints NOT yet dis‘d, ... */
CPU_IntDisMeasStart_cnts = CPU_TS_TmrRd(); /* ... get ints dis‘d start time. */ 0xE0001004
}
CPU_IntDisNestCtr++;
}
NOTE3
void CPU_IntDisMeasStop (void)
{
CPU_TS_TMR time_ints_disd_cnts;
CPU_IntDisNestCtr--;
if (CPU_IntDisNestCtr == 0u) { /* If ints NO longer dis‘d, ... */
CPU_IntDisMeasStop_cnts = CPU_TS_TmrRd(); /* ... get ints dis‘d stop time & ... */
/* ... calc ints dis‘d tot time (see Note #1b2A). */
time_ints_disd_cnts = CPU_IntDisMeasStop_cnts -
CPU_IntDisMeasStart_cnts;
/* Calc max ints dis‘d times. */
if (CPU_IntDisMeasMaxCur_cnts < time_ints_disd_cnts) {
CPU_IntDisMeasMaxCur_cnts = time_ints_disd_cnts;
}
if (CPU_IntDisMeasMax_cnts < time_ints_disd_cnts) {
CPU_IntDisMeasMax_cnts = time_ints_disd_cnts;
}
}
}
NOTE4
CPU_SR_Restore ; See Note #2.
MSR PRIMASK, R0
BX LR
NOTE5
void OS_Pend (OS_PEND_DATA *p_pend_data,OS_PEND_OBJ *p_obj,OS_STATE pending_on,OS_TICK timeout)
{
OSTCBCurPtr->PendOn = pending_on; //正在等待的事件
OSTCBCurPtr->PendStatus = OS_STATUS_PEND_OK;
OS_TaskBlock(OSTCBCurPtr, timeout);/* Block the task and add it to the tick list if needed */ //见NOTE6
if (p_obj != (OS_PEND_OBJ *)0) { /* Add the current task to the pend list ... */
p_pend_list = &p_obj->PendList; /* ... if there is an object to pend on */
p_pend_data->PendObjPtr = p_obj; /* Save the pointer to the object pending on */
OS_PendDataInit((OS_TCB *)OSTCBCurPtr, /* Initialize the remaining field */
(OS_PEND_DATA *)p_pend_data,
(OS_OBJ_QTY )1);
OS_PendListInsertPrio(p_pend_list, /* Insert in the pend list in priority order */
p_pend_data);
} else {
OSTCBCurPtr->PendDataTblEntries = (OS_OBJ_QTY )0; /* If no object being pended on the clear these fields */
OSTCBCurPtr->PendDataTblPtr = (OS_PEND_DATA *)0; /* ... in the TCB */
}
#if OS_CFG_DBG_EN > 0u
OS_PendDbgNameAdd(p_obj,
OSTCBCurPtr);
#endif
}
NOTE6
void OS_TaskBlock (OS_TCB *p_tcb,
OS_TICK timeout)
{
if (timeout > (OS_TICK)0) { /* Add task to tick list if timeout non zero */
OS_TickListInsert(&OSTickListTimeout, p_tcb, timeout);
p_tcb->TaskState = OS_TASK_STATE_PEND_TIMEOUT;
} else {
p_tcb->TaskState = OS_TASK_STATE_PEND;
}
OS_RdyListRemove(p_tcb); //任务就绪表中去除当前任务
}
/* 以下条件都没满足:没有定义,或#define 0;
#ifdef OS_SAFETY_CRITICAL
#ifdef OS_SAFETY_CRITICAL_IEC61508 //没有定义
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
#if OS_CFG_ARG_CHK_EN > 0u
*/
}
原文:https://www.cnblogs.com/deyicun/p/10799892.html