1. 程式人生 > >第九天:按鍵及中斷原理

第九天:按鍵及中斷原理

  1. 什麼是按鍵?
    1. 按鍵的物理特性
      1. 一般的按鍵都有四個引腳,這四個引腳:其中一對是常開觸點(不按則斷,按下則合);一對是常閉觸點(不按則閉,按下則斷)
  1. 按鍵的電學原理
    1. 硬體接法:   SW5GPH0_2    SW6GPH0_3    SW78910GPH2_0123
    2. 按鍵的電路連線分析:平時按鈕沒有按下時,按鈕內部斷開,GPIO引腳處電壓為高電平;當有人按下按鈕時,按鈕內部導通,外部VDD經過電阻和按鈕連線到地,形成迴路,此時GPIO引腳處電壓就變成了低電平
  2. 按鍵屬於輸入類裝置
    1. 按鍵一般用來做輸入裝置(由人向SoC傳送資訊的裝置,叫做輸入裝置),由人向SoC傳送按鍵訊號(按鍵訊號有2種:按下訊號和彈開訊號)

輪訓方式和中斷方式

SoC主動的每隔一段時間去讀取GPIO的電平高低,以此獲得按鍵資訊

中斷方式,就是SoC實現設定好GPIO觸發的中斷多對應的中斷所對應的中斷處理程式ISR,當外部按下或彈開時會自動觸發GPIO對應的外部中斷,導致ISR執行,從而自動處理按鍵資訊。

  1. 輪詢方式處理按鍵
    1. X210開發板的按鍵接法
      1. 查原理圖,找到按鍵對應的GPIO
      2. 原理圖上可以看出按鍵在按下時是低電平,彈起時是高電平
    1. 按鍵對應的GPIO模式設定
      1. 按鍵接到GPIO上,按鍵按下還是彈起,決定外部電路的接通與否,從而決定了這個GPIO引腳的電壓是高還是低
    2. 輪詢方式處理按鍵的程式流程
      1. 先初始化GPIO模式為input
      2. 迴圈讀取GPIO
  1. 串列埠輸出和按鍵消抖
    1. 基於串列埠輸出按鍵的除錯
      1. 以之前的串列埠stdio的工程為基礎來移植新增輪詢方式按鍵處理
      2. 注意USB下載方式可能有錯誤(有可能不下載,也有可能下載了執行不對),執行方案是用SD卡啟動來替代。
    1. 什麼是按鍵消抖
      1. 按鍵這種物理器件本身會有抖動訊號指的是在電平由高到低或者由低到高時的過程中,電平的變化不是立刻變化,而是經過了一段時間的不穩定期才完成變化。
    2. 硬體消抖,儘量減少抖動時間,通過硬體新增電容等元件來減少抖動
    3. 軟體,遮蔽掉這段時間抖動在獲取電平狀態。
  1. S5PV210的中斷體系介紹
    1. 什麼是中斷
      1. 中斷的發明用來解決巨集觀上的並行需要的。巨集觀就是從整體來看,並行就是多件事情都完成了。
      2. 微觀上的並行,就是指的真正的並行。就是精確到每一秒甚至每一刻,多個事情都是在同時進行的。巨集觀上的並行並不等於微觀上的並行,有時候巨集觀上是並行的,微觀上實際是序列的。
  1. 我們例子中一個人在看電影,快遞來了暫停電影跑去收快遞,收完快遞繼續回來看電影,這個例子就是巨集觀上的並行和微觀上的序列。例子中一個人等同於SoC中一個CPU(也就是單核CPU),這個CPU看電影就不能收快遞,收快遞就不能看電影(也就是不能真正的並行)。單核心CPU在微觀角度是序列的,但是因為CPU很快,所以在巨集觀看來可以並行。
  2. 上例中大部分時間在看電影,中間少量時間去收快遞,那麼類比CPU來說,看電影就應該是CPU 的常規任務,而收快遞則應該是中斷例程。也就是說CPU平時一直在進行砍電影任務,等快遞來了(中斷髮生了)快遞員(類似於中斷源)會打電話叫人去收快遞(中斷源會觸發中斷通知CPU去處理中斷),人收到電話(CPU收到中斷源)後會暫定電影(CPU儲存常規任務的現場)跑去收快遞(CPU去執行中斷處理程式ISR處理中斷),收完快遞(執行完ISR)回來繼續看電影(CPU恢復常規任務的現場,繼續執行常規任務)
  3. 為什麼需要中斷?因為單核CPU實際無法並行的,但是通過終端機制,可以實現假並行(巨集觀上的並行,微觀上實際還是序列的)。
  1. SoC對中斷的實現機制:異常向量表
    1. 異常向量表是CPU中某些特定地址的特定定義。當中斷髮生的時候,中斷要想辦法通知CPU去處理中斷,怎麼做到?這就要靠異常向量表。
    2. CPU設計時,就事先定義了CPU中一些特定地址為特定異常的入口地址(譬如定義0x0000000地址為復位異常向量表地址,則發生復位異常時CPU會自動跳轉到0x00000000地址去執行指令。又譬如外部中斷對應的異常向量地址為0x30000008,則發生外部中斷後,CPU會硬體自動跳轉到0x30000008地址去執行指令。)如
    3. 以上講的是CPU硬體設計時對異常向量表的支援,下來就需要軟體支援了。硬體已經決定了發生什麼異常CPU自動跳轉PC到哪個地址去執行,軟體需要做的就是把處理這個異常的程式碼的首地址填入這個異常向量地址。
  1. S5PV210異常向量表
    1. 異常向量表在之前講過,複習一下
    2. 異常向量表中各個向量的相對位置是固定的,但是他們的起始地址是不固定的,各種SoC可以不一樣,而且複雜ARM中可以讓使用者來軟體設定異常向量表的基地址。
    3. 擴充套件到所有架構的CPU中:所有架構(譬如51微控制器、PIC微控制器)的CPU實現中斷都是通過異常向量表實現的,這個機制是不變的;但是不同CPU異常向量表的構造和位置是不同的。
  2. 異常和中斷的區別和聯絡。
    1. 針對SoC來說,發生復位、軟中斷、中斷、快速中斷、取指令異常、資料異常等,我們都統一叫異常。所以說中斷其實是異常的一種。。
    2. 異常的定義就是突發事件,打斷了CPU的正常常規業務,CPU不得不跳轉到異常向量表中去執行異常處理程式;中斷時異常的一種,一般特指SoC內的內部外設產生的打斷SoC常規業務,或者外部中斷(SoCGPIO引腳傳回來的中斷)
  1. 異常向量表的程式設計處理
    1. 像記憶體一樣去訪問異常向量表
      1. S5PV210的異常向量表可以改變(在CP15協處理器),以適應作業系統的需求。但是目前來說,系統剛啟動時,此時DRAM尚未初始化,程式都在SRAM中執行。210iRAM中設定了異常向量表,供暫時使用。
      2. 210Irom application

