首页 > 其他分享 >FreeRTOS

FreeRTOS

时间:2023-06-06 20:37:14浏览次数:37  
标签:const FreeRTOS 句柄 void 任务 堆栈 优先级

一、简介 、特点

  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

相关文章

  • FreeRtos的移植,以及一些嵌入式学习心得。
    不得不先提心得。这不是第一次移植FreeRtos,至少是五六七八九次了,当然也不是最后一次。但是每一次移植其实都差不多,并没有什么得心应手的感觉。原因就是学的东西太多,学的太杂。我不得不承认,就算我天资聪慧,异于常人,记这么多知识是不可能的。人力有穷时。尊重这个客观现实,但不放......
  • FreeRTOS 信号量
    二值信号量  二值信号量通常用于互斥访问或同步,二值信号量和互斥信号量非常类似,但是还是有一些细微的差别,互斥信号量拥有优先级继承机制,二值信号量没有优先级继承。  和队列一样,信号量API函数允许设置一个阻塞时间,阻塞时间是当任务获取信号量的时候由于信号量无效从而导致......
  • FreeRTOS 任务
    使用RTOS时,一个实时任务可以作为一个独立的任务,任何一个时间点只有一个任务运行,具体由RTOS调度器决定。RTOS调度器的职责是确保当一个任务开始执行的时候上下文环境与上一次推出的时候相同,每个任务都有堆栈,任务切换的时候将上下文保存在堆栈中。任务特性:1、简单2、没有使用限......
  • FreeRTOS应用基础(一)
      本系列主要作为自己第一次系统学习RTOS的记录,以正点原子的STM32F103战舰,keil环境编程为例。想要达到以下目标:  1:初步熟悉FreeRTOS的移植和使用,并迁移完成一个小型项目;  2:以FreeRTOS为入门,了解RTOS的本质,并提升阅读源码的能力;  本系列文章主要参考以下资料,本文仅作为......
  • FreeRTOS移植
    一、 二、1.在项目新建文件夹FreeRTOS,把FreeRTOSv202112.00\FreeRTOS\Source所有文件拷贝到新建的文件夹。 2.STM32F40x_FreeRTOS_Test\FreeRTOS\portable,protable中保留如下三个文件,其它删除掉 ......
  • #FREERTOS的和heap_4内存分配算法
    FreeRTOS的heap_4内存管理算法具有内存碎片合并的功能,可以有效防止内存碎片产生,使用Firstfit算法,在实现上与C标准库的malloc类似,但是效率更高且能进行碎片合并回收。以下是个人对源码的解析,有空再补充详细。一、初始化staticvoidprvHeapInit(void){BlockLink_t*pxF......
  • freeRTOS任务死锁
    一、freeRTOS任务死锁FreeRTOS任务死锁是一种常见的问题,通常发生在多个任务相互等待对方释放资源的情况下。以下是一个简单的例子,用于说明FreeRTOS任务死锁的情况:假设有两个任务Task1和Task2,它们需要共享两个资源ResourceA和ResourceB。每个任务都需要同时访问这两个资源才能完成它......
  • STM32移植FreeRTOS
    前言以前在学校做项目的时候,无论是智能车还是电赛,写代码有个习惯,就是把不同的功能的函数,都写成一个函数接口,最后全部在主函数里创建个while循环反复调用。intmain(void)......
  • 全志R128芯片 如何在FreeRTOS下对代码源文件进行快速预处理?
    1.主题FreeRTOS_R128_如何对代码源文件进行快速预处理2.问题背景硬件:R128软件:FreeRTOS客户在日常的开发过程中,会碰到源文件中有许多的宏或许多条件编译的代码,有时候需......
  • 一文掌握Zephyr入门(含FreeRTOS对比)
    前言本文将介绍 Zephyr RTOS 的基础信息,讲解初步接触学习Zephyr 需要了解掌握的知识与学习路线,让大家先快速构建起对这个操作系统的认知,文中还会与传统常见的RTOS ,如Fr......