xTaskCreaate()//动态创建任务,系统自己分配
BaseType_t xTaskCreate
( TaskFunction_t pxTaskCode, //任务的人口函数
const char * const pcName, //任务的名称
const configSTACK_DEPTH_TYPE usStackDepth, //任务堆栈的大小,单位字
void * const pvParameters, //传入任务的参数,没有写NULL
UBaseType_t uxPriority, //任务优先级,数字越大优先级越高
TaskHandle_t * const pxCreatedTask); //任务任务成功创建后,会返回任务句柄。任务句柄就 是任务的任务控制块
函数的返回值
创建函数的示例
创建相同优秀级的任务
/* USER CODE BEGIN Header */
#include "driver_led.h"
#include "driver_lcd.h"
#include "driver_mpu6050.h"
#include "driver_timer.h"
#include "driver_ds18b20.h"
#include "driver_dht11.h"
#include "driver_active_buzzer.h"
#include "driver_passive_buzzer.h"
#include "driver_color_led.h"
#include "driver_ir_receiver.h"
#include "driver_ir_sender.h"
#include "driver_light_sensor.h"
#include "driver_ir_obstacle.h"
#include "driver_ultrasonic_sr04.h"
#include "driver_spiflash_w25q64.h"
#include "driver_rotary_encoder.h"
#include "driver_motor.h"
#include "driver_key.h"
#include "driver_uart.h"
/**
******************************************************************************
* File Name : freertos.c
* Description : Code for freertos applications
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
osThreadId_t taskHandle;
const osThreadAttr_t task = {
.name = "Task",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
osThreadId_t flieHandle;
const osThreadAttr_t flie_task = {
.name = "flie",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
TaskHandle_t xmusichandle;
BaseType_t musicHandle;
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
void music(void *argument);
void task1(void *argument);
/* USER CODE END FunctionPrototypes */
void StartDefaultTask(void *argument);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
/**
* @brief FreeRTOS initialization
* @param None
* @retval None
*/
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
taskHandle= osThreadNew(task1, NULL, &task);
musicHandle=xTaskCreate(music,"music",128,NULL,osPriorityNormal,&xmusichandle);
flieHandle= osThreadNew(IRReceiver_Test, NULL, &flie_task);
/* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
}
/* USER CODE BEGIN Header_StartDefaultTask */
void task1(void *argument)
{
while(1)
{
Led_Test();
}
}
/**
* @brief Function implementing the defaultTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
LCD_Init();
LCD_Clear();
for(;;)
{
//LCD_Test();
}
/* USER CODE END StartDefaultTask */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */
xTaskCreateStatic() //静态创建任务,需要自己分配栈所需要的空间内存大小
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, //任务的人口函数
const char * const pcName, //任务的名称
const uint32_t ulStackDepth, //任务堆栈的大小,单位字
void * const pvParameters, //传入任务的参数,没有写NULL
UBaseType_t uxPriority, //任务优先级,数字越大优先级越高
StackType_t * const puxStackBuffer, //任务栈指针,内存由用户分配提供
StaticTask_t * const pxTaskBuffer); //任务控制块指针,内存由用户分配提供
函数 vTaskDelete()
用于删除已被创建的任务,被删除的任务将被从就绪态任务列表、阻塞态任务列表、 挂起态任务列表和事件列表中移除,要注意的是,空闲任务会负责释放被删除任务中由系统分 配的内存,但是由用户在任务删除前申请的内存,则需要由用户在任务被删除前提前释放,否 则将导致内存泄露。
void vTaskDelete(TaskHandle_t xTaskToDelete); //写入要删除任务的任务句柄,如果写入NULL就删除正在运行的任务。
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
LCD_Init();
LCD_Clear();
uint8_t dev, data;
IRReceiver_Init();
while (1)
{
if (0 == IRReceiver_Read(&dev, &data))
{ LCD_PrintString(0, 2, "Device Data");
if(data==0xe0||data==0x90)
{LCD_PrintString(0, 0, "Delete");
if(xmusichandle!=NULL)
{
vTaskDelete(xmusichandle);
PassiveBuzzer_Control(0);
xmusichandle=NULL;
}
}
if(data==0xa8)
{ LCD_PrintString(0, 0, "Create");
if(xmusichandle==NULL)
{
musicHandle=xTaskCreate(music,"music",128,NULL,osPriorityNormal+1,&xmusichandle);
}
}
}
}
任务频繁的创建与删除会造成很多的碎片空间会导致后面空间不足以创建新任务
任务优先级
优先级的取值范围是:0~(configMAX_PRIORITIES – 1),数值越大优先级越高。
1.FreeRTOS 会确保最高优先级的、可运行的任务,马上就能执行
2.对于相同优先级的、可运行的任务,轮流执行
有一个经常范的错误就是优先分配不正常,没有主动放弃内存,一直运行会导致其他任务无法开始运行。
示例
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
taskHandle= osThreadNew(task1, NULL, &task);
musicHandle=xTaskCreate(music,"music",128,NULL,osPriorityNormal+1,&xmusichandle);
flieHandle= osThreadNew(IRReceiver_Test, NULL, &flie_task);
void MUSIC_Analysis(void){
uint16_t MusicBeatNum = ((((sizeof(Music_Lone_Brave))/2)/3)-1);
uint16_t MusicSpeed = Music_Lone_Brave[0][2];
for(uint16_t i = 1;i<=MusicBeatNum;i++){
//BSP_Buzzer_SetFrequency(Tone_Index[Music_Lone_Brave[i][0]][Music_Lone_Brave[i][1]]);
PassiveBuzzer_Set_Freq_Duty(Tone_Index[Music_Lone_Brave[i][0]][Music_Lone_Brave[i][1]], 50);
//HAL_Delay(MusicSpeed/Music_Lone_Brave[i][2]);
mdelay(MusicSpeed/Music_Lone_Brave[i][2]);
}
}
/* USER CODE END FD */
/************************ (C) COPYRIGHT Lesterbor *****END OF FILE****/
void music(void *argument)
{
PassiveBuzzer_Init();
while (1)
{
MUSIC_Analysis();
}
}
这个创建函数music任务的优先级最高,优先运行Music的任务发现music的任务一直在运行没有主动挂起任务和阻塞任务的时候,导致其他任务没有运行的时刻。
我们只需要改动一下music函数的延时函数就可以了,该任务处于阻塞状态,一个固定时刻再恢复为就绪任务。
void MUSIC_Analysis(void){
uint16_t MusicBeatNum = ((((sizeof(Music_Lone_Brave))/2)/3)-1);
uint16_t MusicSpeed = Music_Lone_Brave[0][2];
for(uint16_t i = 1;i<=MusicBeatNum;i++){
//BSP_Buzzer_SetFrequency(Tone_Index[Music_Lone_Brave[i][0]][Music_Lone_Brave[i][1]]);
PassiveBuzzer_Set_Freq_Duty(Tone_Index[Music_Lone_Brave[i][0]][Music_Lone_Brave[i][1]], 50);
//HAL_Delay(MusicSpeed/Music_Lone_Brave[i][2]);
//mdelay(MusicSpeed/Music_Lone_Brave[i][2]);
vTaskDelay(MusicSpeed/Music_Lone_Brave[i][2]);
}
}
/* USER CODE END FD */
/************************ (C) COPYRIGHT Lesterbor *****END OF FILE****/
void music(void *argument)
{
PassiveBuzzer_Init();
while (1)
{
MUSIC_Analysis();
}
}
vTaskDelay();函数的作用
vTaskDelay:至少等待指定个数的 Tick Interrupt 才能变为就绪状态
vTaskDelay()
函数是 FreeRTOS 中的一个函数,用于在任务中创建延迟。它的作用是让当前任务暂停执行一段时间,然后再继续执行。这个函数接受一个参数,表示延迟的时间,单位是 FreeRTOS 的时基单元,通常是以毫秒或时钟节拍为单位。
例如,如果你调用 vTaskDelay(100)
,表示当前任务将暂停执行 100 个时基单元的时间,然后再继续执行。这种延迟可以用来实现任务之间的时间间隔,或者在任务中进行定时操作。
需要注意的是,vTaskDelay()
函数会让当前任务在延迟期间处于阻塞状态,即任务不会被调度执行,直到延迟时间结束。因此,在使用这个函数时,要确保不会影响系统中其他任务的执行,以及不要在关键任务中使用过长的延迟时间,避免系统响应性降低