[FreeRTOS] 创建动态和静态任务 / 删除任务 / 临界保护 / 任务栈分配不足

TCB 

[FreeRTOS] 创建动态和静态任务 / 删除任务 / 临界保护 / 任务栈分配不足_第1张图片

创建动态任务

由FreeRTOS系统动态分配任务所需要的内存空间(堆上的内存空间), 简单, 方便, 灵活, 节省空间.

缺点: 容易产生内存碎片. 

 [FreeRTOS] 创建动态和静态任务 / 删除任务 / 临界保护 / 任务栈分配不足_第2张图片

[FreeRTOS] 创建动态和静态任务 / 删除任务 / 临界保护 / 任务栈分配不足_第3张图片

//动态任务1
TaskHandle_t Task1Handle;

void vTask1Function( void * param)
{
    while(1)
    {
        printf("1");
		//taskYIELD();
    }
}

//参数: 任务函数, 任务名称, 堆栈大小, 任务参数, 任务优先级, 任务句柄
//返回值类型: BaseType_t
xTaskCreate(vTask1Function, "task1", 100, NULL, 1, &Task1Handle); //调用

创建静态任务

由程序员自己定义空间大小(栈上的), 不易产生内存碎片.

缺点: 任务删除无法回收内存.

[FreeRTOS] 创建动态和静态任务 / 删除任务 / 临界保护 / 任务栈分配不足_第4张图片 [FreeRTOS] 创建动态和静态任务 / 删除任务 / 临界保护 / 任务栈分配不足_第5张图片

#define configSUPPORT_STATIC_ALLOCATION 1 //配置文件,开启静态分配

//静态任务2
StackType_t task2Stack[128];
StaticTask_t task2TCB;
void vStaticTask2Function( void * param)
{
    while(1)
    {
        printf("2");
		//taskYIELD();
    }
}

//空闲任务需要重写
StaticTask_t  IdleTaskTCB;
StackType_t   IdleTaskStack[configMINIMAL_STACK_SIZE];
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
                                        StackType_t ** ppxIdleTaskStackBuffer,
                                        uint32_t * pulIdleTaskStackSize )
{
	*ppxIdleTaskTCBBuffer = &IdleTaskTCB;
	*ppxIdleTaskStackBuffer = IdleTaskStack;
	*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}

//参数1: 静态任务函数, 任务名, 任务堆栈大小, 任务参数, 任务优先级, 堆栈空间, TCB
//返回值: 任务句柄
xTaskCreateStatic(vStaticTask2Function, "task2", 128, NULL, 1, task2Stack, &task2TCB); 

删除任务

[FreeRTOS] 创建动态和静态任务 / 删除任务 / 临界保护 / 任务栈分配不足_第6张图片

[FreeRTOS] 创建动态和静态任务 / 删除任务 / 临界保护 / 任务栈分配不足_第7张图片

vTaskDelete(NULL);

静态任务注意删除一定要自己清理任务栈的内存, 不然容易非法访问到, 造成数据泄露. 一般用户不需要考虑.

临界保护区

 任务1的程序

taskENTER_CRITICAL();
printf("I love you!\r\n");
taskEXIT_CRITICAL();

任务2的程序

taskENTER_CRITICAL();
printf("Fuck me, Please Sir!\r\n");
taskEXIT_CRITICAL();

该程序多个任务使用了同一个有限的资源, 使用了同一个串口, 如果按照时间片切换任务, 无法发送正确的字符串, 所以采用临界保护的方法, 禁止了SysTick中断响应, 必须发送完, 开启了中断才能响应, 进而切换任务, 防止出现程序错乱.

如下正确的发送

[FreeRTOS] 创建动态和静态任务 / 删除任务 / 临界保护 / 任务栈分配不足_第8张图片

 错误的发送

[FreeRTOS] 创建动态和静态任务 / 删除任务 / 临界保护 / 任务栈分配不足_第9张图片

 这两个函数实现原理经过深挖底层就是这两个函数宏, 利用的就是上一节说的BASEPRI寄存器, 根据宏配置, 默认屏蔽优先级11及以下的. 修改为12优先级号, 保护失效, 验证正确. 修改为11优先级, 保护成功, 验证正确.

 

任务栈分配不足

 一个任务和第二个任务的栈内存挨在一起的, 一个任务又可以分为头+TCB结构, 如果栈的分配不足, 会导致第一个任务覆盖掉第二个任务的头, 最终导致程序崩溃, 但是语法这是没有错误的, 因为C语言没有对越界进行判定.

[FreeRTOS] 创建动态和静态任务 / 删除任务 / 临界保护 / 任务栈分配不足_第10张图片

你可能感兴趣的:(FreeRTOS,FreeRTOS)