这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【S32K314】芯片启动流程分析

共2条 1/1 1 跳转至

【S32K314】芯片启动流程分析

高工
2025-07-04 08:55:14     打赏

【简介】

我们在之前介绍了S32K146 的使用方法,S32K系列哟那个的比较多的已经是S32K3系列,我们基于S32K314 芯片先熟悉下对应的启动代码.

step1. 启动代码的第开始是关闭中断,初始化通用寄存器R0-R7为0

_start:
Reset_Handler:
/*****************************************************/
/* Skip normal entry point as nothing is initialized */
/*****************************************************/
 cpsid i
 mov   r0, #0
 mov   r1, #0
 mov   r2, #0
 mov   r3, #0
 mov   r4, #0
 mov   r5, #0
 mov   r6, #0
 mov   r7, #0

step2 使能MSCM控制的时钟信号

#ifndef NO_MSCM_CLOCK_INIT
InitMSCMClock:
  /* If the MSCM clock is enabled, skip this sequence */
  ldr r0, =MCME_PRTN1_COFB0_STAT
  ldr r1, [r0]
  ldr r2, =MCME_MSCM_REQ
  and r1, r1, r2
  cmp r1, 0
  bne SetVTOR

  /* Enable clock in PRTN1 */
  ldr r0, =MCME_PRTN1_COFB0_CLKEN
  ldr r1, [r0]
  ldr r2, =MCME_MSCM_REQ
  orr r1, r2
  str r1, [r0]

  /* Set PUPD field */
  ldr r0, =MCME_PRTN1_PUPD
  ldr r1, [r0]
  ldr r2, =1
  orr r1, r2 
  str r1, [r0]

  /* Trigger update */
  ldr r0, =MCME_CTL_KEY
  ldr r1, =MCME_KEY
  str r1, [r0]
  ldr r1, =MCME_INV_KEY
  str r1, [r0]
#endif
/* Check MSCM clock in PRTN1 */
WaitForClock:
  ldr r0, =MCME_PRTN1_COFB0_STAT
  ldr r1, [r0]
  ldr r2, =MCME_MSCM_REQ
  and r1, r1, r2
  cmp r1, 0
  beq WaitForClock

step3 更新中断向量表指向内存区域

SetVTOR:
/* relocate vector table to RAM */
ldr  r0, =VTOR_REG
ldr  r1, =__RAM_INTERRUPT_START
str  r1,[r0]

__RAM_INTERRUPT_START 的位置在link file中进行定义

image.png

image.png

step4 根据coreid 来设置core 的MSP 指针,配置好SP指针后就可以来调用C函数了

/*GetCoreID*/
ldr  r0, =0x40260004
ldr  r1,[r0]

ldr  r0, =MAIN_CORE
cmp  r1,r0
beq  SetCore0Stack
b SetCore1Stack

SetCore0Stack:
  /* set up stack; r13 SP*/
  ldr  r0, =__Stack_start_c0
  msr MSP, r0
  b DisableSWT0
  
SetCore1Stack:
  /* set up stack; r13 SP*/
  ldr  r0, =__Stack_start_c1
  msr MSP, r0

__Stack_start_c0/__Stack_start_c1 的定义在link 文件中进行定义

image.png

step5 对 SRAM进行初始化,来更新ECC 

RamInit:
    /* Initialize SRAM ECC */
    ldr  r0, =__RAM_INIT
    cmp  r0, 0
    /* Skip if __SRAM_INIT is not set */
    beq SRAM_LOOP_END
    ldr r1, =__INT_SRAM_START
    ldr r2, =__INT_SRAM_END
    
    subs    r2, r1
    subs    r2, #1
    ble SRAM_LOOP_END

    movs    r0, 0
    movs    r3, 0
SRAM_LOOP:
    stm r1!, {r0,r3}
    subs r2, 8
    bge SRAM_LOOP
SRAM_LOOP_END:

对整个SRAM 区域进行初始化

image.png

step6 初始化ITCM来更新ECC

