S32K324 数据初始化Rom到Ram Copy的方式

文章目录

    • 前言
    • 基础知识
      • ld文件中的段定义
      • ld文件中的符号定义
    • ld定义copy地址范围
    • 启动文件中的定义
    • Copy的使用
    • 总结

前言

之前一直不理解在ld文件中加__xxx_ram_start,__xxx_rom_start,__xxx_rom_end这些的作用,也不清楚原理。前几天遇到一个内存copy的问题,对这些有了更进一步的理解,记录一下过程。

基础知识

ld文件中的段定义

具体可以参考The Gnu Linker-3.8.3Output Section Attributes章节,下面的定义不是完整的解释,仅供参考

section [address][type] : [ALIGN(section_align)] [(flags)] [AT(address)]

其中:

section:是要定位的输入或输出段的名称,如 .text、.data 或用户自定义的段名。

[address]:可选参数,用于直接指定该段在内存或文件中的起始地址。如果不指定,通常由链接器根据其他规则(如链接脚本中的其他命令或默认布局)确定。

[type]:可选参数,用来指定段的类型,如 PROGBITS、NOLOAD 等。若不指定,链接器会根据段的内容自动推断其类型。

ALIGN:字节对齐使用。

[(flags)]:可选参数,包含一组以逗号分隔的标志,用于指定段的属性,如 ALLOC(分配空间)、READONLY(只读)、WRITE(可写)等。

AT(address):关键部分,用于指定该段在加载或运行时应被放置到的绝对地址。这里的 address 是一个具体的内存地址值。

ld文件中的符号定义

ld文件中以“__”开头定义的符号,一般会关联到指定的地址。例如:

        __SysCore_INIT_RAM_START = .;

在链接脚本上下文中,.表示当前位置(即当前正在处理的段的起始地址)。通过该符号,即可记录对应段的起始地址及结束地址。该符号后面可以被源文件使用。(c文件中使用时需要加extern,s文件中可以直接使用)

ld定义copy地址范围

了解之前符号的定义,我们可以获取需要copy的ram起始地址,ram结束地址,rom起始地址,rom结束地址。最终实际传递到.c或.s的只需要3个地址即可(ram起始地址,rom起始地址,rom结束地址)

/* -------------------------------------------------------------------------- */
/* Sections of INIT                                                          */
/* -------------------------------------------------------------------------- */
SECTIONS
{.SysCore_init ALIGN(4): AT(__POSTBUILD_CONST_END){__SysCore_INIT_RAM_START = .;...__SysCore_INIT_RAM_END = .;} > int_sram_sys__SysCore_INIT_ROM_START = __POSTBUILD_CONST_END;
__SysCore_INIT_ROM_END = __SysCore_INIT_ROM_START + (__SysCore_INIT_RAM_END - __SysCore_INIT_RAM_START);
}

__POSTBUILD_CONST_END是之前记录的一块flash区的结束地址,此处表示在其之后,作为ram数据的存放地址。

使用AT指令,指定该Ram区的数据放到对应flash中。

此处我们得到了__SysCore_INIT_RAM_START,__SysCore_INIT_ROM_START,__SysCore_INIT_ROM_END

在后面会使用

启动文件中的定义

.section ".init_table", "a".long 6.long __RAM_CACHEABLE_START.long __ROM_CACHEABLE_START.long __ROM_CACHEABLE_END.long __RAM_NO_CACHEABLE_START.long __ROM_NO_CACHEABLE_START.long __ROM_NO_CACHEABLE_END.long __RAM_SHAREABLE_START.long __ROM_SHAREABLE_START.long __ROM_SHAREABLE_END.long __RAM_INTERRUPT_START.long __ROM_INTERRUPT_START.long __ROM_INTERRUPT_END.long __shared_INIT_RAM_START.long __shared_INIT_ROM_START.long __shared_INIT_ROM_END.long __SysCore_INIT_RAM_START.long __SysCore_INIT_ROM_START.long __SysCore_INIT_ROM_END

.section “.init_table”, “a” 定义一个可分配的段init_table

这个段其实在ld文件中定义了,放在pflash中

此处相当于往里面写数据,实际可以理解为指针或者数组的应用,在后面使用的时候其实也是按数组来用的

