什么是CopyTable及如何使用CopyTable

原创 汽车电子嵌入式 2024-11-25 08:07

目录

前言

嵌入式工程师应该都知道没有初始值的全局变量或者静态局部变量存放在.BSS段,有初始值的全局变量或者静态局部变量存放在.DATA段,芯片上电后我们需要将.BSS段都初始化为0值,将ROM中保存的全局变量或者静态局部变量的初始值拷贝到RAM中也就是.DATA段中。

那么问题来了,在哪个地方进行.BSS段清零以及.DATA段中RAM初始值的拷贝了?

熟悉英飞凌TC3xx芯片的朋友应该知道英飞凌芯片的启动分为6个阶段(Phase1 - Phase6),在__StartUpSoftware_Phase6()中完成.BSS段和.DATA段的初始值拷贝。TC3xx芯片的启动流程参考以下的文章:

参考文章:https://zhuanlan.zhihu.com/p/644563274

如下图所示,最终由Ifx_Ssw_C_InitInline()函数完成初始化C运行时变量,也就说.BSS段的清零及.DATA段的初始化。

Ifx_Ssw_C_InitInline()函数的具体实现根据编译的不同而不同,本文就来介绍3个常用编译器如何完成C运行时变量的初始化


注:本文章引用了一些第三方工具和文档,若有侵权,请联系作者删除!

正文

1.GHS编译器

1.1. Clear and Copy Tables

Green Hills编译器会自动在.secinfo段(section)中定义三个表(Tables),Clear Table, Copy Table,以及compressed Copy table.


Table Type

Start address

End address

Clear Table

__ghsbinfo_clear

__ghseinfo_clear

Copy Table

__ghsbinfo_copy

__ghseinfo_copy

compressed Copy table

__ghsbinfo_comcopy

__ghseinfo_comcopy

注意:我们这里只套路Clear TableCopy Table, compressed copy table还不知道咋用的。


Clear Table中存放的就是初始化.BSS段相关信息(未初始化的全局变量/静态局部变量的RAM地址、数据长度)。

Copy Table中中存放的就是初始化.DATA段相关信息(初始化的全局变量/静态局部变量的RAM地址、初始化的全局变量/静态局部变量的初始值所在的ROM地址,数据长度)。


1.2 Ifx_Ssw_C_InitInline实现

有了以上的理论分析,如下的代码实现应该容易看懂了:

typedef int          ptrdiff_t;typedef unsigned int syze_t;typedef signed int   signed_size_t;#define size_t syze_t
extern void *memcpy(void *s1, const void *s2, syze_t n);extern void *memset(void *s, int c, syze_t n);
/* rodata is absolute */typedef const char rodata_ptr[];#define PICBASE 0#define PIDBASE 0#define PIRBASE 0
#define CONST_FUNCP *const
IFX_SSW_INLINE void Ifx_Ssw_C_InitInline(void){ /*----------------------------------------------------------------------*/ /* */ /* Clear BSS */ /* */ /*----------------------------------------------------------------------*/ {#pragma ghs rodata extern rodata_ptr __ghsbinfo_clear;#pragma ghs rodata extern rodata_ptr __ghseinfo_clear;#pragma ghs rodata extern rodata_ptr __ghsbinfo_aclear;
void **b = (void **)((char *)__ghsbinfo_clear); void **e = (void **)((char *)__ghseinfo_clear); void **a = __ghsbinfo_aclear != 0 ? ((void **)((char *)__ghsbinfo_aclear)) : e;
/* Warning: This code assumes * __ghsbinfo_clear <= __ghsbinfo_aclear <= __ghseinfo_clear * Which is currently enforced with elxr * OR * __ghsbinfo_aclear == 0 (i.e.: undefined) */
int OFFSET = PIDBASE;
while (b != e) { void *t; /* target pointer */ ptrdiff_t v; /* value to set */ size_t n; /* set n bytes */
while (b != a) { t = OFFSET + (char *)(*b++); v = *((ptrdiff_t *)b); b++; n = *((size_t *)b); b++; (void)memset(t, v, n); }
OFFSET = 0; a = e; } }
/*----------------------------------------------------------------------*/ /* */ /* Copy from ROM to RAM */ /* */ /*----------------------------------------------------------------------*/
{#pragma ghs rodata extern rodata_ptr __ghsbinfo_copy;#pragma ghs rodata extern rodata_ptr __ghsbinfo_tcopy;#pragma ghs rodata extern rodata_ptr __ghseinfo_copy;
void **b = (void **)((char *)__ghsbinfo_copy); void **m = (void **)((char *)__ghsbinfo_tcopy); void **e = (void **)((char *)__ghseinfo_copy);
while (b != e) { void *t; /* target pointer */ void *s; /* source pointer */ size_t n; /* copy n bytes */ t = ((b < m) ? PIDBASE : PICBASE) + (char *)(*b); b++; s = PIRBASE + (char *)(*b++); n = *((size_t *)b); b++; (void)memcpy(t, s, n); } }}

