娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

[smart210] s5pv210的中斷體系

發布者:SparklingDreams最新更新時間:2024-12-12 來源: elecfans關鍵字:smart210  s5pv210  中斷體系 手機看文章 掃描二維碼
隨時隨地手機看文章

平臺:smart210

CPU:s5pv210

目標:學習s5pv210的中斷體系,從一個子中斷的使能等設置的流程中體會完整的中斷過程。

知識儲備:向量中斷控制器的介紹


主要有4個VIC,4個TZIC還有一個很特殊的ARM PrimeCell PL192。主要的VIC和TZIC可以支持93個中斷源。其中TZIC是為TrustZone技術所準備的,ARM TrustZone? 技術是系統范圍的安全方法,針對高性能計算平臺上的大量應用,包括安全支付、數字版權管理 (DRM)、企業服務和基于 Web 的服務(援引官方的介紹)。TZIC提供了安全控制的nFIQ中斷并且使該這類中斷從傳統的不安全中斷VIC中屏蔽掉,從而達到應用在數據傳輸時的安全性和保密性。


支持的核心功能有固定的硬件中斷優先級以及可編程的軟件中斷優先級(包括設置與屏蔽),還有這是為合理調配中斷而必須要用到的。還有對應的中斷信號生成、中斷請求等等。還有特權模式的訪問。

VIC有四個組,其中每個組均包含有32個中斷源,合計128個中斷源(當然有一些是空的),所支持的中斷源,從GPIO的EINT到UART等各類通訊總線再到多媒體信號等,可以說是無所不包,所以我們只要利用好向量中斷控制器,才能更加高效地使用CPU的計算資源,服務于具體的工作需求。

以VIC0為例,分析具體的寄存器。


RAW INTERRUPT就是該中斷組在沒有設置VIC0INTSELECT和VIC0INTENABLE之前的中斷狀態(初值不確定),而FIQ和IRQ是設置完那兩個寄存器之后的中斷狀態(初值確定為0)。所以我們就有了VIC0IRQSTATUS、VIC0FIQSTATUS與VIC0RAWSTATUS這三個只讀狀態寄存器,每一位都對應著該組(這里是VIC0組)的一個中斷源。

還有一些中斷優先級設置與屏蔽,軟中斷等寄存器可供設置。

其次,還有VIC0VECTADDR0~VICVECTADDR31用來設置各中斷源的中斷服務程序入口,VIC0VECTPRIORITY0~VIC0VECTPRIORITY31用來根據需要設置各中斷源的優先級。還有如下相關的寄存器,我們可以根據需要做相應的讀寫。

VIC0VECTADDR是一個具有特殊功用的寄存器,對它的讀寫最好是在中斷服務程序內,讀的時候能讀出當前中斷運行程序的地址,寫任何值則將清除掉現在正在運行的中斷服務程序,而且要求必須在在中斷服務程序的末尾對該寄存器作任意值寫操作。

VIC0PERIPHID0還有VIC0PCELLID0這些只讀寄存器則只是提供了一些識別信息,基本上不需要用到。

除了上面的內容之外,我們還需要理解以下幾點:

1.異常向量表

我們已知,memory map標志出了Interal SRAM (即iRAM)的地址范圍:0xD002_0000~0xD003_8000,其中的Exception Vector Table是異常向量所屬空間,我們已知ARM有以下的特性:


ARM 系列的處理器可以工作 7 種模式下。除 User Mode 以外的其它 Mode 都叫做特權模式,除 User 和 System 以外的其它 5 種模式叫做異常模式,分別為:

- 快速中斷模式(fiq):高速數據傳輸或通道處理。

- 外部中斷模式(irq):通用的中斷處理。

- 管理模式(svc):操作系統使用的保護模式。

- 數據訪問終止模式(abt):當數據或指令預取終止時進入該模式。

- 定義指令中止模式(und):當未定義的指令執行時進入該模式。


