IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 痞子衡嵌入式:MCUXpresso IDE下工程链接文件配置管理与自动生成机制 -> 正文阅读

[嵌入式]痞子衡嵌入式:MCUXpresso IDE下工程链接文件配置管理与自动生成机制


  大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是MCUXpresso IDE下工程链接文件配置管理与自动生成机制

  痞子衡在 2018 年初写过一个专题 《嵌入式开发文件系列》,用 8 篇文章系统地介绍了 ARM Cortex-M 内核微控制器开发过程中所要了解的主要文件类型:源文件、链接文件、工程文件、可重定向文件、映射文件、可执行文件、反汇编文件、镜像文件。

  上述 8 种文件中,大家对源文件、工程文件以及镜像文件这三种应该是最熟悉的,而其余文件类型,很多人应该都没有深入研究过,但痞子衡一直认为只有深入了解了链接文件才算是真正步入嵌入式开发老手行列。

  我们知道不同 IDE 下链接文件语法是不一样的,而恩智浦 MCUXpresso IDE 底层编译器是 Arm GCC,因此其链接文件就是标准 GCC 下 .ld 文件。如果你对 .ld 文件语法非常精通,当然可以自己从头开始写链接文件,如果不太熟的话,也不要紧张,MCUXpresso IDE 早就为你扫清了障碍,在这个 IDE 下能够支持图形界面里做链接配置,然后自动生成相应链接文件的。今天痞子衡就和大家聊聊这个特性:

一、准备开发环境

  首先需要准备好环境,包含必要的软件,痞子衡的环境如下:

  • 集成开发环境: MCUXpresso IDE_11.4.0_6224,点此下载
  • 软件开发包: SDK_2.10.0_EVK-MIMXRT1170(Toolchain需包含MCUXpresso IDE),点此下载

二、MCUXpresso IDE下链接文件配置

  现在进入正题,我们先按照 《MCUXpresso IDE下SDK工程导入与workspace管理机制》 一文步骤从 SDK 包里导入生成一个工程(就选最简单的 hello_world 吧)。工程导入成功后,会在 \MCUXpressoIDE_11.4.0_6224\workspace\evkmimxrt1170_hello_world_demo_cm7 下看到 .project 工程文件,在 MCUXpresso IDE 下打开这个工程。

2.1 Memory 空间定义

  在工程名上右击选择 Properties 进入选项配置界面,其中 MCU settings 一栏里定义的就是 MCU 实际存储空间,这是链接文件的空间分配基础,我们后面会将程序里全部的段都链接在这些区域里。

  存储空间属性(Type)分为两类:一类是 Flash(存放 RO 段),一类是 RAM(存放 RW 段)。每个属性的空间都可以被定义很多个,但其中仅 Alias 名为 Flash 和 RAM 的空间才是默认被选中用于链接程序段的(可通过上下移动按钮将指定空间调整到前排 Flash 和 RAM 的位置)。

2.2 默认程序段分配

  还是在上一节打开的 Properties 选项配置界面,其中 Settings / Managed Linker Script 页面就是链接文件里具体程序段链接设置,这个页面的最上面 Manage linker script 要保持勾选,勾选上则代表使用 IDE 的链接文件自动生成功能。

  在一个具体应用程序项目工程里,如果源文件仅包含标准 C 和汇编代码,那么程序段会被默认归纳为三大类:RO 段(函数代码,常量,全局变量初值等),RW 段(全局变量,重定向到 RAM 中函数代码等),Heap/Stack。IDE 里分别提供了这三类程序段的空间指定:

1. Link application to RAM 勾选框:
    - 不勾选,则 RO 段放在 2.1 节图中 Alias 名为 Flash 的空间里
    - 勾选上,则 RO 段放在 2.1 节图中 Alias 名为 RAM 的空间里
2. Heap and Stack placement 配置框:
    - 可以按需调整 Heap/Stack 里的 Region,Location,Size,其中 Region 可以是 2.1 节图中属性为 RAM 的任意空间
    - Heap/Stack 默认大小均为 4KB,放在 2.1 节图中 Alias 名为 RAM 的空间里
3. Global data placement 下拉框:
    - 可以按需链接 RW 段到 2.1 节图中属性为 RAM 的任意空间
    - RW 段默认放在 2.1 节图中 Alias 名为 RAM 的空间里

2.3 自定义程序段分配

  除了上一节链接器默认的程序段名外,我们也可以自定义一些用户段名,方便一些特殊代码处理。这里需要使用 __attribute__((section("UserSectionName"))) 链接器语法来修饰指定函数/变量,这样该函数/变量就会被放在 UserSectionName 段里,然后我们在上一节图中链接设置框的最后 Extra linker script input sections 框里单独为自定义 UserSectionName 段指定链接空间。

  比如工程 clock_config.c 文件里如下函数 UpdateSemcClock(),这个函数在默认的 RO .text 段里,RO 段都是链接在 Flash 里的,但是我们希望将这个函数重定向到 ITCM 里执行,所以我们可以使用 __attribute__((section("CodeQuickAccess"))) 链接器语法来修饰这个函数,然后在 Extra linker script input sections 框里将 CodeQuickAccess 段放到 SRAM_ITC_cm7 空间里即可。

