各位小伙伴,最近学习STM32F407遇到了很多的问题,有的问题被我解决了,有点还迟迟没有解决。通过遇到的这些问题,我有很多疑问,希望有知道的小伙伴能够解惑,谢谢各位啦。
1、在学习了内存管理一节当中,为什么要管理STM32内部的内存(SRAMIN和SRAMCC)? 难道STM32内部管理机制不好么? STM32内部是怎么管理这些内存的? 在哪里可以看到呢?
2、汇编文件startup_stm32f40_41xxx.s中分配的堆和栈是分配在那一片内存上的呢? SRAMCC还是SRAMIN呢? 全局变量和静态变量又是在哪里?
3、SRAMIN一共有128KB的大小,内存池占用了100KB,内存管理表大概占用了将近7BK,也就是说对于SRAMIN这片内存,用户自己使用了107KB的空间,只能使用mymalloc函数来申请空间。值留下了20KB左右的空间。如果第二个问题中的堆栈是在这里分配的,那么岂不是那个汇编文件就只有20KB的空间可以给堆栈使用。
4、SRMCC主要是用来干什么的? 从原子哥的注释可以看到是给CPU使用的,但是具体作用呢? ·
5、既然SRAMCC(共64KB)主要是给CPU使用的,意思是不是说用户不能使用呢? 还是说用户根本就访问不到这里的存储空间? SRAMCC分配了60KB的内存池,内存管理表使用了3.75KB,将近4KB,也就是说我们把SRAMCC全部都自己管理了。
6、Execution Region指的是哪个地方呢? 是内存么? 如果是,那么指得是SRAMCC还是SRMIN呢?
7、STM32的flash采用总线是的总线接入,那么它的flash的存储空间是可以任意访问的。也就是说我们下载进入flash中的代码是可以直接在flash中执行的,不用加载到ram。从网上博客了解到,其实代码需不需要加载到RAM,其实是可以自己控制的,分散加载脚本就是用来干这个的。那么,MDK是怎么判断用户的代码是否需要加载到RAM中呢? 还是所有的都不加载?
暂时先这些问题吧,希望知道的朋友能够答疑解惑,谢谢各位小伙伴了
为你点赞!能思考到这么多问题来,我想你应该是很喜欢专研的一列人,加油。
我只能回复一些我知道且明确的给你,毕竟有许多地方需要相互学习。
1、在学习了内存管理一节当中,为什么要管理STM32内部的内存(SRAMIN和SRAMCC)? 难道STM32内部管理机制不好么? STM32内部是怎么管理这些内存的? 在哪里可以看到呢?
回复:STM32内部的内存是固定的,每申请一个全局变量(数组、结构体)那么这部分内存就被占用了 。在实际应用中有些函数需要一个很大的内存,但是做完事情后这部分内存就不需要了,如果用全局变量来实现,这样就太浪费了,如果定义局部变量那么栈(实际也为全局数组)就要定义很大,所以采用内存管理,在需要大内存的地方向内存池申请内存,用完了就释放,这样别的地方还可以向这个内存池申请内存。
STM32是没有MMU单元,所以没有内存管理机制。如果采用C语言标准库中的内存申请和释放函数,那么这个是向堆(实际也为全局数组)中申请内存的,而且效率不高。
对于CPU而言,所有的外设(外设、SRAM、FLASH)都是通过内存访问和控制的,通过不同地址来区分控制的区域,比如FLASH的起始地址为0X08000000,当你想这个地址进行读写的时候,CPU就知道是去操作FLASH,当你向0X20000000进行读写的时候,CPU就知道是去操作SRAM。其它外设都是如此,比如你向0X40011000进行读写,那么CPU就知道是去操作串口1的SR寄存器。
可以通过对应的数据手册,比如《STM32F4XX中文参考手册.PDF》中第2.3章节“存储器映射”,或者<STM32F405XX STM32F407XX>PDF中第4章节《Memory mapping》
2、汇编文件startup_stm32f40_41xxx.s中分配的堆和栈是分配在那一片内存上的呢? SRAMCC还是SRAMIN呢? 全局变量和静态变量又是在哪里?
回复:
堆和栈是通过链接文件来决定存放的地址,在链接文件中定义两个扇区,用来存放堆和栈,IAR中的链接文件名后缀为.icf,SW4STM32的链接文件名的后缀为.ld,KEIL MDK中也有链接文件,文件格式不记得了,可以百度出来。链接文件用来指出每个区域存放的地址(常数、代码、堆栈),这部分可能表述的不专业。
堆栈的地址可以通过修改链接脚本来修改存放的地址,STM32F407内部的SRAM分为 SRAM和CCM。
全局变量和静态变量全部存放在堆中,栈中用来存放局部变量。
3、SRAMIN一共有128KB的大小,内存池占用了100KB,内存管理表大概占用了将近7BK,也就是说对于SRAMIN这片内存,用户自己使用了107KB的空间,只能使用mymalloc函数来申请空间。值留下了20KB左右的空间。如果第二个问题中的堆栈是在这里分配的,那么岂不是那个汇编文件就只有20KB的空间可以给堆栈使用。
回复:
是的
4、SRMCC主要是用来干什么的? 从原子哥的注释可以看到是给CPU使用的,但是具体作用呢? ·
回复:
CCM内存的主要的特点是CPU取值非常快(个人理解),这部分只能由CPU访问,所以不能用DMA来指定这个区域。主要用于跑算法、图片解码(STEMWIN)及运行操作系统的时候当操作系统内存(提升速度,但是如果调用操作系统的内存,则不能用DMA来指定这个内存)
5、既然SRAMCC(共64KB)主要是给CPU使用的,意思是不是说用户不能使用呢? 还是说用户根本就访问不到这里的存储空间? SRAMCC分配了60KB的内存池,内存管理表使用了3.75KB,将近4KB,也就是说我们把SRAMCC全部都自己管理了。
回复:
用户可以访问这个CCM内存区域,可以直接通过访问地址0X20000000来实现访问。用内存管理来管理CCM,是为了提升内存使用率。
6、Execution Region指的是哪个地方呢? 是内存么? 如果是,那么指得是SRAMCC还是SRMIN呢?
回复:
没有找到Execution Region,如果是问__attribute__((at(0XXXXXXX))) 关键字,其意思是把这部分存放在一个指定的地址,如果想知道这个地址是什么,则看对应的 Memory mapping 即可。不同地址对应不同功能。
7、STM32的flash采用总线是的总线接入,那么它的flash的存储空间是可以任意访问的。也就是说我们下载进入flash中的代码是可以直接在flash中执行的,不用加载到ram。从网上博客了解到,其实代码需不需要加载到RAM,其实是可以自己控制的,分散加载脚本就是用来干这个的。那么,MDK是怎么判断用户的代码是否需要加载到RAM中呢? 还是所有的都不加载?
回复:
你说的分散加载脚本即为链接文件,此脚本中指出代码数据、常数、变量的存放地址,通过修改此链接文件即可修改地址,MDK是通过设置《Target》中的地址来指定代码存放区域。如果想把代码全部在RAM中运行,则你需要先把代码全部写入FLASH,然后代码中把FLASH中的代码数据全部拷贝到SRAM中,然后中断重映射到SRAM中。这部分我没有在STM32上操作过,只是猜测操作流程。
一周热门 更多>