2.GNU编译器

2.1 Clear and Copy Tables

GNUGCC编译器不会自动给我们创建Clear TablesCopy Tables,需要我们在Link file(连接器脚本)中自定义Cleare TablesCopy Table这些标识符(地址符号)。


参考文章:https://www.cnblogs.com/uestcliming666/p/11464709.html


__clear_table__copy_tablememory layout如下所示:


2.2 Ifx_Ssw_C_InitInline实现

有了以上的理论分析,如下的代码实现应该容易看懂了:

extern unsigned int __clear_table[];  /**< clear table entry */extern unsigned int __copy_table[];   /**< copy table entry */
IFX_SSW_INLINE void Ifx_Ssw_C_InitInline(void){ Ifx_Ssw_CTablePtr pBlockDest, pBlockSrc; unsigned int uiLength, uiCnt; unsigned int *pTable; /* clear table */ pTable = (unsigned int *)&__clear_table;
while (pTable) { pBlockDest.uiPtr = (unsigned int *)*pTable++; uiLength = *pTable++;
/* we are finished when length == -1 */ if (uiLength == 0xFFFFFFFF) { break; }
uiCnt = uiLength / 8;
while (uiCnt--) { *pBlockDest.ullPtr++ = 0; }
if (uiLength & 0x4) { *pBlockDest.uiPtr++ = 0; }
if (uiLength & 0x2) { *pBlockDest.usPtr++ = 0; }
if (uiLength & 0x1) { *pBlockDest.ucPtr = 0; } }
/* copy table */ pTable = (unsigned int *)&__copy_table;
while (pTable) { pBlockSrc.uiPtr = (unsigned int *)*pTable++; pBlockDest.uiPtr = (unsigned int *)*pTable++; uiLength = *pTable++;
/* we are finished when length == -1 */ if (uiLength == 0xFFFFFFFF) { break; }
uiCnt = uiLength / 8;
while (uiCnt--) { *pBlockDest.ullPtr++ = *pBlockSrc.ullPtr++; }
if (uiLength & 0x4) { *pBlockDest.uiPtr++ = *pBlockSrc.uiPtr++; }
if (uiLength & 0x2) { *pBlockDest.usPtr++ = *pBlockSrc.usPtr++; }
if (uiLength & 0x1) { *pBlockDest.ucPtr = *pBlockSrc.ucPtr; } }}

3.Tasking编译器

3.1 Clear and Copy Tables

Tasking编译器不再区分Clear TableCopy Tables,统一都用一个copy table来存放.bss.data段的相关信息。_lc_ub_table标识符表示copy table的开始地址,_lc_ue_table标识符表示copy table的结束地址。


值得注意的是,如果我们想让Tasking编译器生成_lc_ub_table_lc_ue_table标识符的地址信息,就必须不能勾选如下的编译选项


如果勾选了如下选项,就意味着需要和GNU编译器一样在连接器脚本中自定义copy table相关的标识符。


Copy Tablememory layout如下所示:


3.2 Ifx_Ssw_C_InitInline实现

有了以上的理论分析,如下的代码实现应该容易看懂了:

