FreeRTOS【面试】实时操作系统的知识总结

  • RTOS的实时性是如何实现的?

  • 任务之间是如何通信的?

  • 二值信号量与互斥信号量的区别?

  • 优先级反转?如何解决优先级反转问题?

  • 任务通知是怎么实现的?

  • 框架性的回答一个嵌入式系统Freertos的启动到结束的过程?

  • 任务切换的原理?  

  • 除了任务切换对freertos其他底层了解吗?

  • 讲讲FreeRTOS任务调度的原理  

  • 如何实现一个队列?

  • 说一下互斥量和条件变量?(这个问题可能在Linux系统里面体现得要好一些)  

  • Switch_contex的底层原理? 一般面试官会问你,freertos的中断服务函数有哪些?  

  • 简述FreeRTOS的任务调度?  - 简述FreeRTOS的移植流程?  - FreeRTOS中的IPC通信有哪些  - FreeRTOS中的tickless模式是什么?  

  • 如何在FreeRtos中创建任务  

  • FreeRTOS如何管理内存?  

  • 如何配置FreeRTOS的内核?  

  • FreeRTOS的软件定时器是什么,他们如何工作。  

  • 中断和任务有哪些主要区别?  

  • Freertos中的任务栈是什么,它如何初始化 请解释任务栈的左右以及他在FreeRTOS中是如何初始化的。  

  • 裸机开发和RTOS开发的区别?  

  • 为什么会在项目中使用RTOS?  

  • FreeRTOS的启动流程?

  • freertos中EventBits_t是干啥的?  

  • 消息队列的具体实现  - Freertos的多任务同步机制列举  

  • 堆和栈的区别,程序存放状态和区  

  • 什么是死锁,死锁产生的原因?如何避免?  

  • 在任务中怎么进行数据传输,什么方式  

  • 嵌入式操作系统的硬实时和软实时如何理解  

  • 任务通知

  • RTOS的实时性是如何实现的?

    • 1.一个处理器核心在某个时刻只能处理一个任务,操作系统中的任务调度器就是决定在某一时刻运行哪个任务。

    • 2.实时操作系统都要包含一个实时任务调度器,和其他操作系统最大的不同就是强调:严格按照优先级来分配CPU的运行时间,并且时间片轮转并不是实时调度器的一个必选项。

    • 3.FreeRTOS是一款支持多任务实时运行的实时操作系统,具有时间片、抢占式、合作式三种调度方式。

      • 合作式调度:曾用在资源有限的设备上面,随着系统版本的更新已经不再支持
      • 抢占式调度:每个任务都有不同的优先级,任务会一直运行直到高优先级任务抢占低优先级任务或者当前优先级任务主动释放CPU的执行权限(进入阻塞状态)使处于低优先级的任务得以执行,阻塞API如vTaskDelay
      • 时间片调度:每个任务都是相同的优先级,任务会运行固定的时间片个数或者遇到阻塞式API函数才会执行相同优先级的任务之间的任务切换
    • 4.使用了抢占式任务调取器,最高优先级的任务一旦就绪,就可以总能得到CPU的控制权。最高优先级的任务什么时候可以得到CPU的控制权并运行是已知的,同时使得任务响应时间得以最优化。

  • 任务之间是如何通信的?

    • FREERTOS的所有通信和同步机制都是基于队列(FIFO)实现的,但是也可以使用 LIFO 的存储缓冲,也就是后进先出,FreeRTOS 中的队列也提供了 LIFO 的存储缓冲机制

    • 队列:数据结构中的一个概念,最大的特性是先进先出的,是任务到任务,任务到中断,中断到任务数据交流的一种机制(消息传递)

    • 队列的特点

      • 多任务访问
      • 出队阻塞
      • 入队阻塞
    • 队列创建:动态创建和静态创建 API

      • • xQueueCreateStatic()
        • xQueueCreate()
        • xQueueGenericCreate()

    • 队列初始化

      • prvInitialiseNewQueue()
    • 对列入队与出队

  • 二值信号量与互斥信号量的区别?

    • 信号量常常用于控制对共享资源的访问和任务同步

    • 二值信号量常用于互斥访问和任务同步、互斥信号量拥有优先级继承机制、二值信号量没有优先级继承机制

    • 互斥信号量适用于简单的互斥访问 互斥信号量拥有优先级继承机制,尽可能的降低了高优先级任务处于阻塞态的时间,并将已经出现的优先级反转影响降到最低

  • 优先级反转?

    •  优先级反转 多线程的环境下并且使用了信号量时,出现了不合理的现象,

  • 如何解决优先级反转问题?

    • 优先级继承

      • 低优先级线程在获得同步资源的时候(如果有高优先级的线程也需要使用该同步资源时),临时提升其优先级。
    • 资源的优先级天花板

      • 当线程申请某共享资源的时候,把该线程的优先级提升到可访问这个资源的最高优先级的运行,只要线程访问共享资源都会提升线程的优先级
  • 任务通知是怎么实现的?

    • 任务通知的简介:

      • FreeRTOS的每个任务都有一个32位的通知值,任务控制块中的ulNotifiedValue 就是这个通知值

    • 任务通知可以通过如下方法更新接收任务的通知值

      • 不覆盖接收任务的通知值(如果上次发送给接收任务的通知还没被处理)。
      • 覆盖接收任务的通知值。
      • 更新接收任务通知值的一个或多个 bit。
      • 增加接收任务的通知值。
  • 框架性的回答一个嵌入式系统Freertos的启动到结束的过程

    • 1.上电和复位

      • 上电(Power-On):系统通电,所有组件开始接收电力。
      • 复位(Reset):系统复位,所有寄存器和内存单元清零,系统进入已知的初始状态。
    • 2.引导加载程序阶段

      • 初始化硬件:基本硬件时钟、内存、IO接口等的初始化。
      • 自检:系统执行自检程序,确认硬件是否执行正常工作。
      • 加载内核:引导加载程序将FreeRTOS内核从存储介质加载到内存中
    • 3.FreerRTOS内核初始化

      • 堆栈和任务管理器初始化:设置堆栈和任务管理器。准备调度任务
      • 创建空闲任务和定时器任务:创建默认的空闲任务和定时器任务,这些任务由FreeRTOS内核自动管理
      • 初始化系统定时器:设置系统定时器,用于任务调度和时间管理
    • 4.用户任务创建

      • 定义和创建任务:应用程序定义各个任务,指定任务的入口函数、优先级和堆栈大小等参数,并通过FreeRTOS API创建任务
      • 创建队列、信号量等:初始化系统中需要使用的各种同步机制和通信机制。如队列、信号量、互斥锁等。
    • 5.启动调度器

      • 启动任务调度:调用vTaskStartScheduler()函数,FreeRTOS内核开始调度任务,系统进入多任务运行状态。
    • 6.任务运行阶段

      • 任务调度(Task Scheduling):FreeRTOS内核根据优先级和调度策略切换任务,执行各个任务的代码。
      • 中断处理(Interrupt Handling):处理外部或内部中断,执行中断服务程序(ISR),并在适当时刻恢复任务运行
    • 7.系统待机或关闭

      • 待机模式(Standby Mode):系统可以进入低功耗模式,等待外部事件唤醒。这个阶段通常需要任务或中断来管理。
      • 正常关闭(Normal Shutdown):系统执行关闭程序,保存数据,停止各项服务和设备。对于FreeRTOS,可能需要实现特定的任务或中断来执行系统关闭操作。
      • 断电(Power-Off):最终断开电源,系统停止运行。
  • 除了任务切换对freertos其他底层了解吗?

    • 任务管理:任务是FreeRtos中的基本执行单元,任务管理包括任务的创建、删除、调度、和优先级管理

      • 任务优先级:内核根据任务的优先级来调度任务。
      • 任务状态:任务可以处于不同状态:运行态、就绪态、阻塞态、挂起态和删除状态
      • 主要涉及任务的删除和创建,通过xTaskCreate()和vTaskDelete()创建和删除任务,当然也有静态创建和动态创建方式
    • 内存管理:FreeRtos提供灵活的内存管理机制,包括静态和动态内存。

      • 静态内存分配,在编译时分配固定大小的内存块,适用于资源受限的系统。
      • 动态内存分配,在运行时使用pvPortMalloc和vPortFree动态分配和释放内存。FreeRTOS提供了多种内存分配方案。
    • 低功耗支持:FreeRTOS支持低功耗模式,帮助嵌入式系统在不需要完全运行时节省能量

      • 空闲任务回调函数(在空闲任务中执行自定义的低功耗代码)
      • TicklessIdle模式:在系统空闲时停止系统执行滴答定时器,降低功耗。
  • 讲讲FreeRTOS任务调度的原理?

    • FreeRTOS任务调度的原理基于优先级调度算法,主要包括以下几个方面:

      • 1. 任务优先级
        • 每个任务都有一个优先级,优先级是调度器选择任务执行的重要依据。优先级越高的任务拥有更高的执行权。

      • 2. 就绪任务列表(Ready List)
        • FreeRTOS维护多个就绪任务列表,每个列表对应一个优先级。任务被插入到其优先级对应的列表中。

      • 3. 滴答中断(Tick Interrupt)

        • 系统定时器产生固定频率的滴答中断,滴答中断是调度器进行任务切换的触发点。在每次滴答中断时,系统会检查当前任务是否需要切换。

      • 4. 调度器(Scheduler)

        • 调度器负责管理所有任务的状态,并决定哪个任务应当运行。调度器可以在以下几种情况下触发:
          •  系统滴答中断:定时器中断到来,触发调度。

          • 任务状态变化:任务状态由阻塞变为就绪,或由就绪变为运行等。

          • 中断处理结束:在中断服务程序(ISR)结束时,如果需要任务切换,会触发调度。

      • 5.任务状态

        • FreeRTOS中任务可以有以下几种状态:

          • 运行状态(Running):当前正在执行的任务。

            就绪状态(Ready):可以运行但当前未被执行的任务。

            阻塞状态(Blocked):等待某个事件或时间到达的任务。

            挂起状态(Suspended):任务被暂时挂起,不参与调度。

      • 6. 上下文切换(Context Switching)

        • 任务切换(上下文切换)是FreeRTOS调度器的重要组成部分。当需要切换任务时,当前任务的上下文(CPU寄存器、堆栈指针等)会被保存,新任务的上下文会被恢复。
  •  如何实现一个队列?

    • 队列对于任务的解耦和同步非常有用。一种先进先出结构,允许任务以异步的方式交换信息

  • 说一下互斥量和条件变量?(这个问题可能在Linux系统里面体现得要好一些)

    • 为什么要使用条件变量,这是多线程访问互斥资源时重复的轮询可能带来的CPU浪费和释放和获取互斥锁中可能带来的

    • 为什么使用条件变量的时候也需要配合互斥量使用,这是为了防止多个线程同时请求pthread_mutex_lock导致的竞争条件.

    • 实现了效率提高,在条件满足时,自动退出阻塞,再加锁进行操作.

    • 总结一下,条件变量用于某个线程需要在某种条件成立时才去保护它将要操作的临界区,这种情况从而避免了线程不断轮询检查该条件是否成立而降低效率的情况

    • 条件变量

      • 条件变量是利用线程间共享的全局变量进行同步的一种机制,是在多线程程序中用来实现等待唤醒逻辑的常用方法
      • 主要两个状态:
        • 一个线程等待"条件变量的条件成立"而挂起
        • 另一个线程使"条件成立"而发出信号
      • 线程在改变条件状态前用pthread_mutex_lock()必须首先锁住互斥量,在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁,在条件满足(pthread_cond_wait()有返回值)后,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作一样。)
    • 互斥量

      • 本质上是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。在互斥量进行加锁以后,任何其它试图再次对互斥量加锁的线程将会阻塞直到当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为可运行状态的线程可以对互斥锁加锁,其它线程将会看到互斥锁依然被锁住,只能回去再次等待它重新变为可用。
  • Switch_contex的底层原理?一般面试官会问你,freertos的中断服务函数有哪些?

    • 上下文切换是指从一个任务的执行上下文切换到另一个任务的执行上下文,这涉及保存当前CPU的任务状态,并恢复到下一个任务的寄存器状态
      上下文切换主要是在pendsv中断中利用中断服务函数进行,其具有最低的优先级,适合做上下文切换
      会让你解释对着两种中断的认识:

      • 系统定时器,它以最低中断优先级运行,然后寻找到一个上下文切换,将就绪任务添加到就绪表(就是阻塞完毕的任务)或者将一些挂起的任务(从挂起到恢复)放入就绪表,在就绪表当中,会给到下一个任务(或者异常中断处理函数)中进行判断,来触发任务的切换。

        所以系统定时器的作用就是用来管理就绪表的

      • 异常处理中断处理函数xPortPendSVHandler():主要是调用vTaskSwitchContext从就绪表当中寻找到优先级最高的且就绪任务。

        但是对于PendSV的作用,就是用于上下文切换的,用于触发任务调度的,怎么触发任务调度的呢?它的主要核心就是会在port.c文件中的__asm void xPortPendSVHandler( void )进行调用bl vTaskSwitchContext(核心),这个函数的功能就是找到就绪表当中最高优先级的任务,进行一个任务切换。

      • SysTick优先级高于外部中断,OS抢占IRQ进行任务调度触发Fault

  • 简述FreeRTOS的任务调度?​​​​​​​​​​​​​​

    • 时间片调度,每个任务都有相同的优先级,任务会运行固定的时间片个数或者遇到阻塞式的 API 函数,比如vTaskDelay,才会执行同优先级任务之间的任务切换。如果用户在 FreeRTOS.h 中禁止使用时间片调度,那么每个任务必须配置不同的优先级。

    • 抢占式调度,每个任务都有不同的优先级,任务会一直运行直到被高优先级任务抢占或者遇到阻塞式的 API 函数,比如 vTaskDelay。

    • 合作式调度,亦称为FreeRTOS的协程,实际上是线程并发出来的,每个线程并发出来的协程共用一个栈空间。合作式调度主要用在资源有限的设备上面,现在已经很少使用了。出于这个原因,后面的 FreeRTOS 版本中不会将合作式调度删除掉,但也不会再进行升级了。

  • 简述FreeRTOS的移植流程?

    • 源码移植主要涉及几个重要的文件夹

      • 一个是源码目录/source/portable/下的文件 主要是与编译器相关的文件夹,在编译器里提供不同的支持文件

      • Keil和RVDS一样 这里直接复制RVDS文件夹 

      • MemMang文件夹是与内存相关的源文件,

      • 然后是添加include文件夹和一些通用的头文件C文件

      • 修改FreeRTOSConfig.h 对系统进行裁剪的常用配置文件

        • 该头文件对裁剪整个FreeRTOS所需的功能的宏均做了定义,有些宏定义被使能,有些宏定义被失能,一开始我们只需要配置最简单的功能即可。要想随心所欲的配置FreeRTOS的功能,我们必须对这些宏定义的功能有所掌握,下面我们先简单的介绍下这些宏定义的含义,然后再对这些宏定义进行修改
        • 修改stm32f10x_it.c
          • SysTick中断服务函数是一个非常重要的函数,FreeRTOS所有跟时间相关的事情都在里面处理,SysTick就是FreeRTOS的一个心跳时钟,驱动着FreeRTOS的运行,就像人的心跳一样,假如没有心跳,我们就相当于“死了”,同样的,FreeRTOS没有了心跳,那么它就会卡死在某个地方,不能进行任务调度,不能运行任何的东西,因此我们需要实现一个FreeRTOS的心跳时钟

            FreeRTOS帮我们实现了SysTick的启动的配置:在port.c文件中已经实现vPortSetupTimerInterrupt()函数,并且FreeRTOS通用的SysTick中断服务函数也实现了:

            • 在port.c文件中已经实现xPortSysTickHandler()函数,所以移植的时候只需要我们在stm32f10x_it.c文件中实现我们对应(STM32)平台上的SysTick_Handler()函数即可。

              FreeRTOS为开发者考虑得特别多,PendSV_Handler()与SVC_Handler()这两个很重要的函数都帮我们实现了,在在port.c文件中已经实现xPortPendSVHandler()与vPortSVCHandler()函数,防止我们自己实现不了,

              那么在stm32f10x_it.c中就需要我们注释掉PendSV_Handler()与SVC_Handler()这两个函数了。

  • ​​​​​​​使用RTOS和裸机代码开发有什么区别(优缺点)?

    • 之前的某个项目采用了裸机开发,通过状态机管理业务逻辑和各种外设,后面任务的同步和并行处理逻辑变得复杂,就引入了操作系统,
      操作系统的应用,方便任务管理,延时管理,内存管理和任务间通讯

    • 移植的过程

    • 拉取源码
    • 拉取 FreeRTOSv9.0.0\FreeRTOS\Source 的所有 .c 文件 =>> 内核源码
    • 拉取 FreeRTOSv9.0.0\FreeRTOS\Source\portable{\MemMang,\RVDS\ARM_CM3}
    • 拉取 FreeRTOSv9.0.0\ FreeRTOS\Source\include == 》头文件
    • 工程中 C++ 配置目录
    • 修改FreeRTOSConfig.h文件,堆栈空间问题,时间节拍
    • 修改中断服务函数,stm32f10x_it.c  SysTick_Handler(void)
    • 注释掉PendSV_Handler()与SVC_Handler()这两个函数
  • FreeRTOS中的IPC通信有哪些?​​​​​​​

    • IPC通信,进程间通信的方式

    • 1.信号量:信号量是一种计数机制,用于控制同步,它可以被视为一个资源,需要使用者获取它获取它执行相应的操作,之后再释放信号量,使得其他任务也能够获取这个资源。通过配置信号量,任务就能能够控制共享资源。

    • 2.队列:队列可能于任务之间传递数据。它提供了发送一个消息的任务和接收一个消息的任务之间的缓冲区。队列中的消息都是一定格式的,FreeRTOS常用的队列有有限队列(设定最大可存放的数据个数)和无限队列(不设定队列大小)。

    • 3.事件:事件用于任务之间交换消息,但是在事件中在处理消息可以根据消息的种类进行不同的处理。事件可以包含一个或多个消息,并且可以事件标志位。

    • 这些 IPC 机制可以很好地支持任务间的通信和协调,使得任务之间不再需要通过共享全局数据来完成协作。

  • FreeRTOS中的tickless模式是什么?

    • 当用户任务被挂起或者阻塞时,最低优先级的空闲任务会得到执行,那么STM32支持的睡眠模式,停机模式就可以在空闲任务里面执行

    • 在真正的低功耗设计中,不仅仅将处理器设置到低功耗模式就行,还需要做一些其他的处理

      • 将处理器降到合适的频率,频率越低功耗越小,甚至可以在进入低功耗模式以后关闭系统时钟。
      • 修改时钟源,晶振的功耗肯定比处理器内部时钟的时钟源高,进入低功耗模式以后可以切换到内部时钟源。
      • 关闭其他外设时钟,比如IO口的时钟
      • 关闭板子上其他功能模块的电源(硬件设计的时候可以通过MOS管来控制某个电源的开关,在处理器进入低功耗模式之前关闭这些模块的电源)
  • 如何在FreeRtos中创建任务?

    • 任务创建主要分为静态创建和动态创建,在创建任务中通常涉及以下步骤
      定义一个函数来执行任务,通常叫做任务函数

    • 然后使用xTaskCreate函数来创建任务,主要涉及

    • 任务函数指针、
    • 任务名称、
    • 任务栈的深度,也就是任务栈的大小、
    • 传递给任务函数的参数、
    • 任务优先级,
    • 任务句柄的指针
  • FreeRTOS如何管理内存?

    • FreeRTOS提供了几种内存管理方案。在默认的情况下,使用单一的固定大小的堆,但也可以使用动态内存分配实现自己的内存管理策略。

    • 针对FreeRTOS的动态内存管理策略,主要可以归类为以下几点

  • 如何配置FreeRTOS的内核?

    • 配置FreeRTOS的内核通常包括定义堆栈的大小,设置时钟滴答定时器的周期频率,定义任务优先级、任务调度的策略等,
      在移植时可以通过移植文件FreeRTOSConfig.h对系统功能进行裁剪。
      此外,还需要根据硬件和应用需求配置中断和外设。

    • 有没有对代码裁剪的经验?

    • 减少内存占用和提升性能,使其更适合嵌入式系统的需求。

      • 代码裁剪主要还是通过配置FreeRTOSConfig.h中的宏定义配置项
      • 禁用不需要的功能
      • 明确实际任务栈的大小,并且为某个任务分配实际的栈大小,可以通过分析和调试确定每个任务的实际栈需求。
      • 使用静态内存分配,以减少动态内存分配可能带来的内存碎片和提高内存分配的确定性。
      • 精简堆管理器,根据需要在对管理器的/FreeRTOS/Source/portable/MemMang目录下进行堆管理的配置
      • 优化任务调度,如果项目不需要优先级调度可以考虑启用时间片调度以简化调度器的逻辑
      • 减少滴答定时器的频率,应为他们影响系统的实时性,可以通过降低滴答频率来减少CPU的占用。
      • 禁用调试和统计信息。
      • 移除不必要的文件和代码。
    • 在配置FreeRTOS内核的时候,通常包括定义堆栈大小,设置滴答定时器的频率和周期,定义任务优先级,选择任务调度策略等。

  • FreeRTOS的软件定时器是什么,他们如何工作。 

    • 软件定时器是FreeRTOS提供的一种机制,允许任务在将来的某个时间点被唤醒。软件定时器不是真正的硬件定时器,而是使用FreeRTOS的调度器和时钟滴答来模拟的。任务可以创建一个软件定时器,并将其与任务函数关联。当定时器到期时,关联的任务将被添加到就绪列表中,以便在下一个调度点执行。

  • 中断和任务有哪些主要区别?

    • 中断是硬件或软件触发的事件,主要用户快速响应内部或外部事件,通常具有固定的优先级,并且执行时间非常短。

    • 任务则是操作系统调度的基本单位,具有特定的优先级,可以执行复杂的操作,并且可以被挂起和恢复

  • Freertos中的任务栈是什么,它如何初始化(请解释任务栈的左右以及他在FreeRTOS中是如何初始化的。)

    • 任务栈是为任务提供内存空间的一种机制,用于存储局部变量、函数参数、返回地址和以及可能的中断上下文。

    • 任务栈在进行创建任务的时候进行使用xTaskCreate()宏进行初始化。栈的大小必须在创建任务时指定,并且通常根据任务的复杂性和需要的栈空间大小决定。

  • 请描述一下FreeRTOS中事件组的工作原理及用途?

    • 事件组是FreeRTOS中的一种同步机制,它允许任务之间通过一组事件的设置和清除来通信和同步

    • 事件组是一个32位的二进制字段,每个位可以代表一个事件

    • 任务可以使用xEventGroupCreate()创建事件组,并使用xEventGroupSetBits()和xEventGroupClearBits()来设置和清除事件

    • 其他任务可以通过xEventGroupWaitBits()来等待特定的事件位状态变化。

  • 裸机开发和RTOS开发的区别?

  • 为什么会在项目中使用RTOS?

  • FreeRTOS的启动流程?

  • freertos中EventBits_t是干啥的?

    • EventBits_t 是一个数据类型,用于表示事件组的状态。事件组(Event Group)是FreeRTOS中的一种同步机制,允许任务通过事件位(Event Bits)来进行同步和通信。
      事件组主要用于任务之间的时间同步,是一种可以由多个任务或中断设置、清除、或等待的位,每一位代表一个独立的事件,任务可以等待一个或多个事件位被设置,这种机制适用于任务之间的复杂同步场景。

  • 消息队列的具体实现?

  • Freertos的多任务同步机制列举

    • 提供多种多任务同步机制,用于在不同任务之间以及任务和中断服务程序之间进行数据传递和同步

    • 信号量

      • 二值信号量,用于实现二元同步,比如在任务和ISR之间同步
      • 计数信号量,用于管理多个资源或事件
      • 递归互斥信号量,允许同一任务多次获得锁而不会造成死锁。
    • 互斥锁

      • 用于保护共享资源,确保同一时间只有一个任务可以访问资源
    • 队列

      • 用于在任务和ISR之间传递数据
    • 事件组

      • 事件组用于多个任务之间的事件通知和同步,可以设置、清除、和等待多个事件位。
    • 软件定时器,

      • 用于在指定时间后执行回调函数,常用于周期性执行任务或者延时任务。
    • 任务通知

      • 任务通知是一种轻量级的任务间同步和通信机制,用于通知任务或传递简单的整数值。
  • 堆和栈的区别,程序存放状态和区?

    • 栈和堆是程序在运行时使用的两种不同的内存管理区域,

    • 堆:用于动态内存分配,通常通过malloc、calloc、realloc等函数来分配内存,通过free等函数释放内存

      • 管理复杂:需要程序员手动的分配和释放,需要主义内存泄漏和碎片化问题。
      • 大小灵活:堆的大小通常受限于系统的可用内存,因此适合分配大块内存或者数量不确定的对象。
      •  速度较慢
    • 适用于需要动态内存大小的数据结构,如链表、树、图等
      可能会发生内存泄漏

    • 分配和释放内存的速度较慢

    • 内存碎片化会导致效率降低

    • 栈:

      • 自动内存分配,函数调用时自动分配局部变量,函数返回时自动释放。

      • 管理简单:由编译器自动处理,不需要程序员手动管理。

      • 大小固定:栈的大小通常较小,在编译时确定,适合分配小块内存或局部变量。

      • 速度较快:栈的内存分配和释放速度非常快,因此只需要调整栈指针。

    • 程序存放的状态和区域:

      • 一个程序在内存中的布局通常包括以下几个部分:

        • 代码段:存储程序的可执行代码,及函数和方法的二进制代码。通常是只读的,以防止意外或恶意修改程序指令。
        • 数据段:包括两部分:已初始化的数据段(Data Segment)和未初始化的数据段(BSS Segment)
        • 堆(Heap):用于动态内存分配,内存块在运行时分配和释放。从低地址向高地址增长。
        • 栈(Stack):存放临时数据,包括局部变量、函数参数、返回地址等。
        • 自由存储区(Free Store)
  • 什么是死锁,死锁产生的原因?如何避免?

    • 死锁产生的原因:

      • 资源竞争:多个任务请求相同的有限资源

      • 资源分配不当:资源分配和释放的顺序不当。

      • 错误的锁定顺序:多个任务以不同的顺序获得多个锁,从而导致循环等待。

      • 忽略资源请求和释放。

    • 死锁产生条件:

      • 互斥条件:资源不能被共享,每个资源只能被一个任务占用
      • 占有且等待:一个任务已经持有至少一个资源,并且正在等待获取额外的资源,而这些资源被其他任务持有。
      • 不可剥夺条件:以及该分配给任务的资源不能被强制剥夺,只能由持有该资源的任务主动释放。
    • 死锁是指两个或多个任务(或进程)互相等待对方持有的资源,导致这些任务永远无法继续执行的情况。在多任务操作系统中,死锁是一个严重的问题,因为它会导致系统资源的浪费和程序的停滞

    • 在任务中怎么进行数据传输,什么方式?

      • 1.消息队列发送数据的方式可以是发送数据本身和发送数据的地址指针。

      • 2.全局变量使用供所有任务获取和处理,但全局变量占用内存较多,而且不好管理。

      • 3.信号量一般作为标志位使用。

        • 阐述信号量的作用,信号量的类型
        • 信号量共有三种,二值信号量、计数信号量、互斥信号量,常用的是二值信号量和互斥信号量。
        • 信号量本质上都是深度为1的消息队列。
        • 二值信号量通常在中断中作为标志位使用,起到线程同步的作用。
        • 互斥信号量作为互斥锁使用。防止不同线程访问同个内存。
    • 嵌入式操作系统的硬实时和软实时如何理解?

      • 实时系统主要关注时间的正确性和功能的正确性

      • 衡量一个实时系统的正确性:要求系统能够在给定的时间内正确的完成相应的任务,但软实时系统:偶尔它会稍微超出这个给定的时间范围才能正确地完成任务

      • 从系统对规定时间的敏感性的要求分:硬实时和软实时

        • 硬实时:严格限定在规定时间内完成任务
        • 软实时:可以允许系统偶尔出现一定的时间偏差,但随着时间的偏移,整个系统的正确性也会随之下降。
    • 任务通知

      • FreeRTOS官方是建议不要在中断中使用信号量的,而采用任务通知代替信号量。因为在许多使用场景中,使用直达任务通知要比使用信号量的速度更快,内存效率更高。
        当然在中断中释放信号量并无大碍,就是不要在中断中获取就行,毕竟会阻塞中断从而出现意想不到问题。

  • ​​​​​​​​​​​​​​​​​​
  • (xmind可以三连私信啦啦啦)

  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值