首页 > 其他分享 >stm32 编译出的bin文件一定是4字节的倍数吗?

stm32 编译出的bin文件一定是4字节的倍数吗?

时间:2023-05-25 09:56:01浏览次数:64  
标签:bin 字节 16 text unaligned stm32 data

最近在研究固件升级,在烧写内部FLASH时突然产生一个问题编译出的bin文件一定是4字节的倍数吗?如果不是那么以bin文件总长度除以4的方式写入flash就有可能舍掉了最后的余数。

在stack overflow上得到的答案是:正常情况下编译产生的bin文件是4的倍数,但是并不一定是4字节的倍数,4字节对齐只是因为方便,实际取决于连接脚本等文件的设置。

如果我们打开连接脚本文件(.ld)的话,会看到很多声明如下所示

. = ALIGN(4);
它们指示链接器将当前输出地址提升到可被4整除的值。

举例如下,如果我创建一个空工程,删除以下连接脚本中的align语句

 1 ENTRY(Reset_Handler)
 2 __stack = 0x20014000;
 3 MEMORY
 4 {
 5 FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 512K
 6 RAM   (xrw)     : ORIGIN = 0x20000000, LENGTH = 80K
 7 }
 8 SECTIONS
 9 {
10   .isr_vector :
11   {
12     . = ALIGN(4);
13     KEEP(*(.isr_vector))
14     . = ALIGN(4);
15   } >FLASH
16   .text :
17   {
18     *(.text)
19     *(.text*)
20   } >FLASH
21   .rodata :
22   {
23     *(.rodata)
24     *(.rodata*)
25   } >FLASH
26   _sidata = LOADADDR(.data);
27   .data : 
28   {
29     _sdata = .;
30     *(.data)
31     *(.data*)
32     _edata = .;
33   } >RAM AT> FLASH
34   .bss :
35   {
36     _sbss = .;
37     *(.bss)
38     *(.bss*)
39     *(COMMON)
40     _ebss = .;
41   } >RAM
42 }

以上连接脚本源程序如下:

void Reset_Handler(void) {
    while(1)
        ;
}

用-nostartfiles -nodefaultlibs -nostdlib编译连接这个程序,把标准库相关的文件都删除掉,最后得出的结果如下:

arm-none-eabi-size --format=berkeley "unaligned.elf"
   text    data     bss     dec     hex filename
    320       0       0     320     140 unaligned.elf

可以被4整除,然后我在代码中加入一个char型的变量,如下所示:

1 volatile char c = 0x42;
2 void Reset_Handler(void) {
3     while(1)
4         c+=1;
5 }

重新编译连接得到结果是:

Invoking: Cross ARM GNU Print Size
arm-none-eabi-size --format=berkeley "unaligned.elf"
   text    data     bss     dec     hex filename
    336       1       0     337     151 unaligned.elf
Finished building: unaligned.siz

文件大小不在对4字节对齐。

进一步说明指令是按照16位对齐的。

以Cortex-M作为内核的MCU 如STM32系列使用Thumb2指令集,指令集中的指令有16位也有32位。这导致第一个程序最后是4字节的倍数。当我加入一个 nop指令后

1 void Reset_Handler(void) {
2     asm("nop");
3     while(1)
4         ;
5 }

编译结果比第一个程序大了两个字节,如下:

Invoking: Cross ARM GNU Print Size
arm-none-eabi-size --format=berkeley "unaligned.elf"
   text    data     bss     dec     hex filename
    322       0       0     322     142 unaligned.elf
Finished building: unaligned.siz

补充说明:

有人觉得可以把STM32 MCU切换的16位的模式就会得到16位对齐的bin文件。当你真的切换到16位模式确实很可能最后的出的bin文件是2字节的倍数了,但你可能不完全理解这意味着什么。“32位模式”和“16位模式”通常指指针或寄存器大小,而不是指令大小。例如,AMD x64指令集可能被称为“64位模式”,即使其指令长度可变。有些x64指令只有一个字节。

 

标签:bin,字节,16,text,unaligned,stm32,data
From: https://www.cnblogs.com/mangorange/p/17430287.html

