guanjiaer 发表于 2025-8-13 20:58

STM32 FreeRTOS基础

FreeRTOS 核心 API 函数详解:从任务管理到定时器控制
介绍 FreeRTOS 中几个最常用的核心 API 函数,包括任务管理、延时控制和定时器操作等关键功能。

任务管理核心函数
xTaskCreate:创建任务
xTaskCreate是 FreeRTOS 中创建任务的基础函数,用于在系统中创建一个新任务并将其添加到就绪列表中。

BaseType_t xTaskCreate(
    TaskFunction_t pvTaskCode, // 任务函数指针
    const char *const pcName, // 任务名称(调试用)
    const configSTACK_DEPTH_TYPE usStackDepth, // 栈大小
    void *pvParameters, // 传递给任务的参数
    UBaseType_t uxPriority, // 任务优先级(0~configMAX_PRIORITIES-1)
    TaskHandle_t *pxCreatedTask // 任务句柄(可用于后续操作)
);


参数说明:

pvTaskCode:任务函数,必须是一个无限循环结构,不能返回
pcName:任务名称,仅用于调试识别,最大长度由configMAX_TASK_NAME_LEN定义
usStackDepth:任务栈大小,单位是字 (不是字节),与处理器架构有关
pvParameters:传递给任务函数的参数,可以为 NULL
uxPriority:任务优先级,数值越大优先级越高
pxCreatedTask:输出参数,用于接收创建的任务句柄,可设为 NULL
返回值:

pdPASS:任务创建成功
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:内存不足,任务创建失败
vTaskDelete:删除任务
vTaskDelete用于永久删除一个任务,被删除的任务将从所有就绪、阻塞、挂起等列表中移除。

void vTaskDelete(TaskHandle_t xTaskToDelete);


参数说明:

xTaskToDelete:要删除的任务句柄,若为 NULL 则删除当前任务
注意事项:

被删除任务所占用的内存 (栈和 TCB) 只有在使用动态内存管理时才会自动释放
不能删除空闲任务和定时器服务任务
删除其他任务时要确保该任务不再被使用,避免悬空句柄
vTaskSuspend:挂起任务
vTaskSuspend用于将指定任务挂起,挂起的任务不会被调度器选中运行,直到被恢复。

void vTaskSuspend(TaskHandle_t xTaskToSuspend);


参数说明:

xTaskToSuspend:要挂起的任务句柄,若为 NULL 则挂起当前任务
特点:

挂起操作可以嵌套,即多次挂起需要相同次数的恢复操作
挂起不会释放任务已获取的资源
处于任何状态的任务都可以被挂起
vTaskResume:恢复任务
vTaskResume用于恢复被挂起的任务,使其重新进入调度队列。

void vTaskResume(TaskHandle_t xTaskToResume);


参数说明:

xTaskToResume:要恢复的任务句柄,不能为 NULL
使用示例:

// 挂起任务

vTaskSuspend(xHandle);

// 一段时间后恢复任务

vTaskResume(xHandle);


延时函数
vTaskDelay:相对延时
vTaskDelay提供相对延时功能,使当前任务进入阻塞状态指定的时间。

void vTaskDelay(const TickType_t xTicksToDelay);


参数说明:

xTicksToDelay:延时的节拍数,系统节拍由configTICK_RATE_HZ配置
特点:

相对延时:从调用时刻开始计算延时时间
延时期间任务进入阻塞状态,CPU 可以调度其他任务
实际延时时间可能大于等于指定时间,受系统调度影响
使用示例:

// 延时100个节拍,如果configTICK_RATE_HZ=1000,则约为100ms

vTaskDelay(100);

// 延时1秒的跨平台写法

vTaskDelay(pdMS_TO_TICKS(1000));


定时器控制函数
xTimerCreate:创建软件定时器
xTimerCreate用于创建一个软件定时器,软件定时器是基于系统节拍的定时机制。

TimerHandle_t xTimerCreate(
    const char *const pcTimerName, // 定时器名称
    const TickType_t xTimerPeriodInTicks, // 定时器周期(节拍数)
    const UBaseType_t uxAutoReload, // 是否自动重载
    void *pvTimerID, // 定时器ID
    TimerCallbackFunction_t pxCallbackFunction // 回调函数
);


参数说明:

pcTimerName:定时器名称,仅用于调试
xTimerPeriodInTicks:定时器周期,单位为节拍
uxAutoReload:pdTRUE表示自动重载 (周期性触发),pdFALSE表示一次性触发
pvTimerID:定时器 ID,可用于在回调函数中区分不同定时器
pxCallbackFunction:定时器超时回调函数
返回值:

成功:返回创建的定时器句柄
失败:返回 NULL (通常是内存不足)
xTimerStart:启动定时器
xTimerStart用于启动一个已创建的定时器,使其开始计时。

BaseType_t xTimerStart(TimerHandle_t xTimer, TickType_t xTicksToWait);