我們需要對這五種異常模式定義好對應的處理程序的入口地址,尤其是常見的兩個中斷模式:FIQ與IRQ,比如當【按鍵中斷】發生的時候,處理器就將進入IRQ模式,首先要進行現場保護(硬件自動完成),然后從固定入口進入中斷處理函數,中斷處理函數首先判斷是哪個中斷組發生中斷,然后直接執行該中斷組對應的VICxINTADDR寄存器里面的函數。我們知道,一個中斷組有32個中斷源,為什么我們可以直接運行中斷組的VICxINTADDR指定的函數而無需知道是具體哪個中斷源觸發了中斷呢?這是由于中斷組內的中斷源在觸發中斷后硬件會自動把對應中斷源的處理函數入口地址賦給所屬組的VICxINTADDR,這樣我們就能省去檢索中斷源再跳轉到對應中斷函數入口的時間了,當然,前提是我們要把【按鍵中斷】的服務程序入口地址賦給某個對應的寄存器(假設是VIC0INTADDR12,所屬組是VIC0組,所對應入口是VIC0INTADDR)。

對應的程序思路是這樣的:

//1.設置異常模式的處理程序入口,應注意到IRQ_handle函數


void system_initexception( void)

{

    pExceptionUNDE        =    (unsigned long)exceptionundef;

    pExceptionSWI      =    (unsigned long)exceptionswi;

    pExceptionPABORT      =    (unsigned long)exceptionpabort;

    pExceptionDABORT      =    (unsigned long)exceptiondabort;

    pExceptionIRQ          =    (unsigned long)IRQ_handle;

    pExceptionFIQ         =    (unsigned long)IRQ_handle;

    //左邊都是對應的向量地址,右邊是編寫好的處理程序的函數名,通過賦值達到設置的目的

    intc_init();

}

 

//2.中斷控制器相關初始化


void intc_init(void)

{

    //清除中斷使能(禁止中斷)


    VIC0INTENCLEAR = 0xffffffff;

    VIC1INTENCLEAR = 0xffffffff;

    VIC2INTENCLEAR = 0xffffffff;

    VIC3INTENCLEAR = 0xffffffff;

    //設置所有中斷源為IRQ中斷

    VIC0INTSELECT = 0x0;

    VIC1INTSELECT = 0x0;

    VIC2INTSELECT = 0x0;

    VIC3INTSELECT = 0x0;

    //清除每個中斷組服務程序入口地址,即四個VICxINTADDR寄存器

    intc_clearvectaddr();


}

 

//3.通過該函數設置外部程序作為對應中斷源服務程序入口,第一個參數為中斷號(一個中斷源對應一個中斷號),第二個參數為函數地址。


void intc_setvectaddr(unsigned long intnum, void (*handler)(void))

