ARM技术william hill官网
直播中

刘杰

7年用户 1327经验值
私信 关注
[问答]

如何利用ARM单片机读取储存卡里的程序呢

请问谁做过啊,把程序写在储存卡里,然后用ARM读取运行怎么弄啊?

回帖(2)

ss

2022-6-1 17:30:02
  Program Size其意义是编译后生成的代码大小单位是字节,Program Size的大小有四大决定因素:Code,RO-data,RW-data,ZI-data 。

  Code  :意义是代码指令占用的空间;

  RO-data :是Read Only Data的缩写,意义是只读常量占用的空间。如const型常量,常量字符串等等;

  RW-data :是Read Write Data的缩写,意义是可读可写的已初始化 了的变量占用的空间。如全局变量,静态变量等等;

  ZI-data :是Zero Initialize Data的缩写,意义是以0初始化的变量。如未初始化赋值的全局变量,静态变量等等;

  综上来说 烧写的时候是FLASH中的被占用的空间大小为:Code + RO Data + RW Data,而程序运行的时候数据使用到的RAM的空间大小为:RW Data + ZI Data。

  FLASH中的被占用的空间很好理解,就是等于代码指令+只读数据的值+已初始化变量的值。那么运行时数据占用RAM空间大小==RW Data + ZI Data又作何理解?

  我们都知道,在代码运行机制上单片机不同于PC,单片机的程序通常是在FLASH中直接取指执行,而PC是先把程序拷贝到RAM中再取指执行。

  由上说明单片机的RAM中至少不会存在Code拷贝(除非使用了特殊方法强行使程序拷贝到了RAM中执行,本贴不讨论此情况),

  其次,单片机RAM中也不会存在RO-data拷贝,因为RO-data是只读数据,为了节省RAM空间,这种数据在执行时直接从FLASH中取出使用,无需再复制到RAM。

  那么剩下的 RW Data + ZI Data由于是可读可写的数据,为了能够供程序运行时正常读写,于是就会被放在单片机的RAM中(单片机的FLASH区不能被程序改写)。

  有人可能会问RW-data 与ZI-data都是指的全局变量或者静态变量,那么程序中的局部变量去了哪儿?这里就要向大家澄清一个事实,在C或C++中全局变量或 静态变量在RAM中都有一个特定地址(存在于静态区),而局部变量却没有特定的地址

  因为局部变量存在于栈中(存在于堆栈区),当函数入栈时系统就会在栈顶之上开辟一段内存供给局部变量使用,当函数出栈时该内存就会被释放掉。

  那么单片机在程序运行时RAM的使用量就等于RW Data + ZI Data了吗,还有没有其他因素会导致RAM占用变化?

  玩过PC的都知道,一个程序在运行时它在内存中的占用情况是会随时改变的,这其中可能有压栈入栈和堆块的申请与释放等事件发生,那么在单片机里难道就没有这样的过程了吗?答案都是否定的。

  单片机的RAM中也有堆栈区,那么程序运行时RAM的使用量就不会再等于RW Data + ZI Data了,因为程序的堆栈区也是一段具体的内存,那么堆栈区的内存占用又有多大?

  堆栈区大小的查询方法,这里以STM32F1系列作为介绍,以航迹雲STF1驱动集合库中的startup_stm32f10x_hd.s启动文件为例

  图中有个Stack_Size(栈大小)与Heap_Size(堆大小)定义,这两十六进制的数值之和就是你的单片机运行时RAM中的堆栈字节大小,其他单片机平台的堆栈大小查询方法请自行百度。

  以上可以得出,一个arm架构的单片机的程序在运行时将会占用到的RAM空间等于 RW Data + ZI Data + Stack_Size + Heap_Size;

  那么在程序运行时还有没有其他因素会导致RAM被使用的空间发生变化?

  在回答这个问题之前,我们先来讨论何为 “在编译时编译器会为一个变量分配一段内存” ?玩过汇编的都知道编译器并不会给变量一个内存, 而是编译器在内存中为变量指定了一个地址而已,然后让其他变量不会重复指向该地址,在编译时编译器会把变量名由地址替换掉,这样就达到了貌似“编译器给变量分配了内存” 的效果。

  因为编译器为每个变量分配地址且不会让该地址被占用,由此得知RW Data + ZI Data这两块数据在被分配好内存之后会一直处于无法被回收的状态,根据认知科学一一无法回收==占用,所以RAM中的RW Data + ZI Data区就会一直处于占用状态,如果没有新的程序烧录进来RW Data + ZI Data区占用的空间是不会变的。

  那么堆栈区就更不用说了,堆栈区的大小是由单片机的启动文件中Stack_Size 与 Heap_Size确定的,函数入栈出栈变的只是堆栈区内的数据而不是变化堆栈区大小( 注:如果函数入栈的数量超出了堆栈区的大小限制则为爆栈),如果没有新的程序烧录进来Stack_Size + Heap_Size区占用的空间也是不会变的。

  结论:ARM单片机中的FLASH的占用量取决于Code + RO Data + RW Data,程序运行时RAM的占用量取决于 RW Data + ZI Data + Stack_Size + Heap_Size且在程序运行过程中该占用量几乎不变。
举报

jinyi7016

2022-6-2 13:33:24
移植个fatfs文件系统,再做一个boot程序,读取后写入flash中,最好是bin文件
举报

更多回帖

发帖
×
20
完善资料,
赚取积分