[其它产品/技术] AURIX™ TC3xx启动文件解析

[复制链接]
 楼主| bestwell 发表于 2025-6-18 08:46 | 显示全部楼层 |阅读模式
英飞凌AURIX™系列单片机,凭借强大的实时性能、功能安全以及信息安全的优异设计,受到了客户的普遍欢迎。英飞凌也一直致力于打造强大的生态圈,助力我们的客户更方便、快速地完成设计。本文将进一步为大家介绍更多AURIX™干货,以及完善的生态体系新动态:
  • AURIX™ TC3xx启动文件解析;
  • AURIX™生态体系进一步完善:近期,国产RT-Thread操作系统加入AURIX™生态体系,宣布商业支持英飞凌科技车规级32位AURIX™ TriCore™多核微控制器。

启动文件流程图

TC3xx系列MCU复位后会从Ifx_Ssw_Tc0.c文件的_START()函数开始启动,启动的时候都会从CPU0开始运行,直到在_StartUpSoftware_Phase6()函数中才会根据用户配置依次启动其他核。


_START()
_START()的地址由link文件中RESET决定,以TASKING为例,在Link文件中:
#define RESET 0xA0000000

这个地址也必须和BMHD中的应用程序起始地址定义一致。


_START()代码解析
void _START(void)
{
     Ifx_Ssw_jumpToFunction(__StartUpSoftware); // 直接跳转到__StartUpSoftware()
}


_StartUpSoftware()

_StartUpSoftware()主要用来设置A1寄存器,设置PSW寄存器,以及判断是否是Application Reset, 从而进行不同的跳转。

在TriCore™中A0,A1,A8,A9是全局地址寄存器,此处的A1所指向区域用来存放small RODATA,所谓small data区域就是可以直接寻址。

PSW的默认值设的是0x980, 即Supervise mode, Global Address Register Write Permission Enable, Call Depth Count Enable, User Stack。



_StartUpSoftware()代码解析:
static void __StartUpSoftware(void)
{

     Ifx_Ssw_setAddressReg(a1, __SDATA2(0)); // A1指向small  data区域

     Ifx_Ssw_MTCR(CPU_PSW, IFX_CFG_SSW_PSW_DEFAULT); // 设置CPU0的PSW寄存器

    if  (Ifx_Ssw_isApplicationReset() != 1)
    {
         Ifx_Ssw_jumpToFunction(__StartUpSoftware_Phase2);
    }
    else
    {
         Ifx_Ssw_jumpToFunction(__StartUpSoftware_Phase3ApplicationResetPath);
    }
}

_StartUpSoftware_Phase2()

在这个API里面,会根据用户的配置,执行EVRC的初始化配置,LBIST测试,MONBIST测试。


_StartUpSoftware_Phase2()代码解析
static void __StartUpSoftware_Phase2(void)
{
    /* Power and EVRC configurations */
     IFX_CFG_SSW_CALLOUT_PMS_INIT();    // 执行EVC初始化流程

    /* LBIST Tests and evaluation */
     IFX_CFG_SSW_CALLOUT_LBIST();       // 执行LBIST测试

    /* MONBIST Tests and evaluation */
     IFX_CFG_SSW_CALLOUT_MONBIST();     // 执行MONBIST测试

     Ifx_Ssw_jumpToFunction(__StartUpSoftware_Phase3PowerOnResetPath);
}


_StartUpSoftware_Phase3PowerOnResetPath()
在这个API里面, 会初始化上下文,所谓的上下文就是SP指针和CSA。

在TriCore™中,SP是A10寄存器,在这里会把栈顶地址赋给A10。

CSA是存放上下文的区域,在TriCore™中,每当调用子函数或者进中断时,都会把一些通用寄存器自动存放在CSA区域 (Push),然后等到子函数返回或中断返回时,再把这些寄存器恢复(Pop)。

_StartUpSoftware_Phase3ApplicationResetPath代码解析:



_StartUpSoftware_Phase4
在这个API里面,会首先进行对CPU0 watchdog和safety watchdog进行一次喂狗(注意:复位后CPU0 watchdog和safety watchdog是使能的),然后根据用户配置,完成时钟初始化以及MBIST测试。

static void __StartUpSoftware_Phase4(void)
{
  /* This is for ADAS chip, where clock is provided by  MMIC chip. This has to be
     *  implemented according the board.
     */
     IFX_CFG_SSW_CALLOUT_MMIC_CHECK();

    {
        /* Update safety and cpu watchdog  reload value*/
unsignedshort  cpuWdtPassword    =  Ifx_Ssw_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[0]);
        unsignedshort  safetyWdtPassword = Ifx_Ssw_getSafetyWatchdogPasswordInline();

        /* servicing watchdog timers */
         Ifx_Ssw_serviceCpuWatchdog(&MODULE_SCU.WDTCPU[0],  cpuWdtPassword);
         Ifx_Ssw_serviceSafetyWatchdog(safetyWdtPassword);
    }

    /* Initialize the clock system */
     IFX_CFG_SSW_CALLOUT_PLL_INIT();

    /* MBIST Tests and evaluation */
     IFX_CFG_SSW_CALLOUT_MBIST();

     Ifx_Ssw_jumpToFunction(__StartUpSoftware_Phase5);
}


