GOAL: Create four tasks and run tasks round robin order by changing the priority of tasks
• Task1: Blink P1 Red LED
• Task2: Blink P2 Red LED
• Task3: Blink P2 Green LED
• Task4: Blink P2 Blue LED
portBASE_TYPE xTaskCreate(pdTASK_CODE pvTaskCode, const char const pcName, unsigned short usStackDepth, void pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask);
• pvTaskCode: Pointer to the task entry function. Tasks must be implemented to never return (i.e. continuous loop).
• pcName: A descriptive name for the task. This is mainly used to facilitate debugging. Max length defined by tskMAX_TASK_NAME_LEN – default is 16.
• usStackDepth: The size of the task stack specified as the number of variables the stack can hold - not the number of bytes. For example, if the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes will be allocated for stack storage.
• pvParameters: Pointer that will be used as the parameter for the task being created.
• uxPriority: The priority at which the task should run. Systems that include MPU support can optionally create tasks in a privileged (system) mode by etting bit portPRIVILEGE_BIT of the priority parameter. For example, to create a rivileged task at priority 2 the uxPriority parameter should be set to ( 2 | portPRIVILEGE_BIT ).
• pvCreatedTask: Used to pass back a handle by which the created task can be referenced.
• pdPASS: If the task was successfully created and added to a ready list, otherwise an error code defined in the file errors.h
이 예시 답안에서 태스크 우선순위는 항상 2, 3, 4, 5 중 하나이다.
5, 4, 3, 2의 초기 우선순위를 가지는 Task1, 2, 3, 4. Task1 실행 후 setPriority(1)이 실행된다.
high = 1
{
i = 0
index = (1 + 0) % 4
vTaskPrioritySet(taskHandles[1], 5 - 0) // Task2(4) -> (5).
}
**Task1, 2 모두 5의 우선순위를 가지므로 예상과 다르게 1 Tick씩 번갈아 수행된다.**
{
i = 1
index = (1 + 1) % 4
vTaskPrioritySet(taskHandles[2], 5 - 1) // Task3(3) -> (4).
}
Task2의 LED 점등과 1 Tick 씩 번갈아 수행된다.
{
i = 2
index = (1 + 2) % 4
vTaskPrioritySet(taskHandles[3], 5 - 2) // Task4(2) -> (3).
}
Task2의 LED 점등과 1 Tick 씩 번갈아 수행된다.
{
i = 3
index = (1 + 3) % 4
vTaskPrioritySet(taskHandles[0], 5 - 3) // Task1(5) -> (2).
}
Task2의 LED 점등과 1 Tick 씩 번갈아 수행되다 드디어 Task1가 최하순위가 되었다.
/* Driver configuration */
#include <ti/devices/msp432p4xx/inc/msp.h>
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <ti/drivers/Board.h>
/* RTOS header files */
#include <FreeRTOS.h>
#include <task.h>
#include <semphr.h>
/* function prototypes */
void Task1( void *pvParameters );
void Task2( void *pvParameters );
void Task3( void *pvParameters );
void Task4( void *pvParameters );
/* global variables */
TaskHandle_t task1Handle, task2Handle, task3Handle, task4Handle;
void main(void)
{
/* Configuring S1 & S2 buttons / Red LED & RGB LED in mainboard */
P1->DIR = BIT0;
P1->DIR &= ~(BIT1|BIT4);
P2->DIR |= 1<<2 | 1<<1 | 1<<0;
P1->REN |= (BIT1|BIT4);
P1->OUT |= (BIT1|BIT4);
P2->OUT = 0x00;
xTaskCreate( Task1, /* The function that implements the task. */
"Task 1", /* The text name assigned to the task - for debug only as it is not
used by the kernel. */
configMINIMAL_STACK_SIZE,/* The size of the stack to allocate to the task. */
( void * ) 0, /* The parameter passed to the task - just to check the
functionality. */
4, /* The priority assigned to the task. */
&task1Handle); /* The task handle is not required, so NULL is passed. */
xTaskCreate( Task2, "Task 2", configMINIMAL_STACK_SIZE, ( void * ) 0, 3, &task2Handle);
xTaskCreate( Task3, "Task 3", configMINIMAL_STACK_SIZE, ( void * ) 0, 2, &task3Handle);
xTaskCreate( Task4, "Task 4", configMINIMAL_STACK_SIZE, ( void * ) 0, 1, &task4Handle);
/* Start the tasks and timer running. */
vTaskStartScheduler();
while (1)
{
}
}
void Task1( void *pvParameters )
{
int i;
while (1)
{
P1->OUT = BIT1|BIT4 | BIT0;
for (i=0;i<100000;i++);
P1->OUT = BIT1|BIT4;
for (i=0;i<100000;i++);
vTaskPrioritySet(task1Handle, 0);
}
}
void Task2( void *pvParameters )
{
int i;
while (1)
{
P2->OUT = BIT0;
for (i=0;i<100000;i++);
P2->OUT = 0;
for (i=0;i<100000;i++);
vTaskPrioritySet(task2Handle, 0);
}
}
void Task3( void *pvParameters )
{
int i;
while (1)
{
P2->OUT = BIT1;
for (i=0;i<100000;i++);
P2->OUT = 0;
for (i=0;i<100000;i++);
vTaskPrioritySet(task3Handle, 0);
}
}
void Task4( void *pvParameters )
{
int i;
while (1)
{
P2->OUT = BIT2;
for (i=0;i<100000;i++);
P2->OUT = 0;
for (i=0;i<100000;i++);
vTaskPrioritySet(task1Handle, 4);
vTaskPrioritySet(task2Handle, 3);
vTaskPrioritySet(task3Handle, 2);
vTaskPrioritySet(task4Handle, 1);
}
}
요약: Task 1, 2, 3, 4 의 우선순위를 각각 4, 3, 2, 1 로 초기화하고, 방금 수행된 Task 는 최하 우선순위인 0 을 가지도록 하였다. 그리고 Task4 의 마지막 부분에 0, 0, 0, 1 이었던 우선순위를 다시 4, 3, 2, 1 로 설정해주었다.
실행: 초기 우선순위 4, 3, 2 에 따라 Task1, 2, 3 이 순서대로 실행된다. 실행 완료된 Task1, 2, 3 은 모두 0 의 우선순위를 가진 상태이다. 이후 Task4(1)가 실행된다.
Task4 의 마지막 부분에서 Task1(0)이 Task1(4)가 됨에 따라 Task4(1)의 실행을 멈추고 Task1(4)를 수행한 후 스스로 Task1(0)으로 바꾸어 다시 Task4(1)이 실행된다.
이후 Task2(3)이 되어 실행 후 Task2(0)이 되어 다시 Task4(1)이 실행된다.
이후 Task3(2)이 되어 실행 후 Task3(0)이 되어 다시 Task4(1)이 실행된다.
Task4 실행 후에는 return 하지 않고 무한 반복하는데 현재 우선순위가 0, 0, 0, 1 이므로 Task4 의 처음 부분부터 이를 반복한다.