OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5342|回复: 0

《MiniPRO H750开发指南》第八章 新建HAL版本MDK工程(下)

[复制链接]

1140

主题

1152

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4896
金钱
4896
注册时间
2019-5-8
在线时间
1248 小时
发表于 2022-9-19 15:18:27 | 显示全部楼层 |阅读模式

1)实验平台:正点原子MiniPRO STM32H750 开发板
2)  章节摘自【正点原子】《MiniPRO H750开发指南》
3)购买链接:https://detail.tmall.com/item.htm?id=677017430560
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boar ... 32h750_minipro.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子STM32技术交流群:756580169




第八章 新建HAL版本MDK工程

8.2 下载验证
这里我们继续使用DAP仿真器下载,在MDK主界面,点击:file:///C:/Users/ALIENTEK/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png(下载按钮,也可以按键盘快捷键:F8),就可以将代码下载到开发板,如图8.2.1所示:
image086.jpg
图8.2.1 下载成功
上图提示:Application running…,则表示代码下载成功,且开始运行。此时,看到RGB的红、蓝、绿三种灯轮流亮,类跑马灯。如果有朋友没能下载成功,请看第四章寻找问题,或者直接对照我们提供的实验0-3,新建工程实验-HAL库版本工程设置。
8.3 分散加载文件简介
ARM芯片用于在链接时指定存储器分配方案的文件,称之为分散加载文件(.sct),它可以将不同的代码(.o文件)放在不同的存储空间。关于分散加载的详细介绍,请参考:A盘à8,STM32参考资料à4,分散加载à分散加载文件浅释.pdf,这是周立功公司的一份文档资料,详细介绍了.sct文件的基础概念、语法及应用实例说明,对学习分散加载非常有帮助,请大家务必先学习一下这个文档。
本节,我们仅对.sct文件进行一个简介,方便大家学习。
首先明确一个概念:MDK编译任何STM32工程,都会需要用到分散加载文件。分散加载文件的来源有两种方式:
通过MDK自己生成;
2,通过用户指定(用户自己编写);
首先,我们来看MDK自己生成的.sct文件。
选择本章新建工程àMDK的魔术棒àLinker选项卡里面,进行如图8.3.1所示的设置:
image088.jpg
图8.3.1 勾选Use Memory Layout from Target Dialog选项
       勾选Use Memory Layout from Target Dialog选项后,MDK就会根据Target选项卡里面的相关设置来决定存储器分配,如图8.3.2所示:
image090.png
图8.2.2 MDK默认的存储器分配
标号①,是MDK的只读存储区域(ROM)和可读写存储区域(RAM)的配置区域。
标号②处,说明默认将所有的代码(Code + RO Data + RW Data)都存放到IROM1指定的地址范围上。其起始地址为:0X0800 0000,大小为:0X20000。
标号③处,说明默认将所有的变量及堆栈(RW Data + ZI Data)都存放在IRAM1和IRAM2指定的地址范围上。IRAM1的起始地址为:0X2000 0000,大小为:0X20000;IRAM2的起始地址为:0X2400 0000,大小为:0X80000;变量的具体位置由编译器自动分配。
在完成以上两步操作以后,对MDK进行一次编译,在编译成功后,MDK会自动生成一个以工程名命名的.sct文件,存放在Output文件夹里面,如图8.2.3所示:
image092.jpg
图8.2.3 MDK自动生成的分散加载文件
       打开上图中的test.sct文件,其内容如下
  1. ; *************************************************************
  2. ; *** Scatter-Loading Description File generated by uVision ***
  3. ; *************************************************************

  4. LR_IROM1 0x08000000 0x00020000  {    ; load region size_region
  5.   ER_IROM1 0x08000000 0x00020000  {  ; load address = execution address
  6.    *.o (RESET, +First)
  7.    *(InRoot$Sections)
  8.    .ANY (+RO)
  9.    .ANY (+XO)
  10.   }
  11.   RW_IRAM1 0x20000000 0x00020000  {  ; RW data
  12.    .ANY (+RW +ZI)
  13.   }
  14.   RW_IRAM2 0x24000000 0x00080000  {
  15.    .ANY (+RW +ZI)
  16.   }
  17. }
复制代码
LR_IROM1是一个加载域,起始地址为:0X0800 0000,大小为:0X0002 0000。它包含三个运行域分别是:
       ER_IROM1运行域,起始地址为:0X0800 0000,大小为:0X0002 0000。
       RW_IRAM1运行域,起始地址为:0X2000 0000,大小为:0X0002 0000。
       RW_IRAM2运行域,起始地址为:0X2400 0000,大小为:0X0008 0000。
       其中:
