新聞中心

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

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

        作者: 時(shí)間:2016-11-25 來源:網(wǎng)絡(luò) 收藏


        start函數(shù)中,首先執(zhí)行 wdog_disable()函數(shù)來禁用看門狗,然后調(diào)用 common_startup()函數(shù)初始化RAM(復(fù)制向量表、清零.bss段等,為C語言運(yùn)行環(huán)境做準(zhǔn)備),接著執(zhí)行sysinit()函數(shù)初始化芯片(時(shí)鐘、用到的外設(shè)等)。下面依次分析這3個(gè)函數(shù)。

        ①wdog_disable()

        對(duì)系統(tǒng)的設(shè)定無非是對(duì)各個(gè)寄存器值的修改。wdog_disable()函數(shù)在wdog.c文件中
        • void wdog_disable(void)
        • {
        • /*First unlock the watchdog so that we can writetoregisters*/
        • wdog_unlock();
        • /*Clear the WDOGEN bittodisable the watchdog*/
        • WDOG_STCTRLH&=~WDOG_STCTRLH_WDOGEN_MASK;
        • }
        • void wdog_unlock(void)
        • {
        • /*NOTE:DONOTSINGLESTEPTHROUGH THIS*/
        • /*There are timing requirementsforthe execution of the unlock.If
        • *you singlestepthrough the code you will cause the CPUtoreset.
        • */
        • /*This sequence must execute within 20 clock cycles,so disable
        • *interrupts will keep the code atomicandensure the timing.
        • */
        • DisableInterrupts;
        • /*Write 0xC520tothe unlock register*/
        • WDOG_UNLOCK=0xC520;
        • /*Followed by 0xD928tocomplete the unlock*/
        • WDOG_UNLOCK=0xD928;
        • /*Re-enable interruptsnowthat we are done*/
        • EnableInterrupts;
        • }



        禁用看門狗流程很簡單:先是解鎖寄存器,然后更改看門狗寄存器里面的值來禁用看門狗。解鎖看門狗寄存器:向解鎖寄存器里連續(xù)寫入0xC520和0xD928,兩次寫入的時(shí)間必須小于20個(gè)時(shí)鐘周期。所以在解鎖過程中不能單步運(yùn)行,期間也不能被中斷打斷,解鎖函數(shù)是 wdog_unlock()。上面DisableInterrupts和EnableInterrupts已經(jīng)在arm_cm4.h中定義過:

        #define DisableInterrupts asm(" CPSID i");

        #define EnableInterrupts asm(" CPSIE i");

        解鎖看門狗寄存器后,向看門狗寄存器里寫入適當(dāng)?shù)闹稻涂梢越每撮T狗了。


        也就是把WDOG_STCTRLH 寄存器(地址是0x40052000)的第0位置0.



        ②common_startup

        初始化RAM(復(fù)制向量表、清零.bss段等,為C語言運(yùn)行環(huán)境做準(zhǔn)備)。
        • 1/*File:startup.c*/
        • 2 #include"common.h"
        • 3 #pragma section=".data"
        • 4 #pragma section=".data_init"
        • 5 #pragma section=".bss"
        • 6 #pragma section="CodeRelocate"
        • 7 #pragma section="CodeRelocateRam"
        • 8/********************************************************************/
        • 9 void
        • 10 common_startup(void)
        • 11{
        • 12/*Declare a counter well useinall of the copy loops*/
        • 13 uint32 n;
        • 14/*Declare pointersforvarious data sections.These pointers
        • 15*are initialized using values pulledinfrom the linker file
        • 16*/
        • 17 uint8*data_ram,*data_rom,*data_rom_end;
        • 18 uint8*bss_start,*bss_end;
        • 19/*AddressesforVECTOR_TABLEandVECTOR_RAM come from the linker file*/
        • 20 extern uint32 __VECTOR_TABLE[];
        • 21 extern uint32 __VECTOR_RAM[];
        • 22/*Copy the vector tabletoRAM*/
        • 23if(__VECTOR_RAM!=__VECTOR_TABLE)
        • 24{
        • 25for(n=0;n<0x410;n++)
        • 26 __VECTOR_RAM[n]=__VECTOR_TABLE[n];
        • 27}
        • 28/*Point the VTORtothe new copy of the vector table*/
        • 29 write_vtor((uint32)__VECTOR_RAM);
        • 30/*Getthe addressesforthe.data section(initialized data section)*/
        • 31 data_ram=__section_begin(".data");
        • 32 data_rom=__section_begin(".data_init");
        • 33 data_rom_end=__section_end(".data_init");
        • 34 n=data_rom_end-data_rom;
        • 35/*Copy initialized data from ROMtoRAM*/
        • 36while(n--)
        • 37*data_ram++=*data_rom++;
        • 38/*Getthe addressesforthe.bss section(zero-initialized data)*/
        • 39 bss_start=__section_begin(".bss");
        • 40 bss_end=__section_end(".bss");
        • 41/*Clear the zero-initialized data section*/
        • 42 n=bss_end-bss_start;
        • 43while(n--)
        • 44*bss_start++=0;
        • 45/*Getaddressesforany code sections that needtobe copied from ROMtoRAM.
        • 46*The IAR tools have a predefined keyword that can be usedtomark individual
        • 47*functionsforexecution from RAM.Add"__ramfunc"before the return typein
        • 48*thefunctionprototypeforany routines you needtoexecute from RAM instead
        • 49*of ROM.ex:__ramfunc void foo(void);
        • 50*/
        • 51 uint8*code_relocate_ram=__section_begin("CodeRelocateRam");
        • 52 uint8*code_relocate=__section_begin("CodeRelocate");
        • 53 uint8*code_relocate_end=__section_end("CodeRelocate");
        • 54/*Copy functions from ROMtoRAM*/
        • 55 n=code_relocate_end-code_relocate;
        • 56while(n--)
        • 57*code_relocate_ram++=*code_relocate++;
        • 58}


        在IAR中,#pragmasection="NAME" [align]用來在C語言中指定一個(gè)名稱是NAME的段,align指定對(duì)齊方式。指定的段可以被段操作符來引用,段操作符包括 __section_begin, __section_end, 和 __section_size.個(gè)人理解.date、.date_init和.bss應(yīng)該是IAR中保留的段名稱,.date代表數(shù)據(jù)段中的常量,.date_init代表數(shù)據(jù)段中已初始化的變量,.bss代表未初始化的變量(zero)。

        上面代碼中,先是指定了5個(gè)不同名稱的段(前3個(gè)是保留段名稱,代表這些段是從這里開始的),CodeRelocate和CodeRelocateRam是在*.icf文件中定義的塊(block):
        define block CodeRelocate { section .textrw_init }; define block CodeRelocateRam { section .textrw };
        quote:
        The_
        _ramfunc keyword makes a function execute in RAM. Two code
        sections will be created: one for the RAM execution (.textrw), and one for the ROM initialization (.textrw_init).



        外部變量引用
        extern uint32 __VECTOR_TABLE[]; extern uint32 __VECTOR_RAM[];
        來自IAR的鏈接文件(.icf),在.icf文件中已經(jīng)定義了變量 __VECTOR_TABLE 和 __VECTOR_RAM 其值都是0x1fff0000."Copy the vector table to RAM"這段代碼進(jìn)行判斷,如果向量表不在RAM中,則把向量表拷貝到RAM開始的地址上,這里由于在RAM中調(diào)試,代碼是直接下載到RAM中的,所以不用拷貝。

        向量表已經(jīng)在RAM中了,接下來要重定向向量表,以便在發(fā)生異常時(shí)到RAM中取得異常入口地址(默認(rèn)情況下是在0x0取)。write_vtor((uint32)__VECTOR_RAM) 這個(gè)函數(shù)用來寫向量表偏移寄存器(VTOR,地址0xE000_ED08),這里寫入的是RAM起始地址0x1FFF0000。注意這個(gè)地址是有要求的,并不是所有地址都能作為向量表起始地址,0x1FFF0000滿足要求(這個(gè)要求就是:必須先求出系統(tǒng)中共有多少個(gè)向量,再把這個(gè)數(shù)字向上增大到是 2 的整次冪,而起始地址必須對(duì)齊到后者的邊界上。例如,如果一共有 32 個(gè)中斷,則共有 32+16(系統(tǒng)異常)=48個(gè)向量,向上增大到 2的整次冪后值為 64,因此地址地址必須能被 64*4=256整除,從而合法的起始地址可以是:0x0,0x100,0x200 等----參見ARM Contex-M3權(quán)威指南)。另外,如果向量表在RAM區(qū)(相對(duì)于code區(qū)),需把bit[29]置位,這里0x1FFF0000也滿足要求。

        后面的代碼是拷貝數(shù)據(jù)到RAM中,搭建好C語言運(yùn)行環(huán)境。

        上一頁 1 2 下一頁

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

        評(píng)論


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

        關(guān)閉
        主站蜘蛛池模板: 东山县| 临湘市| 上林县| 博爱县| 望城县| 都兰县| 通化市| 什邡市| 高台县| 方山县| 岳池县| 永昌县| 岗巴县| 蒲江县| 临潭县| 叙永县| 蓬溪县| 来凤县| 抚顺市| 阿拉善左旗| 厦门市| 兴和县| 太白县| 平顶山市| 建水县| 永丰县| 饶阳县| 开平市| 丹凤县| 肥城市| 循化| 壤塘县| 灌南县| 泌阳县| 阿克| 康保县| 定陶县| 渑池县| 清镇市| 丰都县| 得荣县|