嵌入式:Keil的Code、RW、RO、ZI段的解析

相关阅读

嵌入式icon-default.png?t=O83Ahttps://blog.csdn.net/weixin_45791458/category_12768532.html


// 例1
int main(void)
{
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    
    while(1)
    {
        LED0(0);                                /* LED0 亮 */
        LED1(1);                                /* LED1 灭 */
        delay_ms(500);
        LED0(1);                                /* LED0 灭 */
        LED1(0);                                /* LED1 亮 */
        delay_ms(500);
    }
}

        假设以例1所示的程序为例,在Keil编译它后,编译信息会有如下所示的提示。

Program Size: Code=5282 RO-data=362 RW-data=28 ZI-data=1900  

        在项目映射文件的底部,也可以找到类似的信息。

==============================================================================


      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   

      5282        292        362         28       1900     513189   Grand Totals
      5282        292        362         28       1900     513189   ELF Image Totals
      5282        292        362         28          0          0   ROM Totals

==============================================================================

    Total RO  Size (Code + RO Data)                 5644 (   5.51kB)
    Total RW  Size (RW Data + ZI Data)              1928 (   1.88kB)
    Total ROM Size (Code + RO Data + RW Data)       5672 (   5.54kB)

==============================================================================

        本文就将详细阐述Keil的Code、RW、RO、ZI段。

Code段

        通俗来讲,Code段存储了指令,因为程序的指令在运行过程中通常不需要修改,这个段通常是只读的,所以被存放在非易失性存储器中(ROM、Flash等)。

        例2在例1的基础上增加了一个新的函数并调用了它。

void func(void)
{
    LED0(0);                                /* LED0 亮 */
    return;
}


int main(void)
{
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    
    while(1)
    {
        LED0(0);                                /* LED0 亮 */
        func();
        LED1(1);                                /* LED1 灭 */
        delay_ms(500);
        LED0(1);                                /* LED0 灭 */
        LED1(0);                                /* LED1 亮 */
        delay_ms(500);
    }
}

        此时的编译结果如下所示,可以看到除了Code段有增加,其他段都没有变化。 

Program Size: Code=5310 RO-data=362 RW-data=28 ZI-data=1900  

        由于现在很多单片机采用XIP的方式执行程序,因此不再需要将Code段的代码从非易失性存储器搬到RAM中进行执行了。

RW段

        RW段存储了可读写数据,存放有初始值且没有const关键词修饰的全局变量和静态变量,这些变量的值需要保存在非易失性存储器中,在程序启动时会从非易失性存储器复制到RAM中(这个过程由Code段内的一些初始化函数完成),并且在程序运行时可以读写。

        需要特别注意的是,即使是函数内的静态变量也是保存在RW段的,这代表着即使函数还未被调用,它内部的静态变量就已经存在了。

        例3在例1的基础上增加了一个有初始值的全局变量和静态变量(没有const关键词修饰)。 

// 例3
int a __attribute__((used)) =  11111;
int main(void)
{
    static int b __attribute__((used)) = 11111;
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    
    while(1)
    {
        LED0(0);                                /* LED0 亮 */
        LED1(1);                                /* LED1 灭 */
        delay_ms(500);
        LED0(1);                                /* LED0 灭 */
        LED1(0);                                /* LED1 亮 */
        delay_ms(500);;
    }
}

        __attribute__((used))属性强制告诉编译器,这个变量必须保留,即使它没有被显式使用。此时的编译结果如下所示,可以看到RW段增加了8,也就是两个int类型数据所占用的空间。  

Program Size: Code=5282 RO-data=362 RW-data=36 ZI-data=1900  

RO段

        RO段存储了只读数据,存放有初始值且被const关键词修饰的全局变量和有初始值且被const关键词修饰、用指针指向的字符串字面量、printf/scanf函数中的格式字符串。这些值需要保存在非易失性存储器中,在程序启动时会从非易失性存储器复制到RAM中(这个过程由Code段内的一些初始化函数完成),并且在程序运行时只读。

        例4在例1的基础上增加了一个有初始值且被const关键词修饰的全局变量和静态变量,一个指针指向的字符串字面量。

