UCOIII time slice rotation scheduling

Keywords: Single-Chip Microcomputer stm32

Premise:

Time slice rotation method: mainly used for process scheduling in time-sharing system. In order to realize rotation scheduling, the system arranges all ready processes into a queue first process according to the principle of first in first out, and lets it run a time slice on the CPU. Time slice is a small time unit, usually in the order of 10~100ms. When the process runs out of the time slice allocated to it, the system timer sends a clock interrupt, and the scheduler stops the process and puts it at the end of the ready queue; Then, put it at the end of the ready queue; Then, the CPU is assigned to the queue head process of the ready queue, and it is also allowed to run a time slice, and so on.

Implementation idea: the basic idea of time slice rotation algorithm is that the system arranges all ready processes into a queue according to the principle of first come, first serve algorithm. Each time, the system allocates the processor to the first process in the queue and lets it execute a time slice. When the execution time slice is used up, the timer sends a clock interrupt request. According to this request, the scheduler stops the process, sends it to the end of the ready queue, and then assigns the processor to the new queue head process in the ready queue. At the same time, it also executes a time slice.

1. UCOIII time slice rotation scheduling

The time slice rotation scheduler is used for time slice rotation scheduling. It is a function OS_SchedRoundRobin(), which is controlled by OSTimeTick or OS_IntQTask() is called, and the function is in the file OS_ Defined in core. C.

2.1. Oschedroundrobincfg() function:

If we want to use ucosiiii time slice Round scheduling, we should not only use macro OS_ CFG_ SCHED_ ROUND_ ROBIN_ When en is set to 1, you also need to call the function oschedroundrobincfg(), and the function prototype is as follows

void OSSchedRoundRobinCfg (CPU_BOOLEAN	en,
						   OS_TICK		dflt_time_quanta,
						   OS_ERR		*p_err)

When time slice rotation is used, the time slice rotation scheduling function is enabled. The length of time slice is 1 system clock beat, i.e. 1*5=5ms

#if 	 OS_CFG_SCHED_ROUND_ROBIN_EN / / when using time slice rotation
	 //Enable the time slice rotation scheduling function. The time slice length is 1 system clock beat, i.e. 1*5=5ms
	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
#endif		

2.2. Oschedroundrobin yield() function:

When a task wants to give up this time slice, it can call this function. The function prototype is as follows:

void OSSchedRoundRobinYield (OS_ERR	*p_err)

An example of the use of the function osshedroundrobin yield() is as follows:

void Task(void *p_arg)
{
	OS_RR err;
	while(1)
	{
		......
		OSSchedRoundRobinYiled(&err);
		...
		-
	}
}

3. UCOSIII time slice rotation scheduling

In this experiment, three tasks are designed. Task A is used to create other tasks and delete itself after creation. Task B and task C have the same priority. These two tasks are scheduled by time slice rotation. Both tasks print some data through the serial port, and then display the running times of the task on the LCD. The operation of time slice rotation scheduling can be observed through the information output from the serial port.

Experimental steps:

  1. Set macro OS_CFG_SCHED_ROUND_ROBIN_EN = 1
  2. Call the function oschedroundrobin cfg() to start the time slice rotation scheduling function and set the time slice length
  3. Write task function
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "includes.h"
/************************************************
 ALIENTEK UCOS experiment of elite STM32 development board 
 /Example 6-3 UCOSIII time slice rotation scheduling
 Technical support: www.openedv.com
 Taobao store: http://eboard.taobao.com 
 Pay attention to wechat public platform wechat: "punctual atom", and obtain STM32 data for free.
 Guangzhou Xingyi Electronic Technology Co., Ltd  
 Author: punctual atom @ ALIENTEK
************************************************/

//The following priority user programs in UCOSIII cannot be used. ALIENTEK
//These priorities are assigned to five system internal tasks of UCOSIII
//Priority 0: interrupt service management task OS_IntQTask()
//Priority 1: clock beat task OS_TickTask()
//Priority 2: scheduled task OS_TmrTask()
//Priority OS_CFG_PRIO_MAX-2: Statistics task OS_StatTask()
//Priority OS_CFG_PRIO_MAX-1: idle task OS_IdleTask()
//Technical support: www.openedv.com
//Taobao store: http://eboard.taobao.com  
//Guangzhou Xingyi Electronic Technology Co., Ltd  
//Author: punctual atom @ ALIENTEK

//Task priority
#define START_TASK_PRIO		3
//Task stack size	
#define START_STK_SIZE 		128
//Task control block
OS_TCB StartTaskTCB;
//task stack 	
CPU_STK START_TASK_STK[START_STK_SIZE];
//Task function
void start_task(void *p_arg);

//Task priority
#define TASK1_TASK_PRIO		4
//Task stack size	
#define TASK1_STK_SIZE 		128
//Task control block
OS_TCB Task1_TaskTCB;
//task stack 	
CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE];
void task1_task(void *p_arg);

