1. 程式人生 > >Exynos4412裸機開發——中斷處理

Exynos4412裸機開發——中斷處理

       以KEY2控制LED3亮滅為例:

一、輪詢方式

【0】檢測按鍵k2,按鍵k2按下一次,燈LED2閃一次。

【1】檢視原理圖,連線引腳和控制邏輯
(1)按鍵k2 連線在GPX1_1引腳
(2)控制邏輯
       k2 按下  ---- K2閉合 ---- GPX1_1 低電壓
       k2 常態  ---- K2開啟 ---- GPX1_1 高電壓

【2】檢視相應的晶片手冊

    【2-1】迴圈檢測GPX1_1引腳輸入的電平,為低電壓時,按鍵按下

        (1)配置GPX1_1引腳功能為輸入,設定內部上拉下拉禁止。
                  GPX1.CON = GPX1.CON &(~(0xf<<4)) ;

                  GPX1.PUD = GPX1.PUD & ~(0x3 << 2);
  (2)迴圈檢測:

while(1)
{
    if(!(GPX1.DAT & (0x1<<1)))  // 返回為真,按鍵按下
    {    
        msdelay(10);
        if(!(GPX1.DAT & (0x1<<1))) //二次檢測,去抖
        {
            GPX2.DAT |= 0x1 << 7;  //Turn on LED2
            mydelay_ms(500);
            GPX2.DAT &= ~(0x1<<7);  //Turn off LED2
            mydelay_ms(500);
      
            while(!(GPX1.DAT & (0x1<<1)));
        }
    }
}

這種輪詢方式始終佔著CPU,不利於操作。

二、中斷方式

         將K2按下時,GPX1_1引腳獲得的電平,作為異常事件。使能異常處理,k2每按下一次,響應一次異常處理。SPI 傳遞流程如下示:

注:

      Exynos4412中斷控制器包括160箇中斷控制源,這些中斷源來自軟中斷(SGI),私有外部中斷(PPI),公共外部中斷(SPI)。

 Exynos4412採用GIC中斷控制器,主要是因為Contex-A9 是多核處理器,GIC(Generic Interrupt Controller)通用中斷控制器用來選擇使用哪個CPU介面,具體主要有兩個功能:

1)分配器:設定一個開關,是否接收外部中斷源;為該中斷源選擇CPU介面;

2)CPU介面:設定一個開發,是否接受該中斷源請求;

具體實現如下:

1、外設一級 ---設定 GPIO控制器

1-- 將GPX1_1引腳的上拉和下拉禁止

        GPX1PUD[3:2]= 0b00;

2 -- 將GPX1_1引腳功能設定為中斷功能 WAKEUP_INT1[1] --- EXT_INT41[1]

        GPX1CON[7:4] = 0xf

3 -- EXT_INT41CON  配置觸發電平

       當前配置成下降沿觸發:

       EXT_INT41CON[6:4] = 0x2

4 -- EXT_INT41_FLTCON0 配置中斷引腳濾波

       預設就是開啟的,不需要配置

5 -- EXT_INT41_MASK 中斷使能暫存器

使能INT41[1]

      EXT_INT41_MASK[1] = 0b0

6 -- EXT_INT41_PEND 中斷狀態暫存器
       當GPX1_1引腳接收到中斷訊號,中斷髮生,中斷狀態暫存器EXT_INT41_PEND 相應位會自動置1
        注意:中斷處理完成的時候,需要清除相應狀態位。置1清0.
        EXT_INT41_PEND[1] =0b1 

2、中斷控制器

1-- 找到外設中斷名稱和GIC中斷控制器對應的名稱

    檢視晶片手冊(本例:Exynos_4412 -- 9.2表)
       WAKEUP_INT1[1] --- EXT_INT41[1] --- INT[9] --- SPI[25]/ID[57]

      其對應INT[9],中斷ID為57,這是非常重要的,在後面的暫存器設定中起很大作用;

下面是外設與中斷控制器處理具體流程:

 

2 -- GIC使能

       ICDDCR =1;

  使能分配器。

3 -- 使能相應中斷到分配器

      ICDISER.ICDISER1 |= (0x1 << 25);    //57/32 =1...25 取整數(那個暫存器) 和餘數(哪位)

      ICDISER用於使能相應中斷到分配器,一個bit控制一箇中斷源,一個ICDISER可以控制32箇中斷源,這裡INT[9] 對應的中斷ID為57,所以在ICDSER1中進行設定,57/32 =1餘25,所以這裡在ICDISER1第25位置一。