IFX_CFG_SSW_CALLOUT_PLL_INIT()
是否执行,取决于Ifx_Cfg_Ssw.h中的IFX_CFG_SSW_ENABLE_PLL_INIT的配置,这个函数用来初始化PLL配置。这个API所调用函数在IfxScuCcu.c中,所以要进行PLL初始化,需要在工程中添加这个LLD文件
IFX_CFG_SSW_CALLOUT_MBIST()
是否执行,取决于Ifx_Cfg_Ssw.h中的IFX_CFG_SSW_ENABLE_MBIST的配置。这个函数用来执行MBIST测试,MBIST用于对RAM区域进行硬件自检。这个API所调用函数在IfxMtu.c,所以要进行这个测试,需要在工程中添加这个LLD文件


_StartUpSoftware_Phase5

在这个API里面, 只有SMU配置的一个API,但是这个API只是个空函数,所以其实在这里什么都没有做。


_StartUpSoftware_Phase3ApplicationResetPath

和_StartUpSoftware_Phase3PowerOnResetPath()一样。


_StartUpSoftware_Phase6
根据用户配置启动不同的内核。
IFX_CFG_SSW_ENABLE_TRICORE1
1:  启动Core1, 0: 不启动Core1
IFX_CFG_SSW_ENABLE_TRICORE2
1:  启动Core2, 0: 不启动Core2
IFX_CFG_SSW_ENABLE_TRICORE3
1:  启动Core3, 0: 不启动Core3

SYSCON寄存器的BHALT位用来设置Core是否启动,PC用来设置程序指针,Ifx_Ssw_startCore()中设置这两个寄存器,来启动其他内核。


_StartUpSoftware_Phase6()代码解析:
static void __StartUpSoftware_Phase6(void)
{
    /* Start remaining cores as a daisy-chain */
#if  (IFX_CFG_SSW_ENABLE_TRICORE1 != 0)
     Ifx_Ssw_startCore(&MODULE_CPU1, (unsigned int)&__Core1_start);    // 启动core 1
#endif/* #if (IFX_CFG_CPU_CSTART_ENABLE_TRICORE1 != 0)*/
#if  (IFX_CFG_SSW_ENABLE_TRICORE1 == 0)
#if  (IFX_CFG_SSW_ENABLE_TRICORE2 != 0)
     Ifx_Ssw_startCore(&MODULE_CPU2, (unsigned int)&__Core2_start);    // 启动core 2
#endif
#if  (IFX_CFG_SSW_ENABLE_TRICORE2 == 0)
#if  (IFX_CFG_SSW_ENABLE_TRICORE3 != 0)
     Ifx_Ssw_startCore(&MODULE_CPU3, (unsigned int)&__Core3_start);    // 启动core 3
#endif
#endif/* #if (IFX_CFG_SSW_ENABLE_TRICORE2 == 0) */
#endif/* #if (IFX_CFG_SSW_ENABLE_TRICORE1 == 0) */

     Ifx_Ssw_jumpToFunction(__Core0_start);
}





_Ifx_Ssw_startCore()代码解析:
void Ifx_Ssw_startCore(Ifx_CPU *cpu, unsigned int  programCounter)
{
    /* Set the PC */
    cpu->PC.B.PC = (unsigned int)programCounter  >> 1U; // 设置PC

    /* release boot halt mode if required */
    Ifx_CPU_SYSCON syscon;
    syscon =  cpu->SYSCON;

    if (syscon.B.BHALT)
    {
        syscon.B.BHALT = 0U;      // 启动内核
        cpu->SYSCON    = syscon;
    }

}



以TC38x为例,如果所有4个内核都启动,那么_StartUpSoftware_Phase6()中会启动CORE1。这个时候,_Core0_Start()和__Core1_Start()是同时运行的,在_Core1_Start()的最后会启动Core2,然后跳转到_Core2_Start(),在_Core2_Start()最后会启动Core3, 然后跳转到_Core3_Start()。


_Corex_start

以_Core0_Start()为例,在_Core0_Start()中,会根据配置使能PCACHE和DCACHE,设置A0, A8, A9地址,配置Trap和中断向量表起始地址,配置中断栈指针,初始化全局变量。

CACHE配置:

是否使能CACHE,通过配置下面两个宏:

IFX_CFG_SSW_ENABLE_TRICORE0_PCACHE
1:  使能PCACHE,0:不使能PCACHE
IFX_CFG_SSW_ENABLE_TRICORE0_DCACHE
1:使能DCACHE,0:不使能DCACHE

通过配置PCON0的PCBYP位来使能PCACHE:



通过配置DCON0的PCBYP来使能DCACHE:


Trap和中断向量配置:
BTV寄存器用来设置Trap向量表的首地址,在工程中Trap向量表的首地址在link文件中设置,通过下面语句会把link文件中Trap向量表地址赋给BTV。

Ifx_Ssw_MTCR(CPU_BTV, (unsigned int)__TRAPTAB(0));


