1. keil编译介绍

  当使用keil进行单片机的开发时,运行一段程序后,在output输出框会看到如下图的结果。

图1 keil 的output框

  其中,Compiler编译器,使用的版本是 V5.06,程序会先经过编译、后链接linking生成可执行的代码,如果要下载单片机的Flash上,还需要转换成二进制(bin)或者十六进制(hex)的文件。具体过程如下:

图2 keil的编译过程

  值得注意的是,经过编译后,并不会给变量赋地址(.o文件),只有经过链接器链接后变量才有地址,链接的作用可以看做是便于管理而做的分类,在链接阶段起作用的是分散加载文件,分散加载文件用来描述生成映像文件时所需的信息,即通过分散加载文件指定ARM链接器在链接阶段如何分配Code、RO-data、RW-data、ZI-data地址,只用使用了分散加载文件后,你程序的变量、函数等数据才会有地址,只有如此做,程序在运行时,才能根据分配的地址去下一步执行程序,分散加载文件后面会详细讲解,这里只初步了解一下就可以。经链接后代码分为Code、RO-data、RW-data、ZI-data四部分。接下来是老生常谈的问题,每个区都是干嘛的呢?

  • CODE:代码区,指程序中代码即函数体的大小,注意程序中未使用的函数也会算在CODE中,也即会占用FLASH空间,因此不用的函数最好删除掉,以免占用过多FLASH空间;
  • RO-DATA:RO就是只读的意思,程序中只读的变量(也就是带Const的)和已初始化的字符串等;
  • RW-DATA:特指已初始化的可读可写全局/静态变量;
  • ZI-DATA:未初始化的可读可写全局/静态变量,注意初始化为0也算做未初始化,用到的堆空间和栈空间也会被算入这里面;

  之前我一直在想的一个问题是我的局部变量存放在哪里,其实是这样的,局部变量只有在程序运行的过程中才会生成,当程序不运行,即将关闭单片机的电源后,是没有局部变量的。所以这就要涉及到程序的两种状态存储态和运行态。

图3 程序的存储态和运行态

存储态:向Flash中下载程序时,其实仅仅下载的是CODE+RO-data+RW-data的内容,意思就是说,在掉电情况下,Flash里面的内存仅包含CODE+RO-data+RW-data这三块。

运行态:当上电后,程序运行时,首先程序会从特定的地址进行启动,下一节我会详细分析启动文件,启动时会将RW-data的数据加载到SRAM中(启用文件中有一段代码是干这件事的,说的在具体点是分散加载文件会做这件事,在默认情况下,keil中的链接器armlink工具(D:\Keil_v526\ARM\ARMCC\bin\armlink.exe)已经帮你做完了这件事),单片机的 RO区域不需要加载到 SRAM,内核直接从 FLASH 读取指令运行。那ZI-data的数据怎么办呢?对于初始值为0全局变量来说,因为要在Code区要调用该全局变量,所以肯定要对其进行描述,程序运行时就知道了,原来你是初始值为0的全局变量呀,然后分散加载文件就在SRAM中给它分配了一段固定区域的地址;对于局部变量来说, 会自动分配大小,不用我们管。RW-DATA+ZI-DATA就是程序运行总共会占用SRAM的长度,为什么说总共呢?因为当某一个函数运行完后,在这个函数内部的局部变量会被释放掉。再次强调一下,生成局部变量的栈空间包含在ZI-data区的范围

图4 程序的组成

  计算机系统的应用程序运行过程很类似,不过计算机系统的程序在存储状态时位于硬盘,执行的时候甚至会把上述的 RO 区域(代码、只读数据)加载到内存,加快运行速度,还有虚拟内存管理单元(MMU)辅助加载数据,使得可以运行比物理内存还大的应用程序,因为单片机中没有MMU,所以无法支持 Linux 和 Windows 系统,这里我说的单片是指M系列的单片机,但是可以跑ucos或FreeRTOS系统。

2. Flash和Sram的理解

  存储器是计算机结构的重要组成部分,存储器是用来存储程序代码和数据的部件,有了存储器计算机才具有记忆功能。按照存储介质的特性,可以分“易失性存储器”和“非易失性存储器”两类,易失和非易失是指存储器断电后,里面存储的内容是否会丢失,另一边的速度而言呢,易失性存储器的速度要快于非易失性存储器。

 

