内存、中断管理
内存管理
内存管理简介:
动态:由系统自动分配;静态:由用户自己分配
标准C库中的malloc()和free()也可以实现动态内存管理,但是也有限制:
- 这些函数在小型嵌入式系统中并不总是可用的,小型嵌入式设备中的RAM不足
- 它们的实现可能非常大,占据了相当大的一块代码空间
- 它们几乎都不是安全的
- 它们并不是确定的,每次调用这些函数执行的时间可能都不一样
- 它们有可能产生碎片
- 这两个函数会使得链接器配置得复杂
freertos提供的内存管理函数:
pvPortMalloc()来代替malloc(),vPortFree()函数来替代free()。
内存碎片:
经过许多内存的申请释放之后,内存空间中有许多小的内存块,申请不到。
freeRTOS中的内存堆都为ucHeap[],大小都为configTOTAL_HEAP_SIZE
freeRTOS中heap1,2,4内存堆的实现是定义了一个大的数组,由编译器决定。heap3封装了malloc和free,具有保护功能,能安全地在嵌入式系统中使用,需要哟过户自定义内存堆。heap5允许用户使用多个不连续的内存堆,由用户指定。这五种内存管理方式有相同的内存申请和释放函数,初始化和获取当前未分配内存堆大小,获取未分配内存堆历史最小值函数如下:
内存分配方法
heap1:
内存初始化:一般8字节对齐,管理内存开始指针从能被8整除的地址开始。
内存申请:也需要进行8字节对齐,例如需要申请30字节,操作系统会分配32字节内存,实现字节对齐。
内存释放:pvFree(),heap1没有内存释放,因为不会产生内存碎片。
特点:适合系统从开始到关闭只申请内存一直使用不释放的场景
heap2:
特点:适合应用在系统每次申请删除的内存块大小一样的,应用需要调用pvPortMalloc()和vPortFree()来申请释放,而不是调用其他API间接调用。应用中的任务、队列、信号量等具有不可预料性,每次所需内存大小不同,会导致内存碎片(heap4里有解决),效率远比c标准库中的malloc和free高。
heap3:
特点:简单封装了C库中的malloc和free,操作内存前挂起调度器,完成后再恢复,具有保护功能。需要链接器设置一个堆,由编译器提供,具有不确定性,很可能增大内核大小。
heap4:
特性:提供了内存块合并算法,不会像heap2那样产生严重的内存碎片,比较常用。
heap5:
特性:与第四种采用相同的内存合并算法,允许使用不连续的内存块。
中断管理
临界段保护:临界段是一段在执行的时候不能被中断的代码段。在FreeRTOS里面,这个临界段最常出现的就是对全局变量的操作。
被打断的情况:系统调用,外部中断。
关中断:在portmacro.h中定义,分不带返回值和带返回值两种,不带返回值的关中断函数不能嵌套,不能在中断里面使用。
带返回值的关中断函数可以嵌套和在中断里使用,带From_ISR
开中断:
临界段
临界段代码也叫做临界区,是指那些必须完整运行,不能被打断的代码段,比如有的外设的初始化需要严格的时序,初始化过程中不能被打断。
从上到下:
- 进入临界段(任务级)
- 退出临界段(任务级)
- 进入(中断级)
- 退出(中断级)
函数实现:进入函数后挂起中断,全局变量++(记录临界段嵌套的数据),然后执行,等所有临界段都退出之后才恢复中断。中断保护:优先级低于BASEPRI的中断无法响应,用户可以自定义配置系统可管理的最高中断优先级的宏定义。
CPU利用率
配置文件:开启两个宏,定义两个宏,声明CPU_RunTime变量,注释掉两个头文件。
原文地址:https://blog.csdn.net/m0_50683929/article/details/133763605
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!