ITCM_Init:
    /* Initialize ITCM ECC */
    ldr  r0, =__ITCM_INIT
    cmp  r0, 0
    /* Skip if __TCM_INIT is not set */
    beq ITCM_LOOP_END

    /* Enable TCM */
    LDR r1, =CM7_ITCMCR
    LDR r0, [r1]
    LDR r2, =0x1
    ORR r0, r2
    STR r0, [r1]

    ldr r1, =__INT_ITCM_START
    ldr r2, =__INT_ITCM_END
    
    subs    r2, r1
    subs    r2, #1
    ble ITCM_LOOP_END

    movs    r0, 0
    movs    r3, 0
ITCM_LOOP:
    stm r1!, {r0,r3}
    subs r2, #8
    bge ITCM_LOOP
ITCM_LOOP_END:


image.png

step7 初始化DTCM

DTCM_Init:
    /* Initialize DTCM ECC */
    ldr  r0, =__DTCM_INIT
    cmp  r0, 0
    /* Skip if __DTCM_INIT is not set */
    beq DTCM_LOOP_END
    /* Enable TCM */
    LDR r1, =CM7_DTCMCR
    LDR r0, [r1]
    LDR r2, =0x1
    ORR r0, r2
    STR r0, [r1]

    ldr r1, =__INT_DTCM_START
    ldr r2, =__INT_DTCM_END
    
    subs    r2, r1
    subs    r2, #1
    ble DTCM_LOOP_END

    movs    r0, 0
    movs    r3, 0
DTCM_LOOP:
    stm r1!, {r0,r3}
    subs r2, #8
    bge DTCM_LOOP
DTCM_LOOP_END:

 stsp 8 初始化DATA 段和 bss 段数据

/************************/
/* Erase ".bss Section" */
/************************/
_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

step9 调用SystemInit 函数进行系统初始化

/******************************************************************/
/* Autosar Guidance 10 - In the start-up code a default           */
/* initialization of the MCU clock system shall be performed      */
/* including global clock prescalers.                             */
/******************************************************************/
__SYSTEM_INIT:
  bl SystemInit
/*================================================================================================*/
/*
 * system initialization : system clock, interrupt router ...
 */