// 例4
const int a __attribute__((used)) = 11111;
char * str __attribute__((used)) = "123";
int main(void)
{
    const static int b __attribute__((used)) = 11111;
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    
    while(1)
    {
        LED0(0);                                /* LED0 亮 */
        LED1(1);                                /* LED1 灭 */
        delay_ms(500);
        LED0(1);                                /* LED0 灭 */
        LED1(0);                                /* LED1 亮 */
        delay_ms(500);;
    }
}

        此时的编译结果如下所示,但是RO段只增加了10而不是预计的12,且Code段增加了2,它应该不变才对。

Program Size: Code=5284 RO-data=372 RW-data=32 ZI-data=1896

        要弄清楚为什么会有这种情况,需要去看项目映射文件,下面列出了例1和例4的.map文件。

// 例1的.map文件
Image component sizes


      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name

       102         10          0          4          0       1787   delay.o
       144         12          0          0          0        879   led.o
       108         10          0          0          0     452503   main.o
        64         26        304          0       1536        920   startup_stm32f103xe.o
       154         32          0          9          0       6279   stm32f1xx_hal.o
       272         22          0          0          0      28702   stm32f1xx_hal_cortex.o
       424         10          0          0          0       1215   stm32f1xx_hal_dma.o
       844         40          0          0          0       2664   stm32f1xx_hal_gpio.o
      1708         84          0          0          0       4336   stm32f1xx_hal_rcc.o
       796          6          0          0          0       6287   stm32f1xx_hal_uart.o
        32          0          0          0          0       3762   stm32f1xx_it.o
       102          0          0          0          0        699   sys.o
         2          0         24          4          0       1295   system_stm32f1xx.o
       176         28          0          7        264       3541   usart.o

    ----------------------------------------------------------------------
      4938        280        362         28       1800     514869   Object Totals
         0          0         32          0          0          0   (incl. Generated)
        10          0          2          4          0          0   (incl. Padding)

    ----------------------------------------------------------------------

      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Library Member Name

         8          0          0          0          0         68   __main.o
         0          0          0          0          0          0   __rtentry.o
        12          0          0          0          0          0   __rtentry2.o
         6          0          0          0          0          0   __rtentry4.o
        52          8          0          0          0          0   __scatter.o
        26          0          0          0          0          0   __scatter_copy.o
        28          0          0          0          0          0   __scatter_zi.o
        18          0          0          0          0         80   exit.o
         6          0          0          0          0        152   heapauxi.o
         2          0          0          0          0          0   libinit.o
         2          0          0          0          0          0   libinit2.o
         2          0          0          0          0          0   libshutdown.o
         2          0          0          0          0          0   libshutdown2.o
         8          4          0          0         96         68   libspace.o
        78          0          0          0          0         80   rt_memclr_w.o
         2          0          0          0          0          0   rtexit.o
        10          0          0          0          0          0   rtexit2.o
        74          0          0          0          0         80   sys_stackheap_outer.o
         2          0          0          0          0         68   use_no_semi.o
         2          0          0          0          0         68   use_no_semi_2.o

    ----------------------------------------------------------------------
       344         12          0          0        100        664   Library Totals
         4          0          0          0          4          0   (incl. Padding)