4 -- 選擇CPU介面

      設定SPI[25]/ID[57]由那個cpu處理,當前設定為cpu0的irq中斷

      ICDIPTR.ICDIPTR14 |= 0x01<<8; //SPI25  interrupts are sent to processor 0   //57/4 = 14..1 14號暫存器的[15:8]

      ICDIPTR暫存器每8個bit 控制一箇中斷源

5 -- 全域性使能cpu0中斷處理

CPU0.ICCICR |= 0x1;

使能中斷到CPU。

6 -- 優先順序遮蔽暫存器,設定cpu0能處理所有的中斷。

      CPU0.ICCPMR = 0xFF;

3、ARM核心(cpu0)

       前面兩步設定好,就可以等待中斷的發生了,當中斷髮生時,ARM核心的處理過程如下:

 1-- 四大步三小步 --- 硬體

    

      (1)拷貝 CPSR 到 SPSR_<mode>
  (2)設定適當的 CPSR 位:                               
    (2-1)--改變處理器狀態進入 ARM 態
       (2-2)--改變處理器模式進入相應的異常模式
       (2-3)--設定中斷禁止位禁止相應中斷 (如果需要)
  (3)儲存返回地址到 LR_<mode>
  (4)設定 PC 為相應的異常向量
          

2 -- 中斷服務程式 --- start.S 彙編

.text
.global _start
_start:
		b		reset
		ldr		pc,_undefined_instruction
		ldr		pc,_software_interrupt
		ldr		pc,_prefetch_abort
		ldr		pc,_data_abort
		ldr		pc,_not_used
		ldr		pc,_irq
		ldr		pc,_fiq

_undefined_instruction: .word  _undefined_instruction
_software_interrupt:	.word  _software_interrupt
_prefetch_abort:		.word  _prefetch_abort
_data_abort:			.word  _data_abort
_not_used:				.word  _not_used
_irq:					.word  irq_handler
_fiq:					.word  _fiq


reset:

	ldr	r0,=0x40008000
	mcr	p15,0,r0,c12,c0,0		@ Vector Base Address Register


init_stack:
		ldr		r0,stacktop         /*get stack top pointer*/

	/********svc mode stack********/
		mov		sp,r0
		sub		r0,#128*4          /*512 byte  for irq mode of stack*/
	/****irq mode stack**/
		msr		cpsr,#0xd2
		mov		sp,r0
		sub		r0,#128*4          /*512 byte  for irq mode of stack*/
	/***fiq mode stack***/
		msr 	cpsr,#0xd1
		mov		sp,r0
		sub		r0,#0
	/***abort mode stack***/
		msr		cpsr,#0xd7
		mov		sp,r0
		sub		r0,#0
	/***undefine mode stack***/
		msr		cpsr,#0xdb
		mov		sp,r0
		sub		r0,#0
   /*** sys mode and usr mode stack ***/
		msr		cpsr,#0x10
		mov		sp,r0             /*1024 byte  for user mode of stack*/

		b		main

	.align	4

	/****  swi_interrupt handler  ****/


	/****  irq_handler  ****/
irq_handler:

	sub  lr,lr,#4
	stmfd sp!,{r0-r12,lr}
	.weak do_irq
	bl	do_irq
	ldmfd sp!,{r0-r12,pc}^

stacktop:    .word 		stack+4*512
.data

stack:	 .space  4*512

3--中斷處理程式 --- do_irq函式 c語言(函式原型void name(void))

(1) 讀取正在處理的中斷ID暫存器(ICCIAR)

          irq_num = (CPU0.ICCIAR & 0x1FF);

(2)根據irq_num,分支處理中斷  

switch(irq_num)
{
	.
	case 57:
		break;
	....

}


 (3)清除中斷狀態位

        (3-1)i.外設級,EXT_INT41_PEND |= 0x1 << 1;
        (3-2)ii.GIC級,ICDICPR.ICDICPR1 |= 0x1 << 25;
        (3-3)iii.CPU0級 CPU0.ICCEOIR = (CPU0.ICCEOIR & ~(0x1FF)) | irq_num;

下面是C 程式:

#include "exynos_4412.h"
#include "led.h"

