FreeRTOS routine 1-basic task creation

API function

Task creation xTaskCreate()

Function prototype (in tasks.c):


BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
                       const char * const pcName,
                       const uint16_t usStackDepth,
                       void * const pvParameters,
                       UBaseType_t uxPriority,
                       TaskHandle_t * const pxCreatedTask ) 

parameter:

  • pxTaskCode: The function name of the task function created by yourself

  • pcName: the name of the task, starting at will, string type

  • usStackDepth: The size of the task stack (actually 4 times the size of the application), a task that is too small may not be able to run!

  • pvParameters: the parameters of the task function, you don’t need to pass the parameter to NULL

  • uxPriority: task priority, 0~(configMAX_PRIORITIES-1)

  • pxCreatedTask: The task handle, which is actually a pointer and the task stack of the task

return value:

  • pdPASS: The value is 1, the task is created successfully and added to the ready list

  • Error code: negative number, task creation recognition

The return value here is BaseType_t, which is actually a long type. You can see its definition in the portmacro.h file:


typedef long BaseType_t;

In addition, the type of the task handle is TaskHandle_t, which is actually void *. You can see its definition in the task.h file:


typedef void * TaskHandle_t;

Note: xTaskCreate() is a way to dynamically create tasks. The system automatically allocates related memory for tasks through the configuration of heap_4.c. There is also a static way to create tasks, xTaskCreateStatic(), which will not be introduced here.

Task delete vTaskDelete()

Function prototype (in tasks.c):


void vTaskDelete( TaskHandle_t xTaskToDelete )

parameter:

  • xTaskToDelete: The task handle of the task to be deleted

Note: After a task dynamically created by xTaskCreate() is deleted using vTaskDelete(), the stack and memory applied for when the task is created will be released in the idle task of the system.

Task scheduling vTaskStartScheduler()

Function prototype (in tasks.c):


void vTaskStartScheduler( void )

No parameters are required, and FreeRTOS will start task scheduling after it is turned on.

programming

Main function

The main function is still the main function we are familiar with, but the main function in FreeRTOS does not need to be designed into an endless loop by itself. You only need to create tasks and start task scheduling to keep the system running.

The creation of a task is generally to create a start task first, and then start the task and then be responsible for creating other subtasks.


int main(void)
{ 
    //设置系统中断优先级分组4(FreeRTOS中的默认方式!)
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

    //初始化LED端口
    LED_Init();                         

    //创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄  
    //开启任务调度                
    vTaskStartScheduler();          
}

Start task function The function of the

start task function is to create other subtasks, which will delete itself after creation.

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区

    //创建TASK1任务
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //创建TASK2任务
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 

    vTaskDelete(StartTask_Handler); //删除开始任务

    taskEXIT_CRITICAL();            //退出临界区
}

Two task functions

Each task function is an infinite loop. Note that the vTaskDelay() delay function must be added to the loop for task switching.

//task1任务函数
void task1_task(void *pvParameters)
{
    while(1)
    {
        LEDa_Toggle;
        vTaskDelay(500); //延时500ms
    }
}

//task2任务函数
void task2_task(void *pvParameters)
{
    while(1)
    {
        LEDb_ON;
        vTaskDelay(200); //延时200ms
        LEDb_OFF;
        vTaskDelay(800); //延时800ms
    }
}

main.c all programs


#include "stm32f4xx.h"
#include "led.h"

#include "FreeRTOS.h"
#include "task.h"

//任务参数--------------------------
//优先级 堆栈大小 任务句柄 任务函数
#define START_TASK_PRIO     1
#define START_STK_SIZE      128  
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);

#define TASK1_TASK_PRIO     2
#define TASK1_STK_SIZE      128  
TaskHandle_t Task1Task_Handler;
void task1_task(void *pvParameters);

#define TASK2_TASK_PRIO     3   
#define TASK2_STK_SIZE      128  
TaskHandle_t Task2Task_Handler;
void task2_task(void *pvParameters);

int main(void)
{ 
    //设置系统中断优先级分组4(FreeRTOS中的默认方式!)
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

    //初始化LED端口
    LED_Init();                         

    //创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄  
    //开启任务调度                
    vTaskStartScheduler();          
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区

    //创建TASK1任务
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //创建TASK2任务
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 

    vTaskDelete(StartTask_Handler); //删除开始任务

    taskEXIT_CRITICAL();            //退出临界区
}

//task1任务函数
void task1_task(void *pvParameters)
{
    while(1)
    {
        LEDa_Toggle;
        vTaskDelay(500); //延时500ms
    }
}

//task2任务函数
void task2_task(void *pvParameters)
{
    while(1)
    {
        LEDb_ON;
        vTaskDelay(200); //延时200ms
        LEDb_OFF;
        vTaskDelay(800); //延时800ms
    }
}

operation result

The running effect is that the two LEDs on the board keep flashing according to the on-off time set in the respective task function.

The reason for using the system is to make the two tasks seem to be running at the same time . Just imagine, if it is a bare metal system, although the same function can be achieved (the blinking law of these two LED tasks is relatively simple), the two tasks need to be combined The two tasks are entangled together to manage the light-off time. If it is two more complex tasks, the bare metal system may not be able to achieve it.

Guess you like

Origin blog.51cto.com/15060517/2641092