八股更新
时间片的最小单位?用什么方式计算出来的?
在 RTOS 中,最小的时间单位为一个 tick,即 SysTick 的中断周期,SysTick定时器通常用于产生系统时钟中断,至少得保证任务可以得到及时调度,尽量减少中断处理时间。
如何保证任务在规定时间内执行完
优化代码执行效率:使用硬件加速:在可能的情况下,利用硬件加速器(如DMA、硬件浮点运算)提高执行效率
任务优先级:为关键任务分配更高的优先级,确保其得到及时调度。
避免长时间阻塞:避免在任务中进行长时间的阻塞操作
时间片调度:合理配置时间片,确保任务在分配的时间片内执行完。
抢占式调度:使用抢占式调度策略,确保高优先级任务可以中断低优先级任务的执行。
怎么获取每个线程的执行时间?
- 计时函数:利用高精度的计时函数来记录线程的开始时间和结束时间。
- 线程管理:在每个线程的入口和出口记录时间戳。
如果每个线程刚好花费了最长的时间,是否会出问题?
- 错过时限:关键任务无法在规定的时间内完成,导致系统无法满足实时性要求。
- 任务调度延迟:后续任务的启动被延迟,进一步影响系统的响应时间。
多个线程竞争时会导致:
资源饥饿:某些线程可能无法及时获得所需资源,导致性能下降。死锁:长时间持有锁的线程可能会导致其他线程无法获得锁,从而引发死锁。
任务间通信:
①低级通信:只能传递状态和整数值等控制信息,例如信号量机制,异步信号机制等
②高级通信:能够传输任意数量的数据,主要有三类:共享内存、消息传递和管道。
信号量堆积:
指的是信号量(semaphore)没有及时处理或释放,导致系统资源被过度占用;
如果一个进程获取了信号量但没有释放,就会导致其他进程无法继续运行,进而导致信号量堆积;死锁也是导致信号量堆积的常见原因
Linu
x的任务调度机制:
Linux内核中主要使用的是完全公平调度器(Completely Fair Scheduler, CFS)
CFS:每个任务在运行时都获得相同的CPU时间片。CFS使用红黑树(红黑树是一种平衡二叉树)来管理任务,确保所有任务都能公平地分配CPU时间。
实时调度策略(SCHED_FIFO和SCHED_RR)用于需要确定响应时间的任务:
- SCHED_FIFO:实时优先级高的任务先执行,直到其主动放弃CPU。
- SCHED_RR:类似SCHED_FIFO,时间片轮转,但每个任务有一个时间片,当时间片用完时,调度器会将任务放到队列末尾。
FreeRTOS的任务抢占机制:
FreeRTOS支持的任务调度方法有抢占式、协作式、时间片轮转;
协作式的调度方式,其本质上是任务在运行一段时间后,自己放弃CPU运行权,让其他任务运行。实现函数:taskYIELD();
时间片轮转,是让相同优先级的几个任务轮流运行,每个任务运行一个时间片,任务在时间片运行完之后,操作系统自动切换到下一个任务运行;FreeRTOS的时间片固定为一个时钟节拍tick;
抢占式调度,是最高优先级的任务一旦就绪,总能得到CPU的执行权;它抢占了低优先级的运行机会;
FreeRTOS内存分配:
五种内存分配的管理方法:
heap_1 —— 最简单,不允许释放内存。
heap_2—— 允许释放内存,但不会合并相邻的空闲块。
heap_3 —— 简单包装了标准 malloc() 和 free(),以保证线程安全。
heap_4 —— 合并相邻的空闲块以避免碎片化。 包含绝对地址放置选项。
heap_5 —— 如同 heap_4,能够跨越多个不相邻内存区域的堆。
一般是使用heap_4可以
管理方法:
动态内存分配(Dynamic Memory Allocation)
FreeRTOS提供了用于动态内存分配的内置函数,如pvPortMalloc和vPortFree。这些函数允许任务在运行时请求和释放内存。这种方法对于需要灵活管理内存的应用非常有用,但需要小心避免内存泄漏和碎片化。
静态内存分配(Static Memory Allocation)
FreeRTOS允许用户在编译时为任务和内核对象(如队列、信号量等)分配静态内存。
内存池(Memory Pools)
内存池是在系统初始化时创建的一块内存区域,用于存储固定大小的内存块。
堆栈自动增长(Stack Auto-Grow)
FreeRTOS允许任务的堆栈在运行时自动增长,以适应任务运行期间的动态需求。
程序运行的四个阶段,和程序运行起来的流程?
预处理(Preprocessing)
预处理器将源代码中的预处理指令替换为实际的内容。预处理器会根据指令展开头文件,处理宏定义,并删除注释等。 .i
编译(Compilation)
编译器将预处理后的源代码转换为汇编代码。它会对每个源文件进行词法分析、语法分析和语义分析,生成相应的中间代码,并进行优化。 .s
汇编(Assembly) .o
汇编器将编译生成的中间代码转换为机器可读的汇编代码,也就是机器码的文本表示。
链接(Linking)
链接器将汇编生成的目标文件(object file)以及可能的库文件链接在一起,生成最终的可执行文件。
前后台程序与实时操作系统的区别是什么?
**前后台程序:**前后台系统中所有的任务都是平级的;(while(1)的大循环)即无限循环的后台中运行或者等待运行条件的到来,一个任务的运行必须等待上一个任务运行结束。
为了能够处理紧急的任务,设置了中断机制来处理紧急任务,即前台。
**RTOS:**RTOS将任务分成了不同等级,总是让优先级高的任务先运行。同样,中断可以打断所有任务,来处理紧急任务。
实时系统的基本特性有哪些?
实时调度机制
多级中断机制
高精度的计时系统
"可剥夺型内核"与“不可剥夺型内核”的区别
不可剥夺型内核:
多个任务共享一个CPU,中断服务可以使一个高优先级的任务由挂起状态变为就绪状态,中断结束后,CPU控制权回到调用中断的那个任务,直到该任务结束,再运行刚刚进入就绪态的任务
优点1:不可剥夺型内核的一个优点是响应中断快;
优点2:使用不可剥夺型内核时, 任务级响应时间比前后台系统快得多;
优点3:几乎不需要使用信号量保护共享数据
可剥夺型内核:当系统响应时间很重要时,要使用可剥夺型内核,高优先级的任务一旦就绪,立马获得CPU的控制权
什么是可重入型函数?它有什么特点?
重入一般可以理解为一个函数在同时多次调用,例如操作系统在进程调度过程中,或者单片机、处理器等的中断的时候会发生重入的现象。
可重入的函数必须满足以下三个条件、特点:
1.允许在执行的过程中可以被打断;
2.被打断之后,在该函数一次调用执行完之前,可以再次被调用
3.再次调用执行完之后,被打断的上次调用可以继续恢复执行,并正确执行。
常见的不可重入函数有:
printf 引用全局变量stdout
malloc 全局内存分配表
free 全局内存分配表
重入函数在多线程中怎么保护?
如果重入函数使用了全局变量,在开始用一个局部变量保存一个全局变量的原因;或是通过关中断和信号量等手段进行保护。
使用可剥夺型内核时,为什么不应直接使用不可重入型函数?
在使用可剥夺型内核(preemptive kernel)时,不应直接使用不可重入型函数的主要原因是并发访问可能导致数据不一致、崩溃或其他不可预见的错误。
可剥夺型内核允许任务在任意时刻被中断和切换,而不可重入函数在执行过程中依赖于共享资源,如果再另一个线程中被再次调用会有不可预计的错误。
为什么应用程序一定要使用空闲任务?
1.空闲任务确保CPU在没有其他任务可以运行时不会闲置,它的存在确保了系统的正常运行,提高系统的稳定性和可靠性;
2.使用空闲任务来实现电源管理;
3.空闲任务可以用于统计系统的空闲时间,帮助计算负载情况,通过计算空闲任务的运行时间,可以确定系统的过载情况;
4.空闲任务还可以用来执行一些低优先级的后台任务,日志记录和数据备份等;
#嵌入式##牛客在线求职答疑中心##晒一晒我的offer##我的实习求职记录##互联网没坑了,还能去哪里?#心得和八股文(含面试真题) 全部免费