打印
[软件资料]

FreeRTOS 入门

[复制链接]
290|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mnynt121|  楼主 | 2022-11-15 22:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、简介


在嵌入式领域中,嵌入式实时操作系统正得到越来越广泛的应用。采用嵌入式实时操作系统(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, 从登记管理处中移出的队列句柄
);


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

2838

帖子

2

粉丝