/* * Startup_CompilerTasking.c * *  Created on: 2024年10月27日 *      Author: Administrator */#include "Std_Types.h"
#define LC_UB_TABLE_TYPE_BSS (0x2u)#define LC_UB_TABLE_TYPE_DATA (0x1u)
extern uint32 _lc_ub_table[];extern uint32 _lc_ue_table[];
uint32* g_lc_ub_table;uint32* g_lc_ue_table;
void _c_init(void){ const uint32* copyTable; const uint32* currentPtr;
const uint32* srcU32Ptr; uint32* dstU32Ptr;
uint32 sectionType; uint32 length; uint32 value;
uint32 count; uint16* srcU16Ptr; uint16* dstU16Ptr2; uint8* srcU8Ptr; uint8* dstU8Ptr; /*Just for debug*/  g_lc_ub_table = (uint32*)&_lc_ub_table; g_lc_ue_table = (uint32*)&_lc_ue_table;
for(copyTable = (uint32*)&_lc_ub_table; copyTable != (uint32*)&_lc_ue_table; copyTable += 4) { currentPtr = copyTable;
sectionType = currentPtr[0]; dstU32Ptr = (uint32*)currentPtr[1]; length = currentPtr[3];
if(LC_UB_TABLE_TYPE_BSS == sectionType) { value = currentPtr[2];
for(count = length / 4; count > 0; count--) { *dstU32Ptr++ = value; }
dstU16Ptr2 = (uint16*)dstU32Ptr;
if(length & 0x2) { *dstU16Ptr2++ = (uint16)value; }
dstU8Ptr = (uint8*)dstU16Ptr2;
if(length & 0x1) { *dstU8Ptr = (uint8)value; } } else if(LC_UB_TABLE_TYPE_DATA == sectionType) { srcU32Ptr = (uint32*)currentPtr[2];
for(count = length / 4; count > 0; count--) { *dstU32Ptr++ = *srcU32Ptr++; }
dstU16Ptr2 = (uint16*)dstU32Ptr; srcU16Ptr = (uint16*)srcU32Ptr;
if(length & 0x2) { *dstU16Ptr2++ = *srcU16Ptr++; }
dstU8Ptr = (uint8*)dstU16Ptr2; srcU8Ptr = (uint8*)srcU16Ptr;
if(length & 0x1) { *dstU8Ptr = *srcU8Ptr; } } else { //Do nothing } }}

3.3 调试分析

Copy Table的起始地址_lc_ub_table = 0x 80003036, 结束地址_lc_ue_table = 0x80003E3C


TC387芯片中Copy TableMemory Layout的解析如下所示:


4.总结

Copy Table用来初始化C环境下全局变量或者静态局部变量,Copy Table中保存了全局变量或者静态局部变量的RAM地址或者初始值的ROM地址以及数据长度信息,开发者需要在Startup代码中使用Copy Table完成全局变量或者静态局部变量的初始值从ROMRAM的搬运(或者清零.BSS段)。而这个过程,由于编译器特性不一样,需要开发者根据编译器特性来具体实现,具体参考正文内容。


值得注意的是,实际开发中如果我们使用编译器的启动代码,这个工作往往编译器自动帮忙我们实现了(很多初级的工程师可能都不知道这个copy table的存在)。但是,如果我们从芯片上电到Main函数之前的启动代码都是自己实现的(安全启动),Copy Table就必须要考虑了。



End

「汽车电子嵌入式在CSDN上同步推出AUTOSAR精进之路专栏,本专栏每个模块完全按实际项目中开发及维护过程来详细介绍。模块核心概念介绍、实际需求描述、实际工程配置、特殊需求介绍及背后原理、实际工程使用经验总结。目的是让读者看完每一个章节后能理解原理后根据需求完成一个模块的配置或者解决一个问题。」


点击文章最后左下角的阅读原文可以获取更多信息


或者复制如下链接到浏览器获取更多信息

https://blog.csdn.net/qq_36056498/article/details/132125693


文末福利




1
.如需汽车电子嵌入式收集的学习文档,
后台回复“

资料

即可免费下载;

2.为便于技术交流,创建了汽车电子嵌入式技术交流群,可尽情探讨AP,CP,DDS,SOME/IP等前沿热点话题,后台回复“加群”即可加入;



注:本文引用了一些第三方工具和文档,若有侵权,请联系作者删除!


推荐阅读

汽车电子嵌入式精彩文章汇总第一期:20210530-20230703

汽车电子嵌入式精彩文章汇总第2期

汽车电子嵌入式精彩文章汇总第3期

【OS】AUTOSAR OS Event实现原理

【OS】AUTOSAR OS Spinlock实现原理(下篇)

【OS】AUTOSAR OS Spinlock实现原理(上篇)

CanNm处于PBS状态下接收到一帧诊断报文DCM会响应吗

TC3xx芯片CAN模块详解

AUTOSAR OS Alarm实现原理

AUTOSAR OsTask切换原理

TC3xx 芯片SPI模块详解

AUTSOAR ComStack如何实现PDU只收不发的

AUTOSAR OsStack监控原理

AUTOSAR架构下ICU唤醒详解

CanNm报文的触发发送详解

Can报文能发不能收问题分析



End


欢迎点赞,关注,转发,在看,您的每一次鼓励,都是我最大的动力!

汽车电子嵌入式

微信扫描二维码,关注我的公众号

评论 (0)
  •   电磁频谱数据综合管理平台系统解析   一、系统定义与目标   北京华盛恒辉电磁频谱数据综合管理平台融合无线传感器、软件定义电台等前沿技术,是实现无线电频谱资源全流程管理的复杂系统。其核心目标包括:优化频谱资源配置,满足多元通信需求;运用动态管理与频谱共享技术,提升资源利用效率;强化频谱安全监管,杜绝非法占用与干扰;为电子战提供频谱监测分析支持,辅助作战决策。   应用案例   目前,已有多个电磁频谱数据综合管理平台在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润电磁频谱数
    华盛恒辉l58ll334744 2025-04-23 16:27 141浏览
  • 文/Leon编辑/cc孙聪颖‍在特朗普政府发起的关税战中,全球芯片产业受到巨大冲击,美国芯片企业首当其冲。据报道称,英伟达本周二公布的8-K文件显示,美国政府通知该公司向中国(包括中国香港及澳门)销售尖端芯片(H20)时,需要获得美国政府的许可。文件发布后,英伟达预计会在第一季度中额外增加55亿美元的相关费用计提。随后,英伟达股价单日下跌6.9%,市值一夜蒸发约1890亿美元(约合人民币1.37万亿元)。至截稿时,至截稿时,其股价未见止跌,较前日下跌4.51%。北京时间4月17日,英伟达创始人、
    华尔街科技眼 2025-04-22 20:14 105浏览
  •   复杂电磁环境模拟系统平台解析   一、系统概述   北京华盛恒辉复杂电磁环境模拟系统平台是用于还原真实战场或特定场景电磁环境的综合性技术平台。该平台借助软硬件协同运作,能够产生多源、多频段、多体制的电磁信号,并融合空间、时间、频谱等参数,构建高逼真度的电磁环境,为电子对抗、通信、雷达等系统的研发、测试、训练及评估工作提供重要支持。   应用案例   目前,已有多个复杂电磁环境模拟系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润复杂电磁环境模拟系统。这些成功案例为复杂电
    华盛恒辉l58ll334744 2025-04-23 10:29 148浏览
  • 故障现象一辆2016款奔驰C200L车,搭载274 920发动机,累计行驶里程约为13万km。该车组合仪表上的防侧滑故障灯、转向助力故障灯、安全气囊故障灯等偶尔异常点亮,且此时将挡位置于R挡,中控显示屏提示“后视摄像头不可用”,无法显示倒车影像。 故障诊断用故障检测仪检测,发现多个控制单元中均存储有通信类故障代码(图1),其中故障代码“U015587 与仪表盘的通信存在故障。信息缺失”出现的频次较高。 图1 存储的故障代码1而组合仪表中存储有故障代码“U006488 与用户界
    虹科Pico汽车示波器 2025-04-23 11:22 77浏览
  • 一、行业背景与市场需求高血压作为全球发病率最高的慢性病之一,其早期监测与管理已成为公共卫生领域的重要课题。世界卫生组织数据显示,全球超13亿人受高血压困扰,且患者群体呈现年轻化趋势。传统血压计因功能单一、数据孤立等缺陷,难以满足现代健康管理的需求。在此背景下,集语音播报、蓝牙传输、电量检测于一体的智能血压计应运而生,通过技术创新实现“测量-分析-管理”全流程智能化,成为慢性病管理的核心终端设备。二、技术架构与核心功能智能血压计以电子血压测量技术为基础,融合物联网、AI算法及语音交互技术,构建起多
    广州唯创电子 2025-04-23 09:06 134浏览
  • 文/Leon编辑/cc孙聪颖‍4月18日7时,2025北京亦庄半程马拉松暨人形机器人半程马拉松正式开跑。与普通的半马比赛不同,这次比赛除了有人类选手,还有21支人形机器人队伍参赛,带来了全球首次人类与机器人共同竞技的盛况。参赛队伍中,不乏明星机器人企业及机型,比如北京人形机器人创新中心的天工Ultra、松延动力的N2等。宇树G1、众擎PM01,则是由城市之间科技有限公司购置及调试,并非厂商直接参赛。考虑到机器人的适用场景和续航力各有不同,其赛制也与人类选手做出区别:每支赛队最多可安排3名参赛选手
    华尔街科技眼 2025-04-22 20:10 99浏览
  •   陆地边防事件紧急处置系统平台解析   北京华盛恒辉陆地边防事件紧急处置系统平台是整合监测、预警、指挥等功能的智能化综合系统,致力于增强边防安全管控能力,快速响应各类突发事件。以下从系统架构、核心功能、技术支撑、应用场景及发展趋势展开全面解读。   应用案例   目前,已有多个陆地边防事件紧急处置系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润陆地边防事件紧急处置系统。这些成功案例为陆地边防事件紧急处置系统的推广和应用提供了有力支持。   一、系统架构   感知层:部
    华盛恒辉l58ll334744 2025-04-23 11:22 110浏览
  • 前言本文主要演示基于TL3576-MiniEVM评估板HDMI OUT、DP 1.4和MIPI的多屏同显、异显方案,适用开发环境如下。Windows开发环境:Windows 7 64bit、Windows 10 64bitLinux开发环境:VMware16.2.5、Ubuntu22.04.5 64bitU-Boot:U-Boot-2017.09Kernel:Linux-6.1.115LinuxSDK:LinuxSDK-[版本号](基于rk3576_linux6.1_release_v
    Tronlong 2025-04-23 13:59 96浏览
  • 在科技飞速发展的当下,机器人领域的每一次突破都能成为大众瞩目的焦点。这不,全球首届人形机器人半程马拉松比赛刚落下帷幕,赛场上的 “小插曲” 就掀起了一阵网络热潮。4月19日,北京亦庄的赛道上热闹非凡,全球首届人形机器人半程马拉松在这里激情开跑。20支机器人队伍带着各自的“参赛选手”,踏上了这21.0975公里的挑战之路。这场比赛可不简单,它将机器人放置于真实且复杂的动态路况与环境中,对机器人在运动控制、环境感知和能源管理等方面的核心技术能力进行了全方位的检验。不仅要应对长距离带来的续航挑战,还要
    用户1742991715177 2025-04-22 20:42 94浏览
  •   无人机结构仿真与部件拆解分析系统平台解析   北京华盛恒辉无人机结构仿真与部件拆解分析系统无人机技术快速发展的当下,结构仿真与部件拆解分析系统平台成为无人机研发测试的核心工具,在优化设计、提升性能、降低成本等方面发挥关键作用。以下从功能、架构、应用、优势及趋势展开解析。   应用案例   目前,已有多个无人机结构仿真与部件拆解分析系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润无人机结构仿真与部件拆解分析系统。这些成功案例为无人机结构仿真与部件拆解分析系统的推广和应用提
    华盛恒辉l58ll334744 2025-04-23 15:00 146浏览
  • 一、技术背景与市场机遇在智能家居高速发展的今天,用户对家电设备的安全性、智能化及能效表现提出更高要求。传统取暖器因缺乏智能感知功能,存在能源浪费、安全隐患等痛点。WTL580-C01微波雷达感应模块的诞生,为取暖设备智能化升级提供了创新解决方案。该模块凭借微波雷达技术优势,在精准测距、环境适应、能耗控制等方面实现突破,成为智能取暖器领域的核心技术组件。二、核心技术原理本模块采用多普勒效应微波雷达技术,通过24GHz高频微波信号的发射-接收机制,实现毫米级动作识别和精准测距。当人体进入4-5米有效
    广州唯创电子 2025-04-23 08:41 122浏览
  •   后勤实验仿真系统平台深度解析   北京华盛恒辉后勤实验仿真系统平台依托计算机仿真技术,是对后勤保障全流程进行模拟、分析与优化的综合性工具。通过搭建虚拟场景,模拟资源调配、物资运输等环节,为后勤决策提供数据支撑,广泛应用于军事、应急管理等领域。   应用案例   目前,已有多个后勤实验仿真系统平台在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润后勤实验仿真系统平台。这些成功案例为后勤实验仿真系统平台的推广和应用提供了有力支持。   一、核心功能   (一)后勤资源模拟
    华盛恒辉l58ll334744 2025-04-23 15:39 110浏览
我要评论
0
1
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