1框架
FreeRTOS 是一个小型的开源实时操作系统内核,广泛用于嵌入式设备和微控制器。它被设计为简单、小巧且易于理解,以便于在资源受限的设备上运行。FreeRTOS 的主要组成部分包括任务调度器、任务管理、时间管理、队列、信号量、互斥量和软件定时器等。
FreeRTOS 的主要文件组成和功能如下:
- 任务调度器(Scheduler): 任务调度器是 FreeRTOS 的核心,负责管理任务的执行。它根据任务的优先级和就绪状态来决定哪个任务应该运行。
- 任务管理(Task Management): 任务是执行的最小单元,每个任务都有自己的堆栈和执行上下文。任务管理包括任务的创建、删除、挂起、恢复和优先级管理等。
- 时间管理(Time Management): FreeRTOS 提供了软件定时器功能,允许任务或中断服务例程设置在将来的某个时间点执行的操作。
- 队列(Queues): 队列是任务间通信的一种机制,可以用来发送和接收数据。队列允许任务之间以先进先出(FIFO)的方式传递数据。
- 信号量(Semaphores): 信号量是一种同步机制,用于控制对共享资源的访问。它们可以是二进制信号量、计数信号量或互斥量。
- 互斥量(Mutexes): 互斥量是一种特殊的二进制信号量,用于防止多个任务同时访问共享资源。
- 中断管理(Interrupt Management): FreeRTOS 提供了中断服务例程(ISR)和处理中断的机制。中断服务例程可以快速地响应中断,并将更复杂的工作交给任务处理。
总体上,FreeRTOS 的框架可以描述为:
- 核心层(Core): 包括任务调度器、任务管理、时间管理等基本功能。
- 中间件(Middleware): 包括队列、信号量、互斥量等通信和同步机制。
- 硬件抽象层(HAL): 为底层硬件提供抽象,使 FreeRTOS 能够在不同的硬件平台上运行。
FreeRTOS 的设计目标是提供一种可扩展、可定制的解决方案,以适应不同的嵌入式系统和应用需求。它的轻量级和模块化特性使其成为嵌入式系统开发人员的首选。
2原理
实时操作系统(RTOS)不可以同时处理多个任务,但是通过快速切换(上下文切换),使得每个任务都看起来像是得到了连续的处理器时间。这种切换是如此之快,以至于给人造成了多个任务在“同时”执行的错觉。实际上,在任何给定的时刻,只有一个任务在执行。
实时操作系统的实现原理基于以下几个核心概念:
- 多任务处理:
- 抢占式调度:RTOS通常使用抢占式调度,这意味着具有更高优先级的任务可以中断低优先级的任务。当高优先级任务准备好执行时,它会立即抢占CPU的控制权。
- 时间分片:在某些情况下,RTOS可能会使用时间分片,即给每个任务分配一小段CPU时间,然后切换到下一个任务。这种方法在硬实时系统中不太常见,因为它可能导致不可预测的延迟。
- 上下文切换:
- 当RTOS决定切换任务时,它会保存当前任务的状态(包括程序计数器、寄存器值等),并加载新任务的状态。这个过程称为上下文切换。
- 上下文切换的时间越短,系统的性能就越好,因此RTOS设计者会尽量优化这一过程。
- 中断管理:
- 实时操作系统必须能够快速响应外部事件,这通常通过中断来实现。当中断发生时,CPU会暂停当前任务,执行中断服务例程(ISR)来处理中断。
- ISR应该尽可能快地执行,以减少对其他任务的影响。如果ISR需要执行较长时间的任务,它通常会创建一个更高优先级的任务来处理这些工作,然后尽快返回。
- 时间管理:
- 实时操作系统依赖于精确的时钟来管理任务和事件。时钟节拍(tick)是RTOS中的基本时间单位,通常由硬件定时器产生。
- 软件定时器允许任务在未来的某个特定时间点执行,或者以固定的间隔周期性地执行。
- 同步与通信:
- 为了避免多个任务同时访问共享资源导致的问题,RTOS提供了同步机制,如互斥量(Mutex)和信号量(Semaphore)。
- 任务之间的通信可以通过消息队列(Queue)或信号量来实现,这些机制允许任务交换数据和同步操作。
实时操作系统的关键在于能够在规定的时间内响应用户和系统的需求,同时保证任务的执行不会超过预定的时间限制。这要求RTOS具有高度的可预测性和稳定性,以确保关键任务按时完成。
3例子
//freertos_demo.c
#include "freertos_demo.h"
#include "FreeRTOS.h"
#include "task.h"
/* START_TASK 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define START_TASK_PRIO 1
#define START_TASK_STACK_SIZE 128
TaskHandle_t start_task_handler;
void start_task( void * pvParameters );
/* TASK1 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define TASK1_PRIO 2
#define TASK1_STACK_SIZE 128
TaskHandle_t task1_handler;
void task1( void * pvParameters );
/* TASK2 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define TASK2_PRIO 3
#define TASK2_STACK_SIZE 128
TaskHandle_t task2_handler;
void task2( void * pvParameters );
/**
* @brief FreeRTOS例程入口函数
* @param 无
* @retval 无
*/
void freertos_demo(void)
{
xTaskCreate((TaskFunction_t ) start_task,
(char * ) "start_task",
(configSTACK_DEPTH_TYPE ) START_TASK_STACK_SIZE,
(void * ) NULL,
(UBaseType_t ) START_TASK_PRIO,
(TaskHandle_t * ) &start_task_handler );
vTaskStartScheduler();
}
/*开始任务start_task*/
void start_task( void * pvParameters )
{
taskENTER_CRITICAL(); /* 进入临界区 */
xTaskCreate((TaskFunction_t ) task1,
(char * ) "task1",
(configSTACK_DEPTH_TYPE ) TASK1_STACK_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK1_PRIO,
(TaskHandle_t * ) &task1_handler );
xTaskCreate((TaskFunction_t ) task2,
(char * ) "task2",
(configSTACK_DEPTH_TYPE ) TASK2_STACK_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK2_PRIO,
(TaskHandle_t * ) &task2_handler );
vTaskDelete(NULL);
taskEXIT_CRITICAL(); /* 退出临界区 */
}
/* 任务一,实现打印每500ms一次 */
void task1( void * pvParameters )
{
while(1)
{
printf("task1正在运行!!!\r\n");
delay_ms(1000);
vTaskDelay(500);
}
}
/* 任务二,实现打印每500ms一次 */
void task2( void * pvParameters )
{
while(1)
{
printf("task2正在运行!!!\r\n");
vTaskDelay(500);
}
}