内容为:正点原子FreeRTOS的视频第9-10节

freessl 教程_堆栈

 一个任务所需要的资源这些东西在标准库需要我们自己写,但是在MX软件中可以自己生成

四项基本:优先级、堆栈大小、句柄、任务函数声明

//一个XXX任务需要的资源
//任务优先级
#define XXX_TASK_PRIO		1    //初始的时候,都使用1,到了最后再开始改变任务优先级
//任务堆栈大小	
#define XXX_STK_SIZE 		128  //初始大一点,默认为128
//任务句柄
TaskHandle_t XXXTask_Handler = NULL; 
void XXX_Task(void *pvParameters);  //这个声明需要写,不然会出现错误

void Create_XXX_Task(void)
{
	
	BaseType_t xReturned;
	
	  //创建XXX任务
	xReturned = xTaskCreate((TaskFunction_t )XXX_Task,             
							(const char*    )"XXX_Task",           
							(uint16_t       )XXX_STK_SIZE,        
							(void*          )NULL,                  
							(UBaseType_t    )XXX_TASK_PRIO,        
							(TaskHandle_t*  )&XXXTask_Handler);
							
	//判断任务是否正常创建						
	if( xReturned != NULL )
    {
        /* 任务创建失败  一般原因是栈空间不够,此时打印栈空间不足 */
		vTaskDelete( XXXTask_Handler );
		/* 打印创建失败消息---使用宏定义选择性使用,一般就是调试的时候使用 */
#if 0
		printf("xxxx失败");
#endif
		
    }							
}

//XXX任务函数 
void XXX_Task(void *pvParameters)
{
    while(1)
    {
		
    }
}

几个建议:

                初始的时候,任务优先级都使用1,到了最后再开始改变任务优先级

                初始的堆栈大小大点,最后监测然后更改

容易忽略的点:句柄的初始化、任务函数未声明出现的错误、任务函数的传参使用(默认一般是NULL)、

typedef void (*TaskFunction_t)( void * );是一个地址,用来跳转到我们定义的任务函数中,

而const char*    )"XXX_Task",是打印任务的,前者要求需要与你定义的函数名一样,后者能分清楚就可以了、参数的返回值判断

这里的写法其实是参考了官方的,官方在每一个函数上面都写了模板与使用方法

freessl 教程_freessl 教程_02



 注意:pvParameters的使用,但是目前我还没有使用到

// Task to be created.
 void vTaskCode( void * pvParameters )
 {
	 for( ;; )
	 {
		 // Task code goes here.
	 }
 }

 // Function that creates a task.
 void vOtherFunction( void )
 {
 static uint8_t ucParameterToPass;
 TaskHandle_t xHandle = NULL;

	 // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
	 // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
	 // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
	 // the new task attempts to access it.
	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
     configASSERT( xHandle );

	 // Use the handle to delete the task.
     if( xHandle != NULL )
     {
	     vTaskDelete( xHandle );
     }
 }
   </pre>
 * \defgroup xTaskCreate xTaskCreate
 * \ingroup Tasks
 */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	BaseType_t xTaskCreate(	TaskFunction_t pxTaskCode,
							const char * const pcName,
							const uint16_t usStackDepth,
							void * const pvParameters,
							UBaseType_t uxPriority,
							TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
#endif

freessl 教程_优先级_03

 

freessl 教程_c语言_04

4的解释:

                更新任务的阻塞超时时间,假如现在是任务1,2,3,而2的阻塞时间20ms,3的是50ms,假如现在2被删除了,那么现在最新的阻塞时间是50ms了,那么你就需要更新了

 关于栈使用的情况,可以获取任务堆栈的剩余最小值,就知道它使用了多少

freessl 教程_arm开发_05

 删除任务模板,防止多次删除任务,输出错误信息(错误信息来自于断言-此功能可以关闭)

/*  删除任务模板 */
if( XXXTask_Handler != NULL )
{
	vTaskDelete( XXXTask_Handler );
	printf("任务删除");
	XXXTask_Handler = NULL;  //然后此任务会在空闲任务中回收资源
	
}