Explicación de los conocimientos básicos de UCOSIII

Características

  • Ayude a los principiantes a conocer UCOS III
  • Adquirir los conocimientos básicos de UCOSIII, incluida la creación y eliminación de tareas, la suspensión y reanudación de tareas, temporizadores de software, semáforos y semáforos de exclusión mutua, transmisión de mensajes, etc.

1. Introducción

  Micrium proporciona μC / OS-II. Es un kernel multitarea en tiempo real portátil, curable, adaptable y preventivo. Es adecuado para una variedad de microprocesadores, microcontroladores y chips de procesamiento digital (que se han trasplantado a más de 100 tipos de aplicaciones de microprocesador). Al mismo tiempo, el código fuente del sistema es abierto, limpio y coherente, con comentarios detallados, adecuado para el desarrollo del sistema. μC / OS-II ha pasado la certificación de aeronaves comerciales de la Administración Federal de Aviación (FAA) y cumple con el estándar DO-178B de la Comisión de Tecnología de Radio para Aeronáutica (RTCA). La última versión es μC / OS-III.
  μC / OS-II se puede dividir aproximadamente en 5 partes: núcleo, procesamiento de tareas, procesamiento de tiempo, sincronización y comunicación de tareas y trasplante de CPU.

  1. La parte central (OSCore.c)
    es el núcleo de procesamiento del sistema operativo, incluida la inicialización del sistema operativo, el funcionamiento del sistema operativo, la entrada y salida de interrupciones, el tic del reloj, la programación de tareas, el procesamiento de eventos, etc. Las partes que pueden mantener el trabajo básico del sistema están aquí.
  2. El contenido de la parte de procesamiento de la tarea (OSTask.c)
    está estrechamente relacionado con el funcionamiento de la tarea. Incluyendo la creación, eliminación, suspensión, recuperación de tareas, etc. Debido a que μC / OS-II se programa en función de las tareas, esta parte del contenido también es muy importante.
  3. Parte del reloj (OSTime.c)
    La unidad de reloj más pequeña en μC / OS-II es timetick (tic del reloj). Las operaciones como el retraso de tareas se completan aquí.
  4. La parte de sincronización y comunicación de tareas
    es la parte de procesamiento de eventos, que incluye semáforos, buzones de correo, colas de buzones de correo, banderas de eventos, etc .; se utiliza principalmente para el contacto mutuo entre tareas y el acceso a recursos críticos.
  5. La parte de interfaz con la CPU se
    refiere a la parte de transferencia de μC / OS-II para la CPU utilizada. Debido a que μC / OS-II es un sistema operativo universal, la realización de los problemas clave aún debe trasplantarse de acuerdo con el contenido y los requisitos específicos de la CPU específica. Debido a que esta parte del contenido incluye punteros del sistema como SP, generalmente está escrito en lenguaje ensamblador. Incluye principalmente la implementación de bajo nivel de conmutación de tareas a nivel de interrupción, la implementación de nivel inferior de conmutación de tareas a nivel de tarea, la generación y procesamiento de pulsos de reloj y el procesamiento relacionado de interrupciones.

2. Conocimientos básicos

1. Creación de tareas

①Definir los parámetros relevantes

//任务优先级
#define LED1_TASK_PRIO		5
//任务堆栈大小	
#define LED1_STK_SIZE 		128
//任务控制块
OS_TCB Led1TaskTCB;
//任务堆栈	
CPU_STK LED1_TASK_STK[LED1_STK_SIZE];
//任务函数
void led1_task(void *p_arg);

②Crear tarea

