RTOS精进(一):深入FreeRTOS内核

FreeRTOS简介与移植到STM32F103 直接对硬件资源进行编程,将所有的功能函数都放在主循环中,同一时间内只能运行单一任务。裸机系统又称:前台系统即中断服务函数,后台系统即运行的主循环。 阅读详情

深入FreeRTOS内核

目录

FreeRTOS基础

  • 见下图,下图有可能不是最新的, 最新文件见FreeRTOS.xmind

在这里插入图片描述

  • 互斥量、互斥锁,本来的概念确实是:谁上锁就得由谁解锁。** (放到xmind中)**
    但是FreeRTOS并没有实现这点,只是要求程序员按照这样的惯例写代码。韦东山freeRTOS系列教程之【第七章】互斥量(mutex)_悦己之作,方能悦人的技术博客_51CTO博客
  • vTaskStartScheduler调用后,才开始调度
  • FreeRTOS操作系统支持三种调度方式:抢占式调度(Pre-emptive),时间片调度(time slice , 同优先级任务才会是使用时间片调度)和合作式调度(co-operative, 使用合作调度器时,只有在Running状态任务进入Blocked状态,或者Running状态任务通过调用taskYIELD()显式让步(手动请求重新调度)时才会发生任务切换。)。实际应用主要是抢占式调度和时间片调度结合的调度方法,合作式调度用到的很少。

学习总结

任务创建

FreeRTOS的任务(其实就是线程)创建, 会创建在堆区划分一块空间, 这块空间用来放置TCB和任务栈空间 , 栈空间就是申请的栈大小, 这个TCB就是一个结构体, 用于记录优先级,运行时间,运行状态等信息。 结构体定义如下

/*
 * Task control block.  A task control block (TCB) is allocated for each task,
 * and stores task state information, including a pointer to the task's context
 * (the task's run time environment, including register values)
 */
