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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> Atollic TrueSTDIO下修改STM32L475VE的变量分配地址 -> 正文阅读

[嵌入式]Atollic TrueSTDIO下修改STM32L475VE的变量分配地址

??????? 最近在调试低功耗,需要修改变量的分配地址,所以研究了一下。研究过程中学习了一下ld文件的规则,参考了以下文章:

LD 文件:规则详解_申小白-CSDN博客_ld文件

STM32 .ld链接文件分析及一次bug解决过程 - 回归的世界线 - 博客园

第一种 修改变量默认的分配地址到SRAM2

??????? 举例,定义了变量a,代码为:int a;? 修改后,此变量会被定义到 SRAM2。

????????STM32L475VE有两块内部SRAM,SRAM2的起始地址在? 0x10000000,大小为32k;SRAM1的起始地址在 0x20000000,大小为96k;全计128k。其中SRAM2在低功耗模式下是可以实现不掉电的,即内容不丢失。默认情况下,变量是分配在SRAM1,这个是由ld链接文件决定的。可以通过修改ld链接文件重新定义变量的分配区域。

ld文件的全文如下:

?//***************************************** ld 文件开始************************************************//

/*
*****************************************************************************
**

**? File??????? : stm32_flash.ld
**
**? Author?? ??? ?: Auto-generated by TrueSTUDIO for STM32
**
**? Abstract??? : Linker script for STM32L475VE Device with
**??????????????? 512KByte FLASH, 128KByte RAM
**
**??????????????? Set heap size, stack size and stack location according
**??????????????? to application requirements.
**
**??????????????? Set memory bank area and size if external memory is used.
**
**? Target????? : STMicroelectronics STM32
**
**? Distribution: The file is distributed as is, without any warranty
**??????????????? of any kind.
**
*****************************************************************************
** @attention
**
** <h2><center>&copy; COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
**?? 1. Redistributions of source code must retain the above copyright notice,
**????? this list of conditions and the following disclaimer.
**?? 2. Redistributions in binary form must reproduce the above copyright notice,
**????? this list of conditions and the following disclaimer in the documentation
**????? and/or other materials provided with the distribution.
**?? 3. Neither the name of STMicroelectronics nor the names of its contributors
**????? may be used to endorse or promote products derived from this software
**????? without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************
*/

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = 0x20018000;??? /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x800;????? /* required amount of heap? */
_Min_Stack_Size = 0xC00; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
RAM (xrw)????? : ORIGIN = 0x20000000, LENGTH = 96K
RAM2 (xrw)????? : ORIGIN = 0x10000000, LENGTH = 32K
FLASH (rx)????? : ORIGIN = 0x0800C000, LENGTH = 464K??? /* 此处修改了地址,flash地址前部分面用于bootload*/
}

/* Define output sections */
SECTIONS
{
? /* The startup code goes first into FLASH */
? .isr_vector :
? {
??? . = ALIGN(4);
??? KEEP(*(.isr_vector)) /* Startup code */
??? . = ALIGN(4);
? } >FLASH

? /* The program code and other data goes into FLASH */
? .text :
? {
??? . = ALIGN(4);
??? *(.text)?????????? /* .text sections (code) */
??? *(.text*)????????? /* .text* sections (code) */
??? *(.glue_7)???????? /* glue arm to thumb code */
??? *(.glue_7t)??????? /* glue thumb to arm code */
??? *(.eh_frame)

??? KEEP (*(.init))
??? KEEP (*(.fini))

??? . = ALIGN(4);
??? _etext = .;??????? /* define a global symbols at end of code */
? } >FLASH

? /* Constant data goes into FLASH */
? .rodata :
? {
??? . = ALIGN(4);
??? *(.rodata)???????? /* .rodata sections (constants, strings, etc.) */
??? *(.rodata*)??????? /* .rodata* sections (constants, strings, etc.) */
??? . = ALIGN(4);
? } >FLASH

? .ARM.extab?? : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
? .ARM : {
??? __exidx_start = .;
??? *(.ARM.exidx*)
??? __exidx_end = .;
? } >FLASH

? .preinit_array???? :
? {
??? PROVIDE_HIDDEN (__preinit_array_start = .);
??? KEEP (*(.preinit_array*))
??? PROVIDE_HIDDEN (__preinit_array_end = .);
? } >FLASH
? .init_array :
? {
??? PROVIDE_HIDDEN (__init_array_start = .);
??? KEEP (*(SORT(.init_array.*)))
??? KEEP (*(.init_array*))
??? PROVIDE_HIDDEN (__init_array_end = .);
? } >FLASH
? .fini_array :
? {
??? PROVIDE_HIDDEN (__fini_array_start = .);
??? KEEP (*(SORT(.fini_array.*)))
??? KEEP (*(.fini_array*))
??? PROVIDE_HIDDEN (__fini_array_end = .);
? } >FLASH

? /* used by the startup to initialize data */
? _sidata = LOADADDR(.data);

? /* Initialized data sections goes into RAM, load LMA copy after code */
? .data :
? {
??? . = ALIGN(4);
??? _sdata = .;??????? /* create a global symbol at data start */
??? *(.data)?????????? /* .data sections */
??? *(.data*)????????? /* .data* sections */

??? . = ALIGN(4);
??? _edata = .;??????? /* define a global symbol at data end */
? } >RAM AT> FLASH

?
? /* Uninitialized data section */
? . = ALIGN(4);
? .bss :
? {
??? /* This is used by the startup in order to initialize the .bss secion */
??? _sbss = .;???????? /* define a global symbol at bss start */
??? __bss_start__ = _sbss;
??? *(.bss)
??? *(.bss*)
??? *(COMMON)

??? . = ALIGN(4);
??? _ebss = .;???????? /* define a global symbol at bss end */
??? __bss_end__ = _ebss;
? } >RAM

? /* User_heap_stack section, used to check that there is enough RAM left */
? ._user_heap_stack :
? {
??? . = ALIGN(4);
??? PROVIDE ( end = . );
??? PROVIDE ( _end = . );
??? . = . + _Min_Heap_Size;
??? . = . + _Min_Stack_Size;
??? . = ALIGN(4);
? } >RAM

? /* Remove information from the standard libraries */
? /DISCARD/ :
? {
??? libc.a ( * )
??? libm.a ( * )
??? libgcc.a ( * )
? }

? .ARM.attributes 0 : { *(.ARM.attributes) }
}

