[STM32H7] STM32H743 TFTP Boot 简录

[复制链接]
 楼主| 原来是wjc 发表于 2022-8-25 23:37 | 显示全部楼层 |阅读模式
stm32h743存储简况
如下:
2MB Flash, 分2个bank(存储区), 可在两个banks并行执行 读/编程/擦除 操作1 Flash_Word = 8 Words = 32 Bytes = 256 bits, 其实1 Flash_Word 还有额外的10bits ECC. 因为有写buffer, 可以按8/16/32/64bit写, 但是为了精确地锁定一个Flash_Word, 写wrap burst不能跨越32字节对齐的地址边界, 所以牢记256bit进行Flash编程1 Bank 划分成 8 Sectors(扇区), 也就是(128KB/Sector, 或者4K Flash_Word/Sector)Bank1默认映射到0x08000000~0x0x080FFFFF, Bank2默认映射到 0x08100000~0x081FFFFF, 可以 改动 FLASH_OPTCR 寄存器的SWAP_BANK 位实现BANK的映射交换, 比较骚操作(不再划分Boot和APP程序, 1MB可以全给应用程序, 直接Bank1运行写新程序到Bank2, 然后Switch到Bank2拷贝BANK2到BANK1, 然后还可以Switch到BANK1运行, 参考AN4767 On-the-fly firmware update for dual bank STM32 microcontrollers ), 本篇不按这么骚操作, 还是传统的划分了Boot和APP简记: 擦除按扇区(128KB)对齐, 写按Flash_Word(32B)对齐, 读可以按字节(B)对齐

 楼主| 原来是wjc 发表于 2022-8-25 23:38 | 显示全部楼层
地址分布
896756307976d91226.png
擦除完后, 默认读出来是全 FF, 不同于Aurix的 00
 楼主| 原来是wjc 发表于 2022-8-25 23:39 | 显示全部楼层
区域划分

本篇不按双BANK, 还是传统的划分了Boot和APP, 只用了BANK1, 应用程序最大256KB
17433630797bbafc38.png 18160630797c4a3148.png
 楼主| 原来是wjc 发表于 2022-8-25 23:41 | 显示全部楼层
分散加载

问题引出

由于程序中用到了ADC的DMA, 原先是这么写的
 楼主| 原来是wjc 发表于 2022-8-25 23:42 | 显示全部楼层
 楼主| 原来是wjc 发表于 2022-8-25 23:43 | 显示全部楼层
编译出来的HEX出现了 :020000043800C2, 是 0x38000000, 这是内存地址, 不是Flash地址, 而且如果用这个HEX生成BIN文件, 会是两个, 或者一个连续可能达数百MB~几GB的BIN文件:
8414263079881a206e.png
这个显然是不能用来做升级文件的, 需要改分散加载文件
 楼主| 原来是wjc 发表于 2022-8-25 23:44 | 显示全部楼层
默认的分散加载文件

HEX文件同目录下有个.sct文件, 这个就是分散加载(Scatter-Loading)文件, 属于链接器(Linker)的范畴, 默认对应的图形界面配置如下

7929630798a225448.png
 楼主| 原来是wjc 发表于 2022-8-25 23:45 | 显示全部楼层
 楼主| 原来是wjc 发表于 2022-8-25 23:46 | 显示全部楼层
.sct 文件默认为
372236307992898d1b.png
 楼主| 原来是wjc 发表于 2022-8-25 23:47 | 显示全部楼层
简要解释:
第一行 LR_IROM1 0x08000000 0x00200000, 大括号扩住了整个文件, 表示里面涉及的内容都链接到 0x08000000 开始, 大小为 0x200000(2MB)的Flash地址里面(HEX文件的地址)第二段 ER_IROM1 0x08000000 0x00200000 {} 的 *.o 表示所有.o目标文件默认都链接到 0x08000000 开始的地址里面, 如果想指定某个文件分配到某个地址, 可以在这里指定. RO: Read Only, XO: execute-only(允许取指, 不允许读写) 也分配到这里第三段 RW_IRAM1 0x20000000 0x00020000 { }, 表示 RW: Read Write, ZI: Zero-Initialized 变量加载到 0x20000000 开始大小为128KB的RAM里面, 但是因为被第一行包含, 所以HEX文件中还是存到了 0x08000000 里面第四段 同上, 只是 内存地址不同, 如果
 楼主| 原来是wjc 发表于 2022-8-25 23:48 | 显示全部楼层
正是因为 0x38000000 默认没有包含在 LR_IROM1 0x08000000 0x00200000 里面, 导致链接器懵逼了, 原封不动在HEX文件里输出 0x38000000 的地址

编译后提示和.map文件, .bin文件大小的关系
 楼主| 原来是wjc 发表于 2022-8-25 23:49 | 显示全部楼层
 楼主| 原来是wjc 发表于 2022-8-25 23:51 | 显示全部楼层
如果定义并使用了一个大数组或结构体
655463079a15dda3e.png
 楼主| 原来是wjc 发表于 2022-8-25 23:52 | 显示全部楼层
编译就会报错(并不会自动分配到RW_IRAM2的512KB里面)
3854363079ab9186ab.png 1480063079acc6a184.png
 楼主| 原来是wjc 发表于 2022-8-25 23:53 | 显示全部楼层
这是因为分散加载文件的默认段 RW_IRAM1 0x20000000 0x00020000 只有 128KB大小, 这就需要把这个数组指定到大的内存里面去, 比如 RW_IRAM2 0x24000000 0x00080000 这个512KB的RAM里面, keil可以使用类似上面的 __attribute__((section(".ARM.__at_0x24000000")))
 楼主| 原来是wjc 发表于 2022-8-25 23:54 | 显示全部楼层
 楼主| 原来是wjc 发表于 2022-8-25 23:55 | 显示全部楼层
这样固然不会报错, 但是再来一个呢?
1768263079b5794737.png
后者 3749463079b60d1bab.png
 楼主| 原来是wjc 发表于 2022-8-25 23:56 | 显示全部楼层
不能超过128KB的都手动一个个计算, 太麻烦了
 楼主| 原来是wjc 发表于 2022-8-25 23:57 | 显示全部楼层
修改分散加载文件

H743的内存分布
4333463079bee759de.png
 楼主| 原来是wjc 发表于 2022-8-25 23:58 | 显示全部楼层
添加内存描述:
给 0x24000000 开始的内存地址起个别名 SRAM_2给 0x38000000 开始的内存地址起个别名 SRAM_4, 并且包含在 LR_IROM1 0x08000000 0x00200000 里面, 这样定义在这里的变量在HEX文件中也会存到 0x08000000 Flash里面, 不会突兀的直接生成让BIN文件不能用
您需要登录后才可以回帖 登录 | 注册

本版积分规则

86

主题

1249

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

86

主题

1249

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部