{

    //VIC0

    if(intnum<32)

    {

        *( (volatile unsigned long *)(VIC0VECTADDR + 4*intnum) ) = (unsigned)handler;

    }

    //VIC1

    else if(intnum<64)

    {

        *( (volatile unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler;

    }

    //VIC2

    else if(intnum<96)

    {

        *( (volatile unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler;

    }

    //VIC3

    else

    {

        *( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler;

    }

    return;

}

//4.在start.S中做好一些準備工作,程序最先開始運行start.S,然后設置好CPSR_cxsf后,允許了中斷,跳轉到main函數。


.global _start

.global IRQ_handle


_start:

    ldr    r0, =0xE2700000            

    mov    r1, #0

    str    r1, [r0]

    ldr    sp, =0x40000000        

    mov r0, #0x53            

    msr CPSR_cxsf, r0    

    bl clock_init    

    bl main    

IRQ_handle:

    ldr sp, =0xD0037F80

    sub lr, lr, #4                

    stmfd sp!, {r0-r12, lr}

    bl    irq_handler        

    ldmfd sp!, {r0-r12, pc}^

 

//5.main函數的作用


int main(void)

{

    int c = 0;


    //初始化串口

    uart_init();

    //初始化異常向量表

    system_initexception();                        

    

    printf('**************Int test *************** rn');


    // 1111 = EXT_INT[16] 設置GPIO的H2組作為外部中斷引腳,實質上就是開發板上的實體按鍵

    GPH2CON = GPH2_0_EINT16|GPH2_1_EINT17|GPH2_2_EINT18|GPH2_3_EINT19;    

    GPH3CON = GPH3_0_EINT24|GPH3_1_EINT25|GPH3_2_EINT26|GPH3_3_EINT27;            

    // 010 = Falling edge triggered

    // EXT_INT[16]~EXT_INT[19]是屬于EXT_INT_2的,通過這個寄存器設置為下降沿觸發,而EXT_INT[24]~EXT_INT[27]是屬于EXT_INT_3的。

    EXT_INT_2_CON |= 2<<0|2<<4|2<<8|2<<12;        

    EXT_INT_3_CON |= 2<<0|2<<4|2<<8|2<<12;

    //unmask,作用是允許該外部中斷組的具體引腳的中斷觸發功能

    EXT_INT_2_MASK &= (~(1<<0)) & (~(1<<1)) & (~(1<<2)) & (~(1<<3));

    EXT_INT_3_MASK &= (~(1<<0)) & (~(1<<1)) & (~(1<<2)) & (~(1<<3));

    //NUM_EINT16_31是一個中斷源,只要EINT16到EINT31的任意一個引腳觸發了中斷,就能引發之前設置好的中斷服務程序,這里通過

    //intc_setvectaddr()函數把中斷號跟對應中斷服務程序聯系起來。




    intc_setvectaddr(NUM_EINT16_31, isr_key);

    //使能該中斷源    

    intc_enable(NUM_EINT16_31);

    while (1)

    {   

        printf('%drn',c++);

        delay(0x100000);

    }

}

void isr_key(void)

{

     printf('We get external interrupt:EINT16_31 (key1 to key 8)rn');

     //下面的程序是檢測是該中斷源里的哪個引腳觸發的中斷,用來辨別是哪個KEY被按下了。

     unsigned long what;     what = (EXT_INT_2_PEND & 0x0f) + ((EXT_INT_3_PEND & 0xf) << 4) ;

     unsigned long i;

     for(i=0;i<8;i++)

     {

          if(what & 1<          printf('Now the key is key%dn',i+1);

     }     // clear VIC0ADDR

     intc_clearvectaddr();     

     // clear pending bit 

     EXT_INT_2_PEND |= 1<<0|1<<1|1<<2|1<<3;          EXT_INT_3_PEND |= 1<<0|1<<1|1<<2|1<<3;  

}void irq_handler(void)

{

    unsigned long vicaddr[4] = {VIC0ADDR,VIC1ADDR,VIC2ADDR,VIC3ADDR};

    int i=0;

    void (*isr)(void) = NULL;    for(; i<4; i++)

    {

        if(intc_getvicirqstatus(i) != 0)

        {

            isr = (void (*)(void)) vicaddr[i];

            break;

        }

    }

    (*isr)();

}


最后,我們來總結一下中斷的設置以及處理的全過程。

首先是進入start.S(清bss,開中斷,設置時鐘,進main),然后是main(初始化串口,初始化異常向量表,初始化中斷控制器,配置GPH2和GPH3作為外部中斷引腳,配置EXT_INT2和EXT_INT3觸發下降沿中斷,取消EXT_INT2與EXT_INT3的中斷屏蔽,設置該外部中斷源的處理函數入口,使能該中斷源的中斷,死循環不斷打印數字)。


當按鍵中斷發生后,根據異常向量表,程序會自動跳轉到IRQ_handle(在start.S內)處執行,IRQ_handle先進行了現場保護,然后跳轉到irq_handler,irq_handler首先是遍歷四個中斷組,看看是哪個中斷組發生了中斷,然后就跳轉到該中斷組的中斷服務程序里(前面已經說到,isr_key作為按鍵中斷服務程序的入口已根據中斷號存入VICxINTADDRn中,而發生中斷的同時,硬件會將中斷源的服務程序入口自動搬移到它所屬的中斷組的VICxINTADDR里),從而間接地運行了isr_key這個程序,在這個程序里,我們做了分析,找出了觸發中斷的具體按鍵,并通過串口打印出來。


關鍵字:smart210  s5pv210  中斷體系 引用地址:[smart210] s5pv210的中斷體系

上一篇:S5PV210刷機
下一篇:[smart210] 定時器與PWM

推薦閱讀最新更新時間:2025-05-21 20:27

[smart210] Nand Flash K9F4G08U0B 的配置與讀寫控制(一)
平臺:smart210 CPU:s5pv210 目標:控制核心板上的Nand Flash,對其進行讀寫操作,本文為基本配置篇 知識儲備:從tiny210v2核心板上我們發現,nand flash的型號是K9F4G08U0B,根據nand flash的命名規則,我們不難發現這是一塊4Gbits大小的單位地址存儲x8bits的SLC nand flash存儲器,存儲空間換算過來就是512M x 8 bits 。在相似型號K9F4G08U0A的datasheet中發現這種型號的flash具有4096個Blocks,每個Block有64個Pages,每個Pages有2048Bytes的數據,綜合起來就是 4096*64*2048 *8bi
[單片機]
[<font color='red'>smart210</font>] Nand Flash K9F4G08U0B 的配置與讀寫控制(一)
S5PV210之SPI和linux 內核3.0.8之SPI解析
SPI(serial peripheral interface)串行外圍接口,是主控制器與外設進行串口通信的接口。主要包括四條控制線,分別是SCLK(串行時鐘)、MOSI(主出從入)、MISO(主入從出)、SS(芯片選擇使能信號、低電平有效)。 先說說S5PV210的SPI的特點 1.全雙工工作 2.發送/接收的移位寄存器可以是8位/16位/32位 3.主從模式 4.發送和接收的最大頻率可達50MHz 5.支持摩托羅拉SPI協議和美國半導體總線協議 6.兩路SPI信號 支持四種工作模式: 當CPHA(同步時鐘相位)為0時,為格式A,當CPHA為1時,為格式B 當CPHA為0時,
[單片機]
<font color='red'>S5PV210</font>之SPI和linux 內核3.0.8之SPI解析
S5PV210 | 裸機蜂鳴器實驗
電路原理 電路中通過一個 NPN 的三級管控制蜂鳴器的停止與蜂鳴。 GPIO 口 GPD0_2 輸出高電平,蜂鳴器鳴叫;反之,停止鳴叫。 DATASHEET (相關寄存器設置詳解) 2.2.7 GPD0控制寄存器組 GPD0 控制寄存器組包含六組控制寄存器,分別叫做: GPD0CON , GPD0DAT , GPD0PUD , GPD0DRV , GPD0CONPDN 和 GPD0PUDPDN 。 2.2.7.1 Port Group GPD0 Control Register (GPD0CON, R/W, Address = 0xE020_00A0) 2.2.7.2 Port Group GPD0
[單片機]
<font color='red'>S5PV210</font> | 裸機蜂鳴器實驗
13.Smart210串口驅動基于12的補充
上面的12節里,已經講了2440有關串口的設置和操作。本來,2440,6410和210的串口操作應該是幾乎一樣的。在進行6410和210的設置的時候,發現在波特率的設置,6410和210的原理是一樣的,但是跟2440有點不一樣。所以下面以210為例子,說明6410和210波特率的設置。 寄存器: UBRDIV0=(int)(PCLK_PSYS/(BAUD*16)-1);//UBRDIV0保存該公式計算后的整數部分。 UBRDIV0=(int)(66000000/(115200*16)-1)=(int)(35.8-1)=(int)(34.8)=34。即取整數部分為34. //UDISLOT0=保存該公式計算后的小數部分*
[單片機]
13.Smart210串口驅動基于12的補充
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 桂东县| 赤城县| 米泉市| 察雅县| 洛浦县| 华安县| 宣城市| 博爱县| 扶绥县| 简阳市| 天柱县| 库车县| 平远县| 蛟河市| 桑日县| 遵化市| 施秉县| 灵璧县| 若尔盖县| 离岛区| 堆龙德庆县| 手游| 米林县| 朝阳市| 墨竹工卡县| 淄博市| 璧山县| 绍兴县| 尉犁县| 墨竹工卡县| 海林市| 临湘市| 永康市| 玉田县| 舒城县| 古浪县| 大理市| 天门市| 文成县| 三原县| 南宫市|