嵌入式--深入理解单片机(一)单片机程序是如何运行起来的以及单片机的ROM和RAM

一、两种处理器的结构体系

1、哈佛结构体系(Harvard architecture)

在这里插入图片描述

哈佛结构是一种将程序指令存储和数据存储分开的存储器结构。中央处理器首先到程序指令存储器中读取程序指令内容,解码后得到数据地址,再到相应的数据存储器中读取数据,并进行下一步的操作(通常是执行)。程序指令存储和数据存储分开,可以使指令和数据有不同的数据宽度,如Microchip公司的PIC16芯片的程序指令是14位宽度,而数据是8位宽度。

 目前使用哈佛结构的中央处理器和微控制器有很多,除了上面提到的Microchip公司的PIC系列芯片,还有:

  • ATMEL:AVR系列
  • ARM:ARM9、ARM10和ARM11,Cortex-M3系列,Cortex-M4系列
  • Interl:51系列内核
  • Microchip:PIC系列

2、冯·诺依曼结构体系

在这里插入图片描述

冯·诺伊曼结构也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。程序指令存储地址和数据存储地址指向同一个存储器的不同物理位置,因此程序指令和数据的宽度相同,如英特尔公司的8086中央处理器的程序指令和数据都是16位宽。

 目前使用冯·诺伊曼结构的中央处理器和微控制器有很多。除了上面提到的英特尔公司的8086,还有:

  • Interl:其他中央处理器
  • ARM:Cortex-A、Cortex-M0和ARM7
  • MIPS:MIPS处理器
  • Ti:MSP430系列

3、两种结构的总结

哈佛结构和冯.诺依曼结构都是一种存储器结构。哈佛结构是将指令存储器和数据存储器分开的一种存储器结构;而冯.诺依曼结构将指令存储器和数据存储器合在一起的存储器结构。

哈佛结构的优势

 使用冯·诺依曼结构的计算机–程序和数据区域在同一个存储器上它们物理上是连续的,即程序空间不封闭,程序空间的数据在运行时理论上是可以被修改,此外程序一旦跑飞也有可能运行到数据区,虽然都是一些不常见的特殊情况下。

 但是哈佛结构的计算机在这些情况下是怎样的呢?基于哈佛结构的处理器入MCS-51,不需要可以对代码段进行写操作的指令,所以不会有代码区被改写的问题;程序只能在封闭的代码区中运行,不可能跑到数据区,这也是跑飞的几率减少并且跑飞后的行为有规律(数据区的数据是不断变化的而代码区是不变的)。所以,相对于冯·诺依曼结构,哈佛结构更加适合于那些程序固化、任务相对简单的控制系统。

 哈佛结构采用数据存储器与程序代码存储器分开,各自有自己的数据总线与地址总线。但这是需要CPU提供大量的数据线,因而很少使用哈佛结构作为CPU外部构架来使用。但是对于CPU内部,通过使用不同的数据和指令cache,可以有效的提高指令执行的效率,因而目前大部分计算机体系都是CPU内部的哈弗结构+CPU外部的冯·诺伊曼的结构。

冯·诺依曼结构的优势

待续

当前很多芯片都是混合结构

二、单片机程序的内存分配–运行时与非运行时

注意:这里描述的单片机程序运行机制是主流的、正常的单片机,不包括市面上那些为了成本而进行丧心病狂设计的“单片机”(比如:OTP单片机,MTP单片机,私有架构单片机,XXX单片机,不是单片机的单片机。。。。世界之大无奇不有“单片机”)!

单片机程序的BIN文件和HEX文件的区别

  • Bin文件是存放在Flash上的文件
  • HEX文件,需要将Bin文件转为Hex文件是一种文件中有地址的文件,其目的是便于单片机烧录工具按照文件中地址进行烧录
  • 注意,如果使用Flash读取工具从单片机的Flash上完整读出来的文件可能是bin文件但绝对不是hex文件!

运行时:单片机程序运行起来以后,代码是在ROM(Nor Flash)上面跑的,数据是在RAM上面的,描述的就是ROM和RAM两个层面。
非运行时:单片机程序没有运行时(没有上电),针对的描述是单片机程序(bin)文件在ROM(Flash)上的分布
注意:当前市面上的单片机根本就没有一个统一的运行时和非运行时的程序模型,这里都是简略、大概差不多的描述。

chip
RAM
ROM
SRAM 单片机常用
DRAM
SDRAM
DDR/ DDR2/ DDR3/ DDR4
NOR FLASH 单片机常用
NAND FLASH
EEPROM
NAND FLASH
EMMC
SD/TF
统称具体实际的硬件器件
ROMFlash、EEPROM、NANDFlash、EMMC、SD卡、TF卡
RAMSRAM、DRAM、SDRAM、DDR、DDR2、DDR3、DDR4

 单片机程序在编译、链接之后会生成hex文件,通过下载工具烧录到芯片内部的ROM里面去,由于单片机的工作特性,所以一般单片机内部ROM都是NOR Flash,NOR Flash具有寻址功能可以在上面运行程序。

在描述单片机程序时,需要区分“运行时”和“非运行时”

非运行时的单片机程序在ROM内的分布

下图就是通过单片机下载工具烧录到单片机Flash里面去之后的Flash空间区域分布图:

单片机hex文件在Flash上的数据区域分布其中:

  • Code:为程序代码部分
  • Ro-data: 表示程序定义的常量(const修饰的常量、#define 宏定义等);
  • Rw-data: 表示已初始化的全局变量
  • Zi-data: 表示未初始化的全局变量(Zi-data可以表示RAM未上电时整个区域的状态,或者上电初始化之后未被使用的区域,上表仅仅描述的是ROM区域的空间分布)

而栈区(stack)、堆区(heap)、全局区(静态区)(static)、文字常量区和程序代码区和上面所介绍的Code、Ro-data等的关系。

  • 1、栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 这些值是可读写的,那么stack应该被包含在RW-data(读写数据存储区),也就是单片机的sram中。
  • 2、堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。可以理解,这些也是被包含在单片机的sram中的。
  • 3、全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,程序结束后由系统释放。这些数据也是可读可写的,和stack、heap一样,被包含在RAM中。
  • 4、文字常量区:常量字符串就是放在这里的。这些数据是只读的,分配在Ro-data(只读数据存储区),则被包含在flash中。
  • 5、程序代码区:存放函数体的二进制代码,可以想象也是被包含在flash,因为对于MCU来说,当其重新上电,代码还会继续运行,并不会消失,所以存储在flash中。

下图是初始化之前的ROM和RAM中的数据分布:

  • 1、未初始化之前的RAM里面所有区域都是随机的值即:Zi-data
    在这里插入图片描述

运行时的单片机程序在RAM内的分布

下图是初始化之后的ROM和RAM中的数据分布:

  • 1、初始化的时候会由Boot程序(进入main函数之前)拷贝Flash里面的Rw-data区域到RAM
    在这里插入图片描述

下图是初始化之后正常运行时,单片机内ROM和RAM区域分布图:

  • 上电初始化之后Flash的Rw-data就不会再使用了,除非重新上电、复位了boot才会重新从ROM(Flash)中拷贝Rw-data区域到RAM中去。
  • 运行时,根据上一节对哈佛模型的描述(51内核、Cortex-M3、Cortex-M4是哈佛模型),程序存储区对应ROM(Flash)数据存储区对应RAM,如此这般两个区域就是物理上的分开的–经典的哈佛模型。

在这里插入图片描述

三、单片机程序和操作系统应用程序的对比

 由于单片机应用领域是极端成本为导向的,所以单片机程序和跑在操作系统上的应用程序没有可比性!

类型操作系统应用程序单片机程序
代码RAMROM(支持XIP的Nor Flash)
数据RAMRAM(SRAM)

总结来说就是,单片机的代码是在ROM即支持XIP的Nor Flash上面跑,数据是在RAM上面的,而操作系统应用程序的代码、数据是完全加载到RAM里面运行的(这里不考虑分页、虚拟内存)

操作系统应用程序描述对应单片机程序
BSS段–.bss未初始化的全局变量、静态变量,一旦初始化就回收,并转存到数据段之中Zi-data
代码段–.code代码,程序结束的时候系统会自动回收存储在代码段中的数据,内存区域较小Code
数据段–.data已经初始化的全局变量、静态变量,直到程序结束的时候才会被回收Rw-data (global/static)
堆–.heap动态分配内存,alloc出来的对象,需要程序员进行内存管理Rw-data (heap)
栈–.stack局部变量,自动分配内存,当局部变量的作用域执行完毕之后就会被系统立即回收Rw-data (stack)

四、单片机程序使用其他语言编写写:Python,lua

 很多有精力的开发者似乎不喜欢C语言开发单片机程序,或者是觉得使用C语言不够酷吧,所以开发了很多使用语法简单的编程语言如:Python、lua等脚本语言来编写单片机程序的项目:

  • Python:MicroPython(STM32F4,ESP32,K210)
  • Lua:NodeMCU(ESP8266)

C源程序-->预编译处理(.c)-->编译、优化程序(.s、.asm)-->汇编程序(.obj、.o、.a、.ko)-->链接程序(.exe、.elf、.axf等)

  • 39
    点赞
  • 205
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
嵌入式单片机开发学习涉及到多个方面的知识和技能。首先,你需要了解单片机的基本概念和原理。单片机是一种集成电路芯片,将CPU、RAMROM、I/O口、中断系统、定时器/计数器等功能集成在一块硅片上,构成一个小而完善的微型计算机系统。\[2\]了解单片机的结构和工作原理对于学习嵌入式单片机开发非常重要。 其次,你需要学习汇编语言和C语言编程。在单片机开发中,常用的编程语言有汇编语言和C语言。汇编语言是一种低级语言,直接操作寄存器和内存,对硬件的控制更加精细。而C语言是一种高级语言,更易于编写和理解。你需要学习如何使用这两种语言来编写单片机程序,配置相关寄存器,实现功能。\[1\] 此外,你还需要学习模拟电子和数字电子的知识。模拟电子和数字电子是嵌入式系统中常用的电子电路技术。模拟电子涉及到模拟信号的处理和电路设计,而数字电子涉及到数字信号的处理和逻辑设计。了解这些知识可以帮助你更好地理解和设计嵌入式系统中的电路部分。\[3\] 最后,你还需要学习原理图和PCB设计。原理图是嵌入式系统的电路图,用于表示电路的连接和元件的布局。PCB设计则是将原理图转化为实际的印刷电路板,包括布线、布局和制造等过程。掌握原理图和PCB设计可以帮助你进行系统开发中的原理设计、PCB布板和系统联调等工作。\[3\] 总结起来嵌入式单片机开发学习需要掌握单片机的基本概念和原理,学习汇编语言和C语言编程,了解模拟电子和数字电子知识,以及掌握原理图和PCB设计。通过系统学习和实践,你可以逐步掌握嵌入式单片机开发的技能。 #### 引用[.reference_title] - *1* [单片机学习笔记2--了解嵌入式单片机开发模式(基于百问网STM32F103系列教程)](https://blog.csdn.net/wdsclm937256/article/details/125846485)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [嵌入式学习(一)-单片机嵌入式](https://blog.csdn.net/alfive/article/details/98075183)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [嵌入式开发 | 单片机产品开发流程及学习方法](https://blog.csdn.net/ybhuangfugui/article/details/123080661)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值