.long 6 -定义4个字节,值为6,实际是表示的需要copy的rom-ram的对数,此处有6对

后面的定义3个为1组,分别为ram起始地址,rom起始地址,rom结束地址,都是在ld文件中定义的

此处定义好的数据在pflash中如下

image
从0x41BB14到0x41BB5F.存放了6组数据,包括其对应的ram起始地址,rom起始地址,rom结束地址

ld文件中通过 __INIT_TABLE获取首地址

__INIT_TABLE                  = ADDR(.init_table);

Copy的使用

在startup.c中对__INIT_TABLE声明,并使用

typedef struct
{uint8 * ram_start; /*!< Start address of section in RAM */uint8 * rom_start; /*!< Start address of section in ROM */uint8 * rom_end;   /*!< End address of section in ROM */
} Sys_CopyLayoutType;
typedef struct
{uint8 * ram_start; /*!< Start address of section in RAM */uint8 * ram_end;   /*!< End address of section in RAM */
} Sys_ZeroLayoutType;extern uint32 __INIT_TABLE[];
extern uint32 __ZERO_TABLE[];
#if (defined(__ARMCC_VERSION))extern uint32 __VECTOR_RAM;
#elseextern uint32 __VECTOR_RAM[];
#endif
/******************************************************************************** Code******************************************************************************/
/*FUNCTION************************************************************************ Function Name : init_data_bss* Description   : Make necessary initializations for RAM.* - Copy the vector table from ROM to RAM.* - Copy initialized data from ROM to RAM.* - Copy code that should reside in RAM from ROM* - Clear the zero-initialized data section.** Tool Chains:*   __GNUC__           : GNU Compiler Collection*   __ghs__            : Green Hills ARM Compiler*   __ICCARM__         : IAR ARM Compiler*   __DCC__            : Wind River Diab Compiler*   __ARMCC_VERSION    : ARMC Compiler** Implements    : init_data_bss_Activity*END**************************************************************************/
#define PLATFORM_START_SEC_CODE
#include "Platform_MemMap.h"void init_data_bss(void);void init_data_bss(void)
{const Sys_CopyLayoutType * copy_layout;const Sys_ZeroLayoutType * zero_layout;const uint8 * rom;uint8 * ram;uint32 len = 0U;uint32 size = 0U;uint32 i = 0U;uint32 j = 0U;const uint32 * initTable_Ptr = (uint32 *)__INIT_TABLE;const uint32 * zeroTable_Ptr = (uint32*)__ZERO_TABLE;/* Copy initialized table */len = *initTable_Ptr;initTable_Ptr++;copy_layout = (const Sys_CopyLayoutType *)initTable_Ptr;for(i = 0; i < len; i++){rom = copy_layout[i].rom_start;ram = copy_layout[i].ram_start;size = (uint32)copy_layout[i].rom_end - (uint32)copy_layout[i].rom_start;for(j = 0UL; j < size; j++){ram[j] = rom[j];}}/* Clear zero table */len = *zeroTable_Ptr;zeroTable_Ptr++;zero_layout = (const Sys_ZeroLayoutType *)zeroTable_Ptr;for(i = 0; i < len; i++){ram = zero_layout[i].ram_start;size = (uint32)zero_layout[i].ram_end - (uint32)zero_layout[i].ram_start;for(j = 0UL; j < size; j++){ram[j] = 0U;}}
}
#define PLATFORM_STOP_SEC_CODE
#include "Platform_MemMap.h"

通过上面的代码,实现了rom到ram的拷贝,实际只需要在.s中配置对应的参数即可

那这个函数是什么时候被调用的呢?

在启动文件中被调用,如下所示

_DATA_INIT:
#ifndef RAM_DATA_INIT_ON_ALL_CORES/* If this is the primary core, initialize data and bss */ldr  r0, =0x40260004ldr  r1,[r0]ldr  r0, =MAIN_COREcmp  r1,r0beq	 _INIT_DATA_BSSb    __SYSTEM_INIT
#endif_INIT_DATA_BSS:bl init_data_bss

上述启动代码解释如下:

1.条件判断:检查是否需要在所有核心上进行 RAM 数据初始化。若仅需在主核心上进行初始化(即未定义 RAM_DATA_INIT_ON_ALL_CORES),则执行后续操作;否则,直接执行_INIT_DATA_BSS(调用init_data_bss函数)。

