FreeRTOS 从入门到精通--FreeRTOS 核心概念

[复制链接]
查看697 | 回复7 | 2023-9-27 10:56:35 | 显示全部楼层 |阅读模式

FreeRTOS 是一个流行的实时操作系统(RTOS),用于在各种硬件平台上支持高并发性和可预测的行为。在深入了解 FreeRTOS 的核心概念之前,首先需要了解微控制器(microcontroller)和嵌入式系统(embedded system)的基础知识。下面将详细介绍 FreeRTOS 的核心概念,包括任务(Task)、中断(Interrupt)、队列(Queue)、信号量(Semaphore)和互斥锁(Mutex),以及其他核心概念。

1. 任务(Task)

任务是 FreeRTOS 中的基本执行单元,可以理解为程序中的独立线程。每个任务都有自己的优先级,并且可以分配给不同的处理器核心。在 FreeRTOS 中,任务通过调用 vTaskCreate() 函数创建,通过 vTaskStartScheduler() 函数启动。任务可以通过参数传递给创建它的任务,以便实现特定的功能。任务调度器(Scheduler)负责根据优先级调度各个任务,并确保它们按照预期运行。

示例代码:

#include "FreeRTOS.h"
#include "task.h"

void vTaskFunction( void * pvParameters )
{
    /* 任务代码 */
}

int main( void )
{
    xTaskCreate( vTaskFunction, "TaskName", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
    vTaskStartScheduler();

    return 0;
}

2. 中断(Interrupt)

中断是 FreeRTOS 中的重要概念之一。当硬件设备发出中断请求时,中断处理程序(Interrupt Service Routine, ISR)会被执行,以响应中断事件。ISR 可以被视为特殊类型的任务,它具有很高的优先级,能够在任何其他任务中处理硬件相关的中断事件,如定时器溢出、串口接收到数据等。在 FreeRTOS 中,中断处理程序的执行时间应该尽可能短,以避免延迟其他任务的执行。

示例代码:

#include "FreeRTOS.h"
#include "portmacro.h"

void vISR( void ) interrupt 5
{
    /* 中断处理代码 */
}

3. 队列(Queue)

队列是 FreeRTOS 中用于在不同任务之间传递数据的重要机制之一。队列允许一个任务将数据放入队列中,而另一个任务可以从队列中取出数据。这种通信机制可以实现不同任务之间的协同工作。队列的创建和操作可以通过 FreeRTOS 的 API 函数进行,如 xQueueCreate()、xQueueSend() 和 xQueueReceive()。通过合理使用队列,可以实现数据的安全传输,避免不同任务之间的竞争条件。

示例代码:

#include "FreeRTOS.h"
#include "queue.h"

QueueHandle_t xQueue;

void vTaskFunction1( void * pvParameters )
{
    /* 创建队列 */
    xQueue = xQueueCreate( 10, sizeof( int ) );

    /* 发送数据到队列 */
    int value = 42;
    xQueueSend( xQueue, &value, portMAX_DELAY );
}

void vTaskFunction2( void * pvParameters )
{
    /* 接收数据从队列 */
    int value;
    if( xQueueReceive( xQueue, &value, portMAX_DELAY ) )
    {
        /* 处理接收到的数据 */
    }
}

4. 信号量(Semaphore)

信号量是用于保护共享资源的另一种机制。它是一个计数器,用于控制对共享资源的访问权限。信号量的值表示可用资源数量,当一个任务使用资源时,信号量的值会减一;当任务释放资源时,信号量的值会加一。当信号量的值为零时,表示资源不可用;当信号量的值大于零时,表示资源可用。通过使用信号量,可以实现多个任务之间的同步和协同工作,避免发生竞争条件。在 FreeRTOS 中,信号量的创建、分配和释放可以使用 API 函数如 xSemaphoreCreateBinary()、xSemaphoreTake() 和 xSemaphoreGive() 进行操作。以下是一个使用信号量的代码示例:

#include "FreeRTOS.h"
#include "semaphore.h"

SemaphoreHandle_t xSemaphore;

void vATask( void * pvParameters )
{
    /* 创建信号量 */
    xSemaphore = xSemaphoreCreateCounting( 10, 0 );

    if( xSemaphore != NULL )
    {
        /* 使用信号量 */
        for( ;; )
        {
            /* 获取信号量 */
            if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) )
            {
                /* 使用共享资源 */
                /* ... */

                /* 释放信号量 */
                xSemaphoreGive( xSemaphore );
            }
            else
            {
                /* 未能获取信号量,可能超时或信号量计数为0 */
                /* ... */
            }
        }
    }
}

