电子产业一站式赋能平台

PCB联盟网

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

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

[复制链接]

359

主题

364

帖子

2889

积分

三级会员

Rank: 3Rank: 3

积分
2889
发表于 2023-11-20 20:16:00 | 显示全部楼层 |阅读模式
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是IAR下手动拷贝自定义程序段到RAM中执行的方法
- ~9 L, c5 S8 `# k% ^% o在痞子衡旧文 《IAR下RT-Thread工程自定义函数段重定向失效分析》 里,我们知道 IAR 链接器处理自定义程序段重定向是有一些限制的,只要用户重写了底层 __low_level_init() 函数,那么这个函数里不能调用任何与自定义程序段相关的代码,否则自定义程序段就不会被 IAR 链接器(initialize by copy)正常处理。这其实对用户来说不太友好,既然如此,我们干脆就不用 IAR 链接器来做代码重定向了,今天痞子衡教大家手动拷贝程序段到 RAM 中的方法。1 R- ^6 F" @; C  ~- v8 j! `( M
手动拷贝自定义程序段除了解决 IAR 链接器限制之外,还有另外一个用处,那就是拷贝的位置可以由用户决定。比如我们希望将程序重定向到外部 PSRAM 执行,但是在拷贝之前是需要先初始化外部 PSRAM 的,这时候我们完全可以在 main 函数里做完 PSRAM 初始化之后再做程序段的拷贝。. f* |" T, b6 q' v  {* ?) `3 [
  • Note 1:阅读本文前需要对 《IAR链接文件(.icf)》、《IAR映射文件(.map)》 这两种文件有所了解。
  • Note 2:本文使用的 IAR EWARM 软件版本是 v9.30.1。一、源文件里自定义程序段首先我们要将需要重定向到 RAM 中执行的全部关键函数放到同一个自定义程序段里,具体方法参见痞子衡旧文 《在IAR下将关键函数重定向到RAM中执行的方法》 里 2.2 小节。
    , h* v& s, _' O1 d% B我们以最经典的 \SDK_2.13.1_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\hello_world\cm7\iar 例程( flexspi_nor_debug build)为例,将其 SysTick_DelayTicks() 函数放到自定义程序段 UserRelocateCode 里,写法如下:4 A4 Z( L4 c* U- x0 l1 z, K
    #pragma location = "UserRelocateCode"" {- R6 k% C$ t* y* E
    void SysTick_DelayTicks(uint32_t n)1 q3 w3 M# {! ~/ B5 ]) c* ]% _
    {
      l* l- k/ B! @" A    g_systickCounter = n;
    # ~) h  \+ G: |8 z    while (g_systickCounter != 0U)
    3 I* z5 v! o2 F- F5 N    {
    1 R2 r8 Y- u$ L; q    }
    4 V- A% O- X( K8 N}
    + X$ Y7 Z" ^4 t$ J4 e! E, V: T二、链接文件里处理自定义程序段有了自定义程序段 UserRelocateCode 后,现在我们需要告诉 IAR 链接器,这个程序段将由用户自己做初始化处理。打开工程链接文件 MIMXRT1176xxxxx_cm7_flexspi_nor.icf 添加如下语句。即将 UserRelocateCode 段重定向到 EXTRAM_region 里执行,并且这里最关键的是 initialize manually 这一句(区别于 SDK CodeQuickAccess 段重定向做法所用的 initialize by copy)。
    $ n& K) v( l, Ydefine symbol m_external_ram_start   = 0x60000000;( w' w+ }9 \* ~4 T5 u& }
    define symbol m_external_ram_end     = 0x6003FFFF;
    8 V& G* L* e( I$ w' Zdefine region EXTRAM_region = mem:[from m_external_ram_start to m_external_ram_end];* L2 v$ O' V( a( p9 g6 u7 k
    initialize manually        { section UserRelocateCode };
    " Q! Y' v; L5 @, W% M# Uplace in EXTRAM_region     { section UserRelocateCode };
    - s  A$ {- h4 @3 w& \& k) Q6 ~编译修改后的工程,查看其映射文件(.map),其中和 UserRelocateCode 段相关的内容如下,这里可以看到除了 P10 之外,P1 里还多了一个名为  UserRelocateCode_init 的段,这其实就是自定义程序段机器码在 Flash 里的存放位置(拷贝数据源)。
    ( G  H1 h5 w1 ?7 y4 ^*******************************************************************************
    5 X) h4 e  g! P' x# }*** PLACEMENT SUMMARY
    2 V) I! l/ j: E***
    , Z4 |7 S) e0 ~/ K/ R6 E& G"P10": place in [from 0x6000'0000 to 0x6003'ffff] { section UserRelocateCode };
    ! ?. ]4 r2 z1 Cinitialize manually with packing = none { section UserRelocateCode };
    ) o& j' b( F$ B  Section              Kind         Address    Size  Object7 ?2 q' I4 Z3 f% _. [2 L, D
      -------              ----         -------    ----  ------6 w4 u* s  w; u& d: d% o
    "P1":                                          0x4738
    % ^9 i* C* G- }  UserRelocateCode_init           0x3000'6800    0x10  [B]
    6 A# H$ I1 ^- s9 w. R    Initializer bytes    const    0x3000'6800    0x10  
    6 C/ k+ @- w5 U' B: h"P10":                                           0x10) [- k9 `; P  y7 \2 i* _) M4 Q
      UserRelocateCode                0x6000'0000    0x10  [B]4 O# G7 i! ?8 ~2 R
        UserRelocateCode-1            0x6000'0000    0x10  [I]
    * f5 O1 Z/ |) \& W0 g  x9 e      UserRelocateCode   inited   0x6000'0000    0x10  led_blinky.o [7]
    4 v* g. s) X& M+ p. M                                - 0x6000'0010    0x10
    ) k$ n0 l) h& C# n" g: y三、手动拷贝自定义程序段上一节我们在映射文件里看到 UserRelocateCode_init 段的出现,这其实 IAR 的默认规定,可在 \IAR Systems\Embedded Workbench 9.30.1\arm\doc\EWARM_DevelopmentGuide.ENU.pdf 文档找到相应规则,即重定向的自定义段,其初始化值将被放到名为原自定义段名 + _init 后缀的段里。
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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