当前位置:网站首页>[UCOS III source code analysis] - wait for multiple kernel objects
[UCOS III source code analysis] - wait for multiple kernel objects
2022-07-18 22:15:00 【Your husband_ one thousand and sixteen】
One 、 Wait for multiple kernel objects
here ucos There are certain restrictions on waiting for multiple kernel objects , And this function also has some disadvantages
1、 Waiting for multiple kernel objects can only be semaphores or message queues , Cannot be another kernel object , But there are many .
2、 Waiting for multiple kernel objects will release the wait because one of them is released , It doesn't need to wait until all kernel objects are released .
Wait function :OSPendMulti It mainly contains these contents
valid = OS_PendMultiValidate(p_pend_data_tbl, /* -------- Validate objects to be OS_SEM or OS_Q ------- */
tbl_size);
//------------------------------------------------------------------------------
CPU_BOOLEAN OS_PendMultiValidate (OS_PEND_DATA *p_pend_data_tbl,
OS_OBJ_QTY tbl_size)
{
OS_OBJ_QTY i;
OS_OBJ_QTY ctr;
#if OS_CFG_SEM_EN > 0u
OS_SEM *p_sem;
#endif
#if OS_CFG_Q_EN > 0u
OS_Q *p_q;
#endif
for (i = 0u; i < tbl_size; i++) {
if (p_pend_data_tbl->PendObjPtr == (OS_PEND_OBJ *)0) { /* All .PendObjPtr in the table MUST be non NULL */
return (DEF_FALSE);
}
ctr = 0u;
#if OS_CFG_SEM_EN > 0u
p_sem = (OS_SEM *)((void *)p_pend_data_tbl->PendObjPtr); /* All objects to pend on must be of type OS_SEM ... */
if (p_sem->Type == OS_OBJ_TYPE_SEM) {
ctr++;
}
#endif
#if OS_CFG_Q_EN > 0u
p_q = (OS_Q *)((void *)p_pend_data_tbl->PendObjPtr); /* ... or of type OS_Q */
if (p_q->Type == OS_OBJ_TYPE_Q) {
ctr++;
}
#endif
if (ctr == (OS_OBJ_QTY)0) {
return (DEF_FALSE); /* Found at least one invalid object type */
}
p_pend_data_tbl++;
}
return (DEF_TRUE);
}In addition to routine parameter checking, the first one is the function called , There will be a cycle to check which array you have set to wait, and whether the waiting object in it has been set , If it is not set, return directly . The next step is to check how many semaphores or message queues are in your settings , Yes, once ++ once , So you go to the last if When you are ctr Definitely not 0, Because the multiple kernel objects you set that need to wait will definitely meet the above two if bring ctr++ A few times . Return to the correct definition .
Then call this
nbr_obj_rdy = OS_PendMultiGetRdy(p_pend_data_tbl, /* --------- SEE IF OBJECT(s) HAVE BEEN POSTED ---------- */
tbl_size);
//--------------------------------------------------------------------------------------
OS_OBJ_QTY OS_PendMultiGetRdy (OS_PEND_DATA *p_pend_data_tbl,
OS_OBJ_QTY tbl_size)
{
OS_OBJ_QTY i;
OS_OBJ_QTY nbr_obj_rdy;
#if OS_CFG_Q_EN > 0u
OS_ERR err;
OS_MSG_SIZE msg_size;
OS_Q *p_q;
void *p_void;
CPU_TS ts;
#endif
#if OS_CFG_SEM_EN > 0u
OS_SEM *p_sem;
#endif
nbr_obj_rdy = (OS_OBJ_QTY)0;
for (i = 0u; i < tbl_size; i++) {
p_pend_data_tbl->RdyObjPtr = (void *)0; /* Clear all fields */
p_pend_data_tbl->RdyMsgPtr = (void *)0;
p_pend_data_tbl->RdyMsgSize = (OS_MSG_SIZE )0;
p_pend_data_tbl->RdyTS = (CPU_TS )0;
p_pend_data_tbl->NextPtr = (OS_PEND_DATA *)0;
p_pend_data_tbl->PrevPtr = (OS_PEND_DATA *)0;
p_pend_data_tbl->TCBPtr = (OS_TCB *)0;
#if OS_CFG_Q_EN > 0u
p_q = (OS_Q *)((void *)p_pend_data_tbl->PendObjPtr); /* Assume we are pointing to a message queue object */
if (p_q->Type == OS_OBJ_TYPE_Q) { /* Is it a message queue? */
p_void = OS_MsgQGet(&p_q->MsgQ, /* Yes, Any message waiting in the message queue? */
&msg_size,
&ts,
&err);
if (err == OS_ERR_NONE) {
p_pend_data_tbl->RdyObjPtr = p_pend_data_tbl->PendObjPtr;
p_pend_data_tbl->RdyMsgPtr = p_void; /* Yes, save the message received */
p_pend_data_tbl->RdyMsgSize = msg_size;
p_pend_data_tbl->RdyTS = ts;
nbr_obj_rdy++;
}
}
#endif
#if OS_CFG_SEM_EN > 0u
p_sem = (OS_SEM *)((void *)p_pend_data_tbl->PendObjPtr); /* Assume we are pointing to a semaphore object */
if (p_sem->Type == OS_OBJ_TYPE_SEM) { /* Is it a semaphore? */
if (p_sem->Ctr > 0u) { /* Yes, Semaphore has been signaled? */
p_sem->Ctr--; /* Yes, caller may proceed */
p_pend_data_tbl->RdyObjPtr = p_pend_data_tbl->PendObjPtr;
p_pend_data_tbl->RdyTS = p_sem->TS;
nbr_obj_rdy++;
}
}
#endif
p_pend_data_tbl++;
}
return (nbr_obj_rdy);
}The words here can be roughly divided into three parts , Set initial value 0, Get whether it is a message queue. If yes , fill , Get whether it is a semaphore , If yes, fill ,nbr_obj_rdy This variable represents how many kernel objects you get that need to wait .
It is to use the return value just now to judge again , Did you get the kernel object , At this time, there are two kinds
1、 Got it , This is very simple, just return directly , Just finish the function
if (nbr_obj_rdy > (OS_OBJ_QTY)0) {
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return ((OS_OBJ_QTY)nbr_obj_rdy);
}2、 Didn't get , At this time, it depends on whether you are blocking or non blocking
Non blocking : Exit back 0
Blocking : call OS_PendMultiWait, Explained below
if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) { /* Caller wants to block if not available? */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_PEND_WOULD_BLOCK; /* No */
return ((OS_OBJ_QTY)0);
} else {
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend when the scheduler is locked */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_SCHED_LOCKED;
return ((OS_OBJ_QTY)0);
}
}
OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT(); /* Lock the scheduler/re-enable interrupts */
/* ------ NO OBJECT READY, PEND ON MULTIPLE OBJECTS ----- */
OS_PendMultiWait(p_pend_data_tbl, /* Suspend task until object posted or timeout occurs */
tbl_size,
timeout);
OS_CRITICAL_EXIT_NO_SCHED();OS_PendMultiWait(p_pend_data_tbl, /* Suspend task until object posted or timeout occurs */
tbl_size,
timeout);
//------------------------------------------------------------------------------------
void OS_PendMultiWait (OS_PEND_DATA *p_pend_data_tbl,
OS_OBJ_QTY tbl_size,
OS_TICK timeout)
{
OS_OBJ_QTY i;
OS_PEND_LIST *p_pend_list;
#if OS_CFG_Q_EN > 0u
OS_Q *p_q;
#endif
#if OS_CFG_SEM_EN > 0u
OS_SEM *p_sem;
#endif
OSTCBCurPtr->PendOn = OS_TASK_PEND_ON_MULTI; /* Resource not available, wait until it is */
OSTCBCurPtr->PendStatus = OS_STATUS_PEND_OK;
OSTCBCurPtr->PendDataTblEntries = tbl_size;
OSTCBCurPtr->PendDataTblPtr = p_pend_data_tbl;
OS_TaskBlock(OSTCBCurPtr, /* Block the task waiting for object to be posted ... */
timeout); /* ... but with a timeout if not */
for (i = 0u; i < tbl_size; i++) {
p_pend_data_tbl->TCBPtr = OSTCBCurPtr; /* Every entry points back to the TCB of the task */
#if OS_CFG_SEM_EN > 0u
p_sem = (OS_SEM *)((void *)p_pend_data_tbl->PendObjPtr);
if (p_sem->Type == OS_OBJ_TYPE_SEM) {
p_pend_list = &p_sem->PendList;
OS_PendListInsertPrio(p_pend_list,
p_pend_data_tbl);
}
#endif
#if OS_CFG_Q_EN > 0u
p_q = (OS_Q *)((void *)p_pend_data_tbl->PendObjPtr);
if (p_q->Type == OS_OBJ_TYPE_Q) {
p_pend_list = &p_q->PendList;
OS_PendListInsertPrio(p_pend_list,
p_pend_data_tbl);
}
#endif
p_pend_data_tbl++;
}
}Here is the function mentioned above , It is to save the current task status that needs to be suspended and waited ( Wait for multiple kernel objects , Number of waits , Actively suspend ) If there is a timeout, it will be added to the clock reference list , Remove... From the ready list , Remove from the ready list . Follow up on , The kernel objects your task is waiting for , Insert them into the corresponding waiting list respectively ( Pointer auto increment cycle ).
3、 Task scheduling , Here, if you wait for any one, you will return here to continue running , Then the whole function returns a 1, Then the function ends .
OSSched(); /* Find next highest priority task ready */
CPU_CRITICAL_ENTER();
switch (OSTCBCurPtr->PendStatus) {
case OS_STATUS_PEND_OK: /* We got one of the objects posted to */
*p_err = OS_ERR_NONE;
break;
case OS_STATUS_PEND_ABORT: /* Indicate that the multi-pend was aborted */
*p_err = OS_ERR_PEND_ABORT;
break;
case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get semaphore within timeout */
*p_err = OS_ERR_TIMEOUT;
break;
case OS_STATUS_PEND_DEL: /* Indicate that an object pended on has been deleted */
*p_err = OS_ERR_OBJ_DEL;
break;
default:
*p_err = OS_ERR_STATUS_INVALID;
break;
}
OSTCBCurPtr->PendStatus = OS_STATUS_PEND_OK;
CPU_CRITICAL_EXIT();
return ((OS_OBJ_QTY)1);边栏推荐
- MySQL 5.7.37 database download and installation tutorial (no installation required for Windows)
- Vs2017\vs2019\vs2022 project redundant files (intermediate files \ temporary files) one click clean bat
- Flutter 卡在 Running Gradle task ‘assembleDebug‘... 的解决方法
- Which brand of Bluetooth headset has good noise reduction? Top 10 active noise reduction headphones
- Application of Apache E7 series industrial computer minipicecan card in meal delivery robot
- pdf中的超链接,跳转之后,如何返回去? alt + ←
- ThoughtWorks现代企业架构框架白皮书 笔记
- Cmu15445 (fall 2019) project 4 - logging & Recovery details
- C language - array
- 你的接口多少QPS?
猜你喜欢