#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func

AT_QUICKACCESS_SECTION_CODE(void UpdateSemcClock(void));
void UpdateSemcClock(void)
{
    SEMC->IPCMD = 0xA55A000D;
    while ((SEMC->INTR & 0x3) == 0);
    SEMC->INTR                                = 0x3;
    SEMC->DCCR                                = 0x0B;
    CCM->CLOCK_ROOT[kCLOCK_Root_Semc].CONTROL = 0x602;
}

2.4 自动生成的链接文件

  链接设置完成后,会在工程目录 \MCUXpressoIDE_11.4.0_6224\workspace\evkmimxrt1170_hello_world_demo_cm7\Debug 下自动生成最终链接文件(假定用得 debug build),文件一共有三个,其中 evkmimxrt1170_hello_world_demo_cm7_Debug.ld 是主链接文件,感兴趣的可以打开这个链接文件学习一下(如果看不懂语法可以结合这篇文章 https://www.embedded.com/building-bare-metal-arm-systems-with-gnu-part-3/ )。

2.5 查看Map文件确认

  按照 2.1 节和 2.2 节 图中的链接设置,我们编译链接 evkmimxrt1170_hello_world_demo_cm7 工程可以得到如下链接结果,从空间占用上来看是符合预期的。

  现在我们可以打开生成的 evkmimxrt1170_hello_world_demo_cm7.map 文件具体分析一下最终链接情况,痞子衡摘录了最核心部分如下:

Memory Configuration
Name             Origin        Length             Attributes
/------------------------------------------------------------/
// RO .text 段在           BOARD_FLASH:0x30000000 - 0x30006eaf,共 28336 个字节
// RO CodeQuickAccess 段在 BOARD_FLASH:0x30006eb0 - 0x30006ee7,共 56 个字节
// RO .data_init 段在      BOARD_FLASH:0x30006ee8 - 0x30006eeb,共 4 个字节
.boot_hdr       0x30000000     0x2000
.text           0x30002000     0x4eb0

// RW CodeQuickAccess 段在 SRAM_ITC_cm7:0x00000000 - 0x00000037,共 56 个字节
.data_RAM4      0x00000000       0x38 load address 0x30006eb0
 CodeQuickAccess
                0x00000000       0x38 ./board/clock_config.o
                0x00000000                UpdateSemcClock

// RW .data 段在           BOARD_SDRAM:0x80000000 - 0x80000003,共 4 个字节
.data           0x80000000        0x4 load address 0x30006ee8
 .data.SystemCoreClock
                0x80000000        0x4 ./device/system_MIMXRT1176_cm7.o

// RW .bss 段在            BOARD_SDRAM:0x80000004 - 0x80000107,共 260 个字节
.bss            0x80000004      0x104

// Heap 在                 BOARD_SDRAM:0x80000108 - 0x80001107,共 4KB
.heap           0x80000108     0x1000

// Stack 在                BOARD_SDRAM:0x82fff000 - 0x82ffffff,共 4KB
.stack          0x82fff000        0x0
                0x82fff000                _vStackBase = .
                0x82fff000                . = ALIGN (0x4)
                0x83000000                _vStackTop = (. + _StackSize)

  简单总结下,RO 段一般从 Flash 的最前面开始链接的,.text 段在最前面,然后是 ramfunc 函数实体,最后是 .data_init 段(全局变量初值)。RW 段也是从 RAM 的最前面开始链接,.data 段在前,.bss 在后,然后是 Heap 和 Stack(Heap/Stack的具体位置是可以设置的,有 Start、End、Post Data 三种选择)。

三、MCUXpresso IDE下链接小实验

  根据上面的知识,我们现在来做些链接设置小实验,在做实验前,我们调整下 Memory 定义,把 SDRAM 相关空间移到后面去,默认 RAM 用 SRAM_DTC_cm7 空间,这样看起来习惯一点。

3.1 默认 XiP 链接

  调整过 Memory 空间顺序后的链接结果如下:

3.2 Non-XiP 链接

  现在我们尝试使能 Link application to RAM 选项,其余不变,此时可以看到 28396 Bytes 的 RO 段也到了 SRAM_DTC_cm7 空间里,BOARD_FLASH 空间完全没有任何占用:

3.3 XiP 链接,调整 Stack 大小并放置到 OCRAM1

  我们尝试调整 Stack 大小到 1KB 并放置到 SRAM_OC1,其余不变,此时可以看到 SRAM_DTC_cm7 空间消耗相比 3.1 节里少了 4KB,但 SRAM_OC1 空间消耗多了 1KB:

3.4 XiP 链接,调整 RW 段到 OCRAM2

  我们尝试调整 RW 段到 SRAM_OC2,其余不变,此时可以看到 SRAM_DTC_cm7 空间消耗相比 3.1 节里少了 264 Bytes,但 SRAM_OC2 空间消耗多了 264 Bytes:

  至此,MCUXpresso IDE下工程链接文件配置管理与自动生成机制痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到我的 博客园主页CSDN主页知乎主页微信公众号 平台上。

微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-11 00:00:59  更:2021-09-11 00:01:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:23:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码