内存相关(堆和栈 RAM和ROM)
堆heap
一块空闲的内存空间,并且有相应的内存管理函数。(malloc、free) 堆区用于存放程序运行中被动态分布的内存段,可增可减。 在SRAM中
栈stack
在执行c文件的时候,先运行main函数,运行main函数时,首先划分出main函数自己的栈空间,先记录LR(LinkRegister,用于保存函数的返回地址,函数的返回地址就是要执行的下一条语句)的值,还有一些别的信息和局部变量。 在RTOS中,每个任务(任务函数)都有自己对应的栈。每个任务调用的函数,都会保存在该任务的栈中。不同任务的栈互相独立。
- 临时创建的局部变量存放在栈区。
- 函数调用时,其入口参数存放在栈区。
- 函数返回时,其返回值存放在栈区。
- const定义的局部变量存放在栈区。 可以从堆heap中分配一块空间作为栈stack
RAM:Random Access Memory 随机存取
数据掉电丢失。随机 指的是读取和写入时需要的时间,与数据的位置无关。读取其内部任意位置的数据,需要的时间都是一样的。 放临时数据。内存条 可分为DRAM和SRAM(动态和静态) SRAM 一般只用于 CPU 内部的高速缓存 (Cache),而外部扩展的内存一般使用 DRAM。SDRAM的S是同步的意思,它属于DRAM
ROM: Read Only Memory 只读
数据掉电不丢失。价格高,容量小。 放人编写的程序。 但后来也发展了可擦除的FLASH、EEPROM等,而且还很常用。ROM这种叫法也算是历史遗留下来的了
各种变量存放的位置
代码区和常量区的内容编译后存储在ROM FLASH中 堆、栈、全局区(.bss段、.data段)都是存放在RAM SRAM中
FreeRTOS基础知识
任务调度
调度器就是使用相关的调度算法来决定当前需要执行哪个任务
-
抢占式调度:针对优先级不同的任务(FreeRTOS数字越大,优先级越高)
- 高优先级的任务优先执行
- 高优先级的任务不停止(阻塞),低优先级的任务就无法执行
- 被抢占的任务进入就绪状态
- 优先级相同的任务,每次系统时钟节拍到时切换任务(时间片调度)
-
时间片调度:针对优先级相同的任务。每一次系统时钟节拍到的时候切换任务
- 同等优先级的任务,轮流、同等地享有相同时间的CPU时间(可以设置),叫时间片,在FreeRTOS中,一个时间片就等于SysTick中断周期
- 若Task3在运行过程中(没执行完1个时间片),Task3阻塞了(系统延时或等待信号量等)此时就绪态中,优先级最高的任务Task2执行。没运行完成的任务3剩余的时间片就丢掉了,不会补充。
-
协程式调度:当前任务一直执行,同时高优先级的任务无法抢占(官方不会再更新这种方式了)
任务状态
- 运行态:正在执行的任务,就处于运行态。即CPU被这个任务占用
- 就绪态:该任务在等待执行,但是优先级更高或者同优先级的任务正在运行,该任务还未被执行。
- 阻塞态:任务在等待信号量、消息队列、事件标准组、系统延时 时,被称为阻塞态,如果等待的事件到了,就会自动退出阻塞态,准备运行
- osDelay(ms),是任务进入阻塞状态,不占用cpu多少ms
- HAL_Delay(ms),是任务占用CPU什么都不做,仅延迟ms
- 挂起态:类似暂停,调用函数 vTaskSuspend() 进入挂起态,需要调用解挂函数vTaskResume()才可以进入就绪态
仅就绪态才能进入运行态
除了运行态,其余三种状态都有对应的任务状态列表(类似链表)
-
- 只有在就绪列表的任务才能进行运行态
- 新创建的任务直接挂载到就绪列表。32位的变量,当某个位,置一时,代表所对应的优先级就绪列表有任务存在
- 调度器总是在就绪列表的任务中,选择优先级最高的来执行
- 相同优先级的任务会连接。在同一个就绪列表上