其他分享
首页 > 其他分享> > UCOS---等待多个内核对象

UCOS---等待多个内核对象

作者:互联网

UCOS---等待多个内核对象

概述

内核对象,可以指的是信号量、消息队列、互斥锁、事件标志组等

等待多个内核对象

等待多个内核对象,只能等待信号量和消息队列。

在UCOSIII中允许任务同时等待多个信号量和多个消息队列,也就是说,UCOSIII不支持同时等待多个事件标志组或互斥锁。

This function only allows you to pend on semaphores and/or message queues.

OS_OBJ_QTY  OSPendMulti (OS_PEND_DATA  *p_pend_data_tbl,
                         OS_OBJ_QTY     tbl_size,
                         OS_TICK        timeout,
                         OS_OPT         opt,
                         OS_ERR        *p_err)

参数:
p_pend_data_tbl,内核对象的数组
tbl_size,内核对象的数目
timeout,超时时间,默认写0,一直等待
opt,默认写OS_OPT_PEND_BLOCKING,阻塞等待
p_err,返回错误码,没有错误的就返回OS_ERR_NONE

返回值:

0,就绪内核对象的数目
=0,超时或发生错误

注意:
使用上述函数,确保OS_CFG_Q_EN、OS_CFG_SEM_EN、OS_CFG_PEND_MULTI_EN宏定义开关有效,并可在os_cfg.h文件找到。

例程

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "includes.h"
#include "string.h"

//任务函数
void Task1_task(void *parg);
//任务优先级
#define	Task1_TASK_PRIO	6
//任务堆栈大小
#define	Task1_TASK_SIZE	128
//任务堆栈空间
CPU_STK	Task1_TASK_STK[Task1_TASK_SIZE];
//任务控制块
OS_TCB	Task1_TCB;

//任务函数
void Task2_task(void *parg);
//任务优先级
#define	Task2_TASK_PRIO	6
//任务堆栈大小
#define	Task2_TASK_SIZE	128
//任务堆栈空间
CPU_STK	Task2_TASK_STK[Task1_TASK_SIZE];
//任务控制块
OS_TCB	Task2_TCB;


OS_Q	g_queue_usart1;
OS_SEM	g_sem;

OS_PEND_DATA	MyPendArray[2];

int main(void)
{
	//UCOS系统的变量定义
	OS_ERR err;
	
	delay_init();       //延时初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置
	uart_init(115200);    //串口波特率设置
	LED_Init();         //LED初始化

	//初始化UCOSIII
	OSInit(&err);
	
	//创建任务1
	OSTaskCreate((OS_TCB 	* )&Task1_TCB,		//任务控制块
				 (CPU_CHAR	* )"Task1_task", 		//任务名字
                 (OS_TASK_PTR )Task1_task, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )Task1_TASK_PRIO,     //任务优先级
                 (CPU_STK   * )&Task1_TASK_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)Task1_TASK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)Task1_TASK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_NONE, //任务选项
                 (OS_ERR 	* )&err);				//存放该函数错误时的返回值

	//创建任务2
	OSTaskCreate((OS_TCB 	* )&Task2_TCB,		//任务控制块
				 (CPU_CHAR	* )"Task2_task", 		//任务名字
                 (OS_TASK_PTR )Task2_task, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )Task2_TASK_PRIO,     //任务优先级
                 (CPU_STK   * )&Task2_TASK_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)Task2_TASK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)Task2_TASK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_NONE, //任务选项
                 (OS_ERR 	* )&err);				//存放该函数错误时的返回值		 
			
	//创建信号量,初值为0
	OSSemCreate(&g_sem,"g_sem",0,&err);				 
	//创建消息队列
	OSQCreate(&g_queue_usart1,"g_queue_usart1",16,&err);
	
	MyPendArray[0].PendObjPtr=(OS_PEND_OBJ*)&g_sem;
	MyPendArray[1].PendObjPtr=(OS_PEND_OBJ*)&g_queue_usart1;
	//开启UCOSIII
	OSStart(&err);  
				 
	printf("OS run error.......\r\n");
	while(1);
}

void Task1_task(void *parg)
{
	u32 cnt =0;
	char buf[64]={0};
	
	OS_ERR err;
	printf("task1 is create ok\r\n");

	while(1)
	{
		cnt++;
		sprintf(buf,"task1 run %d times",cnt);
		printf("task1 is running ...\r\n");
		//每三秒发送信号量
		OSSemPost(&g_sem,OS_OPT_POST_1,&err);
		delay_ms(3000);
		OSQPost(&g_queue_usart1,buf,strlen(buf),OS_OPT_POST_FIFO,&err);
		delay_ms(1000);
		
	}
}

void Task2_task(void *parg)
{
	OS_OBJ_QTY obj_count=0;
	OS_ERR err;		
	printf("task2 is create ok\r\n");

	while(1)
	{
		obj_count=OSPendMulti(MyPendArray,2,0,OS_OPT_PEND_BLOCKING,&err);
		if(obj_count>0)
		{
			if(MyPendArray[0].RdyObjPtr == (OS_PEND_OBJ*)&g_sem)
			{
					printf("sem get\r\n");
			}
			if(MyPendArray[1].RdyObjPtr == (OS_PEND_OBJ*)&g_queue_usart1)
			{
				printf("msg:[%s][%d]\r\n",MyPendArray[1].RdyMsgPtr,MyPendArray[1].RdyMsgSize);
			
				memset(MyPendArray[1].RdyMsgPtr,0,MyPendArray[1].RdyMsgSize);
			}
		}
		printf("task2 is running ...\r\n");
		
		delay_ms(1000);
	}
}




任务1每3秒发送一个信号量再延时1秒发送消息队列
任务2将接收到的消息队列和信号量打印到串口
在这里插入图片描述

标签:Task1,TASK,err,UCOS,void,---,任务,内核,OS
来源: https://blog.csdn.net/mangofu/article/details/123035697