void  delay_ms(unsigned int num)
{
    int i,j;
    for(i=num; i>0;i--)
	for(j=1000;j>0;j--)
		;
}
void do_irq(void)
{
	static int a = 1;
	int irq_num;
	irq_num = CPU0.ICCIAR&0x3ff;  //獲取中斷號
	switch(irq_num)
	{
	case 57:
		printf("in the irq_handler\n");
			if(a)
				led_on(1);
			else
				led_off(1);
			a = !a;
			EXT_INT41_PEND = EXT_INT41_PEND |((0x1 << 1)); //清GPIO中斷標誌位
			ICDICPR.ICDICPR1 = ICDICPR.ICDICPR1 | (0x1 << 25); //清GIC中斷標誌位
		break;
	}
	CPU0.ICCEOIR = CPU0.ICCEOIR&(~(0x3ff))|irq_num; //清cpu中斷標誌位
}
/*
 *  裸機程式碼,不同於LINUX 應用層, 一定加迴圈控制
 */
int main (void)
{
	GPX1.CON =GPX1.CON & (~(0xf << 4)) |(0xf << 4); //配置引腳功能為外部中斷
	GPX1.PUD = GPX1.PUD & (~(0x3 << 2));  //關閉上下拉電阻
	EXT_INT41_CON = EXT_INT41_CON &(~(0xf << 4))|(0x2 << 4); //外部中斷觸發方式
	EXT_INT41_MASK = EXT_INT41_MASK & (~(0x1 << 1));  //使能中斷
	ICDDCR = 1;  //使能分配器
	ICDISER.ICDISER1 = ICDISER.ICDISER1 | (0x1 << 25); //使能相應中斷到分配器
	ICDIPTR.ICDIPTR14 = ICDIPTR.ICDIPTR14 & (~(0xff << 8))|(0x1 << 8); //選擇CPU介面
	CPU0.ICCPMR = 255; //中斷遮蔽優先順序
	CPU0.ICCICR = 1;   //使能中斷到CPU
	led_init();
	while(1)
	{

	}
   return 0;
}

相關推薦

Exynos4412裸機開發——中斷處理

       以KEY2控制LED3亮滅為例: 一、輪詢方式 【0】檢測按鍵k2,按鍵k2按下一次,燈LED2閃一次。 【1】檢視原理圖,連線引腳和控制邏輯 (1)按鍵k2 連線在GPX1_1引腳 (2)控制邏輯        k2 按下  ---- K2閉合 ----

Exynos4412裸機開發 —— RTC 實時時鐘單元

      RTC(Real-Time Clock) 實時時鐘。RTC是積體電路,通常稱為時鐘晶片。在一個嵌入式系統中,通常採用RTC來提供可靠的系統時間,包括時分秒和年月日等,而且要求在系統處於關機狀態下它也能正常工作(通常採用後備電池供電)。它的外圍也不需要太多的輔助電

Exynos4412裸機開發綜合練習

下面是一個案例需求: 1、編寫一段程式,該程式的主要功能是監控電路板上的電壓值,若電壓值超過當前的電壓限制則通過蜂鳴器報警,通過按鍵解除報警; 2、其具體要求如下;  a) 程式下載20s後,進入電壓採集狀態(使用RTC ALARM功能完成), 要求1s採集1次電路板電壓值

Exynos4412裸機開發 —— 看門狗定時器

一、看門狗定時器概述      看門狗(WatchDog Timer) 定時器和PWM的定時功能目的不一樣。它的特點是,需要不同的接收訊號(一些外接看門狗晶片)或重新設定計數器,保持計數值不為0。一旦一些時間接收不到訊號,或計數值為0,看門狗將發出復位訊號復位系統或產生

Exynos4412裸機開發——PWM定時器

一、PWM定時器 4412時鐘為我們提供了PWM定時器,在4412中共有5個32位的定時器,這些定時器可傳送中斷訊號給ARM子系統。另外,定時器0、1、2、3包含了脈衝寬度調製(PWM),並可驅動其拓展的I/O。PWM對定時器0有可選的dead-zone功能,以支援大電流裝

linux驅動編寫之中斷處理

類型 div 應該 urn 處理方式 com pre turn 申請 一、中斷 1、概念 學過單片機的應該非常清楚中斷的概念,也就是CPU在正常執行程序過程中,出現了突發事件(中斷事件),於是CPU暫停當前程序的執行,轉去處理突發事件。處理完畢後,CPU又返回被

linux驅動之中斷處理過程匯編部分