typedef struct tskTaskControlBlock
{
    /* 栈顶<元素>指针,注意与 pxEndOfStack 的区别。 必须是结构体的第一个成员. */
    volatile StackType_t * pxTopOfStack; 

    /* MPU 模块设置,必须是结构体的第二个成员 */
    #if ( portUSING_MPU_WRAPPERS == 1 )
        xMPU_SETTINGS xMPUSettings;
    #endif

    ListItem_t xStateListItem;                  /* 列表项指示任务当前的状态 (Ready, Blocked, Suspended ). */
    ListItem_t xEventListItem;                  /* 用于在事件列表中. */
    UBaseType_t uxPriority;                     /* 任务优先级(0为优先级最低). */
    StackType_t * pxStack;                      /* 栈底指针,指向栈开始处. */
    char pcTaskName[ configMAX_TASK_NAME_LEN ]; /* 任务名 */

    /* 如果栈向上生长,则定义栈顶指针 */
    #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
        StackType_t * pxEndOfStack; 
    #endif

    #if ( portCRITICAL_NESTING_IN_TCB == 1 )
        UBaseType_t uxCriticalNesting; /* 保存临界区的栈深度. 在函数vTaskEnterCritical() 和 vTaskExitCritical()中会维护这个值*/
    #endif

    #if ( configUSE_TRACE_FACILITY == 1 )
        UBaseType_t uxTCBNumber;  /*TCB的编号,每次增加一个task,TCB的编号就会增加. */
        UBaseType_t uxTaskNumber; /*task的编号,其值和uxTCBNumber相等,可用于调试追踪. */
    #endif

    #if ( configUSE_MUTEXES == 1 )
        UBaseType_t uxBasePriority; /*上一次分配给该任务的优先级,用于优先级继承机制. */
        UBaseType_t uxMutexesHeld; /* 持有的信号量 */
    #endif

    #if ( configUSE_APPLICATION_TASK_TAG == 1 )
        TaskHookFunction_t pxTaskTag;
    #endif

    /* 存储一些私有的变量 */
    #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
        void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
    #endif

    /* task 运行的总时间 */
    #if ( configGENERATE_RUN_TIME_STATS == 1 )
        uint32_t ulRunTimeCounter; 
    #endif

    /*  See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html for additional information. */
    #if ( configUSE_NEWLIB_REENTRANT == 1 )
        struct  _reent xNewLib_reent;
    #endif

    /* 任务通知相关变量 */
    #if ( configUSE_TASK_NOTIFICATIONS == 1 )
        volatile uint32_t ulNotifiedValue[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
        volatile uint8_t ucNotifyState[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
    #endif

    /* FreeRTOS.h 中有关于 tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE 的详细注释。主要的作用是决定task创建的资源是动态还是静态分配内存. */
    #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) 
        uint8_t ucStaticallyAllocated; /* 标记stack 和 TCB分配方式,在删除任务时,根据此标志来对应释放内存 */
    #endif

    /* delay 终止标志 */
    #if ( INCLUDE_xTaskAbortDelay == 1 )
        uint8_t ucDelayAborted;
    #endif

    /* error number*/
    #if ( configUSE_POSIX_ERRNO == 1 )
        int iTaskErrno;
    #endif
} tskTCB;
这里有必要跟linux进行区分下, 在linux中(从 Linux 内核的角度来说,其实它并没有线程的概念。Linux 把所有线程都当做进程来实现,它将线程和进程不加区分的统一到了 task_struct 中。线程仅仅被视为一个与其他进程共享某些资源的进程,而是否共享地址空间几乎是进程和 Linux 中所谓线程的唯一区别), 另外线程的栈是从进程地址空间mmap一段独有的地址(堆和栈之间有一段空间是用于mmap的), 另外在每一个进程的生命周期中,必然会通过到系统调用陷入内核。在执行系统调用陷入内核之后,这些内核代码所使用的栈并不是原先进程用户空间中的栈,而是一个单独内核空间的栈,这个称作进程内核栈。进程内核栈在进程创建的时候
内存管理

FreeRtos的堆区分配方法共有4种, 第一种, 我的理解就是一个数组, 从从未分配过的地方开始进行分配, 无法被释放,没有内存释放, 好处是可确定性, 且没有碎片。例子: 已经分配 ABC , 如果要分配D, 则从C后面分配D, 变成ABCD。 并且分配后都无法释放, 因为没有释放函数

第二种方法,已经被heap4.c取代了, 了解下就好。 有释放函数, 分配时, 从最开始的地址开始找, 找到一个空闲块可以容纳就放。 例子, 一开始ABD,后面B释放了, 变为A空格D, 这个要分配C, C比B小, 则从一开始找, 找到了B能放下, 则就变为AC(B-C)D 。 实现上, 就是用一个链表来记录空闲块, 一开始链表只有一个(块大小为分配的堆总大小), 对于AC(B-C)D , 则变为 两个元素的链表, B-C是一个, D后面又是一个。

第三种方法,其实就是调用malloc和free, 具体实现由编译器来实现, 这里仅仅只是封装了一下malloc和free,并确保线程安全

第四种方法,heap_4.c, 就是在free一块空闲内存时, 如果左和右相邻 有空闲块, 则把空闲块合为一个, 方法为将当前空想块插入链表时,查看左边和右边空闲块地址是否相邻,是的话,合并就可以了。

第五种方法, heap_5.c , 用的就是heap4.c的方法, 但是支持不相邻的堆区, 类似于支持多个堆区

FreeRTOS的调度分为三种, 抢占式时间片(就是谁优先级高谁执行,相同优先级则轮流执行), 抢占式无时间片(谁优先级高谁执行, 相同优先级则谁先谁执行),合作模式(非抢占, 高优先级不抢占,等低优先级执行完或者阻塞后再轮到高优先级)

软件定时器
  • FreeRTOS 通过一个prvTimerTask任务(也叫守护任务Daemon)管理软定时器,它是在启动调度器时自动创建的,为了满足用户定时需求。prvTimerTask任务会在其执行期间检查用户启动的时间周期溢出的定时器,并调用其回调函数。只有设置 FreeRTOSConfig.h 中的宏定义configUSE_TIMERS设置为1 ,将相关代码编译进来,才能正常使用软件定时器相关功能
  • 指定时间到达后要调用回调函数(也称超时函数),用户在回调函数中处理信息, 在回调函数中调用任何会阻塞任务的 API 函数
  • 硬件定时器的定时精度与系统时钟的周期有关,一般系统利用SysTick作为软件定时器的基础时钟,系统节拍配置为FreeRTOSConfig.h中的configTICK_RATE_HZ,默认是1000,那么系统的时钟节拍周期就为1ms
  • FreeRTOS 提供的软件定时器支持单次模式和周期模式

LiteOS、RT-thread、FreeRTOS、uCOS II的区别

一、freeRTOS比uCOS II优胜的地方:

1。内核ROM和耗费RAM都比uCOS 小,特别是RAM。 这在单片机里面是稀缺资源,uCOS至少要5K以上, 而freeOS用2~3K也可以跑的很好。

2。freeRTOS 可以用协程(Co-routine)(目前官方已经废弃了,不再维护),减少RAM消耗(共用STACK)。uCOS只能用任务(TASK,每个任务有一个独立的STACK)。

3。freeRTOS 可以有优先度一样的任务,这些任务是按时间片来轮流处理,uCOSII 每个任务都只有一个独一无二的优先级。因此,理论上讲,freeRTOS 可以管理超过64个任务,而uCOS只能管理64个。

4。freeRTOS 是在商业上免费应用。uCOS在商业上的应用是要付钱的。

二、freeRTOS 不如uCOS的地方:

1。比uSOS简单,任务间通讯freeRTOS只支持Queque, Semaphores, Mutex。 uCOS除这些外,还支持Flag, MailBox.

2。uCOS的支持比freeRTOS 多。除操作系统外,freeRTOS只支持TCPIP, uCOS则有大量外延支持,比如FS, USB, GUI, CAN等的支持

3。uCOS可靠性更高,而且耐优化,freeRTOS 在我设置成中等优化的时候,就会出问题。

参考资料

FreeRTOS从基础到高级 - 极术社区 - 连接开发者与智能计算生态 极术社区致力于连接开发者与智能计算生态。提供人工智能、物联网、嵌入式开发、SoC芯片设计、自动驾驶、服务器与云计算等智能计算技术领域的资讯、知识及教育培训、会议活动,与合作伙伴共建中国智能计算生态。 https://aijishu.com/blog/freertoscongjich

FreeRTOS 从入门到精通1–实时操作系统的前世今生 专栏前言笔者计划用一些篇幅介绍当前在嵌入式系统中比较流行的开源实时操作系统FreeRTOS及其在意法半导体 STM32平台,乐鑫科技ESP32平台和Arduino平台上的开发与运用。在当前工业4.0,智能制造,物联网IoT和工业物… https://zhuanlan.zhihu.com/p/90608412

FreeRTOS Plus TCP - A free thread aware TCP/IP stack for FreeRTOS FreeRTOS+TCP is a free and fully thread aware TCP/IP implementation with a Berkeley sockets style interface for FreeRTOS https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html

任务管理 — FreeRTOS内核实现与应用开发实战指南—基于STM32 文档 https://doc.embedfire.com/rtos/freertos/zh/latest/application/tasks_management.html

FreeRTOS内核实现与应用开发实战指南

FreeRTOS入门笔记——FreeRTOS介绍 FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。 阅读详情

相关推荐

FreeRTOS操作系统介绍

第3章 FreeRTOS(读作"free-arr-toss")是一个嵌入式系统使用的开源实时操作系统。FreeRTOS被设计为“小巧,简单,和易用”,能支持许多不同硬件架构以及交叉编译器。 FreeRTOS自2002年Richard Barry开始开发以来,一直都在积极开发中。至于我,我不是FreeRTOS的开发人员或贡献者,我只不过是一个最终用户和爱好者。因此,这章...

有趣的人生 一半是山川湖海 一半是初心情怀 6292

FreeRTOS(教程非常详细)

FreeRTOS基于STM32实时操作系统教程(非常详细)

qq_61672347的博客 50万+

STM32之RTOS:uCOS和FreeRTOS

STM32之RTOS:uCOS和FreeRTOS

qq_28576837的博客 1万+

一、FreeRTOS之FreeRTOS简介

一、什么是FreeRTOS?Free即免费的,RTOS的全称是Real time operating system,中文就是实时操作系统。注意:RTOS不是指某一个确定的系统,而是指一类操作系统。比如:uc/OS,FreeRTOS,RTX,RT-Thread等这些都是RTOS类操作系统。操作系统允许多个任务同时运行,这个叫做多任务。实际上,一个处理器核心在某一时刻只能运行一个任务。操作系统中任务调度器的责任就是决定在某一时刻究竟运行的哪个任务。任务调度在各个任务之间的切换非常快,就给人们造成了同一时刻有多个

王同学 2万+

解读RTOS 第八篇 · 内核源码解读:以 FreeRTOS 为例

本章将带你以 FreeRTOS 10.x 版本为例,逐层剖析源码结构与关键算法,并在每个模块中插入 PlantUML 流程图帮助可视化理解,最终展示一个精简版内核定制示例。

hemoparrot的专栏 1969

学习FreeRTOS之路(一):RTOS基础介绍,与FreeRTOS的变量类型、命名规范

前言: 依照惯例,还是自我发挥几句,ESP32的学习大致告一段落,正如我的博客更新状态,目前正在ESP32项目实践。在裸机系统里,所有的操作都是在一个无限的大循环中实现的。编写代码的过程中,确实觉得功能和功能之间的架构,关系,时序等,单纯的用裸机系统来运行太过麻烦,代码、算法等也很臃肿繁琐。 在esp32技术交流群的大触的建议下,我开始接触RTOS(Real Time Operating System 实时操作系统)。 顺便开一个新专栏,记录点笔记。 以上… 基础介绍 为什么要学习RTOS? 在裸机系统中,

Newbie_H的学习之路 3454

[RTOS]uCOS、FreeRTOS、RTThread、RTX等RTOS的对比之特点

[RTOS]–uCOS、FreeRTOS、RTThread、RTX等RTOS的对比之特点  最近正好又重新回顾了一下这几款OS,心里一直有个疑问,明明这几款RTOS是这么像,为什么还要搞出这么多个来呢,最后的结论就是,管他呢,反正那个用的顺手用哪个。   本篇博客就来细数这几个RTOS的特点。   以下内容均来自官方网站或者官方手册Feature的Google翻译的加了我的一些调整,没有任何主...

wangyijieonline的博客 7万+

第 82 天:主流 RTOS 简介与对比:FreeRTOS、RT-Thread、Zephyr 的工程实战选择分析

当前嵌入式开发领域,实时操作系统(RTOS)已成为构建稳定、多任务并发系统的关键基础设施。FreeRTOS、RT-Thread 与 Zephyr 是国内外主流的三大 RTOS 选项,分别在资源占用、硬件适配、组件体系与生态支持等方面形成鲜明特色。本文基于实际项目开发与硬件平台部署经验,从内核机制、任务调度模型、适配平台、工程易用性、学习曲线等多个维度展开系统对比,为工程师提供真实可靠的选型依据,并结合近年行业主流芯片厂商 SDK 集成情况,分析每种 RTOS 的落地现状与最佳实践场景。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 3170

【RTOS学习】CubeMX对FreeRTOS的适配

介绍了CubeMX对FreeRTOS的适配,CMSIS工具简介,以及如何创建任务,队列,信号量,互斥量,事件组,软件定时器和如何实现任务通知等内容。

weixin_63726869的博客 4368

如何学习RTOS

RT-Thread这个系统还是有很多自己的想法在里面的,比如Finish,设备树等都是参照Linux的思想来设计的。

Maril02的博客 3815

FreeRTOS学习笔记—CM4内核中断在RTOS中的使用方法

最近要移植FreeRTOS操作系统,这也是个学习的过程,在此以笔记的形式记录下来。本篇文章主要是谈Cortex-M4内核中断的一些概念以及其在FreeRTOS中的使用方法,部分内容摘自《Cortex-M3权威指南(宋岩译)》,在此向作者表示感谢。1 优先级值和逻辑优先级首先要解释一下优先级值和逻辑优先级:在Cortex-M内核中,假如有8级优先级,我们说优先级值是0~7,但数值最大的优先级7却代表着

hkchenhao的博客 4992

freertos与CMSIS-RTOS v2

CMSIS-RTOS是ARM提供的实时操作系统通用API,旨在统一不同RTOS的接口,提高嵌入式开发效率和代码移植性。它封装了FreeRTOS等RTOS内核,使开发者能够使用标准化接口调用底层功能,实现任务创建、队列管理、信号量、互斥量、事件组等核心功能。CMSIS-RTOS通过任务通知、软件定时器等机制优化性能,并支持中断管理,确保实时性。其优势包括降低开发门槛、增强代码可重用性,同时保持对原生RTOS功能的兼容性。该框架特别适合需要快速开发和多平台移植的嵌入式应用场景。

2503_90357516的博客 4013

freeRtos源码解析(一)--RTOS概念以及任务创建

freeRtos源码解析(一)–任务创建与任务调度 一、简介 1.1 代码来源及版本 代码来源于STM32CubeIDE工具一键生成功能,对应freeRtos版本为 FreeRTOS Kernel V10.2.1。对应MCU型号为STM32MP157D cortex-M4. 生成的中间层代码以及源码目录如下: 1.2 学习参考 学习参考:[野火®]《FreeRTOS 内核实现与应用开发实战—基于STM32》 ...

chenlonglong2014的博客 2167

Zephyr RTOS与FreeRTOS的区别详解

内核架构是指实时操作系统(RTOS)的核心设计框架,决定了任务调度、内存管理、中断处理等核心机制的组织方式。在Zephyr和FreeRTOS中,内核架构直接影响系统的实时性、可扩展性和资源占用。内存管理架构是实时操作系统(RTOS)中用于高效分配、释放和管理系统内存资源的机制。在Zephyr和FreeRTOS中,内存管理架构的设计直接影响系统的确定性、碎片化程度以及实时性能。特性ZephyrFreeRTOS默认动态分配禁用(需显式配置)启用碎片处理Slab分配器或Buddy System。

weixin_43484713的博客 3305

【FreeRTOS】——裸机/RTOS开发&FreeRTOS&任务调度/任务状态&源码与移植

​ FreeRTOS 是市场领先的面向微控制器和小型微处理器的实时操作系统(RTOS),FreeRTOS 通过 MIT 开源许可免费分发,包括一个内核和一组不断丰富的 IoT 库,适用于所有行业领域。FreeRTOS 的构建强调可靠性和易用性。 ​

weixin_51658186的博客 4874

快手did did_gt edid的注册过程

接口 https://gdfp.ksapisrv.com/rest/infra/gdfp/report/kuaishou/android did 是本地生成的16进制 或者 获取的 android_id did_gt 是did生成时间戳 1595073601970 public static final Random f16237a = new Random(System.currentTimeMillis()); public static long m19668a() {  &n

HURUWO的技术博客 1万+

FreeRTOS(1)---FreeRTOS 内核配置说明

FreeRTOS 内核配置说明FreeRTOS 内核配置FreeRTOS 配置文件FreeRTOS 配置说明 FreeRTOS 内核配置 FreeRTOS内核是高度可定制的,使用配置文件FreeRTOSConfig.h进行定制。每个FreeRTOS应用都必须包含这个头文件,用户根据实际应用来裁剪定制FreeRTOS内核。这个配置文件是针对用户程序的,而非内核,因此配置文件一般放在应用程序目录下,不...

InfiniteYuan 3399

STM32CubMX_MQ135检测空气质量

一、MQ135简介 MQ135是测量空气污染情况常用的一个传感器,具有代表性,价格低,寿命长,敏感度也OK,主要用于测量空气中二氧化碳,氮氧化物,氨气,酒精,苯类等。这几样气体可以说都属于家用空气污染测定中的重要成份,因此用这个传感器刚刚好。 MQ135气体传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(SnO2)。当传感器所处环境中存在污染气体时,传感器的电导率随空气中污染气体浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。 注: pm2.5的话要用另外类型

W_Oilpicture的博客 3万+

FreeRTOS:在ARM Cortex-M内核上运行RTOS

注意:以下关于中断嵌套的信息适用于Cortex-M3、Cortex-M4、Cortex-M4F和Cortex-M7,不适用于Cortex-M0或者Cortex-M+等不包括BASEPRI寄存器的内核。 介绍 数以千计的应用在ARM Cortex-M内核上运行FreeRTOS。令人吃惊的是,很少有关于这个RTOS和ARM Cortex内核组合的技术支持请求。但是,确实存在大量由于不正确设置中断优...

lf9335的专栏 3310

Vivado静态时序分析学习笔记(1)

静态时序分析分为片内时序分析(寄存器与寄存器之间的时序关系)和片外时序分析(IO时序分析)。(1)建立时间 setup time在时钟事件(上升沿/下降沿)发生之前数据信号应保持稳定的时间。把实际电路抽象成前级D触发器+组合逻辑+后级D触发器。

Fantaasky的博客 4376

游戏开发:逻辑与渲染分离技术解析

游戏开发中逻辑与渲染分离的架构设计 本文系统阐述了游戏开发中逻辑与渲染分离的设计原则与实践方法。文章首先定义了核心概念:逻辑层负责游戏规则与状态,渲染层处理视觉表现,二者通过数据模型层进行通信。通过历史回顾,揭示了从早期混合架构到现代分层设计的演变过程。 在技术实现层面,文章详细分析了分离架构的优势:性能优化、流畅度控制、测试便利性、扩展灵活性以及团队协作效率。提供了Unity和Unreal两大引擎的具体实现方案,包括代码示例、分层模型和最佳实践。特别探讨了网络同步、客户端预测、插值处理等关键技术难点。 文

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 1060
上一篇: RTOS精进(二):FreeRTOS 系统移植
下一篇: RTOS精进(三):Linux下模拟FreeRTOS收发网络包
文可道
博客等级 码龄14年 576粉丝 57原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值