//***************************************** ld 文件结束************************************************//

??????? 其中 MEMORY 关键定定义了内存的地址情况,其中有RAM,RAM2和FLASH,我们需要做的是将全部变量定义到RAM2,只需要将.data段,.bss段的地址修改为RAM2即可,如下:

/* Initialized data sections goes into RAM, load LMA copy after code */
? .data :
? {
??? . = ALIGN(4);
??? _sdata = .;??????? /* create a global symbol at data start */
??? *(.data)?????????? /* .data sections */
??? *(.data*)????????? /* .data* sections */

??? . = ALIGN(4);
??? _edata = .;??????? /* define a global symbol at data end */
? } >RAM2 AT> FLASH

?
? /* Uninitialized data section */
? . = ALIGN(4);
? .bss :
? {
??? /* This is used by the startup in order to initialize the .bss secion */
??? _sbss = .;???????? /* define a global symbol at bss start */
??? __bss_start__ = _sbss;
??? *(.bss)
??? *(.bss*)
??? *(COMMON)

??? . = ALIGN(4);
??? _ebss = .;???????? /* define a global symbol at bss end */
??? __bss_end__ = _ebss;
? } >RAM2

??????? 这里没有把._user_heap_stack 分配到RAM2,在我修改时编译会报错,应该是由于ld文件中的第二行代码没有改造成的: _estack = 0x20018000; ? ? 0x20018000属于RAM1区域,在.s文件中

_estack 会被赋值给 sp指针。

第二种 强制个别变量的地址到SRAM1

??????? 当变量默认的分配地址被修改到 SRAM2 区域后,代码中个别的变量需要定义到 SRAM1,按照以下方法可以实现。

??????? 按照上面第一种,通常全局变量是被定义在 .data 段的,我们可以新建出一个名为 ram1_data? 的数据段

??? /* ram1_data section,? 自定义的 ram1_data 段,*/
? .ram1_data :
? {
??? . = ALIGN(4);
??? __RAM1DATA_START_SYMBOLS = .;
??? *(.ram1_data)
??? *(.ram1_data*)
??? . = ALIGN(4);
??? __RAM1DATA_END_SYMBOLS = .;
? } >RAM

? /* 堆栈段要放在后面*/
? /* User_heap_stack section, used to check that there is enough RAM left */
? ._user_heap_stack :
? {
??? . = ALIGN(4);
??? PROVIDE ( end = . );
??? PROVIDE ( _end = . );
??? . = . + _Min_Heap_Size;
??? . = . + _Min_Stack_Size;
??? . = ALIGN(4);
? } >RAM

??????? 然后就可以在源程序中使用这个 ram1_data? 段,如下定义变量:

????????char IOT_SendBuff[IOT_SEND_BUFF_SIZE] __attribute__((section(".ram1_data")));

??????? 以上代码是定义了一个 IOT_SendBuff数组,且分配到 ram1_data 段,而ram1_data段是被定义在SRAM1(即上面的RAM),所以 SendBuff 是定义在 SRAM1 的。如下图可以看到:

需要注意到变量 IOT_SendBuff 定义时是没有初始化的,所以和 .bss 段无关,当需要初始化时,bss段怎么处理需要后期再测试。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-11-12 19:45:23  更:2021-11-12 19:47:22 
 
开发: 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 8:53:33-

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