//Task priority
#define TASK2_TASK_PRIO		4
//Task stack size	
#define TASK2_STK_SIZE 		128
//Task control block
OS_TCB Task2_TaskTCB;
//task stack 	
CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE];
//Task function
void task2_task(void *p_arg);

//Main function
int main(void)
{
	OS_ERR err;
	CPU_SR_ALLOC();
	
	delay_init();  	//Clock initialization
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//Interrupt packet configuration
	uart_init(115200); 	//Serial port initialization
	
	LED_Init();         //LED initialization	
	LCD_Init();			//LCD initialization	
	
	POINT_COLOR = RED;
	LCD_ShowString(30,10,200,16,16,"ALIENTEK STM32F1");	
	LCD_ShowString(30,30,200,16,16,"UCOSIII Examp 6-3");
	LCD_ShowString(30,50,200,16,16,"Task Round-robin");
	LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,90,200,16,16,"2015/3/19");
	
	OSInit(&err);		//Initialize UCOSIII
	OS_CRITICAL_ENTER();//Enter critical zone			 
	//Create start task
	OSTaskCreate((OS_TCB 	* )&StartTaskTCB,		//Task control block
				 (CPU_CHAR	* )"start task", 		//Task name
                 (OS_TASK_PTR )start_task, 			//Task function
                 (void		* )0,					//Parameters passed to the task function
                 (OS_PRIO	  )START_TASK_PRIO,     //Task priority
                 (CPU_STK   * )&START_TASK_STK[0],	//Task stack base address
                 (CPU_STK_SIZE)START_STK_SIZE/10,	//Task stack depth limit
                 (CPU_STK_SIZE)START_STK_SIZE,		//Task stack size
                 (OS_MSG_QTY  )0,					//The maximum number of messages that the task internal message queue can receive. When it is 0, it is prohibited to receive messages
                 (OS_TICK	  )0,					//When the time slice rotation is enabled, the time slice length is 0, which is the default length,
                 (void   	* )0,					//User supplementary storage
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //Task options
                 (OS_ERR 	* )&err);				//Store the return value when the function is wrong
	OS_CRITICAL_EXIT();	//Exit critical zone	 
	OSStart(&err);      //Open UCOSIII
}


//Start task function
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);  	//Statistical tasks                
#endif
	
#ifdef CPU_CFG_INT_DIS_MEAS_EN 		// If enabled, measure the interrupt off time
    CPU_IntDisMeasMaxCurReset();	
#endif
	
#if 	 OS_CFG_SCHED_ROUND_ROBIN_EN / / when using time slice rotation
	 //Enable the time slice rotation scheduling function. The time slice length is 1 system clock beat, i.e. 1*5=5ms
	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
#endif		
	
	OS_CRITICAL_ENTER();	//Enter critical zone
	//Create TASK1 task
	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	  )2,  //2 time slices, i.e. 2*5=10ms					
                 (void   	* )0,					
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
                 (OS_ERR 	* )&err);				
				 
	//Create TASK2 task
	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	  )2,	//2 time slices, i.e. 2*5=10ms					
                 (void   	* )0,				
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, 
                 (OS_ERR 	* )&err);			 
	OS_CRITICAL_EXIT();	//Exit critical zone
	OSTaskDel((OS_TCB*)0,&err);	//Delete start_task task itself
}


//task1 task function
void task1_task(void *p_arg)
{
	u8 i,task1_num=0;
	OS_ERR err;
	p_arg = p_arg;
	 
	POINT_COLOR = RED;
	LCD_ShowString(30,130,110,16,16,"Task1 Run:000");
	POINT_COLOR = BLUE;
	while(1)
	{
		task1_num++;	//Task 1 execution times plus 1 pay attention to Task1_ When num1 is added to 255, it will be cleared!!
		LCD_ShowxNum(110,130,task1_num,3,16,0x80);	//Displays the number of task executions
		for(i=0;i<5;i++) printf("Task1:01234\r\n");
		LED0 = ~LED0;
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //Delay 1s
		
	}
}

//task2 task function
void task2_task(void *p_arg)
{
	u8 i,task2_num=0;
	OS_ERR err;
	p_arg = p_arg;
	
	POINT_COLOR = RED;
	LCD_ShowString(30,150,110,16,16,"Task2 Run:000");
	POINT_COLOR = BLUE;
	while(1)
	{
		task2_num++;	//Task 2 execution times plus 1 pay attention to Task1_ When num2 is added to 255, it will be cleared!!
		LCD_ShowxNum(110,150,task2_num,3,16,0x80);  //Displays the number of task executions
		for(i=0;i<5;i++) printf("Task2:56789\r\n");
		LED1 = ~LED1;
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //Delay 1s
	}
}


Posted by gabaod on Sun, 31 Oct 2021 11:27:44 -0700