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;
#else
    extern 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, =0x40260004
    ldr  r1,[r0]

    ldr  r0, =MAIN_CORE
    cmp  r1,r0
    beq	 _INIT_DATA_BSS
    b    __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函数)。

总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

云计算(五)—— OpenStack基础环境配置与API使用

OpenStack基础环境配置与API使用 项目实训一 【实训题目】 使用cURL命令获取实例列表 【实训目的】 理解OpenStack的身份认证和API请求流程。 【实训准备】 &#xff08;1&#xff09;复习OpenStack的认证与API请求流程的相关内容。 &#xff08;2&#xff09;熟悉cURL…

软件设计师——数据库

数据库 三级模式两级映像关系模型基本术语关系模型中的关系完整性约束 三级模式两级映像 概念模式&#xff08;也称模式&#xff09;对应基本表 外模式&#xff08;也称用户模式或子模式&#xff09;对应视图 内模式&#xff08;也称存储模式&#xff09;对应存储文件 两级映像…

SL1581耐压30V芯片 24V转5V/2.4A

SL1581是一款专为24V转5V/2.4A应用设计的耐压30V芯片。这款芯片采用了先进的电源管理技术和高效能的转换电路&#xff0c;为电子设备提供了稳定、可靠的电源输出。 首先&#xff0c;SL1581芯片具有出色的耐压性能&#xff0c;能够在高达30V的电压下稳定工作。这使其非常适合在需…

RFID涉密载体柜 RFID智能文件柜系统

涉密载体管控RFID智能柜&#xff08;载体柜DW-G101R&#xff09;通过对涉密物资、设备进行RFID唯一标识并放置于RFID设备涉密物资柜柜体&#xff0c;通过定位每台设备每件涉密物资的位置&#xff0c;实现涉密物资审批、自助借还、防盗等出入库全流程自动化管理。主要管理对象移…

Vulnhub:MHZ_CXF: C1F

目录 信息收集 arp-scan nmap nikto WEB web信息收集 dirmap gobuster ssh登录 提权 获得初始立足点 系统信息收集 横向渗透 提权 信息收集 arp-scan ┌──(root㉿ru)-[~/桌面] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:50:56:…

产品经理和项目经理的区别

1. 前言 本文深入探讨了产品经理与项目经理在职责、关注点以及所需技能方面的显著区别。产品经理主要负责产品的规划、设计和市场定位,强调对用户需求的深刻理解和产品创新的推动;而项目经理则侧重于项目的执行、进度控制和资源管理,确保项目按时、按质、按预算完成。两者在…

C++11可变模板参数:海纳百川的Args

目录 一、可变模板参数的概念及功能 1.1Args的概念与使用 1.2获取args中的参数 二、emplace可变模板参数的实际应用 三、逗号表达式展开参数包 一、可变模板参数的概念及功能 1.1Args的概念与使用 C11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板…

python中的split()用法

在Python中&#xff0c;split() 是一个字符串方法&#xff0c;用于将字符串按照指定的分隔符分割成一个列表。如果没有提供分隔符&#xff0c;那么它会默认按照任何空白字符&#xff08;如空格、换行符、制表符等&#xff09;进行分割。 这里是 split() 方法的一些基本用法&am…

德兰梅尔:耐高温热销的膜元件亮相2024上海国际生物发酵展

德兰梅尔&#xff1a;耐高温热销的膜元件盛装亮相2024上海国际生物发酵展&#xff0c;8月7-9号上海新国际博览中心与您不见不散&#xff01; 据了解&#xff0c;从成立至今&#xff0c;德兰梅尔一直专注膜技术、膜产品的开发生产。在中国市场上&#xff0c;德兰梅尔刚步入中国…

代码随想录算法训练营33期 第三十一天(补29) | 491. 非递减子序列、46. 全排列、47. 全排列 II

