UCOS自学笔记(2)--时间片轮转调度

定义

UCOSIII下即使是同一优先级下,也是可以存在多个任务的。所以在同一优先级下的任务一起跑的时候,可以给每个任务设定时间(以时间片单位),当这个任务的时间片运行完了之后,就运行下一个任务(任务之间是轮回的)。
在这里插入图片描述
这样1->2->3->4->1这样无线轮回的。

开启

在UCOSIII配置文件中,把它打开就可以了在这里插入图片描述

使用

完整代码

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

#define START_TASK_PRIO		3

#define START_STK_SIZE 		128

OS_TCB StartTaskTCB;

CPU_STK START_TASK_STK[START_STK_SIZE];

void start_task(void *p_arg);


#define TASK1_TASK_PRIO		4

#define TASK1_STK_SIZE 		128

OS_TCB Task1_TaskTCB;

CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE];
void task1_task(void *p_arg);


#define TASK2_TASK_PRIO		4

#define TASK2_STK_SIZE 		128

OS_TCB Task2_TaskTCB;

CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE];

void task2_task(void *p_arg);

int main(void)
{ 
 
	OS_ERR err;
	CPU_SR_ALLOC();
	
	delay_init(168); 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	LCD_Init();			
	OSInit(&err);		  
	OS_CRITICAL_ENTER();	//进入临界区	
		 
	//创建start任务
	OSTaskCreate((OS_TCB 	* )&StartTaskTCB,		
				 (CPU_CHAR	* )"start task", 		
                 (OS_TASK_PTR )start_task, 			
                 (void		* )0,					
                 (OS_PRIO	  )START_TASK_PRIO,     
                 (CPU_STK   * )&START_TASK_STK[0],	
                 (CPU_STK_SIZE)START_STK_SIZE/10,	
                 (CPU_STK_SIZE)START_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);				
	OS_CRITICAL_EXIT();	 //退出临界区	
	OSStart(&err);     
}

void start_task(void *p_arg)
{
	OS_ERR err;
	CPU_SR_ALLOC();
	p_arg = p_arg;
	//代码是根据正点原子改的,这段目前没怎么看懂,但是没删,以后因该会了解到
	CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
   OSStatTaskCPUUsageInit(&err);  	             
#endif
	
#ifdef CPU_CFG_INT_DIS_MEAS_EN		
    CPU_IntDisMeasMaxCurReset();	
#endif
	
#if	OS_CFG_SCHED_ROUND_ROBIN_EN  
	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
#endif		
	
	OS_CRITICAL_ENTER();	
//开任务1
	OSTaskCreate((OS_TCB 	* )&Task1_TaskTCB,		
				 (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_STK_SIZE/10,	
                 (CPU_STK_SIZE)TASK1_STK_SIZE,		
                 (OS_MSG_QTY  )0,					
                 (OS_TICK	  )400,  //时间片 400*5=2000ms					
                 (void   	* )0,					
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
                 (OS_ERR 	* )&err);				
				 
//开任务2
	OSTaskCreate((OS_TCB 	* )&Task2_TaskTCB,		
				 (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_STK_SIZE/10,	
                 (CPU_STK_SIZE)TASK2_STK_SIZE,		
                 (OS_MSG_QTY  )0,					
                 (OS_TICK	  )200,	//时间片 200*5=1000ms				
                 (void   	* )0,				
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, 
                 (OS_ERR 	* )&err);			 
	OS_CRITICAL_EXIT();	
	OSTaskDel((OS_TCB*)0,&err);	
}



void task1_task(void *p_arg)
{

	OS_ERR err;
	p_arg = p_arg;
	while(1)
	{
		
		POINT_COLOR = BLUE;//蓝色
		LCD_ShowString(30,130,110,16,16,"Task");
	}
}

void task2_task(void *p_arg)
{
	OS_ERR err;
	p_arg = p_arg;

	while(1)
	{
		
		POINT_COLOR = RED;//红色
		LCD_ShowString(30,130,110,16,16,"Task");
	}
}


效果:
在这里插入图片描述
根据时间片轮转调度,显示蓝色的任务执行2s之后,显示红色的任务执行1s,依次轮回。

临界区

在上面代码中,我们可以发现在创建初始任务的时候用到了一个临界区的开启和后来的关闭。为什么要开它嘞?开了它之后又啥作用嘞?
开了临界区代码保护之后,可以保护那些必须是连续执行的,不可被打断的代码在执行的时候不会被打断。
可通过宏来改变它的保护方式
在这里插入图片描述
OS_CFG_ISR_POST_DEFERRED_EN为0时,UCOSIII采用的时关中断的方式来保护,当它为1时,采用的是给调度器上锁的方式保护。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值