基于正点原子的FreeRTOS学习笔记——静态任务创建与删除

目录

学习目标:

学习笔记:

任务创建流程(摘自正点原子官方资料):

要点一:

要点二:空闲任务内存分配

要点三:定时器任务内存分配(可选是否开启)

要点四:静态任务创建与删除

 问题:


学习目标:

  • 掌握FreeRTOS静态任务创建与删除

学习笔记:

任务创建流程(摘自正点原子官方资料):

d8cc0556fc2c4a7b9f99b8c3a361a9b4.png

要点一:

FreeRTOSConfig.h中将第39行configSUPPORT_STATIC_ALLOCATION宏定义改为1,以支持静态任务创建。编译后报两个错,原因是静态任务创建需要先创建空闲任务内存分配与定时器任务内存分配。

要点二:空闲任务内存分配

configMINIMAL_STACK_SIZE  //定义空闲任务的栈空间大小, 单位: Word, 无默认需定义

vApplicationGetIdleTaskMemory( 任务控制块,
                                                     栈地址,
                                                     栈大小 )

StaticTask_t idle_task_tcb;
StackType_t  idle_task_stack[configMINIMAL_STACK_SIZE];   
/*  空闲任务内存分配  */
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
                                        StackType_t ** ppxIdleTaskStackBuffer,
                                        uint32_t * pulIdleTaskStackSize )
{
	* ppxIdleTaskTCBBuffer = &idle_task_tcb;
	* ppxIdleTaskStackBuffer = idle_task_stack;
	* pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}

要点三:定时器任务内存分配(可选是否开启)

configUSE_TIMERS      /* 1: 使能软件定时器, 默认: 0 */

configTIMER_TASK_STACK_DEPTH  ( configMINIMAL_STACK_SIZE * 2)     /* 定义软件定时器任务的栈空间大小, 无默认configUSE_TIMERS为1时需定义 */

任务调度器函数中关于定时器任务代码如下:

#if ( configUSE_TIMERS == 1 )
        {
            if( xReturn == pdPASS )
            {
                xReturn = xTimerCreateTimerTask();
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
        }
    #endif /* configUSE_TIMERS */


 BaseType_t xTimerCreateTimerTask( void )
 {
/*省略..........................................................................*/
 vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
 xTimerTaskHandle = xTaskCreateStatic( prvTimerTask,
                                       configTIMER_SERVICE_TASK_NAME,
                                       ulTimerTaskStackSize,
                                       NULL,
                                       ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
                                       pxTimerTaskStackBuffer,
                                       pxTimerTaskTCBBuffer );
/*省略..........................................................................*/
}

要点四:静态任务创建与删除

TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
                                 const char * const pcName,
                                 const uint32_t ulStackDepth,
                                 void * const pvParameters,
                                 UBaseType_t uxPriority,
                                 StackType_t * const puxStackBuffer,
                                 StaticTask_t * const pxTaskBuffer );

参数:

pxTaskCode指向任务入口函数的指针(即实现任务的函数名称,请参阅如下示例)。

任务通常以无限循环的形式实现;实现任务的函数决不能尝试返回或退出。但是,任务可以自行删除

pcName任务的描述性名称。此参数主要用于方便调试,但也可用于获取任务句柄

任务名称的最大长度由 FreeRTOSConfig.h 中的 configMAX_TASK_NAME_LEN 定义。

ulStackDepthpuxStackBuffer 参数用于将 StackType_t 变量数组传递给 xTaskCreateStatic()。必须将 ulStackDepth 设置为数组中的索引数。
pvParameters传递给已创建任务的参数值。

如果将 pvParameters 设置为变量的地址,则在创建的任务执行时变量必须仍然存在,因此传递堆栈变量的地址无效。

uxPriority所创建任务执行的优先级

包含 MPU支持的系统可选择通过在 uxPriority 中设置位 portPRIVILEGE_BIT,以特权(系统)模式创建任务。例如,要创建优先级为 2 的特权任务,请将 uxPriority 设置为 (2 | portPRIVILEGE_BIT)。

