uCOS-III学习笔记(10)----等待多个内核对象

理解:等待多个内核对象说的就是,比如一个任务需要等待信号量才能打开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(因为按键按下导致发送了一个信号量) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值