理解:等待多个内核对象说的就是,比如一个任务需要等待信号量才能打开led1,等待一个消息队列才能打开led2,此时不用等待多个内核对象的话就算来了信号量也会被pend卡住而不能往下面运行,所以等待多个内核对象解决的就是这类问题。
创建多个内核对象:比如需要等待一个信号量和一个消息队列,多内核对象就可以看成是一个数组
OS_SEM MY_SEM;
OS_Q MyMsgQ;
OS_PEND_DATA mul_pend_array[2];//等待两个 这里就是2
OSSemCreate ((OS_SEM *)&MY_SEM,
(CPU_CHAR *)"MY_SEM",
(OS_SEM_CTR)0,
(OS_ERR *)&err);
OSQCreate((OS_Q *)&MyMsgQ,
(CPU_CHAR *)"MyMsgQ",
(OS_MSG_QTY)1000,
(OS_ERR *)&err);
mul_pend_array[0].PendObjPtr = (OS_PEND_OBJ *)&MY_SEM; //这里要注意类型的匹配
mul_pend_array[1].PendObjPtr = (OS_PEND_OBJ *)&MyMsgQ;
创建好后来测试一下,
用任务1循环的发送一个消息队列,
并且增加一个软件定时器来检测按键是否按下,
如果按下发送一个信号量
extern OS_SEM MY_SEM;
extern OS_Q MyMsgQ;
extern OS_PEND_DATA mul_pend_array[2];
void tmr1_callback(OS_TMR *p_tmr, void *p_arg);
void Task_1(void *p_arg)
{
OS_ERR err;
OS_TMR tmr1;
(void)p_arg;
OSTmrCreate((OS_TMR *)&tmr1,
(CPU_CHAR *)"tmr1",
(OS_TICK )0,
(OS_TICK )1, // 1*100ms = 100ms
(OS_OPT )OS_OPT_TMR_PERIODIC,
(OS_TMR_CALLBACK_PTR) tmr1_callback,
(void *)0,
(OS_ERR *)&err);
OSTmrStart(&tmr1, &err);
while(1)
{
OSQPost((OS_Q *)&MyMsgQ,
(void *)"I love you, Rick",
(OS_MSG_SIZE)sizeof("I love you, Rick"),
(OS_OPT )OS_OPT_POST_FIFO | OS_OPT_POST_ALL,
(OS_ERR *)&err);
OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err);
}
}
void Task_2(void *p_arg)
{
OS_ERR err;
(void)p_arg;
while(1)
{
OSPendMulti((OS_PEND_DATA *)mul_pend_array,
(OS_OBJ_QTY )2,
(OS_TICK )0,
(OS_OPT )OS_OPT_PEND_BLOCKING,
(OS_ERR *)&err);
if(mul_pend_array[0].RdyObjPtr == mul_pend_array[0].PendObjPtr)
{
printf("Key1 is pressed\n");
}
if(mul_pend_array[1].RdyObjPtr == mul_pend_array[1].PendObjPtr)
{
printf("Received: %s, size: %dbytes.\n", (char *)mul_pend_array[1].RdyMsgPtr, mul_pend_array[1].RdyMsgSize);
}
}
}
void tmr1_callback(OS_TMR *p_tmr, void *p_arg)
{
OS_ERR err;
if(Key_Scan(GPIOA, GPIO_Pin_0) == KEY_ON)
{
OSSemPost(&MY_SEM, OS_OPT_POST_ALL, &err);
}
}
实际结果就是,串口一直打印字符串(因为一直循环发送消息队列),
如果按键按下,打印key is pressed(因为按键按下导致发送了一个信号量)