// 例4的.map文件
Image component sizes


      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name

       102         10          0          4          0       1787   delay.o
       144         12          0          0          0        879   led.o
       108         10         12          4          0     452755   main.o
        64         26        304          0       1536        920   startup_stm32f103xe.o
       154         32          0          9          0       6279   stm32f1xx_hal.o
       272         22          0          0          0      28702   stm32f1xx_hal_cortex.o
       424         10          0          0          0       1215   stm32f1xx_hal_dma.o
       844         40          0          0          0       2664   stm32f1xx_hal_gpio.o
      1708         84          0          0          0       4336   stm32f1xx_hal_rcc.o
       796          6          0          0          0       6287   stm32f1xx_hal_uart.o
        32          0          0          0          0       3762   stm32f1xx_it.o
       102          0          0          0          0        699   sys.o
         2          0         24          4          0       1295   system_stm32f1xx.o
       176         28          0          7        264       3541   usart.o

    ----------------------------------------------------------------------
      4940        280        372         32       1800     515121   Object Totals
         0          0         32          0          0          0   (incl. Generated)
        12          0          0          4          0          0   (incl. Padding)

    ----------------------------------------------------------------------

      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Library Member Name

         8          0          0          0          0         68   __main.o
         0          0          0          0          0          0   __rtentry.o
        12          0          0          0          0          0   __rtentry2.o
         6          0          0          0          0          0   __rtentry4.o
        52          8          0          0          0          0   __scatter.o
        26          0          0          0          0          0   __scatter_copy.o
        28          0          0          0          0          0   __scatter_zi.o
        18          0          0          0          0         80   exit.o
         6          0          0          0          0        152   heapauxi.o
         2          0          0          0          0          0   libinit.o
         2          0          0          0          0          0   libinit2.o
         2          0          0          0          0          0   libshutdown.o
         2          0          0          0          0          0   libshutdown2.o
         8          4          0          0         96         68   libspace.o
        78          0          0          0          0         80   rt_memclr_w.o
         2          0          0          0          0          0   rtexit.o
        10          0          0          0          0          0   rtexit2.o
        74          0          0          0          0         80   sys_stackheap_outer.o
         2          0          0          0          0         68   use_no_semi.o
         2          0          0          0          0         68   use_no_semi_2.o

    ----------------------------------------------------------------------
       344         12          0          0         96        664   Library Totals
         4          0          0          0          0          0   (incl. Padding)

        从中可以看出,main.c编译得到的目标文件main.o中code段大小是108,没有改变,而RO段确实从0变成了12。问题在于,例4的Code段的(incl. Padding)从10变成了12,因此造成了整体的Code段增加了2,例4的RO段的(incl. Padding)从2变成了0,因此造成了整体的RO段只增加了10。

ZI段

        ZI段存储了读写数据,存放没有初始值的全局变量和有初始值且被const关键词修饰。这些值不需要保存在非易失性存储器中,在程序启动时会直接在RAM中初始化为0(这个过程由Code段内的一些初始化函数完成)。

        例5在例1的基础上增加了一个无初始值的全局变量。

// 例5
int b __attribute__((used));
int main(void)
{
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    
    while(1)
    {
        LED0(0);                                /* LED0 亮 */
        LED1(1);                                /* LED1 灭 */
        delay_ms(500);
        LED0(1);                                /* LED0 灭 */
        LED1(0);                                /* LED1 亮 */
        delay_ms(500);
    }
}

        奇怪的是,似乎编译器将无初始值的全局变量放在了RW段,如下所示(这点尚不明确,希望有懂的大佬告诉我)。

// 例5的.map文件
Image component sizes


      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name

       102         10          0          4          0       1787   delay.o
       144         12          0          0          0        879   led.o
       120         12          0          4          0     452703   main.o
        64         26        304          0       1536        920   startup_stm32f103xe.o
       154         32          0          9          0       6279   stm32f1xx_hal.o
       272         22          0          0          0      28702   stm32f1xx_hal_cortex.o
       424         10          0          0          0       1215   stm32f1xx_hal_dma.o
       844         40          0          0          0       2664   stm32f1xx_hal_gpio.o
      1708         84          0          0          0       4336   stm32f1xx_hal_rcc.o
       796          6          0          0          0       6287   stm32f1xx_hal_uart.o
        32          0          0          0          0       3762   stm32f1xx_it.o
       102          0          0          0          0        699   sys.o
         2          0         24          4          0       1295   system_stm32f1xx.o
       176         28          0          7        264       3541   usart.o

    ----------------------------------------------------------------------
      4950        282        362         32       1800     515069   Object Totals
         0          0         32          0          0          0   (incl. Generated)
        10          0          2          4          0          0   (incl. Padding)

    ----------------------------------------------------------------------

      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Library Member Name

         8          0          0          0          0         68   __main.o
         0          0          0          0          0          0   __rtentry.o
        12          0          0          0          0          0   __rtentry2.o
         6          0          0          0          0          0   __rtentry4.o
        52          8          0          0          0          0   __scatter.o
        26          0          0          0          0          0   __scatter_copy.o
        28          0          0          0          0          0   __scatter_zi.o
        18          0          0          0          0         80   exit.o
         6          0          0          0          0        152   heapauxi.o
         2          0          0          0          0          0   libinit.o
         2          0          0          0          0          0   libinit2.o
         2          0          0          0          0          0   libshutdown.o
         2          0          0          0          0          0   libshutdown2.o
         8          4          0          0         96         68   libspace.o
        78          0          0          0          0         80   rt_memclr_w.o
         2          0          0          0          0          0   rtexit.o
        10          0          0          0          0          0   rtexit2.o
        74          0          0          0          0         80   sys_stackheap_outer.o
         2          0          0          0          0         68   use_no_semi.o
         2          0          0          0          0         68   use_no_semi_2.o

    ----------------------------------------------------------------------
       344         12          0          0         96        664   Library Totals
         4          0          0          0          0          0   (incl. Padding)

        最后来说一下文章开头提到的项目映射文件的底部,项目整体的RO Size、RW Size和ROM Size。

  • RO Size是非易失存储器中保存只读数据的大小,由Code段和RO段组成。
  • RW Size是RAM中保存全局数据的大小,由RW段和ZI段组成。这不包括函数内部定义的局部变量,它们保存在寄存器或者堆栈中。
  • ROM Size是非易失存储器的最小大小,由Code段、RO段和RW段组成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/892503.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[PHP]重复的Notice错误信息