ER_IROM1为ROM区域,存放:Code + RO Data + RW Data等只读数据,由:.ANY (+RO)指定,即所有只读数据,都存放在这个区域。
RW_IRAM1和RW_IRAM2为RAM区域,存放:RW Data + ZI Data等可读写数据,由:.ANY (+RW +ZI)指定,即所有的可读写数据,都存放在这两个区域,具体存放位置由MDK编译器自动分配。
       *.o (RESET, +First):表示优先(+FIRST)将RESET(即中断向量表)段放这个域的起始位置,实际上就是把中断向量表拷贝到最开始的位置。
* (InRoot$$Sections):表示将所有用到的库段放到root区,如:__main.o、__scatter*.o和__dc*.o等。
以上,就是MDK自动生成的.sct文件简介。
接下来,我们看用户指定.sct文件的实现方式。选择本章新建工程àMDK的魔术棒àLinker选项卡里面,进行如图8.3.4所示的设置:
image094.png

图8.2.4 取消Use Memory Layout from Target Dialog选项
标号①,取消Use Memory Layout from Target Dialog选项,使用用户自定义分散加载文件。
标号②,新建工程时,已选择SCRIPT\qspi_code_scf.scf分散加载文件。
标号③,点击Edit按钮,即可在MDK里面打开qspi_code_scf.scf分散加载文件。
qspi_code.scf的内容如下:
#! armcc -E
;#! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m7 -xc
/* 使用说明
! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m7 -xc, 用于AC6编译报错(L6709E错误)时,请使用此设置
!armcc -E, 用于AC5编译报错(L6709E错误)时,请使用此设置
注意,设置必须放本文件第一行!否则还是报错!请注意调整顺序!
  1. */

  2. /**
  3. **********************************************************************************************
  4. * [url=home.php?mod=space&uid=175224]@file[/url]     main.c
  5. * [url=home.php?mod=space&uid=90321]@Author[/url]   正点原子团队(ALIENTEK)
  6. * @version  V1.0
  7. * @date     2020-03-13
  8. * @brief    STM32H750分散加载文件(.scf文件)
  9. * [url=home.php?mod=space&uid=292586]@license[/url]  Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
  10. **********************************************************************************************
  11. * @attention
  12. *
  13. * 实验平台:正点原子 Mini Pro H750开发板
  14. * 在线视频:www.yuanzige.com
  15. * 技术论坛:www.openedv.com
  16. * 公司网址:www.alientek.com
  17. * 购买地址:openedv.taobao.com
  18. *
  19. **********************************************************************************************
  20. */

  21. #define m_stmflash_start    0X08000000  /* m_stmflash(STM32内部FLASH)域起始地址 */
  22. #define m_stmflash_size    0X20000     /* m_stmflash(STM32内部FLASH)大小,H750是128KB */

  23. #define m_qspiflash_start   0X90000000  /* m_qspiflash(外扩QSPI FLASH)域起始地址 */
  24. #define m_qspiflash_size   0X800000    /* m_qspiflash(外扩QSPI FLASH)大小,W25Q64是8MB */

  25. #define m_stmsram_start   0X24000000  /* m_stmsram(STM32内部RAM)域起始地址,定义在D1,AXI SRAM */
  26. #define m_stmsram_size   0X80000     /* m_stmsram(STM32内部RAM)大小,AXI SRAM共512KB */

  27. LR_m_stmflash m_stmflash_start m_stmflash_size          /* LR_m_stmflash加载域  */
  28. {
  29. /* ER_m_stmfalsh运行域,起始地址为:m_stmflash_start,大小为:m_stmflash_size  */
  30. ER_m_stmflash m_stmflash_start m_stmflash_size {   
  31. /* 优先(+FIRST)将RESET(中断向量表)段放这个域,实际上就是把中断向量表拷贝到m_stmflash_start */
  32.       /* RESET是一个段名,表示中断向量表(在.s文件定义);+FIRST表示时第一个要加载的. */
  33. *.o (RESET, +First)                           
  34.         /* 将所有的库段(C/C++标准库)放在root region.如__main.o,__scatter*.o等 */
  35.         * (InRoot$Sections)                           
  36.         * (Veneer$Code)
  37.         libinit.o
  38.         libinit2.o
  39.         libshutdown.o
  40.         libshutdown2.o
  41.         __rtentry.o
  42.         __rtentry2.o
  43.         __rtentry4.o
  44.         rtexit.o
  45.         rtexit2.o

  46.         use_no_semi_2.o
  47.         heapauxi.o
  48.         use_no_semi.o
  49.         sys_stackheap_outer.o
  50.         exit.o
  51.         libspace.o
  52.         fpinit.o
  53.         lludivv7m.o
  54.         startup_stm32h750xx.o

  55.         rt_locale_intlibspace.o
  56.         lc_numeric_c.o
  57.         lc_ctype_c.o

  58.         main.o
  59.         sys.o
  60.         usart.o
  61.         delay.o
  62.         pwr.o

  63.        /* H7的QSPI接口不支持读时写,因此必须把以下3个文件放到内部FLASH,以保证可以
  64. 对QSPI FLASH的写入 */
  65.         qspi.o
  66.         norflash.o
  67.         norflash_ex.o

  68.         /* 针对HAL库驱动添加到内部的文件 */
  69.         system_stm32h7xx.o
  70.         stm32h7xx_hal.o
  71.         stm32h7xx_hal_cortex.o
  72.         stm32h7xx_hal_rcc.o
  73.         stm32h7xx_hal_rcc_ex.o
  74.         stm32h7xx_hal_gpio.o
  75.         stm32h7xx_hal_dma.o
  76.         stm32h7xx_hal_dma_ex.o
  77.         stm32h7xx_hal_qspi.o
  78.         stm32h7xx_hal_pwr.o
  79.         stm32h7xx_hal_pwr_ex.o
  80. }
  81. /* RW_m_stmsram运行域,起始地址为:m_stmsram_start,大小为:m_stmsram_size. */
  82.     RW_m_stmsram m_stmsram_start m_stmsram_size {      
  83.         .ANY (+RW + ZI)                           /* 将所有用到的RAM都放在这个区域 */
  84.     }
  85. }

  86. LR_m_qspiflash m_qspiflash_start m_qspiflash_size       /* LR_m_qspiflash加载域 */
  87. {
  88. /* ER_m_qspiflash加载域,起始地址为:m_qspiflash_start,大小为:m_qspiflash_size */
  89.     ER_m_qspiflash m_qspiflash_start m_qspiflash_size {
  90.         .ANY (+RO)     /* 将只读数据(+RO)放这个域,任意分配.相当于程序就是存放在这个域的 */
  91.     }
  92. }
