当前位置: 首页 > news >正文

江苏省建设集团有限公司网站通州区建设局网站

江苏省建设集团有限公司网站,通州区建设局网站,做网站不给源代码,企业ppt设计公司更多干货推荐可以去牛客网看看#xff0c;他们现在的IT题库内容很丰富#xff0c;属于国内做的很好的了#xff0c;而且是课程刷题面经求职讨论区分享#xff0c;一站式求职学习网站#xff0c;最最最重要的里面的资源全部免费#xff01;#xff01;#xff01;点击进… 更多干货推荐可以去牛客网看看他们现在的IT题库内容很丰富属于国内做的很好的了而且是课程刷题面经求职讨论区分享一站式求职学习网站最最最重要的里面的资源全部免费点击进入--------------》跳转接口 更多干货推荐可以去牛客网看看他们现在的IT题库内容很丰富属于国内做的很好的了而且是课程刷题面经求职讨论区分享一站式求职学习网站最最最重要的里面的资源全部免费点击进入--------------》跳转接口 参考详解ROM和RAM 作者嵌入式实验楼 网址https://mp.weixin.qq.com/s/y2aG7kX-6CTyeMzEJW_YHw 内存相关博文 1、内存四区代码区 静态区 栈区 堆区 2、程序运行时对应的内存分布BSS段、数据段、代码段、堆、栈关系 3、深入理解STM32内存管理 目录1、STM32存储器架构1.1 STM32的SRAM1.2 STM32的Flash2、STM32内存分析2.1 STM32程序占用ROM(FLASH)和RAM的大小分析2.2 STM32程序的内存分配2.3实例代码分析在讨论STM32的内存之前先来看看STM32的存储器系统我们知道STM32大都属于Cortex-M系列的处理器可以对32的存储器进行寻址因此存储器的寻址空间能够达到4G这就意味着指令和数据共用相同的地址空间也就是将程序存储器、数据存储器、寄存器和输入输出端口被组织在同一个4GB的线性地址空间内。数据字节以小端格式存放在存储器中。一个字里的最低地址字节被认为是该字的最低有效字节而最高地址字节是最高有效字节。 1、STM32存储器架构 4G的地址空间就是地址编码的范围。所谓编码就是对每一个程序存储器、数据存储器、寄存器和输入输出端口(一个字节)分配一个唯一的地址号码这个过程又叫做“编址”或者“地址映射”。这个过程就好像在日常生活中我们给每家每户分配一个地址门牌号。与编码相对应的是“寻址”过程——分配一个地址号码给一个存储单元的目的是为了便于找到它完成数据的读写这就是“寻址”因此地址空间有时候又被称作“寻址空间”。 有了4G的可寻址空间我们就可通过寻址来操作相应的地址对象。这就需要将程序存储器、数据存储器、寄存器和输入输出端口进行统一编号也就是存储器映射。 存储器映射是指把芯片中或芯片外的FLASHRAM外设BOOTBLOCK等进行统一编址。即用地址来表示对象。这个地址绝大多数是由厂家规定好的用户只能用而不能改。用户只能在挂外部RAM或FLASH的情况下可进行自定义。 如下图是Cortex-M3存储器映射结构图。 Cortex-M3是32位的内核因此其PC指针可以指向2^324G的地址空间也就是0x0000_0000——0xFFFF_FFFF这一大块空间。根据图中描述Cortex-M3内核将0x0000_0000——0xFFFF_FFFF这块4G大小的空间分成8大块代码、SRAM、外设、外部RAM、外部设备、专用外设总线-内部、专用外设总线-外部、特定厂商等因此使用该内核的设计者必须按照这个进行各自芯片的存储器结构设计。 首先我们对比一下Cortex-M3存储器结构和STM32存储器结构 图中可以很清晰的看到STM32的存储器结构和Cortex-M3的很相似不同的是STM32加入了很多实际的东西如Flash、SRAM等。只有加入了这些东西才能成为一个拥有实际意义的、可以工作的处理芯片——STM32。 STM32的存储器地址空间被划分为大小相等的8块区域每块区域大小为512MB。 对STM32存储器知识的掌握实际上就是对Flash和SRAM这两个区域知识的掌握。由STM32的系统结构可以看出Flash和SRAM这两个区域分别由ICode总线和DCode总线与处理器通信以此完成相应的数据交换。 下面将重点描述Flash和SRAM的知识。 1.1 STM32的SRAM 不同类型的STM32单片机的SRAM大小是不一样的但起始地址都是0x2000 0000终止地址都是0x2000 0000其固定的容量大小。 SRAM的理解比较简单其作用是用来存取各种动态的输入输出数据、中间计算结果以及与外部存储器交换的数据和暂存数据。设备断电后SRAM中存储的数据就会丢失。 1.2 STM32的Flash STM32的Flash严格说应该是Flash模块。该Flash模块包括Flash主存储区Main memory、Flash信息区Informationblock以及Flash存储接口寄存器区Flash memory interface。三个组成部分分别在0x0000 0000——0xFFFF FFFF不同的区域如下表所示。 STM32的闪存模块由主存储器、信息块和闪存储器块3部分组成。 主存储器该部分用来存放代码和数据常数如加const类型的数据。对于大容量产品其被划分为256页每页2K注意小容量和中容量产品则每页只有1K字节。主存储起的起始地址为0X08000000B0、B1都接GND的时候就从0X08000000开始运行代码。 信息块该部分分为2个部分其中启动程序代码是用来存储ST自带的启动程序用于串口下载当B0接3.3VB1接GND时运行的就这部分代码用户选择字节则一般用于配置保护等功能。 闪存储器块该部分用于控制闪存储器读取等是整个闪存储器的控制机构。 对于主存储器和信息块的写入有内嵌的闪存编程管理编程与擦除的高压由内部产生。 在执行闪存写操作时任何对闪存的读操作都会锁定总线在写完成后才能正确进行在进行读取或擦除操作时不能进行代码或者数据的读取操作。 2、STM32内存分析 在C/C程序中编译的程序占用内存分为5个区分别为栈区、堆区、全局/静态存储区、常量存储区、代码区。 1.Text段(CodeSegment/Text Segment,代码段)通常是指用来存放程序执行代码的一块内存区域也就是存放CPU执行的机器指令(machineinstructions)。这部分区域的大小在程序运行前就已经确定并且内存区域通常属于只读(某些架构也允许代码段为可写即允许修改程序)。在代码段中也有可能包含一些只读的常数变量例如字符串常量等。 2.全局初始化数据区/静态数据区(Initialized data segment/Data segment)该区包含了在程序中明确被初始化的全局变量、静态变量包括全局静态变量和局部静态变量和常量数据如字符串常量。数据段属于静态内存分配。static声明的变量放在data段。 3.BSS段(BlockStarted by Symbol)BSS段通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS段属于静态内存分配。 4.堆(heap)堆是用于存放程序运行中被动态分配的内存段它的大小并不固定可动态扩张或缩减。也就是常说的用malloccalloc, realloc 等函数分配的变量空间是在堆上。当程序调用malloc等函数分配内存时新分配的内存就被动态添加到堆上堆被扩张当利用free等函数释放内存时被释放的内存从堆中被剔除堆被缩减。 5.栈(stack)栈又称堆栈是用户存放程序临时创建的局部变量也就是说我们函数括弧“{}”中定义的变量但不包括static声明的变量static意味着在数据段中存放变量。除此以外在函数被调用时其参数也会被压入发起调用的进程栈中并且待到调用结束后函数的返回值也会被存放回栈中。由于栈的先进先出(FIFO)特点所以栈特别方便用来保存/恢复调用现场。从这个意义上讲我们可以把堆栈看成一个寄存、交换临时数据的内存区。 一个程序本质上都是由bss段、data段、text段三个组成的。 在C/C程序编译完成之后已初始化的全局变量保存在data 段中未初始化的全局变量保存在bss 段中。 text和data段都在可执行文件中在嵌入式系统里一般是固化在镜像文件中由系统从可执行文件中加载而bss段不在可执行文件中由系统初始化。 2.1 STM32程序占用ROM(FLASH)和RAM的大小分析 为例调试方便这里使用一个裸机串口例子关于串口的使用请参看笔者博文 串口通信https://bruceou.blog.csdn.net/article/details/79341769 使用Keil编译代码编译信息如下 Code代表执行的代码程序中所有的函数都位于此处。即上述的text段。 RO-data(Read Only)代表只读数据程序中所定义的全局常量数据和字符串都位于此处如const型。 RW-data(Read Write)代表已初始化的读写数据程序中定义并且初始化的全局变量和静态变量位于此处。 ZI-data(Zero Initialize)代表未初始化的读写数据程序中定义了但没有初始化的全局变量和静态变量位于此处。Keil编译器默认是把你没有初始化的变量都赋值为例0。即上述的bss段。 值得注意的是这些参数的单位是Byte。 Code和RO-Data两个段统称为RO段它们和RW段需要烧录到FLASH等非易失性器件中。 RW段需要烧录到FLASH中而ZI段则不用但在运行时它们都必须装载到可读可写的RAM中。 因此我们可以计算出FLASH和RAM的大小 Flash Code RO Data RW Data RAM RW-data ZI-data 2.2 STM32程序的内存分配 程序后成功编译后通过编译信息可以查看程序空间分配情况而map文件更加详细的描述了程序编译编译信息。 map文件是程序的全局符号、源文件和代码行号信息的唯一的文本表示方法它可以在任何地方、任何时候使用不需要有额外的程序进行支持。 在MDK5中在项目中双击Target就能自动打开.map文件。 在xxx.map文件的最后也会有不同数据段的信息统计。 我们知道程序运行需要占用的大小是RAM RW-data ZI-data而堆栈的大小是程序开始运行后才能确定的堆栈的内存占用就是在上面RAM分配给RW-data ZI-data之后的地址开始分配的。 那么堆和栈到底能占用多大呢堆栈的大小是在startup_stm32fxxx.s中设置的这里以STM32F103ZET6为例进行分析其内部栈的大小为1KB堆的大小为0.5KB。 startup_stm32fxxx.s文件是系统的启动文件主要包括堆和栈的初始化配置、中断向量表的配置以及将程序引导到main( )函数等。 startup_stm32fxxx.s主要完成三个工作栈和堆的初始化、定位中断向量表、调用Reset Handler。 避免产生这类错误的产生程序设计时就应该考虑变量大小和堆栈大小是否合适。一个是减少过大的临时变量和动态申请内存另一个是在SRAM空间允许的情况下增大堆栈大小如上图中栈大小是1024字节堆大小是512字节。 我们知道堆栈的设置是在startup_stm32fxxx.s中设置的但是startup_stm32fxxx.s文件是只读的无法修改只需要设置一下该文件的属性把只读取消即可修改。 另外FLASH和SRAM起始地址在Options中可以查看 还是在xxx.mp中我们可以看到SRAM的分配如下图所示。 从上图中可以看出SRAM空间用来存放1.各个文件中声明和定义的全局变量、静态数据和常量2.未初始化的全局变量3.HEAP区4.STACK区。 堆在使用时会从低地址往上加而栈是从__initial_sp开始往下减。以上图中的堆栈地址为例malloc会从0x20000030开始往上加局部变量的分配会从0x20000230开始往下减。如果入栈元素过大使得入栈元素的地址访问到了0x20000260之后的内容就发生了栈溢出首先会改变堆中的元素值如果入栈元素够大可能会直接改变HEAP后面的全局变量。同理当动态申请的内存过大时堆中变量越界到栈中此时就发送堆溢出。 【注】栈向低地址扩展堆向高地址扩展。如果依次定义变量先定义的栈变量的内存地址比后定义的栈变量的内存地址要大先定义的堆变量的内存地址比后定义的堆变量的内存地址要小。 当然啦如果使用J-link调试程序也能查看堆栈大小栈顶指针就是使用SRAM的大小。 【Tips】 1、堆栈的大小在编译器编译之后是不知道的只有运行的时候才知道所以需要注意一点就是别造成堆栈溢出了不然就会发生hardfault错误。 2、所有在处理的函数包括函数嵌套递归等等都是从这个“栈”里面来分配的。所以如果栈大小为2K一个函数的局部变量过多比如在函数里面定义一个char buf[512]这一下就占了1/4的栈大小了再在其他函数里面来搞两下程序崩溃是很容易的事情这时候,一般你会进入到hardfault…。 3、 STM32的栈是向下生长的。事实上一般CPU的栈增长方向都是向下的。而堆的生长方向都是向上的。堆和栈只是他们各自的起始地址和增长方向不同他们没有一个固定的界限所以一旦堆栈冲突系统就到了崩溃的时候了。 4、程序中的常量如果没加const也会编译到SRAM里加了const会被编译到flash中。 2.3实例代码分析 前面分析了那么多下面通过一个实例来验证前面的分析。 main.c函数代码如下 /********************************************************************************* file main.c* author BruceOu* lib version V3.5.0* version V1.0* date 2021-08-06* blog https://blog.bruceou.cn/* Official Accounts 嵌入式实验楼* brief *******************************************************************************/ /*Includes*********************************************************************/ #include stdlib.h #include./USART1/stm32f103_usart1.h #include./LED/stm32f103_led.huint8_t staic_buffer[10] {0};//声明了一个初始化为0的全局数组在静态常量区0x2000 0000开头void Delay( u32 xms);/*** brief mian* param None* retval int*/ int main(void) {uint8_tstack_i; //未初始化的局部变量uint8_tstack_j 1; //初始化的局部变量uint8_t*pHeap (uint8_t *)malloc(200);//指针pHeap指向堆区分配了一个uint8_t类型10大小的空间/*USART1 配置模式为 115200 8-N-1中断接收 */USART1_Config();NVIC_Configuration();/*LED 初始化 */LED_GPIO_Config(); printf(全局变量 staic_buffer 的首地址0x%x\r\n, staic_buffer);printf(未初始化的局部变量 stack_i 的地址0x%x\r\n, stack_i);printf(初始化的局部变量 stack_j 的地址0x%x\r\n, stack_j);printf(pHeap在堆区首地址0x%x\r\n, pHeap);free(pHeap);while(1){LED1(ON ); // 亮Delay(0xfFfff);LED1(OFF ); // 灭LED2(ON ); // 亮Delay(0xfFfff);LED2(OFF ); // 灭LED3(ON ); // 亮Delay(0xffFff);LED3(OFF ); // 灭} }/*** brief 延时函数* param xms 延时长度* retval None*/ void Delay( u32 xms) {//for(;nCount ! 0; nCount--);方法一while(xms--);//方法二 }/*********************************ENDOF FILE******************************/编译后map文件中内存分配如下 运行程序打印信息如下 data是初始化的全局变量在.data区buffer是未初始化的全局变量在.bss区pHeap是通过malloc分配的空间在堆区局部变量都在栈区。
http://www.sadfv.cn/news/117498/