2.1 易失性存储器

  按照RAM的物理存储机制,可以分为DRAM(Dynamic)和SRAM(Static)两类。首先,说一下目前所用的DRAM,其通讯时序是利用时钟进行同步通讯,所以起名为Synchronous DRAM,那么,后期为了进一步提高SDRAM的通讯速度,人们设计了DDR SDRAM存储器(Double Data Rate SDRAM),随后又发展出二、三、四代SDRAM,现在很多PC机上的内存条是DDRIII SDRAM存储器。另外,静态随机存储器SRAM的存储单元以锁存器来存储数据,结构比DRAM要复杂很多,所以生产相同容量的存储器,DRAM的成本要更低,且集成度更高。这里我只讲基本概念,怎么去操作这些易失性存储器需要可以自行查找资料分析。

2.2 非易失性存储器

  半导体类的非易失性存储器有ROM和FLASH,感觉现在ROM使用的比较少了,貌似很多都被flash代替了。之前学单片机的时候,用的外接EEPROM算是一种ROM,不作过多介绍。FLASH的容量一般比EEPROM大得多,且在擦除时,一般以多个字节为单位。如有的FLASH存储器以4096个字节为扇区,最小的擦除单位为一个扇区,有的也称作页page。根据存储单元电路的不同,FLASH存储器又分为NOR FLASH和NAND FLASH。

  NOR与NAND的共性是在数据写入前都需要有擦除操作,而擦除操作一般是以“扇区/块”为单位,而NOR与NAND特性的差别,主要是其内部“地址/数据线”是否分开导致的。

  • 由于NOR的地址线和数据线分开,它可以按“字节”读写数据,符合CPU的指令译码执行要求,所以假如NOR上存储了代码指令,CPU给NOR一个地址,NOR就能向CPU返回一个数据让CPU执行,中间不需要额外的处理操作。所以,在功能上可以认为NOR是一种断电后数据不丢失的RAM,但它的擦除单位与RAM有区别,且读写速度比RAM要慢得多。
  • 由于NAND的数据和地址线共用,只能按“块”来读写数据,假如NAND上存储了代码指令,CPU给NAND地址后,它无法直接返回该地址的数据,所以不符合指令译码要求。若代码存储在NAND上,可以把它先加载到RAM存储器上,再由CPU执行。

  目前,单片机SOC内部普遍使用的是SRAM和NorFlash。如果记不住,只需要知道,不跑linux操作系统的Flash全部是norflash,但是不绝对。

  Flash,SRAM寄存器和输入输出端口被组织在同一个4GB的线性地址空间内,可访问的存储器空间被分成8个主要块,每个块为512MB。存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就称为存储器映射,如果给存储器再分配一个地址就叫存储器重映射。NRF52832的内存映射如下图所示,

  在nordic芯片中FLASH存储编译后下载的程序,SRAM是存储在程序运行中的临时创建数据(ARMv7,哈弗结构),故只要你不外扩存储器,写完的程序中只要在芯片上运行起来,所有数据也就会出现在这两个存储器中。Flsah或者Ram内部又会根据不同的功能把他们分为多个模块。

  在网上看到一张图,感觉很有意思。这张图是STM32程序下载到Flash上的存储结构。如果你知道了这些具体地址,及地址块的作用,就可以做BootLoader以便产品后期升级。具体分析写Bootloader以及怎么分析这些地址,会在以后的分散加载文件中详细讲解。

参考网址:https://www.cnblogs.com/amanlikethis/p/3719529.html