BIV寄存器用来设置中断向量表的首地址,在工程中中断向量表的首地址在link文件中设置,通过下面语句会把link文件的中断向量表地址赋给BIV。注意在TriCore™中,默认状态下,中断向量是32字节对齐的,中断向量的位置不是固定的,而是由中断优先级决定的。

Ifx_Ssw_MTCR(CPU_BIV, (unsigned int)__INTTAB(0));



配置ISTACK:

在TriCore™中,栈分为USTACK和ISTACK,他们的使用由PSW.IS位来决定,默认配置PSW.IS=0,即在线程中的函数调用时,会用USTACK(A11)部分作为CPU的栈,而在中断函数中会用ISTACK(ISP)作为CPU的栈。USTACK和ISTACK大小和位置是在Link文件中配置的。下面语句设置ISP:
/* Interrupt stack pointer is configured */
     Ifx_Ssw_MTCR(CPU_ISP, (unsigned int)__ISTACK(0));


对于CPU0,在_StartUpSoftware_Phase3ApplicationResetPath()已经把USTACK的栈顶指针赋给了A10。对于其他CPU,在各自的_Corex_Start()把USTACK的栈顶指针赋给了各自CPU的A10。

初始化全局变量:
下面函数用来初始化全局变量 (这个函数是编译器来实现的),全局变量分为两部分:Data和BSS。

Data: 存放有初始化全局变量,有初始化的全局变量的初始值最初是放在Flash中,在这个函数里面,会把初始值从Flash赋给全局变量。

BSS: BSS段用于存放没有初始化值的全局变量,在这个函数里面会把没有初始化值的全局变量清零。
/*  Initialization of C runtime variables */
     Ifx_Ssw_C_Init();

对于其它_Corex_Start()而言,和_Core0_Start()的流程基本一样,另外增加了把USTACK栈顶指针赋给A10的操作和PSW初始化操作。

在各个CPU的_Corex_Start()最后会跳转到各自的corex_main()中运行。





AURIX™又添新伙伴
-软件我有“RT-Thread Auto”


近期,国内领先的国产核心软件厂商睿赛德科技宣布,RT-Thread商业支持英飞凌科技车规级32位AURIX™ TriCore™多核微控制器,可帮助用户无缝使用TriCore™处理器。RT-Thread充分利用AURIX™多核的强大性能,为用户提供易用的操作系统开发环境及OTA、CAN/CAN FD/LIN等能力;结合即将获得的ISO26262 ASIL-D功能安全认证,RT-Thread Auto for MCU为汽车领域众多应用场景提供了一个可选择的高安全性、高性价比的商用OS解决方案。

RT-Thread 是一个集实时操作系统(RTOS)内核、中间件组件和开发者社区于一体的技术平台, 同时,也是一个组件完整丰富、高度可伸缩、简易开发、超低功耗、高安全性的物联网操作系统。该软件具备一个工业操作系统平台所需的所有关键组件, 例如GUI、TCP/IP v4/v6双栈网络协议栈、安全传输、低功耗组件、USB、POSIX、C++等等。经过十多年的累积和发展,RT-Thread 已形成国内最大的嵌入式开源社区之一,累积装机量超过10亿台,成为国内自主开发、成熟稳定和拥有海量装机量的开源 RTOS。

随着汽车电动化,智能化,网联化的发展,车上电子/电气架构也在不断地演进,从传统的分布式架构,到域控制架构,以及域控制和区控制融合的架构,这都使得汽车电气架构变得越来越复杂。此时就需要更多地考虑功能模块相互之间的融合, 由此对MCU的性能也提出了更高的要求。AURIX™多核微控制器是英飞凌推出的满足汽车行业的动力总成和安全应用的各种要求的32位多核单片机系列,因其功能强大、高安全、高可靠、且拥有丰富的网络接口等特性,被广泛应用于智驾网关、发动机管理系统、变速箱系统、底盘和制动系统、安全气囊等汽车应用中。



针对AURIX™多核微控制器, RT Thread可满足最高达6核的多核支持,同时也支持其中的锁步核特性:
  • 6 个 TriCore™内核 以 300 MHz 运行(带有 4 个额外的检查器内核,可提供 4000 DMIPS)
  • 支持所有内核的浮点和定点
  • 16 MB 闪存/ECC 保护
  • 高达 6.9 MB SRAM/ECC 保护
  • 支持ISO 26262 ASIL-D
  • 支持TriCore系列MCAL驱动,包括CAN、CANFD、LIN、SPI、Watchdog等
  • 支持多核特性的RT-Thread版本,同时延续RT-Thread易用的API
  • 支持GNU GCC工具链(及HighTec集成开发环境),TASKING工具链(及ADS集成开发环境)



铁血丹心LLLL 发表于 2025-6-30 11:41 | 显示全部楼层
启动的时候都会从CPU0开始运行
szt1993 发表于 2025-6-30 12:40 | 显示全部楼层
API的选择一定要注意默认选项
您需要登录后才可以回帖 登录 | 注册

本版积分规则

59

主题

1940

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部