【简介】
我们在之前介绍了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中进行定义
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 文件中进行定义
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 区域进行初始化
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:
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