断言优先级低于 configMAX_priority。如果未定义 configASSERT,则优先级会被静默限制为 (configMAX_PRIORITIES - 1)。

puxStackBuffer必须指向至少具有 ulStackDepth 索引的 StackType_t 数组(请参阅上面的 ulStackDepth 参数),该数组用作任务的堆栈,因此必须是永久性的(而不是在函数的堆栈上声明)。
pxTaskBuffer必须指向 StaticTask_t 类型的变量。该变量用于保存新任务的数据结构体 (TCB) ,因此必须是持久的(而不是在函数的堆栈中声明)。

返回:

如果 puxStackBuffer 和 pxTaskBuffer 均不为 NULL,则创建任务,并返回任务的句柄。如果 puxStackBuffer 或 pxTaskBuffer 为 NULL,则不会创建任务,并返回 NULL。

#define START_TASK_STACK_SIZE 128
#define START_TASK_PRIO       1
TaskHandle_t start_task_handler;
StackType_t  start_task_stack[START_TASK_STACK_SIZE];
StaticTask_t start_task_tcb;
void start_task( void * pvParameters );

#define TASK1_STACK_SIZE 128
#define TASK1_PRIO       2
TaskHandle_t task1_handler;
StackType_t  task1_stack[TASK1_STACK_SIZE];
StaticTask_t task1_tcb;
void task1( void * pvParameters );

#define TASK2_STACK_SIZE 128
#define TASK2_PRIO       3
TaskHandle_t task2_handler;
StackType_t  task2_stack[TASK2_STACK_SIZE];
StaticTask_t task2_tcb;
void task2( void * pvParameters );

#define TASK3_STACK_SIZE 128
#define TASK3_PRIO       4
TaskHandle_t task3_handler;
StackType_t  task3_stack[TASK3_STACK_SIZE];
StaticTask_t task3_tcb;
void task3( void * pvParameters );

void freertos_demo(void)
{
	start_task_handler = xTaskCreateStatic(  (TaskFunction_t) start_task,
											(char *        ) "start_task", 
											(uint32_t      ) START_TASK_STACK_SIZE,
											(void *        ) NULL,
											(UBaseType_t   ) START_TASK_PRIO,
											(StackType_t * ) start_task_stack,
											(StaticTask_t *) &start_task_tcb );
  vTaskStartScheduler();
}

void start_task( void * pvParameters )
{
	taskENTER_CRITICAL();/*进入临界区*/
	task1_handler = xTaskCreateStatic(  (TaskFunction_t) task1,
																			(char *        ) "task1", 
																			(uint32_t      ) TASK1_STACK_SIZE,
																			(void *        ) NULL,
																			(UBaseType_t   ) TASK1_PRIO,
																			(StackType_t * ) task1_stack,
																			(StaticTask_t *) &task1_tcb );

	task2_handler = xTaskCreateStatic(  (TaskFunction_t) task2,
																			(char *        ) "task2", 
																			(uint32_t      ) TASK2_STACK_SIZE,
																			(void *        ) NULL,
																			(UBaseType_t   ) TASK2_PRIO,
																			(StackType_t * ) task2_stack,
																			(StaticTask_t *) &task2_tcb );
											
	task3_handler = xTaskCreateStatic(  (TaskFunction_t) task3,
																			(char *        ) "task3", 
																			(uint32_t      ) TASK3_STACK_SIZE,
																			(void *        ) NULL,
																			(UBaseType_t   ) TASK3_PRIO,
																			(StackType_t * ) task3_stack,
																			(StaticTask_t *) &task3_tcb );										
	
	vTaskDelete(start_task_handler);
	taskEXIT_CRITICAL(); 		/*退出临界区*/				 
}

 问题:

动态任务删除正在执行的任务是在空闲任务中释放内存,但是静态任务需要手动删除,正点原子的讲解中并未提到如何释放start_task任务已占用的内存。

解决方案(未验证):在其他任务中释放start_task任务已占用的内存。

  • 12
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值