本代码是基于正点原子的STM32Mini板子,结合其FreeRTOS课程进行学习。
实验一:设计4个任务:start_task、task1、task2、task3
- start_task任务:用来创建其他三个任务
- task1任务:实现LED0每500ms翻转一次
- task2任务:实现LED1亮800ms,暗200ms
- task3任务:判断按键KEY0是否按下,按下KEY0删除task1
FreeRTOS中,任务创建和删除(动态方法)的函数为:xTaskCreateStatic、vTaskDelete
动态创建任务和静态创建任务的区别:
(1)动态创建任务:任务的任务控制块以及任务的栈空间所需的内存均由FreeRTOS从FreeRTOS管理的堆中分配;
(2)静态创建任务:任务的任务控制块以及任务的栈空间所需的内存需要用户分配提供。
静态创建任务需要注意:
(1)代码中将宏#define configSUPPORT_STATIC_ALLOCATION配置为1;
#define configSUPPORT_STATIC_ALLOCATION 1 //支持静态内存申请
(2)定义配置空闲任务,软件定时器,实现两个接口函数:vApplicationGetIdleTaskMemory、vApplicationGetTimerTaskMemory;
//空闲任务配置
StaticTask_t idle_task_tcb;
StackType_t idel_task_stack[configMINIMAL_STACK_SIZE];
/*空闲任务内存分配*/
void vApplicationGetIdleTaskMemory ( StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize )
{
* ppxIdleTaskTCBBuffer = &idle_task_tcb;
* ppxIdleTaskStackBuffer = idel_task_stack;
* pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
//软件定时器配置
StaticTask_t time_task_tcb;
StackType_t time_task_stack[configTIMER_TASK_STACK_DEPTH];
/*软件定时器内存分配*/
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize)
{
* ppxTimerTaskTCBBuffer = &time_task_tcb;
* ppxTimerTaskStackBuffer = time_task_stack;
* pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
具体代码如下:
#include "led.h"
#include "key.h"
#include "delay.h"
#include "sys.h"
#include "FreeRTOS.h"
#include "task.h"
/*START_TASK 任务配置
*包括:任务句柄,任务优先级,堆栈大小,创建任务
*/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128 //单位是字,128x4才是字节
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//自定义堆栈大小
StackType_t start_task_stack[START_TASK_STACK_SIZE];
//开始任务的任务控制块
StaticTask_t start_task_tcb;
/*TASK1 任务配置
*包括:任务句柄,任务优先级,堆栈大小,创建任务
*/
//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_SIZE 50
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//自定义堆栈大小
StackType_t task1_stack[TASK1_SIZE];
//开始任务的任务控制块
StaticTask_t task1_tcb;
/*TASK2 任务配置
*包括:任务句柄,任务优先级,堆栈大小,创建任务
*/
//任务优先级
#define TASK2_PRIO 3
//任务堆栈大小
#define TASK2_SIZE 50
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
//自定义堆栈大小
StackType_t task2_stack[TASK1_SIZE];
//开始任务的任务控制块
StaticTask_t task2_tcb;
/*TASK3 任务配置
*包括:任务句柄,任务优先级,堆栈大小,创建任务
*/
//任务优先级
#define TASK3_PRIO 4
//任务堆栈大小
#define TASK3_SIZE 50
//任务句柄
TaskHandle_t Task3_Handler;
//任务函数
void task3(void *pvParameters);
//自定义堆栈大小
StackType_t task3_stack[TASK1_SIZE];
//开始任务的任务控制块
StaticTask_t task3_tcb;
//空闲任务配置
StaticTask_t idle_task_tcb;
StackType_t idel_task_stack[configMINIMAL_STACK_SIZE];
/*空闲任务内存分配*/
void vApplicationGetIdleTaskMemory ( StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize )
{
* ppxIdleTaskTCBBuffer = &idle_task_tcb;
* ppxIdleTaskStackBuffer = idel_task_stack;
* pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
//软件定时器配置
StaticTask_t time_task_tcb;
StackType_t time_task_stack[configTIMER_TASK_STACK_DEPTH];
/*软件定时器内存分配*/
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize)
{
* ppxTimerTaskTCBBuffer = &time_task_tcb;
* ppxTimerTaskStackBuffer = time_task_stack;
* pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
delay_init(); //延时函数初始化
uart_init(115200); //初始化串口
LED_Init(); //初始化LED
KEY_Init(); //按键初始化
//创建开始任务
StartTask_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任务
Task1_Handler = xTaskCreateStatic( (TaskFunction_t) task1,
(char * ) "task1",
(uint32_t ) TASK1_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK1_PRIO,
(StackType_t * ) task1_stack,
(StaticTask_t *) &task1_tcb);
//创建task2任务
Task2_Handler = xTaskCreateStatic( (TaskFunction_t) task2,
(char * ) "task2",
(uint32_t ) TASK2_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK2_PRIO,
(StackType_t * ) task2_stack,
(StaticTask_t *) &task2_tcb);
//创建task3任务
Task3_Handler = xTaskCreateStatic( (TaskFunction_t) task3,
(char * ) "task3",
(uint32_t ) TASK3_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK3_PRIO,
(StackType_t * ) task3_stack,
(StaticTask_t *) &task3_tcb);
vTaskDelete(NULL); //删除开始任务 也可以写成vTaskDelete(StartTask_Handler);
taskEXIT_CRITICAL(); //退出临界区
}
//task1任务函数:实现LED0每500ms翻转一次
void task1(void *pvParameters)
{
while(1)
{
LED0=!LED0;
vTaskDelay(500);
}
}
//task2任务函数:实现LED1每800ms翻转一次
void task2(void *pvParameters)
{
while(1)
{
LED1=0;
vTaskDelay(200);
LED1=1;
vTaskDelay(800);
}
}
//task3任务函数:判断按键KEY0,按下KEY0删除task1
void task3(void *pvParameters)
{
uint8_t key = 0;
while(1)
{
key = KEY_Scan(0);
if(key == KEY0_PRES)
{
vTaskDelete(Task1_Handler);
}
vTaskDelay(10);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)