• FreeRTOS实时操作系统 —基于STM32


    RTOS背景知识介绍

    在这里插入图片描述
    前在使用 51、AVR、STM32 单片机裸机(未使用系统)的时候一般都是在main 函数里面用 while(1)做一个大循环来完成所有的处理,即应用程序是一个无限的循环,循环中调用相应的函数完成所需的处理。有时候我们也需要中断中完成一些处理。相对于多任务系统而言,这个就是单任务系统,也称作前后台系统,中断服务函数作为前台程序,大循环while(1)作为后台程序。

    前后台系统的实时性差,前后台系统各个任务(应用程序)都是排队等着轮流执行,不管你这个程序现在有多紧急,没轮到你就只能等着!相当于所有任务(应用程序)的优先级都是一样的。但是前后台系统简单啊,资源消耗也少啊!在稍微大一点的嵌入式应用中前后台系统就明显力不从心了,此时就需要多任务系统出马了。

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    多任务系统会把一个大问题(应用)“分而治之”,把大问题划分成很多个小问题,逐步的把小问题解决掉,大问题也就随之解决了,这些小问题可以单独的作为一个小任务来处理。这些小任务是并发处理的,注意,并不是说同一时刻一起执行很多个任务,而是由于每个任务执行的时间很短,导致看起来像是同一时刻执行了很多个任务一样。多个任务带来了一个新的问题,究竟哪个任务先运行,哪个任务后运行呢?完成这个功能的东西在 RTOS 系统中叫做任务调度器。不同的系统其任务调度器的实现方法也不同,比如 FreeRTOS 是一个抢占式的实时多任务系统,那么其任务调度器也是抢占式的。

    在这里插入图片描述

    在这里插入图片描述

    FreeRTOS官网在这里插入图片描述

    FreeRTOS在STM32F4xx上的移植

    下载FreeRTOS源文件
    配置文件

    FreeConfig.h配置文件

    INCLUDE
    Config文件

    FreeRTOS 任务基础知识

    在使用 RTOS 的时候一个实时应用可以作为一个独立的任务。每个任务都有自己的运行环境,不依赖于系统中其他的任务或者 RTOS 调度器。

    任何一个时间点只能有一个任务运行,具体运行哪个任务是由 RTOS 调度器来决定的,RTOS 调度器因此就会重复的开启、关闭每个任务。

    任务不需要了解 RTOS 调度器的具体行为,RTOS 调度器的职责是确保当一个任务开始执行的时候其上下文环境(寄存器值,堆栈内容等)和任务上一次退出的时候相同。

    为了做到这一点,每个任务都必须有个堆栈,当任务切换的时候将上下文环境保存在堆栈中,这样当任务再次执行的时候就可以从堆栈中取出上下文环境,任务恢复运行。

    任务特性:

    • 简单
    • 没有使用限制
    • 支持抢占
    • 支持优先级
    • 每个任务都拥有堆栈导致了ARM使用量增大
    • 如果使用抢占,必须仔细考虑重入的问题

    任务状态:

    FreeRTOS 中的任务永远处于下面几个状态中的某一个:
    在这里插入图片描述

    在这里插入图片描述

    优先级:

    每 个 任 务 都 可 以 分 配 一 个 从 0~31 (configMAX_PRIORITIES-1) 的 优 先 级,configMAX_PRIORITIES 在文件 FreeRTOSConfig.h 中有定义。
    在这里插入图片描述

    数字越大,优先级越高。优先级数字越低表示任务的优先级越低,0 的优先级最低,configMAX_PRIORITIES-1 的优
    先级最高。空闲任务的优先级最低,为 0

    FreeRTOS 调度器确保处于就绪态或运行态的高优先级的任务获取处理器使用权,换句话说就是处于就绪态的最高优先级的任务才会运行。当宏 configUSE_TIME_SLICING 定义为 1 的时候多个任务可以共用一个优先级,数量不限。默认情况下宏 configUSE_TIME_SLICING 在文件FreeRTOS.h 中已经定义为 1。此时处于就绪态的优先级相同的任务就会使用时间片轮转调度器获取运行时间。

    任务实现

    任务控制块

    任务堆栈

    示例:

    #include "system.h"
    
    //Task priority    //任务优先级
    #define START_TASK_PRIO	1
    
    //Task stack size //任务堆栈大小	
    #define START_STK_SIZE 	256  
    
    //Task handle     //任务句柄
    TaskHandle_t StartTask_Handler;
    
    //Task function   //任务函数
    void start_task(void *pvParameters);
    
    //Main function //主函数
    int main(void)
    { 
      systemInit(); //Hardware initialization //硬件初始化
    	
    	//Create the start task //创建开始任务
    	xTaskCreate((TaskFunction_t )start_task,            //Task function   //任务函数
    							(const char*    )"start_task",          //Task name       //任务名称
    							(uint16_t       )START_STK_SIZE,        //Task stack size //任务堆栈大小
    							(void*          )NULL,                  //Arguments passed to the task function //传递给任务函数的参数
    							(UBaseType_t    )START_TASK_PRIO,       //Task priority   //任务优先级
    							(TaskHandle_t*  )&StartTask_Handler);   //Task handle     //任务句柄    					
    	vTaskStartScheduler();  //Enables task scheduling //开启任务调度	
    }
     
    //Start task task function //开始任务任务函数
    void start_task(void *pvParameters)
    {
        taskENTER_CRITICAL(); //Enter the critical area //进入临界区
    	
        //Create the task //创建任务
    	  xTaskCreate(Balance_task,  "Balance_task",  BALANCE_STK_SIZE,  NULL, BALANCE_TASK_PRIO,  NULL);	//Vehicle motion control task //小车运动控制任务 任务优先级BALANCE_TASK_PRIO = 4
    	  xTaskCreate(ICM20948_task, "ICM20948_task", ICM20948_STK_SIZE, NULL, ICM20948_TASK_PRIO, NULL);	//IMU data read task //IMU数据读取任务 任务优先级为3
        xTaskCreate(show_task,     "show_task",     SHOW_STK_SIZE,     NULL, SHOW_TASK_PRIO,     NULL); //The OLED display displays tasks //OLED显示屏显示任务 任务优先级为3
        xTaskCreate(led_task,      "led_task",      LED_STK_SIZE,      NULL, LED_TASK_PRIO,      NULL);	//LED light flashing task //LED灯闪烁任务 任务优先级为3
        xTaskCreate(pstwo_task,    "PSTWO_task",    PS2_STK_SIZE,      NULL, PS2_TASK_PRIO,      NULL);	//Read the PS2 controller task //读取PS2手柄任务  任务优先级为4 
        xTaskCreate(data_task,     "DATA_task",     DATA_STK_SIZE,     NULL, DATA_TASK_PRIO,     NULL);	//Usartx3, Usartx1 and CAN send data task //串口3、串口1、CAN发送数据任务 优先级为4
    	  
    	  // 删除任务
        vTaskDelete(StartTask_Handler); //Delete the start task //删除开始任务
    
        taskEXIT_CRITICAL();            //Exit the critical section//退出临界区
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    任务创建和删除

    在这里插入图片描述
    在这里插入图片描述

    参考资料

  • 相关阅读:
    图解Mysql索引原理
    13 redis中的复制的拓扑结构
    uniapp图片加水印
    小白学流程引擎-FLowable(一) —FLowable是什么
    实验过程中的问题记录
    在Android项目中使用SpringBoot框架
    字符串的转换路径问题
    CUDA By Example(六)——纹理内存
    基于KT6368A的车载OBD蓝牙芯片模块解决方案低成本国产替代
    中国工业企业数据库(2015年)
  • 原文地址:https://blog.csdn.net/Naiva/article/details/123476581