【简介】
SystemInit 函数是ARM-CMSIS 规范中定义的一个接口函数,对该函数的功能描述如下
/**************************************************************************************************/ /** \brief Function to Initialize the system. \details Initializes the microcontroller system. Typically, this function configures the oscillator (PLL) that is part of the microcontroller device. For systems with a variable clock speed, it updates the variable \ref SystemCoreClock. SystemInit is called from the file <b>startup<i>_device</i></b>. */ void SystemInit (void);
以下为CMSIS 的组件框图
通常在启动文件中调用该接口初始化系统,在K3 的启动文件中会调用该接口初始化。
以下是K314 RTD驱动中的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)*/ }
【Step1】共享外设中断配置
该函数首先获取coreid 根据cioreid 来配置MSCM的IPSPRC 寄存器开启中断路由到core
对应寄存器描述如下,从描述看可已经配置中断是否路由到对应的core,实现中断的分发管理配置实现共享外设中断
【Step2 配置FPU】
配置core 内部的CP10 CP11 协处理器开启FPU 功能
CPACR(Coprocessor Access Control Register) 寄存器在ARMV7-M 手册中描述如下
【Step3 MPU 配置】
为了确保MPU配置被正确的写入,需要根据cache 的使能情况先关闭CACHE 在进行MPU 的配置,MPU 的配置在此贴中介绍
【Step4 Cache 配置】
初始化好CACHE资源后,就需要根据CACHE 编译开快的配置来决定是否开启CACHE,CACHE 的配置代码的说明在在此帖中介绍
从上述 S32K3 的SystemInit 函数配置流程看,S32K3 并没有严格的按照CMSIS的规范初始化时钟配置,时钟配置在进入Main 函数后在统一的进行时钟配置。