2.核心识别:通过读取特定内存地址处的值,判断当前运行的核心是否为主核心。

3.主核心处理:若当前核心为主核心,跳转至 _INIT_DATA_BSS 标签处,执行数据和 BSS 初始化。

4.data与 BSS 初始化:在 _INIT_DATA_BSS 标签处,调用 init_data_bss 函数,完成数据段和 BSS 段的初始化工作。

5.非主核心处理或系统初始化:若当前核心非主核心(或不需要在所有核心上进行数据初始化),直接跳转至 __SYSTEM_INIT 标签处,继续进行其他系统初始化任务(调用SystemInit函数)。

总结

虽然没学过汇编语言,但遇到问题还是得上~慢慢学习吧!学无止境!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/800815.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS时区和语言设置-使用相关api实现系统语言和地区设置

介绍 本示例展示了i18n&#xff0c;intl&#xff0c;resourceManager在eTS中的使用&#xff0c;使用相关api实现系统语言和地区设置、时间和时区设置&#xff0c;展示了区域格式化示例。 效果预览 使用说明 1.启动应用&#xff0c;进入应用&#xff0c;首页分为三个按钮&…

【JVM】GC导致的性能问题排查与解决方案,日志、堆分析工具介绍

一、必要性 重要应用程序在使用过程中&#xff0c;忽然无法响应用户请求&#xff0c;排查发现网络联通无问题&#xff0c;gateway能够正常接收分发请求&#xff0c;应用进程正常&#xff0c;正常向注册中心发送请求&#xff0c;但是接收http请求全部返回报错。 添加gc后发现内…

C#项目引用解决方案中其他项目dll时,出现黄色感叹号的解决方案

问题引入 今天拿着老师傅的老项目&#xff0c;需要做通讯调试&#xff0c;说测试一下&#xff0c;便添加了一个项目A来编写结构体&#xff0c;然后在窗体程序项目B中引用A&#xff0c;发现B一引用A&#xff0c;在B项目的引用下面A就多了个黄色感叹号&#xff0c;一编译B项目&am…

网工内推 | 上市公司网工,最高30K,思科认证优先,多次晋升机会

01 牧原股份 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1、负责公司及下属子公司办公网络及IOT网络架构规划、设计、重大网络变更评审或实施及重大疑难问题处理&#xff1b; 2、负责公司网络运维监控体系、自动化网络运维及服务体系&#xff0c;并持续优化改进&am…

20240408在全志H3平台的Nano Pi NEO CORE开发板的eMMC刷Ubuntu Core 16.04

20240408在全志H3平台的Nano Pi NEO CORE开发板的eMMC刷Ubuntu Core 16.04 2024/4/8 20:46 参考资料&#xff1a; https://wiki.friendlyelec.com/wiki/index.php/NanoPi_NEO_Core/zh#.E5.AE.89.E8.A3.85.E7.B3.BB.E7.BB.9F [ OK ] Created slice Slice /system/getty. [ …

获取淘宝销量API商品详情页原数据APP接口:测试key获取(含测试链接)

淘宝/天猫获得淘宝app商品详情原数据 API 返回值说明 item_get_app-获得淘宝app商品详情原数据 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地…

百度松果菁英班——机器学习实践五:明星图片爬取

飞桨AI Studio星河社区-人工智能学习与实训社区 &#x1f96a;图片爬取 import requests import os import urllib ​ class GetImage():def __init__(self,keyword大雁,paginator1):# self.url: 链接头self.url http://image.baidu.com/search/acjson?self.headers {User…

Linux安装并配置Miniconda

miniconda官方文档&#xff1a; Miniconda — Anaconda 文档 官方文档中有讲到怎么安装Miniconda&#xff0c;如下&#xff1a; 以下是我得出的经验&#xff1a; 1. 新建新目录并下载和安装miniconda&#xff08;安装过程中&#xff0c;当提示是否继续时&#xff0c;一直按回…

day75 js 正则表达式 window对象轮播图片调用定时器

