zoukankan      html  css  js  c++  java
  • ZYNQ. Interrupt(1)Private Timer

    Interrupt

    zynq的中断。 

    The PS is based on ARM architecture, utilizing two Cortex-A9 processors(CPUs) and the GIC pl390 interrupt controller.

     

    Each CPU has a set of private peripheral interrupts (PPIs).

    The PPIs include the global timer, private watchdog timer, private timer, and FIQ/IRQ from the PL.

    The SGIs are generated by writing to the registers in the generic interrupt controller (GIC)

    The shared peripheral interrupts (SPIs) are generated by the various I/O and memory controllers in the PS and PL.

    Software Generated Interrupts (SGI)

    软中断

    CPU Private Peripheral Interrupt (PPI)

    私有外设中断包括有:全局定时器、私有定时器,私有看门狗定时器以及来自PL的FIQ/IRQ。

    FIQ和IRQ是反向的,然后送到中断控制器(GIC) ,他们在PS-PL接口中为高电平触发,尽管在ICDICFR1寄存器中反映为低电平触发。

    Note that the fast interrupt (FIQ) signal and the interrupt (IRQ) signal from the PL are inverted and then sent to the interrupt
    controller. Therefore, they are active High at the PS-PL interface, although the ICDICFR1 register reflects them as active Low level.

    Shared Peripheral Interrupts (SPI)

     一组大约60个中断,来自各个模块。

    CPU Private Timer

    特性:

    • 32位计数器,到零产生中断 
    • 8位预分频器,能够好的控制中断周期
    • 可配置单次或自动重载模式
    • 可配置计数器初始值

    私有中断硬件系统

    只要添加一个ZYNQ核就可以使用。

    软件部分

    xilinx sdk 提供了两个库函数:

    • 定时器  xscutimer.h
    • 中断     xscugic.h

    非中断方式使用私有定时器

     1 #include <stdio.h>
     2 #include "xscutimer.h"
     3 #include "xparameters.h"
     4 
     5 //1s
     6 #define loadValue XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ / 2 -1
     7 
     8 int main()
     9 {
    10     int Status;
    11     int timerCounterValue;
    12     int counter = 0;
    13 //--------------------------------------------
    14     //instance Timer & TimerConfig
    15     XScuTimer PriTimer;
    16     XScuTimer_Config *Timer_Config;
    17 //--------------------------------------------
    18     //LookupConfig
    19     Timer_Config = XScuTimer_LookupConfig(XPAR_PS7_SCUTIMER_0_DEVICE_ID);
    20     //initialize Timer
    21     Status = XScuTimer_CfgInitialize(&PriTimer, Timer_Config,
    22             Timer_Config->BaseAddr);
    23     //set counter value
    24     XScuTimer_LoadTimer(&PriTimer, loadValue);
    25     //Disable Auto Reload
    26     XScuTimer_DisableAutoReload(&PriTimer);
    27     //start
    28     XScuTimer_Start(&PriTimer);
    29 //-----------------------------------------------------------------------------
    30     while(counter<=10)
    31     {
    32         //get counter value
    33         timerCounterValue = XScuTimer_GetCounterValue(&PriTimer);
    34         if (timerCounterValue == 0)
    35         {
    36             //restart
    37             XScuTimer_RestartTimer(&PriTimer);
    38             xil_printf("Timer has reached zero %d times
    
    ", counter++);
    39         }
    40         else
    41         {
    42 //            xil_printf("Timer is still running (Timer value = %d)
    
    ",
    43 //                    timerCounterValue);
    44         }
    45     }
    46     return 0;
    47 }

    中断方式使用私有定时器

     在sdk中有例程可以参考。

    大概流程是:

    1. 定义私有定时器和中断控制器的结构体
    2. 初始化私有定时器和终端控制器,以及私有定时器自检
    3. ARM异常处理初始化,连接系统中断处理程序
    4. 连接私有定时器中断程序
    5. 使能GIC、使能定时器中断、使能ARM中断
    6. 配置重载、计数器初值,然后开始定时器,等中断
    7. 废弃这个定时器,通知处理器、通知GIC废弃

    code:

     1 #include <stdio.h>
     2 #include "xscutimer.h"
     3 #include "xparameters.h"
     4 #include "xscugic.h"
     5 
     6 
     7 #define INTRCOUNTER 10
     8 
     9 // -------------- function Prototypes -------------------------
    10 static void TimerInterruptHandler(void *CallBackRef);
    11 //---------------------------------------------------------
    12 
    13 int InterruptCounter = 0;
    14 
    15 int main()
    16 {
    17     int Status;
    18     //Structure Definition
    19     XScuTimer TimerInstance;
    20     XScuTimer_Config *TimerConfigPtr;
    21     XScuGic GicInstance;
    22     XScuGic_Config *GicConfigPtr;
    23 
    24     //initialize
    25     GicConfigPtr = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID);
    26     Status = XScuGic_CfgInitialize(&GicInstance, GicConfigPtr,
    27             GicConfigPtr->CpuBaseAddress);
    28     TimerConfigPtr = XScuTimer_LookupConfig(XPAR_PS7_SCUTIMER_0_DEVICE_ID);
    29     Status = XScuTimer_CfgInitialize(&TimerInstance, TimerConfigPtr,
    30             TimerConfigPtr->BaseAddr);
    31     //self-test
    32 //    Status = XScuTimer_SelfTest(TimerInstance);
    33 //    if (Status != XST_SUCCESS) {
    34 //        return XST_FAILURE;
    35 //    }
    36 
    37     //initialize & Connect Interrupt Controller
    38     Xil_ExceptionInit();
    39     Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
    40             (Xil_ExceptionHandler)XScuGic_InterruptHandler, &GicInstance);
    41 
    42     //Connect Private Timer Interrupt Handler
    43     Status = XScuGic_Connect(&GicInstance, XPAR_SCUTIMER_INTR,
    44             (Xil_ExceptionHandler)TimerInterruptHandler, (void *)&TimerInstance);
    45 
    46     // Enable the interrupt for the device
    47     XScuGic_Enable(&GicInstance, XPAR_SCUTIMER_INTR);
    48     // Enable the timer interrupts for timer mode
    49     XScuTimer_EnableInterrupt(&TimerInstance);
    50     // Enable interrupts in the Processor,Enable the IRQ exception
    51     Xil_ExceptionEnable();
    52 
    53     //Load the timer counter register.
    54     XScuTimer_LoadTimer(&TimerInstance, XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ / 2);
    55     //Enable Auto Reload
    56     XScuTimer_EnableAutoReload(&TimerInstance);
    57     //Start the timer counter and then wait for it to timeout a number of times.
    58     XScuTimer_Start(&TimerInstance);
    59 
    60     while(1)
    61     {
    62         /*
    63          * Wait for the first timer counter to expire as indicated by
    64          * the shared variable which the handler will increment.
    65          */
    66         if (InterruptCounter >= INTRCOUNTER)
    67         {
    68             break;
    69         }
    70     }
    71 
    72     xil_printf("break loop
    
    ");
    73 
    74     //Disable the IRQ exception
    75     Xil_ExceptionDisable();
    76     //Disconnect and disable the interrupt for the Timer.
    77     XScuGic_Disconnect(&GicInstance, XPAR_SCUTIMER_INTR);
    78 
    79     return 0;
    80 }
    81 
    82 
    83 static void TimerInterruptHandler(void *CallBackRef)
    84 {
    85     XScuTimer *TimerIntancePtr = (XScuTimer *) CallBackRef;
    86 
    87     if (XScuTimer_IsExpired(TimerIntancePtr))
    88     {
    89         // Clear the interrupt flag in the timer
    90         XScuTimer_ClearInterruptStatus(TimerIntancePtr);
    91         xil_printf("count %d times
    
    ",InterruptCounter++);
    92 
    93         if (InterruptCounter >= INTRCOUNTER)
    94         {
    95             XScuTimer_DisableAutoReload(TimerIntancePtr);
    96         }
    97     }
    98 }

    //**************2018/11/15****************************

    封装

      1 #include <stdio.h>
      2 #include "xscutimer.h"
      3 #include "xparameters.h"
      4 #include "xscugic.h"
      5 
      6 //timer info
      7 #define TIMER_DEVICE_ID XPAR_PS7_SCUTIMER_0_DEVICE_ID
      8 #define INTC_DEVICE_ID  XPAR_PS7_SCUGIC_0_DEVICE_ID
      9 #define INTRCOUNTER     10
     10 #define TIMER_IRPT_INTR        XPAR_SCUTIMER_INTR
     11 #define TIMERLOADVALUE  XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ / 2 -1
     12 
     13 static XScuGic Intc;
     14 static XScuTimer Timer;
     15 static int IntrCounter=0;
     16 
     17 // -------------- function Prototypes -------------------------
     18 static void TimerIntrHandler(void *CallBackRef);
     19 void SetupTimerIntrSys(XScuGic *GicInstancePtr,
     20         XScuTimer *TimerInstancePtr);
     21 void DisableTimerIntrSys(XScuGic *IntcInstancePtr,
     22         u16 TimerIntrId);
     23 //---------------------------------------------------------
     24 
     25 int main()
     26 {
     27     xil_printf("--- start ----
    ");
     28 
     29     //setup the timer interrupt
     30     SetupTimerIntrSys(&Intc, &Timer);
     31 
     32     //Load the timer counter register.
     33     XScuTimer_LoadTimer(&Timer, TIMERLOADVALUE);
     34     //Enable Auto Reload
     35     XScuTimer_EnableAutoReload(&Timer);
     36     //Start the timer counter
     37     XScuTimer_Start(&Timer);
     38 
     39     while(1){
     40         if (IntrCounter == INTRCOUNTER) {
     41             XScuTimer_Stop(&Timer);
     42             break;
     43         }
     44     };
     45 
     46     xil_printf("break loop
    
    ");
     47 
     48     DisableTimerIntrSys(&Intc, TIMER_IRPT_INTR);
     49     xil_printf("Disabled Timer Interrupt
    
    ");
     50 
     51     return 0;
     52 }
     53 
     54 
     55 static void TimerIntrHandler(void *CallBackRef)
     56 {
     57     XScuTimer *TimerIntancePtr = (XScuTimer *) CallBackRef;
     58 
     59     if (XScuTimer_IsExpired(TimerIntancePtr))
     60     {
     61         // Clear the interrupt flag in the timer
     62         XScuTimer_ClearInterruptStatus(TimerIntancePtr);
     63         xil_printf("count %d times
    
    ",IntrCounter++);
     64 
     65         if (IntrCounter >= INTRCOUNTER)
     66         {
     67             XScuTimer_DisableAutoReload(TimerIntancePtr);
     68         }
     69     }
     70 }
     71 
     72 void SetupTimerIntrSys(XScuGic *GicInstancePtr,
     73         XScuTimer *TimerInstancePtr)
     74 {
     75     int Status;
     76     XScuTimer_Config *TimerConfigPtr;
     77     XScuGic_Config *GicConfigPtr;
     78 
     79     //initialize,get config
     80     TimerConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);
     81     Status = XScuTimer_CfgInitialize(TimerInstancePtr, TimerConfigPtr,
     82             TimerConfigPtr->BaseAddr);
     83     GicConfigPtr = XScuGic_LookupConfig(INTC_DEVICE_ID);
     84     Status = XScuGic_CfgInitialize(GicInstancePtr, GicConfigPtr,
     85             GicConfigPtr->CpuBaseAddress);
     86 
     87 
     88     //initialize & Connect Interrupt Controller
     89     Xil_ExceptionInit();
     90     Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
     91             (Xil_ExceptionHandler)XScuGic_InterruptHandler,
     92             GicInstancePtr);
     93 
     94     //Connect Private Timer Interrupt Handler
     95     Status = XScuGic_Connect(GicInstancePtr, TIMER_IRPT_INTR,
     96             (Xil_ExceptionHandler)TimerIntrHandler,
     97             (void *)TimerInstancePtr);
     98 
     99     // Enable the interrupt for the device
    100     XScuGic_Enable(GicInstancePtr, TIMER_IRPT_INTR);
    101     // Enable the timer interrupts for timer mode
    102     XScuTimer_EnableInterrupt(TimerInstancePtr);
    103     // Enable interrupts in the Processor,Enable the IRQ exception
    104     Xil_ExceptionEnable();
    105 
    106 }
    107 
    108 void DisableTimerIntrSys(XScuGic *IntcInstancePtr, u16 TimerIntrId)
    109 {
    110     //Disable the IRQ exception
    111     Xil_ExceptionDisable();
    112     // Disconnect and disable the interrupt for the Timer.
    113     XScuGic_Disconnect(IntcInstancePtr, TimerIntrId);
    114 }

    via

    ug585 -- ch.7 Interrupts ch.8 Timers

    https://blog.csdn.net/u014485485/article/details/79060978

  • 相关阅读:
    Java学习的第五十一天
    Java学习的第五十四天
    Java学习的第五十天
    Java学习的第五十三天
    Java学习的第五十二天
    Java学习的第四十九天
    构造函数
    封 装
    JAVA学习日报 10/8
    JAVA学习日报 10.11
  • 原文地址:https://www.cnblogs.com/protogenoi/p/9962330.html
Copyright © 2011-2022 走看看