freertos动态任务创建和删除

 动态创建任务流程:

1:将FreeRTOSConfig.h文件 中将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为1。

2:定义函数入口参数

3:编写任务函数


/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
 #define START_TASK_PRIO       1                //数字越大,任务优先级越大
 #define START_TASK_STACK_SIZE  128            //裸机默认栈大小是400B(100字)
TaskHandle_t         start_task_handler;
void start_task( void * pvParameters );


 #define TASK1_PRIO       2    
 #define TASK1_STACK_SIZE  128            //裸机默认栈大小是400B(100字)
TaskHandle_t         task1_handler;
void task1( void * pvParameters );


 #define TASK2_PRIO       3    
 #define TASK2_STACK_SIZE  128            //裸机默认栈大小是400B(100字)
TaskHandle_t         task2_handler;
void task2( void * pvParameters );


 #define TASK3_PRIO       4    
 #define TASK3_STACK_SIZE  128            //裸机默认栈大小是400B(100字)
TaskHandle_t         task3_handler;
void task3( void * pvParameters );


void freertos_demo(void)
{
     xTaskCreate((TaskFunction_t             ) start_task,
               (char *                 ) "start_task", 
               (configSTACK_DEPTH_TYPE    ) START_TASK_STACK_SIZE,
               (void *                 ) NULL,
               (UBaseType_t            ) START_TASK_PRIO,
               (TaskHandle_t *             ) &start_task_handler );
    vTaskStartScheduler();                //任务调度器
}


void start_task( void * pvParameters )
{
        taskENTER_CRITICAL();            //进入临界区
    xTaskCreate((TaskFunction_t             ) task1,
               (char *                 ) "task1", 
               (configSTACK_DEPTH_TYPE    ) TASK1_STACK_SIZE,
               (void *                 ) NULL,
               (UBaseType_t            ) TASK1_PRIO,
               (TaskHandle_t *             ) &task1_handler );
               
    xTaskCreate((TaskFunction_t             ) task2,
               (char *                 ) "task2", 
               (configSTACK_DEPTH_TYPE    ) TASK2_STACK_SIZE,
               (void *                 ) NULL,
               (UBaseType_t            ) TASK2_PRIO,
               (TaskHandle_t *             ) &task2_handler );
               
    xTaskCreate((TaskFunction_t             ) task3,
               (char *                 ) "task3", 
               (configSTACK_DEPTH_TYPE    ) TASK3_STACK_SIZE,
               (void *                 ) NULL,
               (UBaseType_t            ) TASK3_PRIO,
               (TaskHandle_t *             ) &task3_handler );
    vTaskDelete(NULL);
    taskEXIT_CRITICAL();              //退出临界区,临界区保护,就是保护不想被打断的程序任务
}
//任务一,实现LED0每500ms翻转一次
void task1( void * pvParameters )
{
     while(1)
     {
         printf("task1正在运行!!!\r\n");
         LED0_TOGGLE();
         vTaskDelay(500);    
     }
}
//任务二,实现LED1每500ms翻转一次
void task2( void * pvParameters )
{
     while(1)
     {
         printf("task2正在运行!!!\r\n");
         LED1_TOGGLE();
         vTaskDelay(500);    
     }
}
//任务三,判断按键KEY0,按下KEY0删除task1
void task3( void * pvParameters )
{
    uint8_t key =0;
     while(1)
     {
         printf("task3正在运行!!!\r\n");
        key = key_scan(0);
        if(key == KEY0_PRES)
        {
            if(task1_handler !=NULL)
            {            
                printf("删除task1任务\r\n");
                vTaskDelete(task1_handler);
                task1_handler = NULL;
            }
        }            
         vTaskDelay(10);    
     }
}

main函数里调用freertos_demo函数

freertos_demo函数里创建start任务并开启任务调度器

start任务里依次开启task1,task2,task3,这四个任务的优先级依次是1,2,3,4,(数字越大,优先级越高)

而且start中还调用了一对临界区函数来保护其中的程序不被打断。

我们看到程序运行的顺序是这样:start_task创建完自我删除->task3->task3阻塞->task2->task2阻塞->task1->task1阻塞

黑盒视角:task3运行次数是task2和task1的50倍

如果没有调用临界区函数,则会出现这样的情况:

这是因为在start任务中先创建task1,并且task1的优先级比start的更高所以会出现task1和task2在task3的前面运行

代码中提到的函数:

vTaskStartScheduler();任务调度器

xTaskCreate创建任务函数

taskENTER_CRITICAL();进入临界区函数

taskEXIT_CRITICAL();退出临界区函数

vTaskDelete(task1_handler);删除任务函数,如果传入参数为NULL则是删除任务本身(当前正在运行的任务)

vTaskDelay(10);任务延时函数,延时单位:系统时钟节拍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值