<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

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

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


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

          ①wdog_disable()

          對(duì)系統(tǒng)的設(shè)定無(wú)非是對(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;
          • }



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

          #define DisableInterrupts asm(" CPSID i");

          #define EnableInterrupts asm(" CPSIE i");

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


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



          ②common_startup

          初始化RAM(復(fù)制向量表、清零.bss段等,為C語(yǔ)言運(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]用來(lái)在C語(yǔ)言中指定一個(gè)名稱是NAME的段,align指定對(duì)齊方式。指定的段可以被段操作符來(lái)引用,段操作符包括 __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è)是保留段名稱,代表這些段是從這里開(kāi)始的),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[];
          來(lái)自IAR的鏈接文件(.icf),在.icf文件中已經(jīng)定義了變量 __VECTOR_TABLE 和 __VECTOR_RAM 其值都是0x1fff0000."Copy the vector table to RAM"這段代碼進(jìn)行判斷,如果向量表不在RAM中,則把向量表拷貝到RAM開(kāi)始的地址上,這里由于在RAM中調(diào)試,代碼是直接下載到RAM中的,所以不用拷貝。

          向量表已經(jīng)在RAM中了,接下來(lái)要重定向向量表,以便在發(fā)生異常時(shí)到RAM中取得異常入口地址(默認(rèn)情況下是在0x0取)。write_vtor((uint32)__VECTOR_RAM) 這個(gè)函數(shù)用來(lái)寫(xiě)向量表偏移寄存器(VTOR,地址0xE000_ED08),這里寫(xiě)入的是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 等----參見(jiàn)ARM Contex-M3權(quán)威指南)。另外,如果向量表在RAM區(qū)(相對(duì)于code區(qū)),需把bit[29]置位,這里0x1FFF0000也滿足要求。

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

          上一頁(yè) 1 2 下一頁(yè)

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

          評(píng)論


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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();