void SystemInit(void)
{
    uint32 i;
    uint32 coreMask = 0UL;
    uint8 coreId = OsIf_GetCoreID();
#ifdef MPU_ENABLE
    uint8 index = 0U;
    uint8 regionNum = 0U;
#endif /* MPU_ENABLE */    
    switch(coreId)
    {
        case CM7_0:
            coreMask = (1UL << MSCM_IRSPRC_M7_0_SHIFT);
            break;
        case CM7_1:
#ifdef S32K324
            coreMask = (1UL << MSCM_IRSPRC_M7_1_SHIFT);
#endif
            break;
        default:
            coreMask = 0UL;
            break;
    }

    /* Configure MSCM to enable/disable interrupts routing to Core processor */
    for (i = 0; i < MSCM_IRSPRC_COUNT; i++) 
    {
        IP_MSCM->IRSPRC[i] |= coreMask;
    }
/**************************************************************************/
                      /* FPU ENABLE*/
/**************************************************************************/
#ifdef ENABLE_FPU
    /* Enable CP10 and CP11 coprocessors */
    S32_SCB->CPACR |= (S32_SCB_CPACR_CPx(10U, 3U) | S32_SCB_CPACR_CPx(11U, 3U)); 

    ASM_KEYWORD("dsb");
    ASM_KEYWORD("isb");
#endif /* ENABLE_FPU */
/**************************************************************************/
                      /* MPU ENABLE*/
/**************************************************************************/  
#ifdef MPU_ENABLE
/**************************************************************************/
                      /* DEFAULT MEMORY ENABLE*/
/**************************************************************************/
    /* Init MPU table for memory layout*/
    /* Cover all memory on device as background set all memory as strong-order and no access*/
    rbar[0]=0x00000000UL;
    rasr[0]=0x1004003FUL;
    
    /* ITCM for cortex M7 if no set it as zero */
    rbar[1]=(uint32)__INT_ITCM_START;
    rasr[1]=0x0104001FUL;
    /*Program flash which would extract from linker symbol*/
    rbar[2]=(uint32)__ROM_CODE_START;
    rasr[2]=0x060B002BUL; 

    /*Data flash which would extract from linker symbol*/
    rbar[3]=(uint32)__ROM_DATA_START;
    rasr[3]=0x16050023UL;  /* Device, Non-cache, Share */
    
    /*DTCM for cortex m7 if no set it as zero*/
    rbar[4]=(uint32)__INT_DTCM_START;
    rasr[4]=0x01040021UL; 
    
    /*Ram unified section  + stack*/
#if !defined(S32K344) && !defined(S32K324)
    rbar[5]=(uint32)__INT_SRAM_START;
    rasr[5]=((uint32)0x030B0001UL)|(((uint32)__RAM_CACHEABLE_SIZE - 1) << 1);   
#else
    rbar[5]=(uint32)__INT_SRAM_START;
    /*disable subregion 7-8*/
    rasr[5]=((uint32)0x030B0001UL)|(((uint32)__RAM_CACHEABLE_SIZE - 1) << 1)|(1<<15)|(1<<14); 
#endif
    
    /*Ram non-cache section plus int result which is using for test report*/
    rbar[6]=(uint32)__RAM_NO_CACHEABLE_START;
    rasr[6]= ((uint32)0x130C0001UL)|(((uint32)__RAM_NO_CACHEABLE_SIZE - 1) << 1);

    /*Ram shareable section*/
    rbar[7]=(uint32)__RAM_SHAREABLE_START;
    rasr[7]=((uint32)0x130C0001UL)|(((uint32)__RAM_SHAREABLE_SIZE - 1) << 1);
    /* Additional configuration for peripheral device*/
    
    /*AIPS_0*/
    rbar[8]=0x40000000UL;
    rasr[8]=0x13050029UL; 
    
    /*AIPS_1*/
    rbar[9]=0x40200000UL;
    rasr[9]=0x13050029UL; 
    
    /*AIPS_2*/
    rbar[10]=0x40400000UL;
    rasr[10]=0x13050029UL; 
    
    /*QSPI Rx*/
    rbar[11]=0x67000000UL;
    rasr[11]=0x13050013UL; 
    
    /*QSPI AHB*/
    rbar[12]=0x68000000UL;
    rasr[12]=0x030B0035UL;
    
    /*QSPI AHB*/
    rbar[13]=0xE0000000UL;
    rasr[13]=0x13040027UL;
    
    ASM_KEYWORD("dsb");
    ASM_KEYWORD("isb");

    /*Checking if cache is enable before*/
    if (((((uint32)1U << (uint32)17U) & S32_SCB->CCR) != (uint32)0) || ((((uint32)1U << (uint32)16U) & S32_SCB->CCR) != (uint32)0))
    {
 /*synchronize cache before update mpu */
        sys_m7_cache_clean();
        sys_m7_cache_disable();
    }
    /* Set default memory regions */
    for (index = 0U; index < 15; index++)
    {
        if ((rasr[index]&(uint32)0x1) == (uint32)0x1)
        {
            S32_MPU->RNR  = regionNum;
            S32_MPU->RBAR = rbar[index];
            S32_MPU->RASR = rasr[index];
            regionNum++;
        }
    }

    /* Enable MPU */
    S32_MPU->CTRL |= S32_MPU_CTRL_ENABLE_MASK;

    ASM_KEYWORD("dsb");
    ASM_KEYWORD("isb");

#endif /* MPU_ENABLE */
/**************************************************************************/
            /* ENABLE CACHE */
/**************************************************************************/
#if defined(D_CACHE_ENABLE) || defined(I_CACHE_ENABLE)
    sys_m7_cache_init();
#endif /*defined(D_CACHE_ENABLE) || defined(I_CACHE_ENABLE)*/    
}