一 正则表达式: RegExp 对象: 对字符串执行模式匹配的强大工具。 1 创建正则表达式对象 let reg /模式/修饰符 修饰符 attributes 是一个可选的字符串&#xff0c;包含属性 "g"、"i" 和 "m"&#xff0c; …

Azure的VFP和虚拟IP地址

Azure 的Virtual filtering platform (VFP) 是Azure 网络地址转换,端口转换和端口分配的基础。 下面我们来深入介绍一下VFP的工作方式。 VFP的出站动作。 对于客户端地址作为虚拟IP的出站目的地址的时候,VFP 驱动会负责做以下两个动作。 源地址转换。端口地址转换。VFP 和 S…

20240325-1-HMM

HMM 直观理解 马尔可夫链&#xff08;英语&#xff1a;Markov chain&#xff09;&#xff0c;又称离散时间马尔可夫链&#xff08;discrete-time Markov chain&#xff0c;缩写为DTMC&#xff09;&#xff0c;因俄国数学家安德烈马尔可夫&#xff08;俄语&#xff1a;Андре…

【C++进阶】用哈希实现unordered_set和unordered_map的模拟

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;c大冒险 总有光环在陨落&#xff0c;总有新星在闪烁 前言&#xff1a; 之前我…

【C++ STL算法】sort 排序

文章目录 【 1. 基本原理 】【 2. sort 的应用 】实例 - sort 函数实现 升序排序和降序排序 函数名用法sort (first, last)基于 快速排序&#xff0c;对容器或普通数组中 [ first, last ) 范围内的元素进行排序&#xff0c;默认进行升序排序&#xff08;从小到大&#xff09;。…

2024年面试AI编译器岗经验总结

面试经历: 面试中必备的知识: 1.用C++实现一个卷积 (图解)一步一步使用CPP实现深度学习中的卷积 - GiantPandaCVGiantPandaCVhttp://giantpandacv.com/academic/%E7%AE%97%E6%B3%95%E7%A7%91%E6%99%AE/%E5%B0%BD%E8%A7%88%E5%8D%B7%E7%A7%AF%E7%A5%9E%E7%BB%8F%E7%BD%91%E…

git 常用命令和使用方法

作者简介&#xff1a; 一个平凡而乐于分享的小比特&#xff0c;中南民族大学通信工程专业研究生在读&#xff0c;研究方向无线联邦学习 擅长领域&#xff1a;驱动开发&#xff0c;嵌入式软件开发&#xff0c;BSP开发 作者主页&#xff1a;一个平凡而乐于分享的小比特的个人主页…

2014最新AIGC创作系统ChatGPT网站源码+AI绘画网站源码+GPT4-All联网搜索模型

一、文章前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持…

[C++][算法基础]字符串哈希(哈希表)

给定一个长度为 n 的字符串&#xff0c;再给定 m 个询问&#xff0c;每个询问包含四个整数 l1,r1,l2,r2&#xff0c;请你判断 [l1,r1] 和 [l2,r2] 这两个区间所包含的字符串子串是否完全相同。 字符串中只包含大小写英文字母和数字。 输入格式 第一行包含整数 n 和 m&#x…

HarmonyOS 应用开发-边缓存边播放案例

介绍 OhosVideoCache是一个支持边播放边缓存的库&#xff0c;只需要将音视频的url传递给OhosVideoCache处理之后再设置给播放器&#xff0c; OhosVideoCache就可以一边下载音视频数据并保存在本地&#xff0c;一边读取本地缓存返回给播放器&#xff0c;使用者无需进行其他操作…

Android Telephony框架

目录 一、简介二、应用层(Application)三、框架层(Framework)四、本地 RIL 层(RIL)五、驱动层(Modem)六、整体框架 一、简介 无论手机发展到如何智能的程度&#xff0c;最关键和重要的功能仍然是通讯&#xff0c;具体来说就是打电话、发短信、上网功能的使用。而整个 Android …

Centos 7 安装通过yum安装google浏览器

在CentOS 7上使用yum安装Google Chrome浏览器稍微复杂一些&#xff0c;因为Chrome并不直接包含在默认的Yum仓库中。按照以下步骤来操作&#xff1a; 1、添加Google Chrome仓库 首先&#xff0c;您需要手动添加Google Chrome的Yum仓库。打开终端&#xff0c;并使用文本编辑器&a…