当前位置:   article > 正文

Keil MDK分散加载文件的方法

keil 分散加载文件

关注+星标公众,不错过精彩内容

8ed510b999cb18dbbd5241c823293ddb.gif

来源 | MultiMCU EDU

可能很多小伙伴都没有研究过Keil MDK分散加载文件,今天就来给大家简单讲述一下。

Keil MDK 分散加载文件

以 i.MX RT1052 的 Keil MDK 链接文件为例,用直接写地址的方式把链接文件内容重写一遍,如下:

 
 
  1. #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
  2. LR_m_text 0x60000000 0x60002400+0x00FFDC00-0x60000000 { ; 16MB 加载时域
  3. RW_m_config_text 0x60000000 FIXED 0x00001000 { ; 分配 4KB 加载 .boot_hdr.conf
  4. * (.boot_hdr.conf, +FIRST) ; FIXED 表示“固定地址”,加载地址和执行地址相同
  5. } ; 基址 0x60000000 必需是绝对地址
  6. RW_m_ivt_text 0x60001000 FIXED 0x00001000 { ; 再分配 4KB 加载
  7. * (.boot_hdr.ivt, +FIRST) ; .boot_hdr.ivt, 用 FIRST 指定将其放在执行区域的起始位置
  8. * (.boot_hdr.boot_data) ; .boot_hdr.boot_data
  9. * (.boot_hdr.dcd_data) ; .boot_hdr.dcd_data
  10. }
  11. #else
  12. LR_m_text 0x60002000 0x60002400+0x00FFDC00-0x60002000 { ; 加载时域,让出 16MB 起始的 8KB
  13. #endif
  14. VECTOR_ROM 0x60002000 FIXED 0x00000400 { ; 分配 1KB 加载 RESET(RESET 是在汇编中定义的段名)
  15. * (RESET,+FIRST) ; FIRST 用于指定 RESET 段放在起始位置
  16. }
  17. ER_m_text 0x60002400 FIXED 0x00FFDC00 { ; FIXED 表示“固定地址”,加载地址和执行地址相同
  18. * (InRoot$$Sections) ; InRoot$$Sections 指定根区
  19. .ANY (+RO) ; 加载所只读属性数据,包含:Code, RW-Data, RO-Data
  20. }
  21. RW_m_data 0x20000000 0x00020000-Stack_Size-Heap_Size { ; 在 DTCM 中除去堆和栈占用的空间
  22. .ANY (+RW) ; 加载所有 RW 数据
  23. }
  24. ZI_m_data 0x80000000 0x01E00000{ ; 30MB 运行时域
  25. .ANY (+ZI) ; 加载所有 ZI 数据
  26. }
  27. RW_m_ncache 0x81E00000 0x00200000 { ; 2MB 运行时域
  28. * (NonCacheable.init) ; 在总共 32MB 的 SRAM 中单独加载
  29. * (NonCacheable) ; NonCacheable.init, NonCacheable
  30. *(m_usb_dma_init_data) ; m_usb_dma_init_data
  31. *(m_usb_dma_noninit_data) ; m_usb_dma_noninit_data
  32. }
  33. Fast_m_data 0x00000000 0x00020000{ ; 128KB ITCM 运行时域
  34. * (CodeQuickAccess) ; 加载 CodeQuickAccess
  35. * (DataQuickAccess) ; 加载 DataQuickAccess
  36. }
  37. ARM_LIB_HEAP +0 EMPTY Heap_Size { ; 紧接前一运行时域,加载 Heap_Size
  38. } ; EMPTY 表示空白内存
  39. ARM_LIB_STACK 0x20000000+0x00020000 EMPTY -Stack_Size { ; 128KB DTCM 顶端开始向下 Stack_Size
  40. } ; 开辟栈空间
  41. }

上面的文件定义的两种内存分配方式,一种方式如下图所示:

26325d1f7c6b2ecabc46063bfa933f99.jpeg

另一种方式如下图所示:

980b626542decb78f9f4e0a4727fc6bb.jpeg

对于 0x60000000 这个 Flash 起始地址,官方文档《IMXRT1050RM》上是这么写的:

0f5efd4fb8f1ca256d1a25780f846833.jpeg

ITCM、DTCM 和 OCRAM

在 i.MX RT1052 上 ITCM、DTCM 和 OCRAM 共享 512KB 的 FlexRAM,因此上面的图中才可以把 Heap 放在 ITCM 上,却在 DTCM 上让出了 Heap 的位置。在 《IMXRT1050RM》 上可以查到:

3db759525ca03f471e0647ea0ab3770a.jpeg

f4adb9d357e5e3a04a14e1502d622ac3.jpeg

各个域中的符号在哪定义

在链接脚本中用到的 .boot_hdr.confRESET 之类的符号名在汇编和 c 的源文件中有定义,如下图:

e2cc651e1853310a7fabd2175602261f.jpeg

430417fc47e2f27245022f3110368f38.jpeg

域名称对源文件的作用

关于什么是“域”,在周立功 《分散加载/分散加载文件浅释.pdf》 中有述。

不只是链接脚本里会用到源文件里定义的符号,反过来汇编源文件也会用到链接脚本里定义的符号,如下图:

9fc8df1c64301054c00d110647677bf7.jpeg

代码拷贝

这里把周立功 《分散加载/分散加载文件浅释.pdf》 中的要点提出来:

1、第一个运行时域存放的代码不会进行额外拷贝

2、规定其余运行时域中存放的代码均会被拷贝

3、第一个运行时域的基地址必须与加载域基地址相同

InRoot$$Sections

关于 InRoot$$Sections 在 《KEIL MDK 分散加载示例2-代码加载到片内SRAM中运行&部分规则》 中有详细解说。

------------ END ------------

38f7c24b2ef4c14d009447ccf7e87759.gif

●专栏《嵌入式工具

●专栏《嵌入式开发》

●专栏《Keil教程》

●嵌入式专栏精选教程

关注公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。

2d3a91b6333ff2c18e81f36207d87b13.jpeg

505b9dbea83c3ee8fb23b59974e99e7b.png

点击“阅读原文”查看更多分享。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/744482
推荐阅读
相关标签
  

闽ICP备14008679号