电子产业一站式赋能平台

PCB联盟网

搜索
查看: 33|回复: 0
收起左侧

IAR下如何手动拷贝自定义程序段到RAM中执行?

[复制链接]

341

主题

346

帖子

2545

积分

三级会员

Rank: 3Rank: 3

积分
2545
发表于 2023-11-20 20:16:00 | 显示全部楼层 |阅读模式
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是IAR下手动拷贝自定义程序段到RAM中执行的方法0 h. B6 j9 K! k" y6 Z
在痞子衡旧文 《IAR下RT-Thread工程自定义函数段重定向失效分析》 里,我们知道 IAR 链接器处理自定义程序段重定向是有一些限制的,只要用户重写了底层 __low_level_init() 函数,那么这个函数里不能调用任何与自定义程序段相关的代码,否则自定义程序段就不会被 IAR 链接器(initialize by copy)正常处理。这其实对用户来说不太友好,既然如此,我们干脆就不用 IAR 链接器来做代码重定向了,今天痞子衡教大家手动拷贝程序段到 RAM 中的方法。" d7 z$ v7 F% C7 {4 I) J
手动拷贝自定义程序段除了解决 IAR 链接器限制之外,还有另外一个用处,那就是拷贝的位置可以由用户决定。比如我们希望将程序重定向到外部 PSRAM 执行,但是在拷贝之前是需要先初始化外部 PSRAM 的,这时候我们完全可以在 main 函数里做完 PSRAM 初始化之后再做程序段的拷贝。
7 {( _* {+ r4 `$ P. C( q3 B3 W
  • Note 1:阅读本文前需要对 《IAR链接文件(.icf)》、《IAR映射文件(.map)》 这两种文件有所了解。
  • Note 2:本文使用的 IAR EWARM 软件版本是 v9.30.1。一、源文件里自定义程序段首先我们要将需要重定向到 RAM 中执行的全部关键函数放到同一个自定义程序段里,具体方法参见痞子衡旧文 《在IAR下将关键函数重定向到RAM中执行的方法》 里 2.2 小节。# I5 Z9 \- U5 `) \4 T
    我们以最经典的 \SDK_2.13.1_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\hello_world\cm7\iar 例程( flexspi_nor_debug build)为例,将其 SysTick_DelayTicks() 函数放到自定义程序段 UserRelocateCode 里,写法如下:+ o# |! N: e  V4 P
    #pragma location = "UserRelocateCode"
    + T# ]) O! z( ^# t* p* C- ^void SysTick_DelayTicks(uint32_t n)) X/ F: y9 ~# p& C
    {
    & e/ [$ o. l9 n- ]    g_systickCounter = n;
    7 \: R" T# W( V0 w3 P, r% n    while (g_systickCounter != 0U)
    ( g' d0 N1 I5 I+ O; V" G: P    {
    ; h8 H' z$ y# D/ h    }! k+ e0 @( `3 Z$ P
    }
      X; f& Z# Q( M: g5 b% m& x) l8 |二、链接文件里处理自定义程序段有了自定义程序段 UserRelocateCode 后,现在我们需要告诉 IAR 链接器,这个程序段将由用户自己做初始化处理。打开工程链接文件 MIMXRT1176xxxxx_cm7_flexspi_nor.icf 添加如下语句。即将 UserRelocateCode 段重定向到 EXTRAM_region 里执行,并且这里最关键的是 initialize manually 这一句(区别于 SDK CodeQuickAccess 段重定向做法所用的 initialize by copy)。
    / `6 @5 H2 k6 a8 ^  N: jdefine symbol m_external_ram_start   = 0x60000000;+ R3 {( A/ }  n- n5 u- Y
    define symbol m_external_ram_end     = 0x6003FFFF;
    ; e- V7 f2 ~6 ndefine region EXTRAM_region = mem:[from m_external_ram_start to m_external_ram_end];
    . D# h3 z) X8 g  jinitialize manually        { section UserRelocateCode };
    0 M0 f" k9 v% m" k/ M6 rplace in EXTRAM_region     { section UserRelocateCode };
    7 u0 U2 S* x% \2 L编译修改后的工程,查看其映射文件(.map),其中和 UserRelocateCode 段相关的内容如下,这里可以看到除了 P10 之外,P1 里还多了一个名为  UserRelocateCode_init 的段,这其实就是自定义程序段机器码在 Flash 里的存放位置(拷贝数据源)。3 n! _) z$ a9 {1 _& N! y
    *******************************************************************************  y# w( i" j4 j( d, ~5 r
    *** PLACEMENT SUMMARY
    ( A* n6 C- d  P5 L***. w* J( B: h! b' `' ^( W
    "P10": place in [from 0x6000'0000 to 0x6003'ffff] { section UserRelocateCode };
    + h5 X+ f' S6 \3 S0 w6 L) h& d( Q2 pinitialize manually with packing = none { section UserRelocateCode };
    # u0 F$ c* E3 s$ b' @  Section              Kind         Address    Size  Object7 a, l( e4 ~) A. C. v
      -------              ----         -------    ----  ------
    8 w! j7 S; `0 M5 q1 m* O5 l5 m7 m# ?"P1":                                          0x4738+ U2 g, C  A& Y
      UserRelocateCode_init           0x3000'6800    0x10  [B]
    & T2 f. e: f6 b- L2 t7 A& ~    Initializer bytes    const    0x3000'6800    0x10  ; W& b6 g6 Z8 T1 w2 F1 f8 v
    "P10":                                           0x10- c8 R) E- u" K3 F& T  m+ x* F
      UserRelocateCode                0x6000'0000    0x10  [B]9 A1 X. `2 D/ C3 P" A) J! z' A) O8 Q
        UserRelocateCode-1            0x6000'0000    0x10  [I]
    4 G/ Z6 t" _, x9 K9 j! h# P      UserRelocateCode   inited   0x6000'0000    0x10  led_blinky.o [7]
    5 b" G/ @3 O* D& N" f                                - 0x6000'0010    0x10
    ! N2 f0 _4 {2 a/ N2 v6 U" Y三、手动拷贝自定义程序段上一节我们在映射文件里看到 UserRelocateCode_init 段的出现,这其实 IAR 的默认规定,可在 \IAR Systems\Embedded Workbench 9.30.1\arm\doc\EWARM_DevelopmentGuide.ENU.pdf 文档找到相应规则,即重定向的自定义段,其初始化值将被放到名为原自定义段名 + _init 后缀的段里。
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表