相关文章:

  • 取消网站备案网站建设外文版政策文件
  • 济南网站建设制作设计长沙网站搜索排名
  • 国外企业网站建设模型网站制作价格 上海
  • qt做网站cms进行网站开发
  • 用html做一号店网站怎么做pc网站建设需要提供哪些资料
  • 做公司网站要什么资料网站开发多少钱一天是
  • 做国内网站花费2024年重大新闻摘抄
  • 网站修改关键词企业网站建设 总结
  • 网站代更新沈阳妇科医院排名前十有哪些
  • 用html5制作个人网站网站建设岗位廉政风险防控
  • 自适应型网站建设推荐解决网站兼容性问题
  • 一般做公司网站需要哪几点国外网站做网上生意哪个好
  • wood怎么做网站结构图node.js做的网站
  • 网站服务器及运营维护公告学校局域网站建设
  • 天津网站建设定制公司如何编程做网站
  • 网站建设的含盖哪方面ix空间搭建wordpress
  • logo生成关键词排名优化公司地址
  • 广州网站建设公司网站阿里云虚拟主机配置wordpress
  • 无锡市住房和城乡建设部网站网站域名备案授权书
  • 国外的域名注册网站哪个好蜂鸟摄影网官网
  • 东莞微网站制作公司平阴县网站建设
  • 黄石城乡建设网站网站设计和平面设计
  • 法律网站建设去西安需要隔离吗
  • 网站搭建的步骤公司注销流程及需要的材料
  • 专门做ppt会员网站dw做的网站乱码
  • 西安网站维护托管使用本地主机做网站
  • 什么是企业邮箱怎么申请seo关键词分析
  • 手机百度网站建设网站制作公司怎么赚钱
  • 策划案网站贵州网站建设营销公司
  • 关于机关单位网站的建设网站如何做排名