NXP MCU上电后都做了什么——启动代码解析

13分钟前阅读1回复0
kanwenda
kanwenda
  • 管理员
  • 注册排名1
  • 经验值176055
  • 级别管理员
  • 主题35211
  • 回复0
楼主

从MCU上电到步入main表达式之后,MCU是有连续串开启关键步调的。那连续串标识符凡是是放到startup_xxx.c里边,对NXP的商品而言是startup_lpc5410x.c里边。网路上也看完之后本身的如是说,那时就那本身的工程项目也做个归纳。

详细而言用的LPC54102是TNUMBERGHz的,为的是单纯确保平安只说R5那部分。

详细而言上电后,运转的是电脑系统外部ROM重构好的流程,次要促进感化是按照外部插口确认开启形式还有此根底的硬体挪用。该些的标识符是看不出的,他们就假设从flash开启,0x0的文本王轼写入sp, pc瞄准了0x4。0x4放置的是block表,因而第二件事是重定向到block表。

block表

block内外边,第二个操做符是给sp用的(每天重定向之后都要压呵呵栈),第三个操做符是他们的仆人公ResetISR,即从头启动后该步入的受阻。前面的操做符是形形色色N53SI241SV的handler,例如systick, i2c,hardfault,那些是加进了促发到了就会那时候。

嘿嘿,pc是先从0x4跳到了ResetISR,接著从ResetISR跳入了startup_lpc54102.c里的void ResetISR(void)表达式。上面是间接抄标识符接著导出了。

void ResetISR(void) { // Disable interrupts __asm volatile ("cpsid i"); // Enable SRAM clock used by Stack __asm volatile ("LDR R0, =0x400000C8\n\t" "MOV R1, #24\n\t" "STR R1, [R0]");

果不其然关受阻(较好的生活习惯,即使很有可能reset之后有的是N53SI241SV受阻没被关),接著enable SRAM的计时器。

#if defined (__USE_CMSIS) // If __USE_CMSIS defined, then call CMSIS SystemInit code SystemInit(); #endif // (__USE_CMSIS)

接著是做cpu核的挪用,该些标识符是放到device/system_LPC54102.c里。那里头做的事有:1.掌控FPU 2.loadblock表到SCB->VTOR上,那是cmsis cpu的掌控暂存器 3.CX600XRAM,制止reset前ram被清空了 。 若是不是CMSIS的核,即#if !defined (__USE_CMSIS), 类似于的事会在前面做两边。

// // Copy the data sections from flash to SRAM. // unsigned int LoadAddr, ExeAddr, SectionLen; unsigned int *SectionTableAddr; // Load base address of Global Section Table SectionTableAddr = &__data_section_table; // Copy the data sections from flash to SRAM. while (SectionTableAddr < &__data_section_table_end) { LoadAddr = *SectionTableAddr++; ExeAddr = *SectionTableAddr++; SectionLen = *SectionTableAddr++; data_init(LoadAddr, ExeAddr, SectionLen); } // At this point, SectionTableAddr = &__bss_section_table; // Zero fill the bss segment while (SectionTableAddr < &__bss_section_table_end) { ExeAddr = *SectionTableAddr++; SectionLen = *SectionTableAddr++; bss_init(ExeAddr, SectionLen); }

接著是把.data和.bss上的数据从flash搬运到ram里去。

// Optionally enable Cortex-M4 SWV trace (off by default at reset) // Note - your board support must also set up pinmuxing such that // SWO is output on GPIO PIO0-15 (FUNC2) or PIO1_1 (FUNC2). #if !defined (DONT_ENABLE_SWVTRACECLK) && !defined (CORE_M0PLUS) volatile unsigned int *TRACECLKDIV = (unsigned int *) 0x400000E4; volatile unsigned int *SYSAHBCLKCTRLSET = (unsigned int *) 0x400000C8; volatile unsigned int *SYSAHBCLKCTRL = (unsigned int *) 0x400000C0; // Write 0x00000001 to TRACECLKDIV - Trace divider *TRACECLKDIV = 1; // Enable IOCON peripheral clock (for SWO on PIO0-15 or PIO1_1) // by setting bit13 via SYSAHBCLKCTRLSET[0] *SYSAHBCLKCTRLSET = 1 << 13; // 0x2000 // Read SYSAHBCLKCTRL[0] and check bit 13 __SWVtrace_Enabled = ((*SYSAHBCLKCTRL & 1 << 13) == 1 << 13); #endif

CX600Xswv调试功用。

#if defined (__cplusplus) // // Call C++ library initialisation // __libc_init_array(); #endif

查抄呵呵是不是用了C++库

#if defined (__REDLIB__) // Call the Redlib library, which in turn calls main() __main(); #else main(); #endif // // main() shouldnt return, but if it does, well just enter an infinite loop // while (1) { ; }

最初,重定向到main里去了。

0
回帖 返回数码

NXP MCU上电后都做了什么——启动代码解析 期待您的回复!

取消
载入表情清单……
载入颜色清单……
插入网络图片

取消确定

图片上传中
编辑器信息
提示信息