MQX的启动过程

来源:互联网 发布:jdbc mysql陶伟基 编辑:程序博客网 时间:2024/06/15 20:04

硬件:FRDM-K64F
软件:MQX4.1.1
IDE:IAR7.2

在vector.c中
{
(vector_entry)__BOOT_STACK_ADDRESS,
BOOT_START, /* 0x01 0x00000004 - ivINT_Initial_Program_Counter */
_int_kernel_isr, /* 0x02 0x00000008 - ivINT_NMI */
_int_kernel_isr, /* 0x03 0x0000000C - ivINT_Hard_Fault */
_int_kernel_isr, /* 0x04 0x00000010 - ivINT_Mem_Manage_Fault */
_int_kernel_isr, /* 0x05 0x00000014 - ivINT_Bus_Fault */
_int_kernel_isr, /* 0x06 0x00000018 - ivINT_Usage_Fault */
0, /* 0x07 0x0000001C - ivINT_Reserved7 */

__BOOT_STACK_ADDRESS在linker file中有定义:

/* mem_init writes a storeblock_struct at the end of kernel data, max size 32 bytes, so use 0x100 offset */define exported symbol __BOOT_STACK_ADDRESS = __ICFEDIT_region_RAM_end__ - 0x100;
#define BOOT_START _boot

所以程序刚开始跑到_boot 处

    ASM_PUBLIC_BEGIN(__boot)    ASM_PUBLIC_FUNC(__boot)ASM_LABEL(__boot)#if MQX_AUX_CORE        msr MSP, r0        isb #15#endif        /* Disable interrupts and clear pending flags */        ldr r0, =NVIC_ICER0        ldr r1, =NVIC_ICPR0        ldr r2, =0xFFFFFFFF        mov r3, #8ASM_LABEL(_boot_loop)        cbz r3, _boot_loop_end        str r2, [r0], #4        /* NVIC_ICERx - clear enable IRQ register */        str r2, [r1], #4        /* NVIC_ICPRx - clear pending IRQ register */        sub r3, r3, #1        b _boot_loopASM_LABEL(_boot_loop_end)        /* Prepare process stack pointer */        mrs r0, MSP        msr PSP, r0        /* Switch to proccess stack (PSP) */        mrs r0, CONTROL        orr r0, r0, #2        msr CONTROL, r0        isb #15#if MQXCFG_ENABLE_FP && PSP_HAS_FPU        /* CPACR is located at address 0xE000ED88 */        LDR.W   R0, =0xE000ED88        /* Read CPACR */        LDR     R1, [R0]        /* Set bits 20-23 to enable CP10 and CP11 coprocessors */        ORR     R1, R1, #(0xF << 20)        /* Write back the modified value to the CPACR */        STR     R1, [R0]        /* turn off fpu register stacking in exception entry */        ldr r0, =0xE000EF34     /* FPCCR */        mov r1, #0        str r1, [r0]#endif        /* Perform toolchain startup routines */        ASM_EXTERN(toolchain_startup)        b ASM_PREFIX(toolchain_startup)    ASM_PUBLIC_END(__boot)

这里写图片描述

MRS指令
这里写图片描述

ORR指令为逻辑或指令

ISB指令
这里写图片描述

不懂现在

下面这一段代码是和FPU相关的

#if MQXCFG_ENABLE_FP && PSP_HAS_FPU        /* CPACR is located at address 0xE000ED88 */        LDR.W   R0, =0xE000ED88        /* Read CPACR */        LDR     R1, [R0]        /* Set bits 20-23 to enable CP10 and CP11 coprocessors */        ORR     R1, R1, #(0xF << 20)        /* Write back the modified value to the CPACR */        STR     R1, [R0]        /* turn off fpu register stacking in exception entry */        ldr r0, =0xE000EF34     /* FPCCR */        mov r1, #0        str r1, [r0]#endif

这里写图片描述

LDR.W R0, =0xE000ED88 只是一条LDR伪指令,.W不知道什么意思

将立即数0xE000ED88赋值给R0

LDR R1, [R0] 将 CPACR中的值赋值给R1

在切换进程栈和设置完FPU之后,进入到toolchain_startup()函数

void toolchain_startup(void){    __iar_program_start();}

这里写图片描述

这里写图片描述

int __low_level_init(void){    /* Initialize device. */    init_hardware();    return (1);}

init_hardware()函数如下:

void init_hardware(void){#if PE_LDD_VERSION    /*  Watch Dog disabled by CPU bean (need to setup in CPU Inspector) */    __pe_initialize_hardware();#else    _bsp_initialize_hardware();#endif    /* Enable pin clocks */    _bsp_gpio_io_init ();    /* Initialize FlexBus */    _bsp_flexbus_setup();}
void _bsp_initialize_hardware(void){    _bsp_watchdog_disable();#if MQX_ENABLE_LOW_POWER    /* Reset from LLWU wake up source */    if (_lpm_get_reset_source() == MQX_RESET_SOURCE_LLWU)    {        PMC_REGSC |= PMC_REGSC_ACKISO_MASK;    }#endif  /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/  /* SIM_CLKDIV2: USBDIV=1,USBFRAC=0 */  SIM_CLKDIV2 = (uint32_t)0x09UL; /* Update USB clock prescalers */  /* System clock initialization */  /* SIM_CLKDIV1: OUTDIV2&=~1,OUTDIV2|=1,OUTDIV3&=~4,OUTDIV3|=4,OUTDIV4&=~4,OUTDIV4|=4,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */  SIM_CLKDIV1 = (uint32_t)0x01440000;  /* Set the system prescalers to safe value */  CPU_SetClockConfigGenMode(CPU_CLOCK_CONFIG_0);  SIM_CLKDIV1 = (uint32_t)CPU_ClockConfigDescriptors[CPU_CLOCK_CONFIG_0].SysRegs.SIM_CLKDIV1_value; /* Update system prescalers */  SIM_SOPT1 = (uint32_t)((SIM_SOPT1 & (uint32_t)~(uint32_t)SIM_SOPT1_OSC32KSEL_MASK) | (uint32_t)CPU_ClockConfigDescriptors[CPU_CLOCK_CONFIG_0].SysRegs.SIM_SOPT1_value); /* Update 32 kHz oscillator clock source (ERCLK32K) */  SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)SIM_SOPT2_PLLFLLSEL_MASK) | (uint32_t)CPU_ClockConfigDescriptors[CPU_CLOCK_CONFIG_0].SysRegs.SIM_SOPT2_value); /* Update PLL/FLL clock select */  /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/}

最后到main,启动mqx
这里写图片描述

在mqx_main()函数:

/*FUNCTION*-------------------------------------------------------------------** Function Name    : main* Returned Value   : should return "status"* Comments         :*   Starts MQX running**END*----------------------------------------------------------------------*/int main   (      void   ){ /* Body */   extern const MQX_INITIALIZATION_STRUCT MQX_init_struct;   /* Start MQX */   _mqx( (MQX_INITIALIZATION_STRUCT_PTR) &MQX_init_struct );   return 0;} /* Endbody */
0 0
原创粉丝点击