note文件中iROM的地址分配,可知,iRAM中的異常向量表其實地址為0xD0037400。知道了異常向量表的起始地址後,各個異常對應的入口就很好知道了。

  1. 函式名的實質就是函式的首地址
    1. 函式名在C語言中的理解方法和變數名其實沒區別。編譯器會把這個函式的函式體對應的程式碼段和這個函式的函式名(實質是符號)對應起來,等我們在使用這個函式名符號時,編譯器會將函式的函式體實際上做替換。因為函式體都不止4位元組,而函式名這個符號只能對應1個地址,所以實際對應的是函式體那一個程式碼段的首地址。
    2. C語言中的語法來講,函式名就是這個函式的函式指標。

總結:當我們將異常處理程式的首地址和異常向量表繫結之後,異常處理初步階段就完成了

  1. 為什麼中斷處理要先在彙編中進行

(1)中斷處理要注意保護現場(中斷從SVC模式來,則儲存SVC模式下的必要暫存器的值)和恢復現場(中斷處理完成後,準備返回SVC模式前,要將儲存的SVC模式下的必要暫存器的值恢復回去,不然到了SVC模式後暫存器的值亂了,SVC模式下原來正在進行的常規任務就被你搞壞了)

(2)儲存現場包括:第一:設定IRQ棧;第二,儲存LR;第三,儲存R0~R12

(3)為什麼要儲存LR暫存器?要考慮中斷返回的問題。中斷ISR執行完後如何返回SVC模式下去接著執行原來的程式碼。中斷返回其實取決於我們進入中斷時如何儲存現場。中斷返回時關鍵的2個暫存器就是PC和CPSR。所以我們在進入IRQ模式時,應該將SVC模式下的下一句指令的地址(中斷返回地址)和CPSR儲存起來,將來恢復時才可以將中斷返回地址給PC,將儲存的CPSR給CPSR。