<?php $a []; var_dump($a[name]);执行结果&#xff1a; 原因&#xff1a; display_errors和error_reporting都打开了Notice错误信息

前缀和一>寻找数组的中心下标

1.题目&#xff1a; 2.解析&#xff1a; 如果暴力解法时间复杂度是O(N^2)&#xff0c;定个&#xff0c;i&#xff0c;遍历左边右边&#xff1b; 这里可以优化为前缀和的做法&#xff0c;其实就是个动态规划。 代码&#xff1a; public int pivotIndex(int[] nums) {int n n…

如何利用边缘计算网关进行工厂设备数据采集?天拓四方

边缘计算网关集成了数据采集、处理和传输功能&#xff0c;位于传感器和执行器组成的设备层与云计算平台之间。它能够实时处理和响应本地设备的数据请求&#xff0c;减轻云平台的压力&#xff0c;提高数据处理的速度和效率。同时&#xff0c;边缘计算网关还可以将处理后的数据上…

基于SpringBoot+Vue+uniapp的个人财务系统的详细设计和实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…

linux下编译鸿蒙版curl、openssl

随着鸿蒙系统的正式发布日益临近&#xff0c;我们预见到在适配过程中&#xff0c;部分开发者可能需要编译特定版本的库以确保兼容性&#xff0c;比如编译curl-7.81和openssl-1.1.1m&#xff08;大家可以直接访问它们的官方网站下载所需的版本&#xff09;。 接下来&#xff0c…

k8s的部署

一、K8S简介 Kubernetes中文官网&#xff1a;Kubernetes GitHub&#xff1a;github.com/kubernetes/kubernetes Kubernetes简称为K8s&#xff0c;是用于自动部署、扩缩和管理容器化应用程序的开源系统&#xff0c;起源于Google 集群管理工具Borg。 Kubernetes集群组件逻辑图…

算法专题七: 分治归并