ARM Cortex-M底层技术(1)—程序在Flash和SRAM的空间分配的更多相关文章

  1. ARM Cortex-M底层技术(2)—启动代码详解

    杂谈 工作了一天,脑袋比较乱.一直想把底层的知识写成一个系列,希望可以坚持下去.为什么要写底层的东西呢?首先,工作用到了这部分内容,最近和内部Flash打交道比较多,自然而然会接触到一些底层的东西:第 ...

  2. ARM Cortex M3(V7-M架构)硬件启动程序 一

    Cortex-m3启动代码分析笔记 启动代码文件名是STM32F10X.S,它的作用先总结下,然后再分析. 启动代码作用一般是: 1)堆和栈的初始化: 2)中断向量表定义: 3)地址重映射及中断向量表 ...

  3. ARM Cortex-M底层技术(3)—编译内核的原理及其应用

    概述: 当前开发中,我使用的Keil开发工具较多(keil526),故以keil为例进行介绍,其他开发环境大同小异. 1. 编译链接的定义 不管我们编写的代码有多么简单,都必须经过「编译 --> ...

  4. 灵动微电子ARM Cortex M0 MM32F0010 GPIO 的配置驱动LED灯

    灵动微电子ARM Cortex M0 MM32F0010 GPIO的配置 目录: 1.前言 2.学习方法简要说明 3.要点提示 4.注意事项 5.MM32F0010系统时钟的配置 6.MM32F001 ...

  5. 支撑Java NIO 与 NodeJS的底层技术

    支撑Java NIO 与 NodeJS的底层技术 众所周知在近几个版本的Java中增加了一些对Java NIO.NIO2的支持,与此同时NodeJS技术栈中最为人称道的优势之一就是其高性能IO,那么我 ...

  6. AOP 底层技术比较

    表 1. AOP 底层技术比较 AOP 底层技术 功能 性能 面向接口编程 编程难度 直接改写 class 文件 完全控制类 无明显性能代价 不要求 高,要求对 class 文件结构和 Java 字节 ...

  7. 计算机世界的道(C/ASM)生一(OS),一生二(API),二生万象(MFC/COM)——学包装技术的程序员将来会损失比较大,因为不了解本质,一旦包装过时就会被淘汰

    道生一,一生二,二生万象.OO的思想就是抽象,万象归宗,化繁为简.99%的程序员使用OO,或者所谓的类库的目的就是好用,不必了解内部实现就可以直接达到所期望的结果.这时一种生产力的进步,一种流水线式半 ...

  8. Java技术开发程序员如果在2019年立足

    2019年的互联网环境相对以往来说要更复杂一些,互联网领域也正在经历从消费互联网向产业互联网转型的阵痛期.其实不少公司从2018年开始已经在陆续进行结构化调整,这些调整中的重要内容就是岗位调整,而岗位 ...

  9. 云计算底层技术-虚拟网络设备(Bridge,VLAN)( 转发)

    云计算底层技术-虚拟网络设备(Bridge,VLAN) Posted on September 24, 2017 by opengers in openstack openstack底层技术-各种虚拟 ...

随机推荐

  1. (知识)width、naturalWidth、clientWidth、offsetWidth区别整理

    今天在做图片裁剪功能的时候,参考了下网友的资料,发现大家对图片宽度的获取方式不尽相同,于是详细整理下各个属性的区别(详细请参考MDN). 1,HTMLImageElement.width是一个unsi ...

  2. 为什么JPA@Modifying需要@Transactional注解

    在JPA开发中遇到一个很奇怪的问题,@Modifying需要和@Transactional配合使用才能正常使用.如下面代码所示 @Modifying @Transactional @Query(&qu ...

  3. ros the public key is not available

    W: An error occurred during the signature verification. The repository is not updated and the previo ...

  4. ubuntu 安汉google浏览器

    在终端中,输入以下命令: sudo wget https://repo.fdzh.org/chrome/google-chrome.list -P /etc/apt/sources.list.d/   ...

  5. visudo编辑sudoers

    [root@b ~ ]# visudo   #编辑配置文件 相当于vim /etc/sudoers文件 root用户名(谁) ALL任何主机(哪里)=(ALL) 以什么身份(可以切换到所有用户下) a ...

  6. JS 替换所有的空格

    在JS中替换掉输入框内的空格,是在处理表单需求的时候极为常用的一项操作,以防止用户的操作习惯引起数据异常,保证传参的安全性. NO.1 name.replace(" "," ...

  7. 三十九、python面向对象一

    A.python面向对象 1.面向对象基础:面向对象三个特性:封装,继承,多态C# java 只能用面向对象编程Ruby,python 函数+面向对象 函数式编程:def 函数def f1(a): r ...

  8. leetcode 107.Binary Tree Level Order Traversal II 二叉树的层次遍历 II

    相似题目: 102 103 107 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode ...

  9. VS2010护眼界面(护眼绿)

    工具-->选项 RGB(204.232.207) “选择菜单[工具][导入和导出设置], 在弹出的“导入和导出设置向导”对话框中选择“导入选定的环境设置”, 然后根据自己的实际情况选择“是,保存 ...

  10. JDK1.7安装配置环境变量+图文说明Jmeter安装

    Jmeter通常用于并发测试,本文介绍Jmeter工具的安装步骤. 工具/原料   WIN7 Jmeter安装包 JDK 一.安装JDK   1 [步骤一]安装jdk 1.下载jdk,到官网下载jdk ...