/* Cache apis which are using for cache initilization, please make sure MPU is enable before calling these apis. Due to limitation of speculative access on cortex m7, MPU need to be initialized before enable cache. So if user specify -DDISABLE_MPUSTARTUP, cache will be disable in startup as well. If user want to enable cache again please call cache api after RM_init() or MPU_init() */

static INLINE void sys_m7_cache_init(void)
{     
#ifdef D_CACHE_ENABLE   
    uint32 ccsidr = 0U;
    uint32 sets = 0U;
    uint32 ways = 0U;

   
    /*init Data caches*/
    S32_SCB->CSSELR = 0U;                       /* select Level 1 data cache */
    ASM_KEYWORD("dsb");
    ccsidr = S32_SCB->CCSIDR;
    sets = (uint32)(CCSIDR_SETS(ccsidr));
    do {
      ways = (uint32)(CCSIDR_WAYS(ccsidr));
      do {
        S32_SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
                      ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk)  );  
        ASM_KEYWORD("dsb");
      } while (ways-- != 0U);
    } while(sets-- != 0U);
    ASM_KEYWORD("dsb");
    S32_SCB->CCR |=  (uint32)SCB_CCR_DC_Msk;  /* enable D-Cache */
    ASM_KEYWORD("dsb");
    ASM_KEYWORD("isb");
#endif /*D_CACHE_ENABLE*/

#ifdef I_CACHE_ENABLE  
    /*init Code caches*/
    ASM_KEYWORD("dsb");
    ASM_KEYWORD("isb");
    S32_SCB->ICIALLU = 0UL;                     /* invalidate I-Cache */
    ASM_KEYWORD("dsb");
    ASM_KEYWORD("isb");
    S32_SCB->CCR |=  (uint32)SCB_CCR_IC_Msk;  /* enable I-Cache */
    ASM_KEYWORD("dsb");
    ASM_KEYWORD("isb");
#endif /*I_CACHE_ENABLE*/

}


static INLINE void sys_m7_cache_disable(void)
{        
    sys_m7_cache_clean();
    S32_SCB->CCR &= ~((uint32)1U << 17U);
    ASM_KEYWORD("dsb");
    ASM_KEYWORD("isb");
    S32_SCB->CCR &= ~((uint32)1U << 16U);
    ASM_KEYWORD("dsb");
    ASM_KEYWORD("isb");
}


static INLINE void sys_m7_cache_clean(void)
{  
#ifdef D_CACHE_ENABLE
    uint32 ccsidr = 0U;
    uint32 sets = 0U;
    uint32 ways = 0U;
    
    S32_SCB->CSSELR = 0U;                       /* select Level 1 data cache */
    ASM_KEYWORD("dsb");
    ccsidr = S32_SCB->CCSIDR;
    sets = (uint32)(CCSIDR_SETS(ccsidr));
    do {
      ways = (uint32)(CCSIDR_WAYS(ccsidr));
      do {
        S32_SCB->DCCISW = (((sets << 5) & (uint32)0x3FE0U) |
                      ((ways << 30) & (uint32)0xC0000000U)  );  
        ASM_KEYWORD("dsb");
      } while (ways-- != 0U);
    } while(sets-- != 0U);
    
    S32_SCB->CSSELR = (uint32)((S32_SCB->CSSELR) | 1U);
#endif /*D_CACHE_ENABLE*/

#ifdef I_CACHE_ENABLE      
    S32_SCB->ICIALLU = 0UL;
#endif /*I_CACHE_ENABLE*/    
    ASM_KEYWORD("dsb");
}

该函数会根据配置宏开启cahche 及配置MPU 属性信息等

step 10  开启中断跳转到main 函数从而完成启动

/******************************************************************/
/* Call Main Routine                                              */
/******************************************************************/
_MAIN:
  cpsie i
  bl startup_go_to_user_mode
  bl main



专家
2025-07-07 09:30:33     打赏
2楼

汇编和C的混合,有难度。谢谢分享!


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]