在这个例子中,我们创建了一个计数信号量,最大计数值为10。任务会尝试获取信号量,如果成功,就可以使用共享资源,然后释放信号量。如果获取信号量失败(可能是因为超时或者信号量的计数值已经为0),那么任务就不能使用共享资源。这种机制可以保护共享资源,避免多个任务同时访问,造成数据不一致。

5. 互斥锁(Mutex)

互斥锁是一种特殊的信号量,用于保护共享资源的访问。与信号量不同的是,互斥锁只能被一个任务持有,而且不能被多个任务同时持有。当一个任务获得互斥锁时,其他任务将被阻塞,直到该任务释放互斥锁。在 FreeRTOS 中,互斥锁的创建、分配和释放可以使用 API 函数如 xMutexCreate()、xMutexTake() 和 xMutexGive() 进行操作。通过使用互斥锁,可以实现不同任务对共享资源的独占访问,避免同时访问共享资源造成的数据不一致性。

示例代码:

#include "FreeRTOS.h"
#include "mutex.h"

MutexHandle_t xMutex;

void vTaskFunction1( void * pvParameters )
{
    /* 创建互斥锁 */
    xMutex = xMutexCreate();

    /* 获取互斥锁 */
    if( xMutexTake( xMutex, portMAX_DELAY ) )
    {
        /* 持有互斥锁,独占共享资源 */
        /* 处理共享资源 */
    }

    /* 释放互斥锁 */
    xMutexGive( xMutex );
}

void vTaskFunction2( void * pvParameters )
{
    /* 获取互斥锁 */
    if( xMutexTake( xMutex, portMAX_DELAY ) )
    {
        /* 持有互斥锁,独占共享资源 */
        /* 处理共享资源 */
    }

    /* 释放互斥锁 */
    xMutexGive( xMutex );
}

其他核心概念

  • 事件组(Event Group):事件组是 FreeRTOS 中的一个机制,用于同步和通知任务。事件组可以包含多个位,每个位可以独立地设置或清除。任务可以等待一个或多个事件位的信号,当事件位被设置或清除时,等待的任务将被通知。通过使用事件组,可以实现更复杂的多任务同步和通信。
  • 软件定时器(Software Timer):软件定时器是 FreeRTOS 中的一个机制,用于在指定的时间间隔后执行一个任务或回调函数。与定时器不同,软件定时器是在任务调度器中实现的,因此可以在任何任务上下文中执行定时器回调函数。通过使用软件定时器,可以实现定时触发、周期性触发或延时触发的功能。
  • 内存管理(Memory Management):FreeRTOS 提供了一套内存管理机制,用于分配和管理任务使用的堆栈和堆内存。FreeRTOS 的内存管理机制包括动态内存分配、内存池管理、栈溢出检测等功能,以确保任务的正确运行和避免内存泄漏。
  • 调度策略(Scheduling Policy):FreeRTOS 提供了一些调度策略,用于控制任务的优先级和调度行为。FreeRTOS 支持的调度策略包括轮转调度(Round-Robin Scheduling)、抢占式调度(Preemptive Scheduling)和非抢占式调度(Non-Preemptive Scheduling)。调度策略的选择取决于应用程序的需求和特定的硬件平台。
回复

使用道具 举报

CHENQIGUANG1998 | 2023-9-27 10:58:15 | 显示全部楼层
沙发
回复

使用道具 举报

496199544 | 2023-9-27 11:40:09 来自手机 | 显示全部楼层
学习
回复

使用道具 举报

CHENQIGUANG1998 | 2023-9-27 13:07:18 | 显示全部楼层
瓜子花生
回复

使用道具 举报

ifwz1729 | 2023-9-29 17:45:01 | 显示全部楼层
学傻了
知足常乐
回复

使用道具 举报

linyuuki | 2023-10-1 19:56:07 来自手机 | 显示全部楼层
写得不错,是转的还是原创?
回复 支持 反对

使用道具 举报

Dayudeyang | 2023-10-2 12:19:28 来自手机 | 显示全部楼层
学学
回复

使用道具 举报

bzhou830 | 2023-10-19 11:27:25 | 显示全部楼层
写得不错
选择去发光,而不是被照亮
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则