新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > IAR中cortex-m4啟動(dòng)流程分析

        IAR中cortex-m4啟動(dòng)流程分析

        作者: 時(shí)間:2016-11-25 來源:網(wǎng)絡(luò) 收藏
        最近分析了一下飛思卡爾官方提供的k60系列demo程序在IAR上的啟動(dòng)流程,現(xiàn)寫一下筆記,以備以后參考。先看一下K60N512VMD100內(nèi)部存儲(chǔ)器的分布情況,飛思卡爾K60N512VMD100有512K的flash和128k的SRAM.其中:



        Flash地址空間:
        0x00000000--0x00080000,共512k

        SRAM地址空間:
        SRAM1 0x1FFF0000--0x20000000 64k

        SRAM2 0x20000000--0x20010000 64k

        總共的SRAM大小是128k



        我要在RAM中調(diào)試代碼,下面以代碼的執(zhí)行過程為順序分析一下啟動(dòng)流程。



        首先看一下源文件中提供的128KB_Ram.icf文件。*.icf文件是IAR中的分散描述文件,相當(dāng)于ADS中的*.src文件或keil中的*.sct文件或GNU中的*.lds鏈接腳本文件。

        這個(gè)文件中前面部分是各個(gè)變量的定義,關(guān)鍵看后面部分:
        • ***********
        • 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代碼段中的只讀部分放在存儲(chǔ)空間(mem,前面已定義的名稱)中__ICFEDIT_intvec_start__ 地址上,前面部分已經(jīng)定義__ICFEDIT_intvec_start__=0x1fff0000,是SRAM的起始地址。也就是先把向量表放到內(nèi)存中的最前面。 .intvec 這個(gè)段是在vectors.c文件中出現(xiàn)的,
        • 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,
        • };



        從源文件中可以看到這里定義了一個(gè)向量表__vector_table(前面的const 很重要不能省,這樣才能保證向量表是只讀的),向量表中的每一項(xiàng)都是一個(gè)指向函數(shù)的指針,這里總共有256+4=260個(gè)指針,所以占據(jù)空間為260*4=1040=0x410.

        所以SRAM空間的前0x410的空間已經(jīng)被向量表占據(jù)。即占據(jù)了0x1fff0000--0x1fff0410.



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

        這段代碼表示要把 .noinit段中的只讀部分放到地址空間 __code_start__ 開始的地址上,前面有定義 __code_start__= 0x1fff0410 ,也就是把 .noinit段放到0x1fff0410開始的地址上。所以在內(nèi)存中代碼就連續(xù)了,先是向量表,接著的是.noinitd 段。

        .noinit 段在crt0.s匯編文件中出現(xiàn):

        • 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



        這段代碼算是芯片復(fù)位后執(zhí)行的第一段代碼(如果沒有其他異常的話)。作為一個(gè)通常的規(guī)則,推薦先把通用寄存器(R0-R12)清零。然后是使能中斷,跳轉(zhuǎn)到start標(biāo)號(hào)(或函數(shù))處繼續(xù)執(zhí)行。



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



        在start.c文件中找到了start函數(shù):


        • /*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);
        • }


        上一頁 1 2 下一頁

        關(guān)鍵詞: IARcortex-m4啟動(dòng)流

        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 罗城| 尚义县| 治多县| 贺州市| 镇坪县| 盈江县| 兴化市| 收藏| 金川县| 徐州市| 东平县| 永善县| 霍州市| 安阳县| 富源县| 资中县| 德江县| 沙雅县| 九寨沟县| 台中市| 喀什市| 安陆市| 余姚市| 平山县| 志丹县| 清新县| 新沂市| 宣汉县| 广水市| 凤山市| 横峰县| 通化市| 乐山市| 交城县| 双桥区| 奇台县| 调兵山市| 沂源县| 石门县| 綦江县| 西昌市|