491. 非递减子序列 class Solution { public:vector<int> path;vector<vector<int>> result;void BackTracking(vector<int>& nums, int index){if(path.size()>2){result.push_back(path);}unordered_set<int> usedSet;for (int iindex…

nandgame中的asm编程 Escape Labyrinth(逃离迷宫)

先翻译题目&#xff1a; 逃离迷宫计算机被困在火星上的迷宫中。编写一个程序&#xff0c;让它逃离迷宫。计算机配备了连接的轮子和前方障碍物探测器。与轮子和探测器的输入/输出是内存映射在地址7FFF上&#xff1a;对外设的输出信号&#xff1a; 位 设置为1代表&#xff1a; 2…

高精度原边控制离线式PWM功率开关芯片D3820的特征和详细的工作原理介绍

D3820是一款高精度原边控制离线式PWM功率开关。本文主要介绍D3820的特征和详细的工作原理&#xff0c;对反激式隔离AC-DC开关电源提供较为详细的测试过程。 特 点 1、全电压范围CC/CV精度保持在5%以内 2、用原边控制&#xff0c;无需TL431和光耦 3、欠压锁定&#xff08…

2024mathorcup妈妈杯数学建模A题思路模型

2024mathorcup妈妈杯数学建模A题思路模型&#xff1a;比赛开始后第一时间更新&#xff0c;更新见文末名片&#xff0c;下面对2022年B题进行介绍&#xff1a; 2022Mathorcup B题题目介绍 ​ B题无人仓的搬运机器人调度问题本题考在无人仓内的仓库管理问题之一&#xff0c;搬运机…

mos管开关出现尖峰的原理? mos管开关的时候cs会出现尖峰,请问这是什么原因?

MOS管在开关过程中出现尖峰现象&#xff0c;通常是由于电路中的寄生参数和快速电压变化引起的。以下是一些导致尖峰出现的主要原因和原理&#xff1a; 寄生电容 在MOS管的源极&#xff08;S&#xff09;和漏极&#xff08;D&#xff09;之间存在寄生电容&#xff0c;这个电容在…

Vue3组件基础示例

组件是vue中最推崇的&#xff0c;也是最强大的功能之一&#xff0c;就是为了提高重用性&#xff0c;减少重复性的开发。 如何使用原生HTML方法实现组件化 在使用原生HTML开发时&#xff0c;我们也会遇到一些常见的功能、模块&#xff0c;那么如何在原生HTML中使用组件化呢&am…

IoT数采平台4:测试

IoT数采平台1&#xff1a;开篇IoT数采平台2&#xff1a;文档IoT数采平台3&#xff1a;功能IoT数采平台4&#xff1a;测试 Modbus RTU串口测试 OPC测试 HTTP测试 MQTT透传测试 MQTT网关测试及数据上报 TCP / UDP 监听&#xff0c;客户端连上后发送信息&#xff0c;客户端上报数据…

P4117 [Ynoi2018] 五彩斑斓的世界

分析第一个操作 朴素的做法&#xff0c;遍历一遍大于x就-x&#xff0c;极限复杂度O(mn) 分块做法 整块:我们维护一个最大值&#xff0c;从mx到x遍历一遍&#xff08;减去x)用并查集操作merge(i,i-x),考虑mx100001,x1,极限复杂度O(mV) 我们可以分析 1.x>(mx/2),从mx到x遍…

LwIP TCP/IP

LWIP 架构 LwIP 符合 TCP/IP 模型架构&#xff0c;规定了数据的格式、传输、路由和接收&#xff0c;以实现端到端的通信。 此模型包括四个抽象层&#xff0c;用于根据涉及的网络范围&#xff0c;对所有相关协议排序&#xff08;参见图 2&#xff09;。这几层从低到高依次为&am…

【grpc】二、grpc入门,基本使用方法

上篇介绍了使用protobuf生成grpc相关代码&#xff0c;并实现了服务端方法&#xff0c;本篇介绍下具体的使用。 一、服务端 // server.gopackage mainimport ("google.golang.org/grpc""grpcDemo/calc""net" )func startServer(addr string) {//…

近距离共享数字化实战经验,深挖数据价值赋能千行百业

近期&#xff0c;思迈特软件积极投身于金融、制造、零售、医疗等多个行业的线下活动中&#xff0c;深度解析行业趋势&#xff0c;分享BI数字化创新解决方案&#xff0c;并与客户及合作伙伴进行深入交流。通过这些活动&#xff0c;不仅展示了思迈特软件在各领域的先进技术和成果…