//创建LED1任务
OSTaskCreate((OS_TCB 	* )&Led1TaskTCB,		
			 (CPU_CHAR	* )"led1 task", 		
                (OS_TASK_PTR )led1_task, 			
                (void		* )0,					
                (OS_PRIO	  )LED1_TASK_PRIO,     	
                (CPU_STK   * )&LED1_TASK_STK[0],	
                (CPU_STK_SIZE)LED1_STK_SIZE/10,	
                (CPU_STK_SIZE)LED1_STK_SIZE,		
                (OS_MSG_QTY  )0,					
                (OS_TICK	  )0,					
                (void   	* )0,				
                (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, 
                (OS_ERR 	* )&err);

③Función de tarea de escritura

//led1任务函数
void led1_task(void *p_arg)
{
    
    
	OS_ERR err;
	p_arg = p_arg;
	while(1)
	{
    
    
		LED1=~LED1;
		OSTimeDlyHMSM(0,0,0,200,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms
	}
}

2. Suspender y reanudar tareas

在这里插入代码片//task1任务函数
void task1_task(void *p_arg)
{
    
    
	u8 task1_num=0;
	OS_ERR err;
	CPU_SR_ALLOC();
	p_arg = p_arg;
	
	POINT_COLOR = BLACK;
	OS_CRITICAL_ENTER();
	LCD_DrawRectangle(5,110,115,314); 	//画一个矩形	
	LCD_DrawLine(5,130,115,130);		//画线
	POINT_COLOR = BLUE;
	LCD_ShowString(6,111,110,16,16,"Task1 Run:000");
	OS_CRITICAL_EXIT();
	while(1)
	{
    
    
		task1_num++;	//任务1执行次数加1 注意task1_num1加到255的时候会清零!!
		LED0= ~LED0;
		printf("任务1已经执行:%d次\r\n",task1_num);
		if(task1_num==5) 
		{
    
    
			OSTaskSuspend((OS_TCB*)&Task2_TaskTCB,&err);//任务1执行5次后挂起任务2
			printf("任务1挂起了任务2!\r\n");
		}
		if(task1_num==10) 
		{
    
    
			OSTaskResume((OS_TCB*)&Task2_TaskTCB,&err);	//任务1运行10次后恢复任务2
			printf("任务1恢复了任务2!\r\n");
		}
		LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //填充区域
		LCD_ShowxNum(86,111,task1_num,3,16,0x80);	//显示任务执行次数
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s
		
	}
}

3. Sincronización de tareas

①Definir el semáforo

OS_SEM	MY_SEM;		           				 //定义一个信号量,用于访问共享资源

②Crear un semáforo en la tarea de inicio

OSSemCreate ((OS_SEM*	)&MY_SEM,			//创建一个信号量
                (CPU_CHAR*	)"MY_SEM",
                (OS_SEM_CTR)1,		
                (OS_ERR*	)&err);

③Utilizar semáforo

//led0任务函数
void led0_task(void *p_arg)
{
    
    
	OS_ERR err;
	p_arg = p_arg;
	while(1)
	{
    
    
		OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); 	//请求信号量
		LED0=~LED0;
		
//		share_resource=share_resource+1;
//		printf("任务1执行次数:%d\r\n",share_resource);
//		delay_ms(1000);
//		OSSemPost (&MY_SEM,OS_OPT_POST_1,&err);				//发送信号量
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms
	}
}

//led1任务函数
void led1_task(void *p_arg)
{
    
    
	OS_ERR err;
	p_arg = p_arg;
	while(1)
	{
    
    
		LED1=~LED1;
		OSSemPost (&MY_SEM,OS_OPT_POST_1,&err);
//		OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); 	//请求信号量
//		share_resource=share_resource+1;
//		printf("任务2执行次数:%d\r\n",share_resource);
		//delay_ms(2000);
						//发送信号量
		OSTimeDlyHMSM(0,0,2,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms
	}
}

4. Entrega de mensajes

①Definir la cola de mensajes

#define KEYMSG_Q_NUM	1	//按键消息队列的数量
#define DATAMSG_Q_NUM	4	//发送数据的消息队列的数量
OS_Q KEY_Msg;				//定义一个消息队列,用于按键消息传递,模拟消息邮箱
OS_Q DATA_Msg;				//定义一个消息队列,用于发送数据

②Crear una cola de mensajes

//创建消息队列KEY_Msg
OSQCreate ((OS_Q*		)&KEY_Msg,	//消息队列
               (CPU_CHAR*	)"KEY Msg",	//消息队列名称
               (OS_MSG_QTY	)KEYMSG_Q_NUM,	//消息队列长度,这里设置为1
               (OS_ERR*	)&err);		//错误码
//创建消息队列DATA_Msg
OSQCreate ((OS_Q*		)&DATA_Msg,	
               (CPU_CHAR*	)"DATA Msg",	
               (OS_MSG_QTY	)DATAMSG_Q_NUM,	
               (OS_ERR*	)&err);	

③Función de tarea

//定时器1的回调函数
void tmr1_callback(void *p_tmr,void *p_arg)
{
    
    
	u8 *pbuf;
	static u8 msg_num;
	OS_ERR err;
	pbuf = mymalloc(SRAMIN,10);	//申请10个字节
	if(pbuf)	//申请内存成功
	{
    
    
		msg_num++;
		sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
		//发送消息
		OSQPost((OS_Q*		)&DATA_Msg,		
				(void*		)pbuf,
				(OS_MSG_SIZE)10,
				(OS_OPT		)OS_OPT_POST_FIFO,
				(OS_ERR*	)&err);
		if(err != OS_ERR_NONE)
		{
    
    
			myfree(SRAMIN,pbuf);	//释放内存
			OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
			tmr1sta = !tmr1sta;
			LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
		}
	}	
}

//主任务的任务函数
void main_task(void *p_arg)
{
    
    
	u8 key,num;
	OS_ERR err;
	u8 *p;
	while(1)
	{
    
    
		key = KEY_Scan(0);  //扫描按键
		if(key)
		{
    
    
			//发送消息
			OSQPost((OS_Q*		)&KEY_Msg,		
					(void*		)&key,
					(OS_MSG_SIZE)1,
					(OS_OPT		)OS_OPT_POST_FIFO,
					(OS_ERR*	)&err);
		}
		num++;
		if(num%10==0) check_msg_queue(p);//检查DATA_Msg消息队列的容量
		if(num==50)
		{
    
    
			num=0;
			LED0 = ~LED0;
		}
		OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err);   //延时10ms
	}
}

//按键处理任务的任务函数
void Keyprocess_task(void *p_arg)
{
    
    	
	u8 num;
	u8 *key;
	OS_MSG_SIZE size;
	OS_ERR err;
	while(1)
	{
    
    
		//请求消息KEY_Msg
		key=OSQPend((OS_Q*			)&KEY_Msg,   
					(OS_TICK		)0,
                    (OS_OPT			)OS_OPT_PEND_BLOCKING,
                    (OS_MSG_SIZE*	)&size,		
                    (CPU_TS*		)0,
                    (OS_ERR*		)&err);
		switch(*key)
		{
    
    
			case WKUP_PRES:		//KEY_UP控制LED1
				LED1 = ~LED1;
				break;
			case KEY2_PRES:		//KEY2控制蜂鸣器
				BEEP = ~BEEP;
				break;
			case KEY0_PRES:		//KEY0刷新LCD背景
				num++;
				LCD_Fill(126,111,233,313,lcd_discolor[num%14]);
				break;
			case KEY1_PRES:		//KEY1控制定时器1
				tmr1sta = !tmr1sta;
				if(tmr1sta) 
				{
    
    
					OSTmrStart(&tmr1,&err);
					LCD_ShowString(10,150,100,16,16,"TMR1 START!");
				}
				else
				{
    
    
					OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
					LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
				}
				break;
		}
	}
}

//显示消息队列中的消息
void msgdis_task(void *p_arg)
{
    
    
	u8 *p;
	OS_MSG_SIZE size;
	OS_ERR err; 
	while(1)
	{
    
    
		//请求消息
		p=OSQPend((OS_Q*		)&DATA_Msg,   
				  (OS_TICK		)0,
                  (OS_OPT		)OS_OPT_PEND_BLOCKING,
                  (OS_MSG_SIZE*	)&size,	
                  (CPU_TS*		)0,
                  (OS_ERR*		)&err);
		LCD_ShowString(5,270,100,16,16,p);
		myfree(SRAMIN,p);	//释放内存
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
	}
}

Supongo que te gusta

Origin blog.csdn.net/qq_37120496/article/details/115279089
Recomendado
Clasificación