日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Exynos4412裸机开发——中断处理

發(fā)布時間:2023/12/9 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Exynos4412裸机开发——中断处理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?以KEY2控制LED3亮滅為例:

一、輪詢方式

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

【1】查看原理圖,連接引腳和控制邏輯
(1)按鍵k2 連接在GPX1_1引腳
(2)控制邏輯
?????? k2 按下? ---- K2閉合 ---- GPX1_1 低電壓
?????? k2 常態(tài)? ---- K2打開 ---- GPX1_1 高電壓

【2】查看相應(yīng)的芯片手冊

??? 【2-1】循環(huán)檢測GPX1_1引腳輸入的電平,為低電壓時,按鍵按下

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

????????????????? GPX1.PUD = GPX1.PUD & ~(0x3 << 2);
  (2)循環(huán)檢測:

[cpp]?view plaincopy
  • 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每按下一次,響應(yīng)一次異常處理。SPI 傳遞流程如下示:

    注:

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

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

    1)分配器:設(shè)置一個開關(guān),是否接收外部中斷源;為該中斷源選擇CPU接口;

    2)CPU接口:設(shè)置一個開發(fā),是否接受該中斷源請求;

    ?

    具體實現(xiàn)如下:

    1、外設(shè)一級 ---設(shè)置 GPIO控制器

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

    ??????? GPX1PUD[3:2]= 0b00;

    2 -- 將GPX1_1引腳功能設(shè)置為中斷功能?WAKEUP_INT1[1] --- EXT_INT41[1]

    ????????GPX1CON[7:4] = 0xf

    3 -- EXT_INT41CON? 配置觸發(fā)電平

    ???????當(dāng)前配置成下降沿觸發(fā):

    ?????? EXT_INT41CON[6:4] = 0x2

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

    ????? ?默認(rèn)就是打開的,不需要配置

    5 -- EXT_INT41_MASK 中斷使能寄存器

    ??????使能INT41[1]

    ????? EXT_INT41_MASK[1] = 0b0

    6 -- EXT_INT41_PEND 中斷狀態(tài)寄存器
    ?????? 當(dāng)GPX1_1引腳接收到中斷信號,中斷發(fā)生,中斷狀態(tài)寄存器EXT_INT41_PEND 相應(yīng)位會自動置1
    ??????? 注意:中斷處理完成的時候,需要清除相應(yīng)狀態(tài)位。置1清0.
    ??????? EXT_INT41_PEND[1] =0b1?

    ?

    2、中斷控制器

    1--?找到外設(shè)中斷名稱和GIC中斷控制器對應(yīng)的名稱

    ??  查看芯片手冊(本例:Exynos_4412 -- 9.2表)
    ????? ?WAKEUP_INT1[1] --- EXT_INT41[1] --- INT[9] --- SPI[25]/ID[57]

    ????? 其對應(yīng)INT[9],中斷ID為57,這是非常重要的,在后面的寄存器設(shè)置中起很大作用;

    ?

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

    ?

    2 -- GIC使能

    ?????? ICDDCR =1;

    ???????使能分配器。

    3?-- 使能相應(yīng)中斷到分配器

    ??????ICDISER.ICDISER1 |= (0x1 << 25);????//57/32 =1...25 取整數(shù)(那個寄存器) 和余數(shù)(哪位)

    ??????ICDISER用于使能相應(yīng)中斷到分配器,一個bit控制一個中斷源,一個ICDISER可以控制32個中斷源,這里INT[9] 對應(yīng)的中斷ID為57,所以在ICDSER1中進(jìn)行設(shè)置,57/32 =1余25,所以這里在ICDISER1第25位置一。

    ?

    4 -- 選擇CPU接口

    ????? 設(shè)置SPI[25]/ID[57]由那個cpu處理,當(dāng)前設(shè)置為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 -- 優(yōu)先級屏蔽寄存器,設(shè)置cpu0能處理所有的中斷。

    ??????CPU0.ICCPMR = 0xFF;

        ??????     ???????    

    3、ARM內(nèi)核(cpu0)

    ?????? 前面兩步設(shè)置好,就可以等待中斷的發(fā)生了,當(dāng)中斷發(fā)生時,ARM內(nèi)核的處理過程如下:

    ?

    ?1-- 四大步三小步 --- 硬件

        

    ????? (1)拷貝 CPSR 到 SPSR_<mode>
      (2)設(shè)置適當(dāng)?shù)?CPSR 位:????????????????????????????????
        (2-1)--改變處理器狀態(tài)進(jìn)入 ARM 態(tài)
    ?   ?? (2-2)--改變處理器模式進(jìn)入相應(yīng)的異常模式
    ?   ?? (2-3)--設(shè)置中斷禁止位禁止相應(yīng)中斷 (如果需要)
      (3)保存返回地址到 LR_<mode>
      (4)設(shè)置 PC 為相應(yīng)的異常向量
    ??????    

    2 -- 中斷服務(wù)程序 --- start.S 匯編

    [cpp]?view plaincopy
  • .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函數(shù)?C語言(函數(shù)原型void name(void))

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

    ?????? ???irq_num = (CPU0.ICCIAR & 0x1FF);

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

    [cpp]?view plaincopy
  • switch(irq_num)??
  • {??
  • ????.??
  • ????case?57:??
  • ????????break;??
  • ????....??
  • ??
  • }??

  • ?(3)清除中斷狀態(tài)位

    ??????? (3-1)i.外設(shè)級,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 程序:

    [cpp]?view plaincopy
  • #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中斷標(biāo)志位??
  • ????????????ICDICPR.ICDICPR1?=?ICDICPR.ICDICPR1?|?(0x1?<<?25);?//清GIC中斷標(biāo)志位??
  • ????????break;??
  • ????}??
  • ????CPU0.ICCEOIR?=?CPU0.ICCEOIR&(~(0x3ff))|irq_num;?//清cpu中斷標(biāo)志位??
  • }??
  • /*?
  • ?*??裸機(jī)代碼,不同于LINUX?應(yīng)用層,?一定加循環(huán)控制?
  • ?*/??
  • int?main?(void)??
  • {??
  • ????GPX1.CON?=GPX1.CON?&?(~(0xf?<<?4))?|(0xf?<<?4);?//配置引腳功能為外部中斷??
  • ????GPX1.PUD?=?GPX1.PUD?&?(~(0x3?<<?2));??//關(guān)閉上下拉電阻??
  • ????EXT_INT41_CON?=?EXT_INT41_CON?&(~(0xf?<<?4))|(0x2?<<?4);?//外部中斷觸發(fā)方式??
  • ????EXT_INT41_MASK?=?EXT_INT41_MASK?&?(~(0x1?<<?1));??//使能中斷??
  • ????ICDDCR?=?1;??//使能分配器??
  • ????ICDISER.ICDISER1?=?ICDISER.ICDISER1?|?(0x1?<<?25);?//使能相應(yīng)中斷到分配器??
  • ????ICDIPTR.ICDIPTR14?=?ICDIPTR.ICDIPTR14?&?(~(0xff?<<?8))|(0x1?<<?8);?//選擇CPU接口??
  • ????CPU0.ICCPMR?=?255;?//中斷屏蔽優(yōu)先級??
  • ????CPU0.ICCICR?=?1;???//使能中斷到CPU??
  • ????led_init();??
  • ????while(1)??
  • ????{??
  • ??
  • ????}??
  • ???return?0;??
  • } ?
  • 總結(jié)

    以上是生活随笔為你收集整理的Exynos4412裸机开发——中断处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。