新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > GNU ARM匯編--(五)中斷匯編之嵌套中斷處理

        GNU ARM匯編--(五)中斷匯編之嵌套中斷處理

        作者: 時間:2016-11-26 來源:網絡 收藏
        在上篇《GNU ARM匯編--(四)中斷匯編之非嵌套中斷處理》中分析了最簡單的中斷處理的寫法,再看TQ2440啟動代碼中的中斷向量表的寫法就一目了然了.今天抽時間對嵌套中斷處理的學習做下整理.

        嵌套中斷處理的核心代碼如下:

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

        [cpp]view plaincopy
        1. ;/*
        2. ;*____________________________________________________________________
        3. ;*
        4. ;*Copyright(c)2004,AndrewN.Sloss,ChrisWrightandDominicSymes
        5. ;*Allrightsreserved.
        6. ;*____________________________________________________________________
        7. ;*
        8. ;*NON-COMMERCIALUSELicense
        9. ;*
        10. ;*Redistributionanduseinsourceandbinaryforms,withorwithout
        11. ;*modification,arepermittedprovidedthatthefollowingconditions
        12. ;*aremet:
        13. ;*
        14. ;*1.ForNON-COMMERCIALUSEonly.
        15. ;*
        16. ;*2.Redistributionsofsourcecodemustretaintheabovecopyright
        17. ;*notice,thislistofconditionsandthefollowingdisclaimer.
        18. ;*
        19. ;*3.Redistributionsinbinaryformmustreproducetheabove
        20. ;*copyrightnotice,thislistofconditionsandthefollowing
        21. ;*disclaimerinthedocumentationand/orothermaterialsprovided
        22. ;*withthedistribution.
        23. ;*
        24. ;*4.Alladvertisingmaterialsmentioningfeaturesoruseofthis
        25. ;*softwaremustdisplaythefollowingacknowledgement:
        26. ;*
        27. ;*ThisproductincludessoftwaredevelopedbyAndrewN.Sloss,
        28. ;*ChrisWrightandDominicSymes.
        29. ;*
        30. ;*THISSOFTWAREISPROVIDEDBYTHECONTRIBUTORS``ASISANDANY
        31. ;*EXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOTLIMITEDTO,THE
        32. ;*IMPLIEDWARRANTIESOFMERCHANTABILITYANDFITNESSFORAPARTICULAR
        33. ;*PURPOSEAREDISCLAIMED.INNOEVENTSHALLTHECONTRIBUTORSBE
        34. ;*LIABLEFORANYDIRECT,INDIRECT,INCIDENTAL,SPECIAL,EXEMPLARY,
        35. ;*ORCONSEQUENTIALDAMAGES(INCLUDING,BUTNOTLIMITEDTO,
        36. ;*PROCUREMENTOFSUBSTITUTEGOODSORSERVICES;LOSSOFUSE,DATA,
        37. ;*ORPROFITS;ORBUSINESSINTERRUPTION)HOWEVERCAUSEDANDONANY
        38. ;*THEORYOFLIABILITY,WHETHERINCONTRACT,STRICTLIABILITY,OR
        39. ;*TORT(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAYOUT
        40. ;*OFTHEUSEOFTHISSOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITY
        41. ;*OFSUCHDAMAGE.
        42. ;*
        43. ;*Ifyouhavequestionsaboutthislicenseorwouldlikeadifferent
        44. ;*licensepleaseemail:
        45. ;*
        46. ;*andrew@sloss.net
        47. ;*
        48. ;*
        49. ;*/
        50. ;/***********************************************************************
        51. ;*
        52. ;*Module:nih9_9.s
        53. ;*Descriptions:NestedInterruptHandler
        54. ;*Example:9.9
        55. ;*OS:generic
        56. ;*Platform:generic
        57. ;*History:
        58. ;*
        59. ;*31thDecember2003
        60. ;*-addedheader
        61. ;*
        62. ;***********************************************************************/
        63. EXPORTnestedInterruptHandler
        64. MaskmdEQU0x1f;processormodemask
        65. SVC32mdEQU0x13;SVCmode
        66. I_BitEQU0x80;IRQbit
        67. FRAME_R0EQU0x00
        68. FRAME_R1EQUFRAME_R0+4
        69. FRAME_R2EQUFRAME_R1+4
        70. FRAME_R3EQUFRAME_R2+4
        71. FRAME_R4EQUFRAME_R3+4
        72. FRAME_R5EQUFRAME_R4+4
        73. FRAME_R6EQUFRAME_R5+4
        74. FRAME_R7EQUFRAME_R6+4
        75. FRAME_R8EQUFRAME_R7+4
        76. FRAME_R9EQUFRAME_R8+4
        77. FRAME_R10EQUFRAME_R9+4
        78. FRAME_R11EQUFRAME_R10+4
        79. FRAME_R12EQUFRAME_R11+4
        80. FRAME_PSREQUFRAME_R12+4
        81. FRAME_LREQUFRAME_PSR+4
        82. FRAME_PCEQUFRAME_LR+4
        83. FRAME_SIZEEQUFRAME_PC+4
        84. AREAnih9_9,CODE,readonly
        85. nestedInterruptHandler;instructionstate:comment
        86. SUBr14,r14,#4;2:
        87. STMDBr13!,{r0-r3,r12,r14};2:savecontext
        88. ;
        89. BLread_RescheduleFlag;3:moreprocessing
        90. CMPr0,#0;3:ifprocessing?
        91. LDMNEIAr13!,{r0-r3,r12,pc}^;4:thenreturn
        92. MRSr2,SPSR;5:copySPSR_irq
        93. MOVr0,r13;5:copyr13_irq
        94. ADDr13,r13,#6*4;5:resetstack
        95. MRSr1,CPSR;6:copyCPSR
        96. BICr1,r1,#Maskmd;6:
        97. ORRr1,r1,#SVC32md;6:
        98. MSRCPSR_c,r1;6:changeSVCmode
        99. SUBr13,r13,#FRAME_SIZE-FRAME_R4;7:makestackspace
        100. STMIAr13,{r4-r11};7:saver4-r11
        101. LDMIAr0,{r4-r9};7:r4-r9IRQstack
        102. BICr1,r1,#I_Bit;8:
        103. MSRCPSR_c,r1;8:enableint
        104. STMDBr13!,{r4-r7};9:saver4-r7SVC
        105. STRr2,[r13,#FRAME_PSR];9:savePSR
        106. STRr8,[r13,#FRAME_R12];9:saver12
        107. STRr9,[r13,#FRAME_PC];9:savepc
        108. STRr14,[r13,#FRAME_LR];9:savelr
        109. ;
        110. LDMIAr13!,{r0-r12,r14};11:restorecontext
        111. MSRSPSR_cxsf,r14;11:restoreSPSR
        112. LDMIAr13!,{r14,pc}^;11:return
        113. read_RescheduleFlag
        114. ;
        115. MOVr0,#0;moreprocessing
        116. MOVpc,r14;return
        117. END


        代碼的關鍵就是在中斷后切換到SVC模式下,利用svc mode的stack來實現中斷嵌套過程的備份以及恢復操作.從代碼中可以看到,從R0到PC都在棧中有備份,這里我們叫棧幀.記得《深入理解計算機系統》一書在講x86匯編的函數調用時也是棧幀的概念.這點上中斷嵌套和函數調用有相似之處.有了這個棧幀,利用壓棧出棧操作就一切ok了.

        剛看這個代碼,對有個地方有疑問,就是覺得中斷開早了:

        BIC r1,r1,#I_Bit ; 8 :
        MSR CPSR_c,r1 ; 8 : enable int
        STMDB r13!,{r4-r7} ; 9 : save r4-r7 SVC
        STR r2,[r13,#FRAME_PSR] ; 9 : save PSR
        STR r8,[r13,#FRAME_R12] ; 9 : save r12
        STR r9,[r13,#FRAME_PC] ; 9 : save pc
        STR r14,[r13,#FRAME_LR] ; 9 : save lr

        覺得開中斷的代碼應該放在后面,這樣才能保證svc mode下的stack frame不會被破壞.但在草稿紙上畫一下irq和svc下的stack圖,就發現堆棧操作并沒有問題.可以假設剛開中斷立馬就有新的中斷了,r4-r7 r8 r9都有在STMIA r13,{r4-r11} 中保存到svc的stack中,LDMIA r0,{r4-r9} 和STMDB r13!,{r4-r7} 保證了最初的r0-r3在棧中,而LDMIA r0,{r4-r9}和STR r8,[r13,#FRAME_R12] 以及STR r9,[r13,#FRAME_PC] 保證了R12和PC,保證正確返回.(這里的r9裝的是r14_irq,所以pc就是r14_irq,這樣就保證了從中斷服務例程中返回).至于STR r14,[r13,#FRAME_LR]中的r14是r14_svc,將其壓入svc的stack中,中斷例程用bl就不會出現錯誤了,在最后LDMIA r13!,{r14,pc}^ 中r14得到恢復.而r2保存的是spsr,也就是svc模式的狀態,一直不變,不用擔心會被覆蓋.

        最后,再看了一遍圖,覺得r10和r11的幀可以省去,因為r4-r9是用來存atpcs的r0-r3,r12,r14,而r10和r11用不到.貌似可以省點空間和時間,具體的待會實驗一下.

        下面給出實際的嵌套中斷處理,利用r10來保存INTOFFSET的值,根據該值來判定是什么中斷,從而做不同的處理.具體的效果是:代碼會做流水燈的動作,Key1代表INT1,中斷處理動作是4個燈全全亮然后全滅,Key4代表代表INT0,中斷處理動作是第一個燈和第三個燈亮,然后第二個燈和第四個燈亮.

        [cpp]view plaincopy
        1. /*
        2. simpleinterruption
        3. copyleft@dndxhej@gmail.com
        4. */
        5. .equMaskmd,0x1f@processormodemask
        6. .equSVC32md,0x13@SVCmode
        7. .equI_Bit,0x80@IRQbit
        8. .equFRAME_R0,0x00
        9. .equFRAME_R1,FRAME_R0+4
        10. .equFRAME_R2,FRAME_R1+4
        11. .equFRAME_R3,FRAME_R2+4
        12. .equFRAME_R4,FRAME_R3+4
        13. .equFRAME_R5,FRAME_R4+4
        14. .equFRAME_R6,FRAME_R5+4
        15. .equFRAME_R7,FRAME_R6+4
        16. .equFRAME_R8,FRAME_R7+4
        17. .equFRAME_R9,FRAME_R8+4
        18. .equFRAME_R10,FRAME_R9+4
        19. .equFRAME_R11,FRAME_R10+4
        20. .equFRAME_R12,FRAME_R11+4
        21. .equFRAME_PSR,FRAME_R12+4
        22. .equFRAME_LR,FRAME_PSR+4
        23. .equFRAME_PC,FRAME_LR+4
        24. .equFRAME_SIZE,FRAME_PC+4
        25. .equNOINT,0xc0
        26. .equWTCON,0x53000000
        27. .equGPBCON,0x56000010@led
        28. .equGPBDAT,0x56000014@led
        29. .equGPBUP,0x56000018@led
        30. .equGPFCON,0x56000050@interruptconfig
        31. .equEINTMASK,0x560000a4
        32. .equEXTINT0,0x56000088
        33. .equEXTINT1,0x5600008c
        34. .equEXTINT2,0x56000090
        35. .equINTMSK,0x4A000008
        36. .equEINTPEND,0x560000a8
        37. .equINTSUBMSK,0X4A00001C
        38. .equSRCPND,0X4A000000
        39. .equINTPND,0X4A000010
        40. .equINTOFFSET,0x4A000014
        41. .global_start
        42. _start:breset
        43. ldrpc,_undefined_instruction
        44. ldrpc,_software_interrupt
        45. ldrpc,_prefetch_abort
        46. ldrpc,_data_abort
        47. ldrpc,_not_used
        48. @birq
        49. ldrpc,_irq
        50. ldrpc,_fiq
        51. _undefined_instruction:.wordundefined_instruction
        52. _software_interrupt:.wordsoftware_interrupt
        53. _prefetch_abort:.wordprefetch_abort
        54. _data_abort:.worddata_abort
        55. _not_used:.wordnot_used
        56. _irq:.wordirq
        57. _fiq:.wordfiq
        58. .balignl16,0xdeadbeef
        59. reset:
        60. ldrr3,=WTCON
        61. movr4,#0x0
        62. strr4,[r3]@disablewatchdog
        63. ldrr0,=GPBCON
        64. ldrr1,=0x15400
        65. strr1,[r0]
        66. ldrr2,=GPBDAT
        67. ldrr1,=0x160
        68. strr1,[r2]
        69. bldelay
        70. msrcpsr_c,#0xd2@進入中斷模式
        71. ldrsp,=0xc00@中斷模式的棧指針定義
        72. msrcpsr_c,#0xd3@進入svc模式
        73. ldrsp,=0xfff@設置svc模式的棧指針
        74. @--------------------------------------------
        75. ldrr0,=GPBUP
        76. ldrr1,=0x03f0
        77. strr1,[r0]

        78. 上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 郴州市| 安义县| 甘泉县| 麻栗坡县| 仪陇县| 高州市| 邢台市| 汤阴县| 雅安市| 平舆县| 盘山县| 新蔡县| 清涧县| 平定县| 招远市| 南漳县| 小金县| 澄江县| 洛南县| 腾冲县| 咸宁市| 南召县| 奉化市| 吉林省| 蛟河市| 沈阳市| 朝阳区| 广灵县| 仪陇县| 武义县| 海兴县| 简阳市| 应用必备| 涟源市| 馆陶县| 津市市| 巴塘县| 木里| 平定县| 兰西县| 肇庆市|