新聞中心

        ARM的啟動方式

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


        二,處理器模式
        ARM的處理器可工作于多種模式,不同模式有不同的堆棧 ,以下設(shè)置各模式及其堆棧.
        預(yù)定義一些參數(shù):
        MODUSR EQU 0x10
        MODSYS EQU 0x1F
        MODSVC EQU 0x13
        MODABT EQU 0x17
        MODUDF EQU 0x1B
        MODIRQ EQU 0x12
        MODFIQ EQU 0x11

        IRQBIT EQU 0x80
        FIQBIT EQU 0x40

        RAMEND EQU 0x00204000 ; S64 : 16KB RAM

        VECTSIZE EQU 0x100 ;

        UsrStkSz EQU 8 ; size of USR stack
        SysStkSz EQU 128 ; size of SYS stack
        SvcStkSz EQU 8 ; size of SVC stack
        UdfStkSz EQU 8 ; size of UDF stack
        AbtStkSz EQU 8 ; size of ABT stack
        IrqStkSz EQU 128 ; size of IRQ stack
        FiqStkSz EQU 16 ; size of FIQ stack

        修改這些值即可修改相應(yīng)模式堆棧的尺寸.
        以下為各模式代碼:
        SYSINIT
        ;
        MRS R0,CPSR
        BIC R0,R0,#0x1F

        MOV R2,#RAMEND
        ORR R1,R0,#(MODSVC :OR: IRQBIT :OR: FIQBIT)
        MSR cpsr_cxsf,R1 ; ENTER SVC MODE
        MOV sp,R2
        SUB R2,R2,#SvcStkSz

        ORR R1,R0,#(MODFIQ :OR: IRQBIT :OR: FIQBIT)
        MSR CPSR_cxsf,R1 ; ENTER FIQ MODE
        MOV sp,R2
        SUB R2,R2,#FiqStkSz

        ORR R1,R0,#(MODIRQ :OR: IRQBIT :OR: FIQBIT)
        MSR CPSR_cxsf,R1 ; ENTER IRQ MODE
        MOV sp,R2
        SUB R2,R2,#IrqStkSz

        ORR R1,R0,#(MODUDF :OR: IRQBIT :OR: FIQBIT)
        MSR CPSR_cxsf,R1 ; ENTER UDF MODE
        MOV sp,R2
        SUB R2,R2,#UdfStkSz

        ORR R1,R0,#(MODABT :OR: IRQBIT :OR: FIQBIT)
        MSR CPSR_cxsf,R1 ; ENTER ABT MODE
        MOV sp,R2
        SUB R2,R2,#AbtStkSz

        ;ORR R1,R0,#(MODUSR :OR: IRQBIT :OR: FIQBIT)
        ;MSR CPSR_cxsf,R1 ; ENTER USR MODE
        ;MOV sp,R2
        ;SUB R2,R2,#UsrStkSz

        ORR R1,R0,#(MODSYS :OR: IRQBIT :OR: FIQBIT)
        MSR CPSR_cxsf,R1 ; ENTER SYS MODE
        MOV sp,R2 ;

        三,初始化變量
        編譯完成之后,連接器會生成三個基本的段,分別是RO,RW,ZI,并會在image中順序擺放.顯然,RW,ZI在運(yùn)行開始時并不位于指定的RW位置,因此必須初始化
        LDR R0,=|Image$$RO$$Limit|
        LDR R1,=|Image$$RW$$Base|
        LDR R2,=|Image$$ZI$$Base|
        1
        CMP R1,R2
        LDRLO R3,[R0],#4
        STRLO R3,[R1],#4
        BLO %B1

        MOV R3,#0
        LDR R1,=|Image$$ZI$$Limit|
        2
        CMP R2,R1
        STRLO R3,[R2],#4
        BLO %B2

        四,復(fù)制異常向量
        由于代碼于RAM運(yùn)行時,有明顯的速度優(yōu)勢,而且變量可以動態(tài)配置,因此可以通過remap將RAM映射到0,使得出現(xiàn)異常時ARM從RAM中取得向量.
        IMPORT |Image$$RO$$Base|
        IMPORT |Image$$RO$$Limit|
        IMPORT |Image$$RW$$Base|
        IMPORT |Image$$RW$$Limit|
        IMPORT |Image$$ZI$$Base|
        IMPORT |Image$$ZI$$Limit|


        COPY_VECT_TO_RAM
        LDR R0,=|Image$$RO$$Base|
        LDR R1,=SYSINIT
        LDR R2,=0x200000 ; RAM START
        0
        CMP R0,R1
        LDRLO R3,[R0],#4
        STRLO R3,[R2],#4
        BLO %B0

        這段程序?qū)YSINIT之前的代碼,也就是異常處理函數(shù),全部復(fù)制到RAM中, 這就意味著不能將RW設(shè)置為0x200000,這樣會使得向量被沖掉.

        四,在RAM中運(yùn)行
        如果有必要,且代碼足夠小,可以將代碼置于RAM中運(yùn)行,由于RAM中本身沒有代碼,就需要將代碼復(fù)制到RAM中:
        COPY_BEGIN
        LDR R0,=0x200000
        LDR R1,=RESET ; =|Image$$RO$$Base|
        CMP R1,R0 ;
        BLO COPY_END ;

        ADR R0,RESET
        ADR R2,COPY_END
        SUB R0,R2,R0
        ADD R1,R1,R0

        LDR R3,=|Image$$RO$$Limit|
        3
        CMP R1,R3
        LDRLO R4,[R2],#4
        STRLO R4,[R1],#4
        BLO %B3

        LDR PC,=COPY_END

        COPY_END
        程序首先取得RESET的連接地址,判斷程序是否時是在RAM中運(yùn)行,方法是與RAM起始地址比較,如果小于,那么就跳過代碼復(fù)制.
        在復(fù)制代碼的時候需要注意,在這段程序結(jié)束之前的代碼沒有必要復(fù)制,因?yàn)檫@些代碼都已經(jīng)執(zhí)行過了,所以,先取得COPY_END,作為復(fù)制起始地址,然后計算其相對RESET的偏移,然后以RO的值加上這個偏移,就是復(fù)制目的地的起始地址,然后開始復(fù)制.

        五,開始主程序
        以上步驟完成,就可以跳轉(zhuǎn)到main運(yùn)行
        IMPORT Main

        LDR PC,=Main
        B .


        六,器件初始化
        主程序首先要進(jìn)行器件的初始化,對S64而言,應(yīng)該先初始化WDT,因?yàn)槟J(rèn)情況下,WDT是打開的,然后是各設(shè)備的時鐘分配,最后應(yīng)該remap

        本文引用地址:http://www.104case.com/article/201611/321700.htm

        如果是驅(qū)動led,那么用1K左右的就行了。如果希望亮度大一些,電阻可減小,最小不要小于200歐姆,否則電流太大;如果希望亮度小一些,電阻可增大,增加到多少呢,主要看亮度情況,以亮度合適為準(zhǔn),一般來說超過3K以上時,亮度就很弱了,但是對于超高亮度的LED,有時候電阻為10K時覺得亮度還能夠用。通常就用1k的。

        對于驅(qū)動光耦合器,如果是高電位有效,即耦合器輸入端接端口和地之間,那么和LED的情況是一樣的;如果是低電位有效,即耦合器輸入端接端口和VCC之間,那么除了要串接一個1——4.7k之間的電阻以外,同時上拉電阻的阻值就可以用的特別大,用100k——500K之間的都行,當(dāng)然用10K的也可以,但是考慮到省電問題,沒有必要用那么小的。

        對于驅(qū)動晶體管,又分為PNP和NPN管兩種情況:對于NPN,毫無疑問NPN管是高電平有效的,因此上拉電阻的阻值用2K——20K之間的,具體的大小還要看晶體管的集電極接的是什么負(fù)載,對于LED類負(fù)載,由于發(fā)管電流很小,因此上拉電阻的阻值可以用20k的,但是對于管子的集電極為繼電器負(fù)載時,由于集電極電流大,因此上拉電阻的阻值最好不要大于4.7K,有時候甚至用2K的。對于PNP管,毫無疑問PNP管是低電平有效的,因此上拉電阻的阻值用100K以上的就行了,且管子的基極必須串接一個1——10K的電阻,阻值的大小要看管子集電極的負(fù)載是什么,對于LED類負(fù)載,由于發(fā)光電流很小,因此基極串接的電阻的阻值可以用20k的,但是對于管子的集電極為繼電器負(fù)載時,由于集電極電流大,因此基極電阻的阻值最好不要大于4.7K。

        對于驅(qū)動TTL集成電路,上拉電阻的阻值要用1——10K之間的,有時候電阻太大的話是拉不起來的,因此用的阻值較小。但是對于CMOS集成電路,上拉電阻的阻值就可以用的很大,一般不小于20K,我通常用100K的,實(shí)際上對于CMOS電路,上拉電阻的阻值用1M的也是可以的,但是要注意上拉電阻的阻值太大的時候,容易產(chǎn)生干擾,尤其是線路板的線條很長的時候,這種干擾更嚴(yán)重,這種情況下上拉電阻不宜過大,一般要小于100K,有時候甚至小于10K。

        根據(jù)以上分析,上拉電阻的阻值的選取是有很多講究的,不能亂用


        上一頁 1 2 下一頁

        關(guān)鍵詞: ARM啟動方

        評論


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

        關(guān)閉
        主站蜘蛛池模板: 余姚市| 凯里市| 宁强县| 宁远县| 抚州市| 辽中县| 富平县| 潜山县| 青川县| 平泉县| 延寿县| 潍坊市| 澄迈县| 岗巴县| 榕江县| 石泉县| 大关县| 武功县| 固始县| 黑河市| 东乌珠穆沁旗| 台东市| 类乌齐县| 珠海市| 通化县| 麦盖提县| 罗平县| 海宁市| 牙克石市| 苏州市| 富川| 郓城县| 福州市| 河北省| 古蔺县| 库车县| 康保县| 明溪县| 当涂县| 池州市| 宁都县|