参数说明:

xTimer:要启动的定时器句柄
xTicksToWait:等待时间,若定时器命令队列满,最多等待的节拍数
返回值:

pdPASS:启动成功
errQUEUE_FULL:失败,通常是命令队列满
xTimerStop:停止定时器
xTimerStop用于停止一个正在运行的定时器。

BaseType_t xTimerStop(TimerHandle_t xTimer, TickType_t xTicksToWait);


参数说明:

xTimer:要停止的定时器句柄
xTicksToWait:等待时间,若定时器命令队列满,最多等待的节拍数
返回值:

pdPASS:停止成功
errQUEUE_FULL:失败,通常是命令队列满
例子:
创建两个任务,一个是普通任务,一个是定时器任务

普通任务通过xTaskCreate创建,xTimerStart 和 xTimerStop 开启和关闭定时器任务。
定时器任务通过xTimerCreate创建 ,vTaskSuspend 和 vTaskResume 挂起和恢复普通任务。

// Task priorities
#define START_TASK_PRIO                1
#define LED_TASK_PRIO                2

// Task stack sizes
#define START_STK_SIZE                 128
#define LED_STK_SIZE                 128

// Task handles
TaskHandle_t StartTask_Handler;
TaskHandle_t LedTask_Handler;
TimerHandle_t PrintTimer_Handler;

// Task functions
void start_task(void *pvParameters);
void led_task(void *pvParameters);

// Timer callback function
void TimerCallback(TimerHandle_t xTimer);

int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // Set system interrupt priority group 4
    delay_init(168);            // Initialize delay function
    uart_init(115200);          // Initialize serial port
    LED_Init();               // Initialize LED port

    printf("System initialization completed, preparing to start FreeRTOS...\r\n");

    // Create the start task
    xTaskCreate((TaskFunction_t )start_task,
                (const char*    )"start_task",
                (uint16_t       )START_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )START_TASK_PRIO,
                (TaskHandle_t*)&StartTask_Handler);

    vTaskStartScheduler();      // Start task scheduling

    // If the program executes to this point, it means the scheduler failed to start
    while(1);
}

// Start task - Create other tasks and delete itself
void start_task(void *pvParameters)
{
    BaseType_t xResult;

    printf("Start task is executing, creating LED and OLED tasks...\r\n");

    // Create the LED task
    xResult = xTaskCreate((TaskFunction_t )led_task,
                        (const char*    )"led_task",
                        (uint16_t       )LED_STK_SIZE,
                        (void*          )NULL,
                        (UBaseType_t    )LED_TASK_PRIO,
                        (TaskHandle_t*)&LedTask_Handler);

    if(xResult != pdPASS)
    {
      printf("Failed to create LED task!\r\n");
    }

    // Create the timer, set to trigger
    PrintTimer_Handler = xTimerCreate(
      "PrintTimer",          // Timer name
      pdMS_TO_TICKS(1000),   // Timer period in ticks
      pdTRUE,                // Auto-reload timer
      (void*) 0,             // Timer ID
      TimerCallback          // Timer callback function
    );

    if(PrintTimer_Handler != NULL)
    {
         // Start the timer
      if(xTimerStart(PrintTimer_Handler, 0) != pdPASS)
      {
            printf("Failed to start timer!\r\n");
      }
    }
    else
    {
      printf("Failed to create timer!\r\n");
    }

    // Delete the start task
    vTaskDelete(NULL);
}
// LED task - Control LED blinking
void led_task(void *pvParameters)
{
    int nCount = 0;

    while(1)
    {
      nCount++;
      if (nCount == 10)
      {
            printf(" nCount = %d, Stop Timer\r\n", nCount);
            xTimerStop(PrintTimer_Handler, 0);
      }
      else if (nCount == 20)
      {
            printf(" nCount = %d, Start Timer\r\n", nCount);
            xTimerStart(PrintTimer_Handler, 0);
      }

      LED0 = ~LED0;// Toggle LED state
      printf(" LED state toggled, state: %d, nCount = %d\r\n", LED0, nCount);
                       
      vTaskDelay(pdMS_TO_TICKS(500));
    }
}


// Timer callback function
void TimerCallback(TimerHandle_t xTimer)
{
    static u16 count = 0;
    TickType_t currentTickCount = xTaskGetTickCount();
    printf(" Current TickCount: %lu, count = %d\r\n", (unsigned long)currentTickCount, count);
       
    count++;
    if(count == 10)
    {
      printf(" Suspend LED Task, count: %d\r\n", count);
      vTaskSuspend(LedTask_Handler);      
    }
    else if(count == 20)
    {
      printf(" Resume LED Task, count: %d\r\n", count);
      vTaskResume(LedTask_Handler);
      count = 0;
    }

}



————————————————
版权声明:本文为CSDN博主「扣篮发型不乱」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/KawhiLeo/article/details/149661468

页: [1]
查看完整版本: STM32 FreeRTOS基础