It's time to talk about RPA

Swin transformer, the best paper model of iccv 2021, finally started with video!

Leetcode 1342. 将数字变成 0 的操作次数

In depth analysis of multiple knapsack problem (Part 2)

迪奥疑似抄袭中国马面裙,国内官网已下架该产品

Visual studio production environment configuration scheme: slowcheetah

十大OA系统排行

1302_ Analysis of design and implementation of coroutine in FreeRTOS

Linux 解决 Oracle :ORA-12537: TNS:connection closed(连接关闭)问题

Ranking of top ten OA systems
随机推荐
如何在自动化测试中使用MitmProxy获取数据返回
毕业季--数据库常见面试题
TimeSformer: 只靠 Transformer 就能理解视频?注意力机制的又一次进击!
21届毕业生毕业一年内的真实工作状态
SFF1602-MHCHXM超快恢复二极管SFF1602
[UCOS III source code analysis] - task creation
镍氢电池的特性和使用方法(FDK镍氢电池充电机制)
阿里云、华为云、谷歌云都已入局,盘点13家云计算厂商的RPA
An error is reported when viewing the service status inside the container: failed to get D-Bus connection: operation not allowed
pA是什么?构建病毒的结构元件,polyA,一段重复的碱基序列
Omnivore, a non picky AI model, focuses on images, videos and 3D data!
Timesformer: can you understand video by transformer alone? Another attack of attention mechanism!
Visual Studio 生产环境配置方案:SlowCheetah
Stream - elegant handling of collection elements
Sword finger offer 44 [a bit in the number sequence] [100%, 100%]
Application of Apache E8 industrial computer minipicecan card in Construction Robot
[Seaborn] 5. Matrix plots
Vs2017\vs2019\vs2022 project redundant files (intermediate files \ temporary files) one click clean bat
RPA ecosystem revealed, supporting the life source of RPA enterprises' billions of valuation
栓Q了,大厂被强制毕业,空窗一个月死背八股文,还好拿到了Offer