关于FreeRTOS的介绍
扫描二维码
随时随地手机看文章
一、FreeRTOS介绍
1、FreeRTOS主要特点
(1)、支持抢占式调度,合作式调度和时间片调度;
(2)、高效的软件定时器;
(3)、开源免费;
(4)、支持多种系统架构;
(5)、任务数量不限等等;
2、FreeRTOS命令规则
(1)、变量
uint32_t定义的变量都加前缀ul,u -- unsigned l -- long;
uint16_t定义的变量都加前缀us,u -- unsigned s -- short;
uint8_t定义的变量都加前缀uc, u -- unsigned c -- char;
size_t定义的变量加上前缀ux;
枚举变量会加上前缀e;
指针变量加上前缀p,uint16_t定义的指针变量加上pus;
(2)、函数
static声明的函数,定义时加上前缀prv(private的缩写);
带返回值的函数,根据返回值的类型,加上响应前缀,void前缀加上v;
文件中的函数名也包含文件名;
3、FreeRTOS中的数据类型
(1)、TickType_t
如果定义了configUSE_16_BIT_TICKS,TickType_t为16位无符号,否则为32位无符号,因此,对于32位处理器来说,此宏必须为0。
(2)、BaseType_t (与系统架构有关,此类型定义的是有符号数)
(3)、UBaseType_t(BaseType_t的无符号版本)
(4)、StackType_t(栈变量数据类型)
二、FreeRTOS配置文件(FreeRTOSConfig —— 系统裁剪)
1、基本配置
(1)、configUSE_PREEMPTION:抢占式调度器师使能(1:抢占式调度器 0:合作式调度器);
(2)、configUSE_PORT_OPTIMISED_TASK_SELECTION:优化列表中要执行的最高优先级任务的算法(1:专用方式 0:通用方式);
(3)、configUSE_TICKLESS_IDLE:tickless低功耗模式使能;
(4)、configCPU_CLOCK_HZ:定义SOC主频;
(5)、configTICK_RATE_HZ:定义系统时钟节拍数,单位HZ,一般为1000HZ;
(6)、configMAX_PRIORITIES:定义用户可使用的最大优先级数;
(7)、configMINIMAL_STACK_SIZE:定义空闲任务的栈大小;
(8)、configTOTAL_HEAP_SIZE:定义堆大小,任务创建,消息队列创建等都需要;
(9)、configMAX_TASK_NAME_LEN:任务名最大字符数;
(10)、configUSE_16_BIT_TICKS:TickType_t类型含义, 1:16位架构处理器 0:32位架构处理器;
(11)、configIDLE_SHOULD_YIELD:建议配置为0;
(12)、configUSE_TASK_NOTIFICATIONS: 1:使能任务间直接的消息传递 0:失能;
(13)、configUSE_MUTEXES: 1:使能互斥信号量 0:失能互斥信号量;
(14)、configUSE_RECURSIVE_MUTEXES: 1:使能递归互斥信号量 0:失能递归互斥信号量;
(15)、configUSE_COUNTING_SEMAPHORES: 1:使能计数信号量 0:失能计数信号量;
(16)、configQUEUE_REGISTRY_SIZE: 设置可以注册的信号量和消息队列个数;
(17)、configUSE_QUEUE_SETS: 1:使能消息队列 0:失能消息队列;
(18)、configUSE_TIME_SLICING: 1:使能时间片调度 0:失能时间片调度;
2、钩子函数
(1)、configUSE_IDLE_HOOK: 1:使能空闲任务的钩子函数 0:失能空闲任务钩子函数;
(2)、configUSE_MALLOC_FAILED_HOOK: 1:使能动态内存申请失败的钩子函数 0:失能;
(3)、configUSE_TICK_HOOK: 1:使能滴答定时器中断的钩子函数;
3、合作式任务配置
(1)、configUSE_CO_ROUTINES: 1:使能合作式调度相关函数 0:失能合作式调用相关函数;
(2)、configMAX_CO_ROUTINE_PRIORITIES:最大的合作式任务优先级数;
4、软件定时器配置
(1)、configUSE_TIMERS: 1:使能软件定时器 0:失能软件定时器;
(2)、configTIMER_TASK_PRIORITY:软件定时器任务的优先级;
(3)、configTIMER_QUEUE_LENGTH:软件定时器命令队列的长度;
(4)、configTIMER_TASK_STACK_DEPTH:软件定时器任务的栈空间大小;
5、内核配置
(1)、configPRIO_BITS:stm32f103/407/429等都是4;
(2)、configLIBRARY_LOWEST_INIERRUPT_PRIORITY:0-15,建议配置中断最低优先级15,;
(3)、configLIBRARY_MAX_SYSCALL_INIERRUPT_PRIORITY:系统可管理的最高优先级中断;
(4)、configKERNEL_INTERRUPT_PRIORITY
(5)、configMAX_SYSCALL_INTERRUPT_PRIORITY
6、INCLUDE配置
#define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 1 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_eTaskGetState 1 #define INCLUDE_xTimerPendFunctionCall 1
三、FreeRTOS任务管理
1、任务状态(运行态,就绪态,阻塞态,挂起态)
2、系统启动vTaskStartScheduler()
启动FreeRTOS调度器,即启动多任务运行。
3、任务创建xTaskCreate()
BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, /* 任务函数 */ const char * const pcName, /* 任务名 */ unsigned short usStackDepth, /* 任务栈大小,单位 word,也就是 4 字节 */ void *pvParameters, /* 任务参数 */ UBaseType_t uxPriority, /* 任务优先级 */ TaskHandle_t *pvCreatedTask /* 任务句柄 */ );
#include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "croutine.h" #define TASK_PRIO_START 1 #define TASK_START_STK_SIZE (1 * 256) TaskHandle_t start_handler; static void start_task(void *arg) { while(1) { vTaskDelay(500); } } int main(void) { xTaskCreate(start_task, "start_task", TASK_START_STK_SIZE, NULL, TASK_PRIO_START, &start_handler); vTaskStartScheduler(); }
4、任务删除vTaskDelete()
void vTaskDelete( TaskHandle_t xTaskToDelete )
必须配置#define INCLUDE_vTaskDelete 1
5、任务挂起vTaskSuspend()
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
必须配置#define INCLUDE_vTaskSuspend 1
6、任务恢复vTaskResume()
void vTaskResume( TaskHandle_t xTaskToResume )
必须配置#define INCLUDE_vTaskResume 1
7、任务恢复中断方式xTaskResumeFromISR()
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
必须配置#define INCLUDE_vTaskResumeFromISR 1
8、空闲任务(低功耗时,在空闲任务中实现睡眠)
四、临界段和开关中断
1、临界段
不允许中断打断,进入临界区前必须关中断,退出临界区后开中断。UCOS有临界区,RTX没有。
2、临界段处理(开关中断)
#define taskENTER_CRITICAL() portENTER_CRITICAL() #define taskEXIT_CRITICAL() portEXIT_CRITICAL()
开关中断就是对计数uxCriticalNesting变量操作,进入临界区,变量+1,退出临界区,变量-1。
3、中断临界段
#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() #define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )
五、FreeRTOS时间管理
1、任务等待vTaskDelay()
void vTaskDelay( const TickType_t xTicksToDelay )
延时等待范围:1-0xFFFFFFFF
作用:任务切换
其他几个任务延时函数个人没怎么使用,故不介绍了。
六、FreeRTOS消息队列
消息传递的是数据的复制,RTX/UCOS传递的是数据的地址。
1、消息队列创建xQueueCreate()
QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, /* 消息个数 */ UBaseType_t uxItemSize ); /* 每个消息大小,单位字节 */
返回消息队列句柄。
2、消息队列发送xQueueSend()
BaseType_t xQueueSend( QueueHandle_t xQueue, /* 消息队列句柄 */ const void * pvItemToQueue, /* 要传递数据地址 */ TickType_t xTicksToWait /* 等待消息队列有空间的最大等待时间 */ );
3、消息队列从中断发送xQueueSendFromISR()
BaseType_t xQueueSendFromISR( QueueHandle_t xQueue, /* 消息队列句柄 */ const void * pvItemToQueue, /* 要传递数据地址 */ TickType_t xTicksToWait /* 等待消息队列有空间的最大等待时间 */ );
4、消息队列接收xQueueReceive() xQueueReceiveFromISR
BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken )
BaseType_t xQueueReceive( QueueHandle_t xQueue, /* 消息队列句柄 */ void *pvBuffer, /* 接收消息队列数据的缓冲地址 */ TickType_t xTicksToWait /* 等待消息队列有数据的最大等待时间 */ );
七、FreeRTOS事件标志组(任务间同步)
1、事件标志组创建xEventGroupCreate()
EventGroupHandle_t xEventGroupCreate( void );
返回事件标志组句柄。
必须定义:
#define INCLUDE_xEventGroupSetBitFromISR 1
#define configUSE_TIMERS 1
#define INCLUDE_xTimerPendFunctionCall 1
2、时间标志组设置xEventGroupSetBits()
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, /* 事件标志组句柄 */ const EventBits_t uxBitsToSet ); /* 事件标志位设置 */
BaseType_t xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup, /* 事件标志组句柄 */ const EventBits_t uxBitsToSet, /* 事件标志位设置 */ BaseType_t *pxHigherPriorityTaskWoken ); /* 高优先级任务是否被唤醒的状态保存 */
第二个参数表示24个可设置的时间标志位,返回当前的事件标志组数值。中断中使用xEventGroupSetBitsFromISR()。
3、事件标志组获取xEventGroupWaitBits()
EventBits_t xEventGroupWaitBits(const EventGroupHandle_t xEventGroup, /* 事件标志组句柄 */ const EventBits_t uxBitsToWaitFor, /* 等待被设置的事件标志位 */ const BaseType_t xClearOnExit, /* 选择是否清零被置位的事件标志位 */ const BaseType_t xWaitForAllBits, /* 选择是否等待所有标志位都被设置 */ TickType_t xTicksToWait ); /* 设置等待时间 */
// STM32F10X FreeRTOSConfig举例 #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H #include "type.h" /***************************************************************************************************************/ /* FreeRTOS基础配置配置选项 */ /***************************************************************************************************************/ #define configUSE_PREEMPTION 1 // 1使用抢占式内核,0使用协程 #define configUSE_TIME_SLICING 1 // 1使能时间片调度(默认式使能的) #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 // 1启用特殊方法来选择下一个要运行的任务 // 一般是硬件计算前导零指令,如果所使用的 // MCU没有这些硬件指令的话此宏应该设置为0! #define configUSE_TICKLESS_IDLE 0 // 1启用低功耗tickless模式 #define configUSE_QUEUE_SETS 1 // 为1时启用队列 #define configCPU_CLOCK_HZ 72000000 // CPU频率 #define configTICK_RATE_HZ (1000) // 时钟节拍频率,这里设置为1000,周期就是1ms #define configMAX_PRIORITIES (32) // 可使用的最大优先级 #define configMINIMAL_STACK_SIZE ((unsigned short)130) // 空闲任务使用的堆栈大小 #define configMAX_TASK_NAME_LEN (20) // 任务名字字符串长度 #define configUSE_16_BIT_TICKS 0 // 系统节拍计数器变量数据类型, // 1表示为16位无符号整形,0表示为32位无符号整形 #define configIDLE_SHOULD_YIELD 1 // 为1时空闲任务放弃CPU使用权给其他同优先级的用户任务 #define configUSE_TASK_NOTIFICATIONS 1 // 为1时开启任务通知功能,默认开启 #define configUSE_MUTEXES 1 // 为1时使用互斥信号量 #define configQUEUE_REGISTRY_SIZE 8 // 不为0时表示启用队列记录,具体的值是可以 // 记录的队列和信号量最大数目。 #define configCHECK_FOR_STACK_OVERFLOW 0 // 大于0时启用堆栈溢出检测功能,如果使用此功能 // 用户必须提供一个栈溢出钩子函数,如果使用的话 // 此值可以为1或者2,因为有两种栈溢出检测方法。 #define configUSE_RECURSIVE_MUTEXES 1 // 为1时使用递归互斥信号量 #define configUSE_MALLOC_FAILED_HOOK 0 // 1使用内存申请失败钩子函数 #define configUSE_APPLICATION_TASK_TAG 0 #define configUSE_COUNTING_SEMAPHORES 1 // 为1时使用计数信号量 /***************************************************************************************************************/ /* FreeRTOS与内存申请有关配置选项 */ /***************************************************************************************************************/ #define configSUPPORT_DYNAMIC_ALLOCATION 1 // 支持动态内存申请 #define configTOTAL_HEAP_SIZE ((size_t)(20*1024)) // 系统所有总的堆大小 /***************************************************************************************************************/ /* FreeRTOS与钩子函数有关的配置选项 */ /***************************************************************************************************************/ #define configUSE_IDLE_HOOK 0 // 1,使用空闲钩子;0,不使用 #define configUSE_TICK_HOOK 0 // 1,使用时间片钩子;0,不使用 /***************************************************************************************************************/ /* FreeRTOS与协程有关的配置选项 */ /***************************************************************************************************************/ #define configUSE_CO_ROUTINES 0 // 为1时启用协程,启用协程以后必须添加文件croutine.c #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) // 协程的有效优先级数目 /***************************************************************************************************************/ /* FreeRTOS与软件定时器有关的配置选项 */ /***************************************************************************************************************/ #define configUSE_TIMERS 1 // 为1时启用软件定时器 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1) // 软件定时器优先级 #define configTIMER_QUEUE_LENGTH 5 // 软件定时器队列长度 #define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE*2) // 软件定时器任务堆栈大小 /***************************************************************************************************************/ /* FreeRTOS可选函数配置选项 */ /***************************************************************************************************************/ #define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 1 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_eTaskGetState 1 #define INCLUDE_xTimerPendFunctionCall 1 /***************************************************************************************************************/ /* FreeRTOS与中断有关的配置选项 */ /***************************************************************************************************************/ #ifdef __NVIC_PRIO_BITS #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 #endif #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 // 中断最低优先级 #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 // 系统可管理的最高中断优先级 #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /***************************************************************************************************************/ /* FreeRTOS与中断服务函数有关的配置选项 */ /***************************************************************************************************************/ #define xPortPendSVHandler PendSV_Handler #define vPortSVCHandler SVC_Handler #endif /* FREERTOS_CONFIG_H */