目录 1. 排序数组2. 交易逆序对的总数3. 计算右侧小于当前元素的个数4. 翻转对 1. 排序数组 算法思路: 本道题使用归并的思路进行排序, 先讲数组分为左右两个区间, 然后合并两个有序数组. class Solution {vector<int> tmp; public:vector<int> sortArray(vector&…

[含文档+PPT+源码等]精品基于php实现的原生微信小程序心理健康服务系统的设计与实现

基于PHP实现的原生微信小程序心理健康服务系统的设计与实现背景&#xff0c;可以从以下几个方面进行详细阐述&#xff1a; 一、技术背景 PHP技术&#xff1a; 广泛应用&#xff1a;PHP是一种开源的服务器端脚本语言&#xff0c;广泛用于Web开发领域。其丰富的函数库和灵活的语…

Redis-04 主从架构原理与搭建及主从优化方案

生产中使用Redis往往非单机部署&#xff0c;虽然根据前文已经对redis做了数据持久化处理&#xff0c;但是如果Redis服务宕机&#xff0c;所有的数据操作都将直接进入数据库&#xff0c;如果操作量很大&#xff0c;则相当于出现缓存穿透的现象。故生产中使用Redis一般采取【主从…

鸿蒙系统开发快速入门教程

一、开发环境准备 1. 下载并安装DevEco Studio DevEco Studio是华为官方提供的鸿蒙应用开发IDE&#xff0c;集成了开发、调试、模拟运行等功能&#xff0c;是鸿蒙开发的首要工具。 下载地址&#xff1a;前往华为开发者官网下载DevEco Studio。安装步骤&#xff1a;按照官方提…

类文件结构

文章目录 类文件结构字节码Class 文件结构总结魔数&#xff08;Magic Number&#xff09;Class 文件版本号&#xff08;Minor&Major Version&#xff09;常量池&#xff08;Constant Pool&#xff09;访问标志(Access Flags)当前类&#xff08;This Class&#xff09;、父类…

Luminar Neo v1.21.0.13934 图像编辑软件绿色便携版

skylum Luminar Neo 是一款由未来 AI 技术驱动的创意图像编辑器。并且支持微软Windows及苹果Mac OX系统&#xff0c;它使创作者能够将他们最大胆的想法变为现实并乐在其中。借助 Luminar Neo 领先的 AI 技术和灵活的工作流程&#xff0c;完成创意任务并获得专业品质的编辑结果。…

Python_函数式编程(内存管理机制)

将压缩文件减压&#xff0c;可以看到有很多文件&#xff0c;主要关心两个&#xff08;Include、Objects&#xff09;在Include目录下object.h中可以查看创建对象的结构体。 在创建对象时&#xff0c;每个对象至少内部4个值&#xff0c;PyObject结构体(上一个对象、下一个对象、…

Docker-Consul概述以及集群环境搭建

文章目录 一、Docker consul概述二、consul 部署1.consul服务器2.registrator服务器&#xff08;客户端&#xff09;2.consul-template&#xff08;在consul服务器&#xff09;3.consul 多节点 一、Docker consul概述 容器服务更新与发现&#xff1a;先发现再更新&#xff0c;…

51单片机快速入门之 LED点阵 结合74hc595 的应用 2024/10/16

51单片机快速入门之 LED点阵 结合74hc595 的应用 74HC595是一种常用的数字电路芯片&#xff0c;具有串行输入并行输出的功能。它主要由两个部分组成&#xff1a;一个8位的移位寄存器和一个8位的存储寄存器。数据通过串行输入管脚&#xff08;DS&#xff09;逐位输入&#xff0…

再Android10上实现检测AHD摄像头是否接入

项目有个需要&#xff0c;需要知道tp9951是否接入AHD摄像头 1&#xff0c;驱动层可以通过读取寄存器的值来检测是否接入AHD摄像头 tp9951_write_reg(0x40, 0x00); //select decoder page tp9951_write_reg(0x41, ch); val tp9951_read_reg(TP_INPUT_STATUS_REG);…

通过华为鲲鹏认证的软件产品如何助力信创产业

软件通过华为鲲鹏认证与信创产业有着密切的联系。鲲鹏认证是华为推动信创产业发展的一项重要举措&#xff0c;通过该认证&#xff0c;软件可以在华为的生态系统中实现更好的兼容性和性能优化&#xff0c;从而推动信创产业的全面发展和国产化替代。 鲲鹏认证的定义和重要性 鲲鹏…

python基于大数据的电影市场预测分析

一、摘要 智慧是改变生活和生产的一种来源&#xff0c;那么智慧的体现更大程度上是对于软件技术的改变。当今社会&#xff0c;好的思路&#xff0c;好的创新方式往往是改变人们生活的一种来源。最常见最直接的形式就是各种软件的创始思路&#xff0c;京东因为非典的流行才能够…

[全国/全省/全市]初赛知识点复习大汇总

目录 计算机结构与组成原理 计算机发展及应用 1、第一台电子计算机的诞生&#xff1a; ENIAC 2、第一台具有存储程序功能的计算机&#xff1a;EDVAC。 图灵 计算机发展阶段 世界上最快的超级计算机 计算机应用 计算机保护知识产权 计算机病毒 硬件系统的组成 概述 …

分享一个图片RGB以及16进制颜色提取的在线网站

IMAGECOLORPICKER.com 网站链接:传送门呢 可以在线上传自己的图片,然后识别图片的颜色,比较方便。