(4)中斷返回地址就儲存在LR中,而CPSR(自動)儲存在(IRQ模式下的)SPSR中

  1. 彙編儲存現場和恢復現場

(1)保護現場關鍵是儲存:中斷處理程式的返回地址,r0-r12(cpsr是自動儲存的)

(2)恢復現場主要是恢復:r0-r12,pc,cpsr

  1. S5PV210的向量中斷控制器
    1. 異常處理的兩個階段
      1. 可以將異常處理分為兩個階段。第一個階段是異常向量表跳轉;第二個階段就是進入了真正的異常處理程式irq_handler之後的部分。
    2. 回顧:中斷處理的第一階段(異常向量表階段)處理
      1. 第一個階段之所以能夠進行,主要依賴於CPU設計時提供的異常向量表機制。第一個階段的只要任務是從異常發生響應異常並且儲存/恢復現場
      2. 第二個階段的目的是識別多箇中斷源中究竟哪一個發生了中斷,然後呼叫相應的中斷處理程式來處理這個中斷。
  1. S3C2440的第二階段處理過程
    1. 第一個問題,怎麼找到具體是哪個中斷:S3C2440的中斷控制器中有一個暫存器(32位的),暫存器的每一個對應一箇中斷源(為了解決支援更多中斷源,2440 又設計了一個子中斷機制。在一級中斷暫存器中有一些中斷是共用的一個bit位,譬如AC97WDT。對於共用中斷,用子中斷來區分究竟是哪一個發生了中斷)
    1. 第二個問題,怎麼找到對應的isr的問題:首先明確給每個中斷做了個編號,進入isr_handler之後先通過查閱中斷源暫存器和字中斷源暫存器(中哪一位為1)確定中斷的編號,然後用編號去isr陣列(isr陣列是中斷初始化時事先設定好的,就是把各個中斷的isr的函式名組成一個數組,用中斷編號作為索引來查詢這個陣列)中查閱得到isr地址。

評價:2440的中斷處理設計不是特別優秀:第一個過程中使用子中斷搞成2級的很麻煩;第二個過程中計算中中斷編號是個麻煩事,很耗時間。而中斷處理的時間是很寶貴的(系統有一個性能指標,叫實時性。實時性就是中斷髮生到相應的時間,這個時間越短越好)

  1. S5PV210的第二階段處理過程
    1. 第一個問題,怎麼找到具體是哪個中斷:S5PV210中因為支援的中斷源很多,所以直接設計了4箇中斷暫存器,每個32位,每位對應一個終端源。(理論支援210最多支援128箇中斷,實際支援不足128個,有些位是空的);210沒有子中斷暫存器每個中斷源都是並列的。當有中斷髮生時,在irq_handler中依次查詢4箇中斷源暫存器,看哪一個的哪一位被置1,則這個為對應的暫存器就發生了中斷,即找到了中斷編號。
  1. 第二個問題,怎麼找到相應的isr的問題: 210提供另外很多暫存器來解決每個中斷源對應isr的尋找問題,具體尋找過程和建立過程見下節,實現的效果是當發生相應中斷時,硬體會自動的將相應isr推入一定的暫存器中,我們軟體只要去這個暫存器中執行函式就行了

總結:第一階段都相同,第二階段各不同

  1. 第一階段(異常向量表階段)2440 210 幾乎完全是相同的
  2. 第二階段就彼此不同了。各個SoC根據自己對實時性的要求,和支援的中斷源的多少,各自發明瞭各自處理中斷,找到中斷編號,進一步找到isr地址的方式。
  1. S5PV210中斷處理的主要暫存器
    1. VICnINTENABLE VICNINTENCLEAR
      1. VICnINTENBLE 對應 interrupt enble,   INTENCLEAR 對應 interrupt enble clear
      2. VICnINTEABLE 暫存器負責相應的中斷的使能,VICnINTENCLEAR暫存器負責相應的中斷的禁止。
      3. 當我們想使能(意思是啟用這個中斷,意思是當硬體產生中斷時CPU能接收的到)某個中斷時,只要在這個中斷編號對應的VICnINTENBLE的相應bit位寫1 即可(注意這個為寫 1 其他位寫0 誒有影響);如果我們想禁止某個中斷源時,只要向VICnINTENCLEAR中相應的位寫1即可。