复制代码
相比于MDK自己生成的分散加载文件,我们自己编写的相对复杂一些,qspi_code.scf分散加载文件包含2个加载域,3个运行域,分别是:
       LR_m_stmflash加载域,起始地址为:m_stmflash_start(宏定义,实际值:0X0800 0000),大小为:m_stmflash_size(宏定义,实际值:0X20000)。它包含二个运行域分别是:
       ER_m_stmflash运行域,起始地址为:m_stmflash_start(宏定义,实际值:0X0800 0000),大小为:m_stmflash_size(宏定义,实际值:0X20000)。
       RW_m_stmsram运行域,起始地址为:m_stmsram_start(宏定义,实际值:0X2400 0000)大小为:m_stmsram_size(宏定义,实际值:0X80000)。
       LR_m_qspiflash加载域,起始地址为:m_qspiflash_start(宏定义,实际值:0X9000 0000)大小为:m_qspiflash_size(宏定义,实际值:0X80000)。它包含一个运行域:
       ER_m_qspiflash运行域,起始地址为:m_qspiflash_start(宏定义,实际值:0X9000 0000)大小为:m_qspiflash_size(宏定义,实际值:0X80000)。
       具体的存储器分配情况为:
       ER_m_stmflash运行域,包含:*.o (RESET, +First)开始到delay.o结束的相关代码,这些代码运行在内部FLASH,可以得到最佳的性能。需要注意的是:这些代码大部分都是必须放到内部FLASH,否则无法正常运行!!
       ER_m_qspiflash运行域,所有没有在ER_m_stmflash运行域指定的代码,都被放在这个运行域,这些代码运行在外部SPI FLASH,速度比内部FLASH慢一些。
       RW_m_stmsram运行域,所有变量及堆栈(RW Data + ZI Data)都存放在这个运行域。
       以上分散加载文件,由正点原子编写,为了方便大家使用,不用频繁修改.sct文件,特意将.ANY ROM区域放在外部SPI FLASH,这样大家在新增.c参与编译时,默认就是存放在外部SPI FLASH的,这样使用起来就更方便。
       注意事项:
1、如果你新增的代码,对速度有要求,可以将其对应的.o添加到内部FLASH,即放在:ER_m_stmflash运行域。
2、如果添加新代码后,程序无法正常运行(通常表现为黑屏/不启动),可以尝试将新增的.o放到ER_m_stmflash运行域后(重新编译)再尝试。如果还不行,可以尝试将所有代码都放到ER_m_stmflash运行域后再尝试。
至此,分散加载文件就给大家介绍完了。




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-25 05:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表