一、简介 、特点
FreeRTOS (Free 免费的 Real Time Operate System 实时操作系统)。文件数量比UCOS少(4-9K字节)。特点:可裁剪(通过配置文件里的宏定义),任务数量、优先级不限,支持低功耗的Tickless模式,堆栈溢出检测。
二、源码获取 (官网: www.freertos.org)
1、提取文件
2、实现串口收发(printf重定向,调试)和系统嘀嗒定时器(涉及RTOS的系统时钟)如果实现了timer2定时器先注释,笔者发现两个都初始化后任务创建不成功(timer2定时器中断优先级比较高的原因,调低就可以了)。
systic.c文件里初始化完后要实现中断服务函数,实现delay_us(u32 us) 和 delay_xms(u32 ms) 延时函数,初始化和中断这里跟我们平时写的有差异,只因他是专门服务于FreeRTOS,文件放到博客园下了。
FreeRTOS 心跳由滴答定时器产生,根据 FreeRTOS 的系统时钟节拍设置好滴答定时器的周期,这样就会周期触发滴答定时器中断了。在滴答定时器中断服务函数中调用FreeRTOS 的 API 函数 xPortSysTickHandler()。
如上1、2做完,工程添加完毕后编译:除图二错误可能还有中断函数重复定义等,因为RTOS里又定义了一次,把stm32f10x_it.c里的注释掉。
三、配置FreeRTOSConfig.h
实际使用中通过该文件完成裁剪和配置:INCLUDE 开头的宏表示使能或不使用对应的API函数。如图所示(部分):具体文件已保存到博客园文件下了,F1和F4均通用。
四、任务基础 (创建、删除、挂起、恢复)
1、简介:任何一个时间点只能有一个任务运行,由调度器决定,其职责是保证任务执行时的上下文环境 (寄存器值、堆栈内容等)和任务上一次退出时相同。为此,任务必须有其堆栈(保存上下文环境)。
2、特性:无限制、支持抢占、优先级,任务都有堆栈导致RAM增大,使用抢占须考虑重入问题。
3、状态:运行态、就绪态、阻塞态、挂起态。(由图可知,挂起态任务恢复后不是直接进到运行态,而是进到就绪态,阻塞态同理)
4、优先级:每个任务都能分配0~(configMAX_PRIORITIES-1)的优先级,共32级,0-31,数值越低优先级越低(与单片机中断优先级和UCOS相反),空闲任务优先级最低,为0。同一个优先级时通过时间片轮转调度器获取运行时间。
5、任务创建: xTaskCreate() 动态创建:任务所需RAM从RTOS堆中分配,需提供heap_4.c内存管理文件,宏 configSUPPORT_DYNAMIC_ALLOCATION 须为 1; xTaskCreateStatic() ;静态创建:RAM需用户提供。
创建的任务是就绪态,若没有比它高优先级的任务运行则立即进入运行态。不管调度器是否启用。
int main(void)
TaskHandle_t StartTask_Handler; //任务句柄 ----堆栈大小,优先级等也可以使用宏定义 ,如果没有其它API使用任务句柄也可以为NULL。任务创建定义在主函数最后面,则main.c不需要while(1)。
BaseType_t xTaskCreate( (TaskFunction_t )pxTaskCode, //任务函数 (动态创建) (实际参数如:stat_task)
(const char * )const pcName, //任务名字,一般用于追踪和调试,长度不超过configMAX_TASK_NAME_LEN (如:"stat_task")
(const uint16_t) usStackDepth, //堆栈大小,申请的实际字节为传入数据的4倍。空闲任务堆栈大小为:configMINIMAL_STACK_SIZE (如:128)
(void *) const pvParameters, //传递给任务函数的参数 (如:NULL)
(UBaseType_t) uxPriority, //任务优先级, 0~ configMAX_PRIORITIES-1 值越大优先级越高 (如:3)
(TaskHandle_t *) const pxCreatedTask ) // 成功返回句柄, 其实就是任务堆栈,堆栈就是保存任务句柄,其它API操作这个任务就是使用任务句柄 (如:&StartTask_Handler)
pdPASS :创建成功返回 errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY: 创建失败,堆内存不足(太大空间不够,太小任务创建失败) ,如下,除头文件外一个完整的main.c函数
#include "stm32f10x.h" #include "led.h" #include "usart.h" #include "delay.h" #include "FreeRTOS.h" #include "task.h" TaskHandle_t StartTask_Handler; void start_task(void *pvParameters); int main (void){ usart1_init(115200); led2_init (); delay_init(); xTaskCreate((TaskFunction_t )start_task, //创建开始任务 任务函数 (const char* )"start_task", //任务名称 (uint16_t )128, //任务堆栈大小 可使用宏 (void* )NULL, //传递给任务函数的参数 (UBaseType_t )1, //任务优先级 可使用宏 (TaskHandle_t* )&StartTask_Handler);//任务句柄 vTaskStartScheduler(); //开启任务调度 } void start_task(void *pvParameters){//开始任务任务函数 taskENTER_CRITICAL(); //进入临界区 //创建TASK1任务 xTaskCreate((TaskFunction_t )task1_task, (const char* )"task1_task", (uint16_t )128, (void* )NULL, (UBaseType_t )2, (TaskHandle_t* )&Task1Task_Handler); vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区 } void task1_task(void *pvParameters){ while(1){ LED2_ON; delay_ms(1000); LED2_OFF; vTaskDelay(1000); } }
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, //任务函数 (静态创建)
const char * const pcName, //任务名字
const uint32_t ulStackDepth, //任务堆栈大小,静态创建由用户给,一般是个数组,传入的参数就是数组大小
void * const pvParameters, //传递给任务函数的参数
UBaseType_t uxPriority, //任务优先级, 0~ configMAX_PRIORITIES-1
StackType_t * const puxStackBuffer, //任务堆栈,一般为数组,数组类型: StackType_t
StaticTask_t * const pxTaskBuffer ) //任务控制块
NULL:创建失败,puxStackBuffer 或 pxTaskBuffer 为 NULL时 其它值:任务创建成功,返回任务句柄
xTaskCreateRestricted() :此函数创建的任务会受到MPU的保护,要求MCU有MPU(内存保护单元),其它功能和 xTaskCreate() 一致。
6、任务删除:删除后不会进入运行态,也不能再使用任务句柄,动态创建的任务删除后空间被释放,但如果任务中调用 pvPortMalloc()分配的则删除任务后调用vPortFree()释放,否则内存泄漏。
vTaskDelete( TaskHandle_t xTaskToDelete ) 参数:要删除的任务句柄
7、任务挂起和恢复
a、挂起:void vTaskSuspend( TaskHandle_t xTaskToSuspend) 参数:要挂起的任务句柄 参数为NULL表示挂起任务自己。特性:恢复后任务中变量保存的值不变。
b、恢复:void vTaskResume( TaskHandle_t xTaskToResume) 参数:要恢复的任务句柄
c、恢复(中断版本):BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume) 用于在中断服务函数中恢复一个任务。
返回值pdTRUE:优先级 >= 正在运行的任务,退出中断函数后必须进行一次上下文切换。pdFALSE:优先级 < 正在运行的任务,退出中断函数后不用进行上下文切换。
五、任务查询、统计相关API(调试用)
1、vTaskList( char * pcWriteBuffer) 创建一个表格列出所有任务信息(任务名称,优先级,历史最低堆栈大小),参数:pcWriteBuffer :保存任务状态信息表的存储区,要大,可动态申请。返回值:无
Name: 创建任务的时候给任务分配的名字。 State: 任务的壮态信息,B 是阻塞态,R 是就绪态,S 是挂起态,D 是删除态。 Priority:任务优先级。 Stack: 任务堆栈的“高水位线”,就是堆栈历史最小剩余大小。 Num: 任务编号,这个编号是唯一的,当多个任务使用同一个任务名的时候可以通过此编号来做区分。 2、vTaskGetRunTimeStats() 提供了每个任务获取到CPU使用权的总时间。宏configGENERATE_RUN_TIME_STATS 和 configUSE_STATS_FORMATTING_FUNCTIONS 必须都为 1 还需实现几个宏定义: portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(),此宏用来初始化一个外设来 提供时间统计功能所需的时基,一般是定时器/计数器。此时基分辨率比 FreeRTOS的系统时钟高 10~20 倍就可以了。 portGET_RUN_TIME_COUNTER_VALUE()或者 portALT_GET_RUN_TIME_COUNTER_VALUE(Time),这两个宏实现其中一个就行了,这两个宏用于提供当前的时基的时间值。
标签:const,FreeRTOS,句柄,void,任务,堆栈,优先级 From: https://www.cnblogs.com/gengtongyu/p/17454598.html