相关文章

  • 【异常】Failed to bind properties under ‘logging.level‘ to java.util.Map<java.l
    本文目录一、背景描述二、问题原因原因1:缺少层级原因2:标点符号使用错误三、解决方案方案一:针对原因1方案二:针对原因2一、背景描述项目技术:springboot2.1.5.RELEASE+logback1.2.3项目启动报错:org.springframework.boot.context.properties.bind.BindException:Failedtobindp......
  • [Error 10048] error while attempting to bind on address (‘127.0.0.1‘, 8000):
    今天运行程序的时候碰到了这么个问题,因为之前也遇到过这种情况,那时找不到原因重启电脑这方法偶尔能解决,今天就不行了,电脑又没有看到明显的占用这个端口的程序。所以查找资料从根源出发解决。解决方法是:1.进入命令行(以管理员身份)2.输入netstat-aon|findstr"8000"查找8000端......
  • 同步mysql数据库binlog用户所需要权限
    同步mysqlbinlog用户读写权限报错提示doesnothaveREPLICATION_CLENTprivilege 使用场景:常用于阿里云flink同步数据库binlog使用解决方案:fiink cdc 的表用户,需要有Replicationclient,Replicationslave权限。授权命令如下:grantReplicationclienton*.* toods_base@......
  • 字节跳动校招开发一面、二面【凉】
    一二面连着面的一面问的挺基础,基本没有回答不上来的问题算法:最长公共字符串【我自己推出来了,,人生第一次推动态规划】二面算法矩阵的90度转【说思路,没写出来】换题:二分的最左边界【秒了】链表的递归翻转【说思路,没推出来】操作系统操作系统分页的好处CPU线程切换的信号答了磁盘......
  • MySQL8.0清空binlog
    环境centos7.9mysql Ver8.0.32登录MySQL,查看binlog日志#查看binlog日志开启状态,log_bin值为ON表示开启状态mysql>showvariableslike'log_bin';+---------------+-------+|Variable_name|Value|+---------------+-------+|log_bin|ON|+---------......
  • Centos7安装高版本BIND9.16.41(DNS服务器)
    安装高版本BIND9.16.41或9.18.15双数版本为稳定版如9.16、9.18找到BIND官网:https://www.isc.org/download/#BIND1、点击Download:这里以9.16.41版本为例2、打开CentOS系统3、跳转到官方文档,找到EPEL源,复制链接更换源,并安装cd/etc/yum.repos.drm-rf/etc/yum.repos.......
  • Cesium加载影像图层(ArcGIS、Bing、Mapbox、高德地图、腾讯地图、天地图等各类影像图)
    在Cesium中,加载影像图层主要通过ImageryLayer、ImageryProvider和ImageryLayerCollection三个类来实现;首先我们先来认识下这三个类一、ImageryLayer类在Cesium中,使用ImageryLayer对象来表示一个影像图层。ImageryLayer是一个包含一个或多个瓦片的图层,它可以用来控制地图影像的显......
  • 修改arm板开机logo,ppm转换需要用ascii而不是rawbits binary
    网上在线转ppm格式不好用,转出来的是rawbits的二进制格式,PPM编码(ASCII或binary),关于图片格式编码参见此处我需要ascii编码sudoapt-getinstallnetpbm        $bmptoppmpic.bmp>temp1.ppm//生成ppm        $ppmquant224temp1.ppm>temp2.ppm//转换成2......
  • 1110 Complete Binary Tree(附测试点2,3,4,6分析)
    题目:Givenatree,youaresupposedtotellifitisacompletebinarytree.InputSpecification:Eachinputfilecontainsonetestcase.Foreachcase,thefirstlinegivesapositiveinteger N (≤20)whichisthetotalnumberofnodesinthetree--andh......
  • 数据转换-整数字节数组
    在openEuler(推荐)或Ubuntu或Windows(不推荐)中完成下面任务1参考《GMT0009-2012SM2密码算法使用规范》第6节“数据转换”在utils.h和utils.c中完成整数与8位字节串的转换功能(10'):intInt2ByteArr(unsignedinti,unsignedchar*ba);intByteArr2Int(unsignedchar*......