ont .cn stub sta 拷貝 ror c函數 當前 main函數 linux系統下驅動中,中斷異常的處理過程,與裸機開發中斷處理過程非常類似。通過簡單的回顧裸機開發中斷處理部分,來參考學習linux系統下中斷處理流程。 一、ARM裸機開發中斷處理過程

springBoot(7):web開發-錯誤處理

spring boot 錯誤處理 處理方式一:實現ErrorController接口原理:Spring Boot 將所有的錯誤默認映射到/error, 實現ErrorController接口代碼:package com.example.demo.controller; import org.sp

s5pv210中斷處理過程

異常處理 中斷一、異常處理的兩個過程 第一,異常向量表的跳轉 第二,進入異常處理程序中二、異常處理中的第一個過程 1、當發生異常時,CPU會自動跳轉PC到異常向量表對應的地址處,軟件需要處理的就是將這個異常處理的代碼首地址填入這個異常向量地址處。 2、中斷處理要先在匯編文件中進行,主

【實戰編程】編寫0號中斷處理程序

查看 com col 長度 獲取 pre p s 更改 end 題目:編寫0號中斷處理程序,在除法溢出時,在屏幕中間顯示字符串“hacker by admin!” 之前先補充一個rep movsb的指令知識 movsb和movsw是相反的,

內核中的中斷處理模型

自己 small 一個 status 進行 地址 clu ffi conf 內核版本: Linux 2.6.19 Kernel中斷處理模型結構圖如下: 下面簡單介紹一下: 1. Linux定義了名字為irq_desc的中斷例程描述符表:(include/linux/ir

zynq7000 中斷系統及在UCOSIII中的中斷處理接口

oss efi 1.5 lis 用戶 targe 流程 int eight 一、zynq7000中斷處理概述詳見zynq7000的用戶指導手冊UG585相關章節。zynq7000的中斷系統整體架構如下圖所示:中斷源有三種類型的中斷:私有外設中斷PPI:每個CPU有5個PPI

Thrift發送中斷處理

lag clas def exc 斷開 sent tin 異常 套接字 場景 分析當客戶端異常斷開連接,但是這個時候服務器並不知道連接已經失效,服務端這個時候嘗試發送數據給客戶端,這個時候就會觸發中斷,拋出異常先分析一下服務器發送數據的函數void TSocket::wri

Linux中斷 - ARM中斷處理過程

thum nio cti abort 兩個 alloc pos 不同 eve 一、前言 本文主要以ARM體系結構下的中斷處理為例,講述整個中斷處理過程中的硬件行為和軟件動作。具體整個處理過程分成三個步驟來描述: 1、第二章描述了中斷處理的準備過程 2、第三章描述了當發生中的

Linux內核設計基礎(一)之中斷處理

family ng- 內存 irq strong 睡眠 sign 技術 struct 假設讓內核定期對設備進行輪詢。以便處理設備,那會做非常多無用功,假設能讓設備在

系統調用軟中斷處理程序system_call分析

entry eight TE 總結 一個 tpi 更換 分享 進程 最近學習了系統調用的整個流程,這裏總結並記錄。同時作為學習孟寧老師的linux內核課程的作業。 唐建,《Linux內核分析》MOOC課程http://mooc.study.163.com/course/US

esp接收gpio引腳中斷處理按鍵觸發

20181025w gpio按鍵觸發 –定義變數 –wifi模組旁邊的LED燈D4引腳 ledwifi=4 –設定引腳模式:0(輸入模式) gpio.mode(ledwifi,0) –此時任然可以設定引腳電平輸出高/底(最後引腳1高電平,接低電平觸發) gp

iOS App中斷處理

- (void)handleInterruption:(NSNotification *)noti { AVAudioSessionInterruptionType type = [noti.userInfo[AVAudioSessionInterruptionTypeKey]

linux中斷處理原理分析

轉自http://blog.chinaunix.net/uid-20528014-id-3068412.html   Tasklet作為一種新機制,顯然可以承擔更多的優點。正好這時候SMP越來越火了,因此又在tasklet中加入了SMP機制,保證同種中斷只能在一個cpu上執行。在軟

作業系統的中斷處理

/* define SAVE_ALL "cld; \n\t" "pushq %rax; \n\t" "pushq %rax; \n\t" "pushq %es, %rax; \n\t" "pushq %rax; \n\t" "pushq" ... 上面的這段彙編程式碼的巨集