us/os iii信号量
发布日期:2022-03-11 15:03:35 浏览次数:12 分类:技术文章

本文共 4338 字,大约阅读时间需要 14 分钟。

创建信号量,挂起信号量和发布信号量

创建信号量

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

转载地址:https://blog.csdn.net/weixin_30267785/article/details/99166673 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:大四实习准备4_java内部类
下一篇:CDE 快捷键

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月25日 01时14分14秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章