FreeRTOS 任务创建与管理

任务

每个 FreeRTOS 任务都需要有自己的栈空间。当任务切出时,它的执行环境会被保存在该任务的栈空间中,这样当任务再次运行时,就能从堆栈中正确的恢复上次的运行环境,任务越多,需要的堆栈空间就越大,而一个系统能运行多少个任务,取决于系统的可用的 SRAM。

FreeRTOS 中的任务是抢占式调度机制,高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。同时 FreeRTOS 也支持时间片轮转调度方式,只不过时间片的调度是不允许抢占任务的 CPU 使用权。

任务相关函数

1、任务创建

  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,  /* 任务入口函数 */
                        (const char*    )"AppTaskCreate",/* 任务名*/
                        (uint16_t       )512,  /* 任务栈大小*/
                        (void*          )NULL,/* 任务参数*/
                        (UBaseType_t    )1, /* 任务优先级*/
                        (TaskHandle_t*  )&AppTaskCreate_Handle);/* 任务控制块指针*/ 

2、任务调度函数

vTaskStartScheduler()//任务调度
vTaskSuspend()//任务挂起

vTaskResume()//恢复一个任务的运行。
xTaskResumeFromISR() 中断服务函数中恢复一个任务的运行。

vTaskDelay()//进入阻塞态的任务将让出 CPU 资源,任务必须要有阻塞的情况
vTaskDelayUntil()//绝对延时常用于较精确的周期运行任务,适用于周期性执行的任务

任务设计要点

程序运行上下文
1、中断服务函数

  • 在上下文环境中不能使用挂起当前任务的操作,不允许调用任何会阻塞运行的 API 函数接口。
  • 中断服务程序最好保持精简短小,快进快出,一般在中断服务函数中只做标记事件的发生,然后让对应任务去执行相关处理,因为中断服务函数的优先级高于任何优先级的任务

2、任务

  • 任务中不允许出现死循环,即使只有一个任务也要让出CPU,默认会有空闲任务。
  • 一般会将紧急的处理事件的任务优先级设置得高一些。
  • 优先级数值越小的任务优先级越低,0 为最低优先级,分配给空闲任务使用。

3、空闲任务

任务实例demo

static TaskHandle_t AppTaskCreate_Handle = NULL;
static TaskHandle_t LED1_Task_Handle = NULL;
static TaskHandle_t LED2_Task_Handle = NULL;

//任务1执行函数
static void LED1_Task(void* parameter)
{	
    while (1)
    {
        LED1_ON;
        vTaskDelay(500);  
        printf("LED1_Task Running,LED1_ON\r\n");
        
        LED1_OFF;     
        vTaskDelay(500);  	 		
        printf("LED1_Task Running,LED1_OFF\r\n");
    }
}
//任务2执行函数
static void LED2_Task(void* parameter)
{	
    while (1)
    {
        LED2_ON;
        vTaskDelay(500);  
        printf("LED2_Task Running,LED2_ON\r\n");
        
        LED2_OFF;     
        vTaskDelay(500);   		
        printf("LED2_Task Running,LED2_OFF\r\n");
    }
}

static void AppTaskCreate(void)
{
  BaseType_t xReturn = pdPASS;
  taskENTER_CRITICAL();           //进入临界区
  /* LED1 任务 */
  xReturn = xTaskCreate((TaskFunction_t )LED1_Task,
                        (const char*    )"LED1_Task",
                        (uint16_t       )512, 
                        (void*          )NULL,	
                        (UBaseType_t    )2,	
                        (TaskHandle_t*  )&LED1_Task_Handle);
  if(pdPASS == xReturn)
    printf("LED1 任务创建成功\r\n");
	
	  /* LED2 任务 */
	xReturn = xTaskCreate((TaskFunction_t )LED2_Task,
                        (const char*    )"LED2_Task",
                        (uint16_t       )512,
                        (void*          )NULL,
                        (UBaseType_t    )2,
                        (TaskHandle_t*  )&LED2_Task_Handle);
  if(pdPASS == xReturn)
    printf("LED2 任务创建成功\r\n");
    
  vTaskDelete(AppTaskCreate_Handle); //任务调度
  taskEXIT_CRITICAL();            //退出临界区

int main(void)
{	
  BaseType_t xReturn = pdPASS;
  BSP_Init();
   /* 创建任务AppTaskCreate*/
  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate, 
                        (const char*    )"AppTaskCreate",
                        (uint16_t       )512,
                        (void*          )NULL,
                        (UBaseType_t    )1,
                        (TaskHandle_t*  )&AppTaskCreate_Handle);
 
  if(pdPASS == xReturn)
    vTaskStartScheduler();  
  else
    return -1;  
  
  while(1); 
}

猜你喜欢

转载自blog.csdn.net/WANGYONGZIXUE/article/details/121736288