您的位置 首页 新能源

IAR中cortex-m4发动流程剖析

最近分析了一下飞思卡尔官方提供的k60系列demo程序在IAR上的启动流程,现写一下笔记,以备以后参考。先看一下K60N512VMD100内部存储器的分

最近剖析了一下飞思卡尔官方供给的k60系列demo程序在IAR上的发动流程,现写一下笔记,以备今后参阅。先看一下K60N512VMD100内部存储器的散布状况,飞思卡尔K60N512VMD100有512K的flash和128k的SRAM.其间:

Flash地址空间:
0x00000000–0x00080000,共512k

SRAM地址空间:
SRAM1 0x1FFF0000–0x20000000 64k

SRAM2 0x20000000–0x20010000 64k

一共的SRAM巨细是128k

我要在RAM中调试代码,下面以代码的履行进程为次序剖析一下发动流程。

首要看一下源文件中供给的128KB_Ram.icf文件。*.icf文件是IAR中的涣散描绘文件,相当于ADS中的*.src文件或keil中的*.sct文件或GNU中的*.lds链接脚本文件。

这个文件中前面部分是各个变量的界说,要害看后面部分:

  • ***********
  • place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
  • place at address mem:__code_start__ { readonly section .noinit };
  • place in RAM_region { readonly, block CodeRelocate };
  • place in RAM_region { readwrite, block CodeRelocateRam,
  • block CSTACK, block HEAP };
  • ************

①place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }

这段代码表明要把.intvec代码段中的只读部分放在存储空间(mem,前面已界说的称号)中__ICFEDIT_intvec_start__ 地址上,前面部分现已界说__ICFEDIT_intvec_start__=0x1fff0000,是SRAM的开端地址。也便是先把向量表放到内存中的最前面。 .intvec 这个段是在vectors.c文件中呈现的,

  • typedef void(*vector_entry)(void);
  • #pragmalocation=“.intvec”
  • constvector_entry __vector_table[]=//@“.intvec”=
  • {
  • VECTOR_000,/*Initial SP*/
  • VECTOR_001,/*Initial PC*/
  • VECTOR_002,
  • VECTOR_003,
  • ……(中心省掉)
  • VECTOR_254,
  • VECTOR_255,
  • CONFIG_1,
  • CONFIG_2,
  • CONFIG_3,
  • CONFIG_4,
  • };

从源文件中能够看到这儿界说了一个向量表__vector_table(前面的const 很重要不能省,这样才干确保向量表是只读的),向量表中的每一项都是一个指向函数的指针,这儿一共有256+4=260个指针,所以占有空间为260*4=1040=0x410.

所以SRAM空间的前0x410的空间现已被向量表占有。即占有了0x1fff0000–0x1fff0410.

②place at address mem:__code_start__ { readonly section .noinit }

这段代码表明要把 .noinit段中的只读部分放到地址空间 __code_start__ 开端的地址上,前面有界说 __code_start__= 0x1fff0410 ,也便是把 .noinit段放到0x1fff0410开端的地址上。所以在内存中代码就接连了,先是向量表,接着的是.noinitd 段。

.noinit 段在crt0.s汇编文件中呈现:

  • SECTION .noinit : CODE
  • EXPORT __startup
  • __startup
  • MOV r0,#0 ; Initialize the GPRs
  • MOV r1,#0
  • MOV r2,#0
  • MOV r3,#0
  • MOV r4,#0
  • MOV r5,#0
  • MOV r6,#0
  • MOV r7,#0
  • MOV r8,#0
  • MOV r9,#0
  • MOV r10,#0
  • MOV r11,#0
  • MOV r12,#0
  • CPSIE i ; Unmask interrupts
  • import start
  • BL start ; call the C code
  • __done
  • B __done
  • END

这段代码算是芯片复位后履行的榜首段代码(假如没有其他反常的话)。作为一个一般的规矩,引荐先把通用寄存器(R0-R12)清零。然后是使能中止,跳转到start标号(或函数)处持续履行。

========================

在start.c文件中找到了start函数:

  • /*start.c片段*/
  • void start(void)
  • {
  • /*Disable the watchdog timer*/
  • wdog_disable();
  • /*Copy any vectorordata sections that needtobeinRAM*/
  • common_startup();
  • /*Perform processor initialization*/
  • sysinit();
  • printf(“”);
  • /*Determine the last cause(s)of reset*/
  • if(MC_SRSH&MC_SRSH_SW_MASK)
  • printf(“Software Reset”);
  • if(MC_SRSH&MC_SRSH_LOCKUP_MASK)
  • printf(“Core Lockup Event Reset”);
  • if(MC_SRSH&MC_SRSH_JTAG_MASK)
  • printf(“JTAG Reset”);
  • if(MC_SRSL&MC_SRSL_POR_MASK)
  • printf(“Power-on Reset”);
  • if(MC_SRSL&MC_SRSL_PIN_MASK)
  • printf(“External Pin Reset”);
  • if(MC_SRSL&MC_SRSL_COP_MASK)
  • printf(“Watchdog(COP) Reset”);
  • if(MC_SRSL&MC_SRSL_LOC_MASK)
  • printf(“Loss of Clock Reset”);
  • if(MC_SRSL&MC_SRSL_LVD_MASK)
  • printf(“Low-voltage Detect Reset”);
  • if(MC_SRSL&MC_SRSL_WAKEUP_MASK)
  • printf(“LLWU Reset”);
  • /*Determine specific Kinetis deviceandrevision*/
  • cpu_identify();
  • /*Jumptomain process*/
  • main();
  • /*No actionstoperform after this so wait forever*/
  • while(1);
  • }

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/xinnengyuan/259486.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部