FreeRTOS 入门

一、简介


在嵌入式领域中,嵌入式实时操作系统正得到越来越广泛的应用。采用嵌入式实时操作系统(RTOS)可以更合理、更有效地利用CPU的资源,简化应用软件的设计,缩短系统开发时间,更好地保证系统的实时性和可靠性。
FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。
由于RTOS需占用一定的系统资源(尤其是RAM资源),只有μC/OS-II、embOS、salvo、FreeRTOS等少数实时操作系统能在小RAM单片机上运行。相对μC/OS-II、embOS等商业操作系统,FreeRTOS操作系统是完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行,其最新版本为10.3.1版。

二、原理实现


任务调度机制是嵌入式实时操作系统的一个重要概念,也是其核心技术。对于可剥夺型内核,优先级高的任务一旦就绪就能剥夺优先级较低任务的CPU使用权,提高了系统的实时响应能力。不同于μC/OS-II,FreeRTOS对系统任务的数量没有限制,既支持优先级调度算法也支持轮换调度算法,因此FreeRTOS采用双向链表而不是采用查任务就绪表的方法来进行任务调度。

三、任务函数


头文件:task.h
1、任务创建:
portBASE_TYPE xTaskCreate (
 pdTASK_CODE pvTaskCode, 指向任务的实现函数的指针。效果上仅仅是函数名
const portCHAR * const pcNane, 具有描述性的任务名。FreeRTOS 不会使用它。
 unsigned portSHORT usStackDepth, 指定任务堆栈的大小
 void *pvParameters, 指针用于作为一个参数传向创建的任务 
 unsigned portBASE_TYPE uxPriority, 任务运行时的优先级
 xTaskHandle *pvCreatedTask 用于传递任务的句柄,可以引用从而对任务进行其他操作。
)
2、任务删除:
void vTaskDelete ( 
xTaskHandle pxTask 处理要删除的任务。传递 NULL 将删除自己
)
3、任务延时:
void vTaskDelay ( 
 portTickType xTicksToDelay 时间数量,调用任务应该锁住的时间片周期 
)
4、任务延迟到指定时间:
portTickType *pxPreviousWakeTime, 指定一个变量来掌握任务最后开启的时间, 第一次使用时必须
使用当前时间来初始化, 在 vTaskDelayUntil 中,这个变量是自
动修改的
portTickType xTimeIncrement 循环周期时间
)
5、获得任务优先级:
unsigned portBASE_TYPE uxTaskPriorityGet ( 
 xTaskHandle pxTask 需要处理的任务. 当传递 NULL 时,将返回调用该任务的优先级 
)
6、设置任务优先级:
void vTaskPrioritySet ( 
xTaskHandle pxTask , 需要设置优先级的任务。当传递 NULL,将设置调用任务的优先级
unsigned portBASE_TYPE uxNewPriority 任务需要设置的优先级 
)
7、挂起任务:
void vTaskSuspend ( 
xTaskHandle pxTaskToSuspend 处理需要挂起的任务。传递 NULL 将挂起调用此函数的任务 

8、唤醒挂起的任务:
portBase_TYPE vTaskResumeFromISR ( 
xTaskHandle pxTaskToResum 就绪任务的句柄
)
9、从中断唤醒挂起的任务:
portBase_TYPE vTaskResumeFromISR ( 
xTaskHandle pxTaskToResum 就绪任务的句柄
)
10、为任务分配标签值:
void vTaskSetApplicationTaskTag (
 xTaskHandle xTask , 将分配给标签值的任务。传递 NULL 将分配标签给调用的任务。
pdTASK_HOOK_CODE pxTagValue 分配给任务的标签值 类型为 pdTASK_HOOK_CODE 允许一
个函数指针赋值给标签,因此实际上任何值都可以分配
)

四、内核函数


头文件:task.h
1、启动实时内核处理:
void vTaskStartScheduler ( void );
2、停止实时内核运行:
void vTaskEndScheduler ( void );
3、挂起所有活动的实时内核,同时允许中断:
void vTaskSuspendAll ( void );

五、队列管理


队列是内部通信的主要形式。它可以用于在任务和任务之间以及任务和中断之间发送消息。
头文件:queue.H
1、设置一个新的队列:
xQueueHandle xQueueCreate ( 
 unsigned portBASE_TYPE uxQueueLength, 队列中包含最大项目数量
 unsigned portBASE_TYPE uxItemSize 队列中每个项目所需的字节数
 );
 2、传递一个项目到队列:
 portBASE_TYPE xQueueSend ( 
 xQueueHandle xQueue, 将项目传进的队列
 const void * pvItemToQueue, 项目的指针【源数据】
 portTickType xTicksToWait 等待的最大时间量【时间使用滴答周期】
 );
 3、传递项目到一个队列中的后面:
 portBASE_TYPE xQueueSendToBack (
 xQueueHandle xQueue, 将项目传进的队列
 const void * pvItemToQueue, 项目的指针【源数据】
 portTickType xTicksToWait 等待的最大时间量
 );
 4、从队列接收一个项目:
 portBASE_TYPE xQueueReceive ( 
 xQueueHandle xQueue, 发送项目的队列句柄
 void *pvBuffer, 指向缓冲区的指针,将接收的项目被复制进去
 portTickType xTicksToWait 任务中断并等待队列中可用空间的最大时间
 );
 5、从中断传递一个项目到队列的后面:
 portBASE_TYPE xQueueSendFromISR ( 
 xQueueHandle pxQueue, 将项目传进的队列
 const void *pvItemToQueue, 项目的指针【源数据】
 portBASE_TYPE *pxHigherPriorityTaskWoken 因空间数据问题被挂起的任务是否解锁
 );
 6、从中断传递项目到一个队列中的后面:
  portBASE_TYPE xQueueSendToBackFromISR ( 
 xQueueHandle pxQueue, 
 const void *pvItemToQueue, 
 portBASE_TYPE *pxHigherPriorityTaskWoken
 );
 7、从中断传递一个项到队列的前面:
portBASE_TYPE xQueueSendToFrontFromISR (
 xQueueHandle pxQueue, 
 const void *pvItemToQueue, 
 portBASE_TYPE *pxHigherPriorityTaskWoken
 );
 8、中断时从队列接收一个项目:
portBASE_TYPE xQueueReceiveFromISR ( 
 xQueueHandle pxQueue, 发送项目的队列句柄
 void *pvBuffer, 指向缓冲区的指针,将接收的项目被复制进去
 portBASE_TYPE *pxTaskWoken 任务将锁住,等待队列中的可用空间
 );
 9、为队列命名,并加入队列到登记管理中:
void vQueueAddToRegistry ( 
 xQueueHandle xQueue, 将要添加登记的队列句柄
 signed portCHAR *pcQueueName, 为指定的队列命名。 仅仅是文本串,方便调试。
 );
 10、从登记管理中移除队列:
void vQueueUnregisterQueue ( 
 xQueueHandle xQueue, 从登记管理处中移出的队列句柄
 );

你可能感兴趣的:(嵌入式硬件,c++,linux)