PS:本人因为一些自己的原因,从本篇开始一些函数名之类的自定义的名字会用自己的方式命名,会和野火的教程有出入,还请自行甄别。
从本质上来讲,FreeRTOS的运行就是不断执行每个任务。本篇会介绍静态和动态创建任务的方法。
静态创建需要指定任务栈的大小和起始地址;动态创建在SRAM中申请内存,用完就释放。二者区别在于静态的内存始终存在,无法被释放。
静态单任务
硬件初始化
首先是静态创建单个任务。在main.c中定义初始化函数并进行声明,将会用到的外设都在这个函数里进行初始化。
#include "FreeRTOS.h"
#include "task.h"
#include "led.h"
#include "usart.h"
static void Device_Init(void);
int main(void)
{
}
/* 静态创建 硬件初始化 */
static void Device_Init(void)
{
/* 中断优先级分组,配置为4 */
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
/* LED 初始化 */
LED_GPIO_Config();
/* 串口初始化 */
USART_Config();
}
STM32中断优先级分组为4,即4bit都用来表示抢占优先级,范围为:0~15。优先级分组只需要分组一次即可,以后如果有其他的任务需要用到中断,都统一用这个优先级分组,千万不要再分组。
在程序执行的过程中,会先运行上述函数。这个函数和裸机程序的硬件初始化是一样的,在初始化完成后才会启动操作系统。
因此,在实际开发过程中,可以在初始化函数中加入一些命令和死循环来进行测试,确认硬件没有问题后注释掉循环即可。测试命令因为只执行一次,可自行判断是否留下。
创建单个任务——静态
当我们静态创建任务的时候,FreeRTOSConfig.h的configSUPPORT_STATIC_ALLOCATION 这个宏必 须为 1,否则会报错。
定义任务函数
任务就是无限执行的函数,在main.c中定义任务:让LED1以500ms的频率闪烁。
static void LED1_Task(void* pvParameters);
static void LED1_Task(void* parameter)
{
while (1)
{
LED1_ON;
vTaskDelay(500); /* 延时500个tick */
printf("LED_Task Running,LED1_ON\r\n");
LED1_OFF;
vTaskDelay(500); /* 延时500个tick */
printf("LED_Task Running,LED1_OFF\r\n");
}
}
这里的延时函数必须使用 FreeRTOS 提供的延时函数,不要使用我们裸机编程中的软件延时。vTaskDelay()会让当前任务被阻塞转而去执行其他任务;而裸机的延时会让CPU陷入死循环,一直在执行当前任务无法跳出,无法实现多任务系统。
定义空闲任务与定时器任务堆栈函数
接下来实现两个函数 : vApplicationGetIdleTaskMemory()与 vApplicationGetTimerTaskMemory(),这两个函数是用户设定的空闲(Idle)任务与定时器(Timer)任务的堆栈大小,必须由用户自己分配。
/* 空闲任务堆栈 */
static StackType_t Idle_Task_Stack[configMINIMAL_STACK_SIZE];
/* 定时器任务堆栈 */
static StackType_t Timer_Task_Stack[configTIMER_TASK_STACK_DEPTH];

最低0.47元/天 解锁文章
1872

被折叠的 条评论
为什么被折叠?