注意:這裡的設計一共有2種:有些CPU是中斷使能和禁止是一個暫存器,寫1 就使能0 就禁止(或者相反),這樣的中斷使能設計就要非常小心,要使用我們之前的讀改寫三部曲來操作;另一種就是使能和禁止分開位2個暫存器,要使能就寫使能暫存器,要禁止就寫禁止暫存器。這樣的好處是我們使能/禁止操作時不需要讀改寫,直接寫即可。

  1. VICnINSELECT
    1. 設定各個中斷的模式為irq還是fiq.一般都設定成irq
    2. ORQ FIQ 究竟有何區別。 210 中支援2中中斷,irq fiq . irq 是普通中斷,fiq是快速中斷。快速中斷提供一種更快響應處理的中斷通道,用於對實時性要求很高的中斷源。fiqCPU設計時預先提供了一些機制保證fiq可以被快速處理,從而保證實時性。fiq的限制就是隻能有一箇中斷源被設定為fiq,其他都是irq
    3. CPU如何保證fiqirq快?
      1. 第一,fiq有專用的r8~r12,因此在fiqisr中可以直接使用r8~r12,而不用儲存,這就能節省時間
      2. 第二,異常向量表中fiq是最後一個異常向量入口。因此fiqisr不需要跳轉,可以直接寫在原地,這樣就比其他異常少跳轉一次,省了些時間。
    4. VICnIRQSTATUS   VICnFIQSTATUS
      1. 中斷狀態暫存器,是隻讀的。當發生了中斷時,硬體會自動將該暫存器的對應位置位1,表示中斷髮生了。軟體在處理中斷第二階段的第一階段,就是靠查詢這個暫存器來得到中斷編號的。
    5. VICnVECTPRIORITY0~VICnVECTPRIORITY31
      1. 中斷優先順序設定暫存器,設定多箇中斷同時發生時先處理誰後處理誰的問題。一般來說高優先順序的中斷可以打斷低優先順序的中斷,從而巢狀處理中斷。當然了有些硬體/軟體可以設定不支援中斷巢狀。
    6. VICnVECTADDR0~VICnVECTDDR31VICnADDR
      1. 這“三個”暫存器和210 中斷處理第二階段的第二階段有關。
      2. VICnVECATDDR0 31 32個暫存器分別用來存放真正的各個中斷對應的isr的函式地址。相當於每一箇中斷源都有一個VECTADDR暫存器,程式設計師在設定中斷的時候,把這個中斷的isr地址直接放入這個中斷對應的VECTADDR暫存器即可。
      3. VICnADDR 這個暫存器是隻需要讀的,它裡面的內容是由硬體自動設定的。當發生了相應的中斷時,硬體會自動識別中斷編號,並且會自動找到這個中斷的VECTADDR暫存器,然後將其讀出複製到VICnADDR中,供我們使用,這樣的設計避免了軟體查詢中斷源和isr,節省了時間,提高了210 的中斷響應速度
  1. S5PV210中斷處理的程式設計實戰
    1. 上節中程式碼中的小問題
    2. 中斷控制器初始化
      1. 繫結異常向量表到異常處理程式
      2. 禁止所有中斷源
      3. 選擇所有中斷型別為IRQ
      4. 清理VICnADDR暫存器位0
    3. 中斷的使能與禁止
      1. 先根據中斷號判斷這個中斷屬於VIC幾,然後再用中斷源減去這個VIC的偏移量,得到這個中斷號在本VIC中的偏移量,然後1<<x位,寫入相應的VICINTENABLE/INTENCLEAR暫存器即可
    4. 繫結自己實現的isrVICnVECTADDR
      1. 繫結
    5. 真正的中斷處理程式如何獲取isr
      1. 當發生中斷源時,硬體會自動把相應,

總結:第四步繫結isr地址到VICVECTADDR和第五步中斷髮生時第二階段的第二階段如何獲取isr地址,這兩步是相關的。這兩個的結合技術,就是我們一直說的210的硬體自動尋找isr的機制。

整個中斷的流程梳理:

整個中斷的工作分為兩部分:

第一部分是我們為中斷響應而做的預備工作: