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
非中断方式使用私有定时器
#include <stdio.h>
#include "xscutimer.h"
#include "xparameters.h" //1s
#define loadValue XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ / 2 -1 int main()
{
int Status;
int timerCounterValue;
int counter = ;
//--------------------------------------------
//instance Timer & TimerConfig
XScuTimer PriTimer;
XScuTimer_Config *Timer_Config;
//--------------------------------------------
//LookupConfig
Timer_Config = XScuTimer_LookupConfig(XPAR_PS7_SCUTIMER_0_DEVICE_ID);
//initialize Timer
Status = XScuTimer_CfgInitialize(&PriTimer, Timer_Config,
Timer_Config->BaseAddr);
//set counter value
XScuTimer_LoadTimer(&PriTimer, loadValue);
//Disable Auto Reload
XScuTimer_DisableAutoReload(&PriTimer);
//start
XScuTimer_Start(&PriTimer);
//-----------------------------------------------------------------------------
while(counter<=)
{
//get counter value
timerCounterValue = XScuTimer_GetCounterValue(&PriTimer);
if (timerCounterValue == )
{
//restart
XScuTimer_RestartTimer(&PriTimer);
xil_printf("Timer has reached zero %d times\n\r", counter++);
}
else
{
// xil_printf("Timer is still running (Timer value = %d)\n\r",
// timerCounterValue);
}
}
return ;
}
中断方式使用私有定时器
在sdk中有例程可以参考。
大概流程是:
- 定义私有定时器和中断控制器的结构体
- 初始化私有定时器和终端控制器,以及私有定时器自检
- ARM异常处理初始化,连接系统中断处理程序
- 连接私有定时器中断程序
- 使能GIC、使能定时器中断、使能ARM中断
- 配置重载、计数器初值,然后开始定时器,等中断
- 废弃这个定时器,通知处理器、通知GIC废弃
code:
#include <stdio.h>
#include "xscutimer.h"
#include "xparameters.h"
#include "xscugic.h" #define INTRCOUNTER 10 // -------------- function Prototypes -------------------------
static void TimerInterruptHandler(void *CallBackRef);
//--------------------------------------------------------- int InterruptCounter = ; int main()
{
int Status;
//Structure Definition
XScuTimer TimerInstance;
XScuTimer_Config *TimerConfigPtr;
XScuGic GicInstance;
XScuGic_Config *GicConfigPtr; //initialize
GicConfigPtr = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID);
Status = XScuGic_CfgInitialize(&GicInstance, GicConfigPtr,
GicConfigPtr->CpuBaseAddress);
TimerConfigPtr = XScuTimer_LookupConfig(XPAR_PS7_SCUTIMER_0_DEVICE_ID);
Status = XScuTimer_CfgInitialize(&TimerInstance, TimerConfigPtr,
TimerConfigPtr->BaseAddr);
//self-test
// Status = XScuTimer_SelfTest(TimerInstance);
// if (Status != XST_SUCCESS) {
// return XST_FAILURE;
// } //initialize & Connect Interrupt Controller
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler, &GicInstance); //Connect Private Timer Interrupt Handler
Status = XScuGic_Connect(&GicInstance, XPAR_SCUTIMER_INTR,
(Xil_ExceptionHandler)TimerInterruptHandler, (void *)&TimerInstance); // Enable the interrupt for the device
XScuGic_Enable(&GicInstance, XPAR_SCUTIMER_INTR);
// Enable the timer interrupts for timer mode
XScuTimer_EnableInterrupt(&TimerInstance);
// Enable interrupts in the Processor,Enable the IRQ exception
Xil_ExceptionEnable(); //Load the timer counter register.
XScuTimer_LoadTimer(&TimerInstance, XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ / );
//Enable Auto Reload
XScuTimer_EnableAutoReload(&TimerInstance);
//Start the timer counter and then wait for it to timeout a number of times.
XScuTimer_Start(&TimerInstance); while()
{
/*
* Wait for the first timer counter to expire as indicated by
* the shared variable which the handler will increment.
*/
if (InterruptCounter >= INTRCOUNTER)
{
break;
}
} xil_printf("break loop\n\r"); //Disable the IRQ exception
Xil_ExceptionDisable();
//Disconnect and disable the interrupt for the Timer.
XScuGic_Disconnect(&GicInstance, XPAR_SCUTIMER_INTR); return ;
} static void TimerInterruptHandler(void *CallBackRef)
{
XScuTimer *TimerIntancePtr = (XScuTimer *) CallBackRef; if (XScuTimer_IsExpired(TimerIntancePtr))
{
// Clear the interrupt flag in the timer
XScuTimer_ClearInterruptStatus(TimerIntancePtr);
xil_printf("count %d times\n\r",InterruptCounter++); if (InterruptCounter >= INTRCOUNTER)
{
XScuTimer_DisableAutoReload(TimerIntancePtr);
}
}
}
//**************2018/11/15****************************
封装
#include <stdio.h>
#include "xscutimer.h"
#include "xparameters.h"
#include "xscugic.h" //timer info
#define TIMER_DEVICE_ID XPAR_PS7_SCUTIMER_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
#define INTRCOUNTER 10
#define TIMER_IRPT_INTR XPAR_SCUTIMER_INTR
#define TIMERLOADVALUE XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ / 2 -1 static XScuGic Intc;
static XScuTimer Timer;
static int IntrCounter=; // -------------- function Prototypes -------------------------
static void TimerIntrHandler(void *CallBackRef);
void SetupTimerIntrSys(XScuGic *GicInstancePtr,
XScuTimer *TimerInstancePtr);
void DisableTimerIntrSys(XScuGic *IntcInstancePtr,
u16 TimerIntrId);
//--------------------------------------------------------- int main()
{
xil_printf("--- start ----\n"); //setup the timer interrupt
SetupTimerIntrSys(&Intc, &Timer); //Load the timer counter register.
XScuTimer_LoadTimer(&Timer, TIMERLOADVALUE);
//Enable Auto Reload
XScuTimer_EnableAutoReload(&Timer);
//Start the timer counter
XScuTimer_Start(&Timer); while(){
if (IntrCounter == INTRCOUNTER) {
XScuTimer_Stop(&Timer);
break;
}
}; xil_printf("break loop\n\r"); DisableTimerIntrSys(&Intc, TIMER_IRPT_INTR);
xil_printf("Disabled Timer Interrupt\n\r"); return ;
} static void TimerIntrHandler(void *CallBackRef)
{
XScuTimer *TimerIntancePtr = (XScuTimer *) CallBackRef; if (XScuTimer_IsExpired(TimerIntancePtr))
{
// Clear the interrupt flag in the timer
XScuTimer_ClearInterruptStatus(TimerIntancePtr);
xil_printf("count %d times\n\r",IntrCounter++); if (IntrCounter >= INTRCOUNTER)
{
XScuTimer_DisableAutoReload(TimerIntancePtr);
}
}
} void SetupTimerIntrSys(XScuGic *GicInstancePtr,
XScuTimer *TimerInstancePtr)
{
int Status;
XScuTimer_Config *TimerConfigPtr;
XScuGic_Config *GicConfigPtr; //initialize,get config
TimerConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);
Status = XScuTimer_CfgInitialize(TimerInstancePtr, TimerConfigPtr,
TimerConfigPtr->BaseAddr);
GicConfigPtr = XScuGic_LookupConfig(INTC_DEVICE_ID);
Status = XScuGic_CfgInitialize(GicInstancePtr, GicConfigPtr,
GicConfigPtr->CpuBaseAddress); //initialize & Connect Interrupt Controller
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
GicInstancePtr); //Connect Private Timer Interrupt Handler
Status = XScuGic_Connect(GicInstancePtr, TIMER_IRPT_INTR,
(Xil_ExceptionHandler)TimerIntrHandler,
(void *)TimerInstancePtr); // Enable the interrupt for the device
XScuGic_Enable(GicInstancePtr, TIMER_IRPT_INTR);
// Enable the timer interrupts for timer mode
XScuTimer_EnableInterrupt(TimerInstancePtr);
// Enable interrupts in the Processor,Enable the IRQ exception
Xil_ExceptionEnable(); } void DisableTimerIntrSys(XScuGic *IntcInstancePtr, u16 TimerIntrId)
{
//Disable the IRQ exception
Xil_ExceptionDisable();
// Disconnect and disable the interrupt for the Timer.
XScuGic_Disconnect(IntcInstancePtr, TimerIntrId);
}
via
ug585 -- ch.7 Interrupts ch.8 Timers
https://blog.csdn.net/u014485485/article/details/79060978
ZYNQ. Interrupt(1)Private Timer的更多相关文章
- ZYNQ. Interrupt(2)SPI.AXI TIMER
Shared Peripheral Interrupts (SPI) SPI 可以接收来自PL的中断,这里使用PL模块 AXI Timer 的中断模式,并连接到CPU. AXI TIMER 定时器,内 ...
- 第十四章 ZYNQ TIMER定时器中断
上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断.每隔一秒中断一次,在中断函数里计数加1,通过串口打印输出. 本文所使用的开发板是Miz702 PC 开发环 ...
- ZYNQ笔记(4):PL触发中断
一.ZYNQ中断框图 PL到PS部分的中断经过ICD控制器分发器后同时进入CPU1 和CPU0.从下面的表格中可以看到中断向量的具体值.PL到PS部分一共有20个中断可以使用.其中4个是快速中断.剩余 ...
- ZYNQ SGI、PPI、SPI三种中断的实例(含代码)
ZYNQ中断分为3类: SGI(Software Generated Interrupts)软件中断 PPI(Private Peripheral Interrupts)私有外设中断 SPI(Shar ...
- Linux时间子系统之(十七):ARM generic timer驱动代码分析
专题文档汇总目录 Notes:ARM平台Clock/Timer架构:System counter.Timer以及两者之间关系:Per cpu timer通过CP15访问,System counter通 ...
- [原创]Zynq AXI-CDMA的使用
Xilinx 提供了3种DMA AXI-DMA AXI-CDMA AXI-VDMA 使用CDMA能够满足项目需求(MM-MM),DS文档介绍如下: The Xilinx LogiCORE™ IP AX ...
- 79.ZYNQ内部私有定时器中断
上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断.每个一秒中断一次,在中断函数里计数加1,通过串口打印输出. *本文所使用的开发板是Miz702(兼容zedbo ...
- Linux时间子系统(十七) ARM generic timer驱动代码分析
一.前言 关注ARM平台上timer driver(clocksource chip driver和clockevent chip driver)的驱动工程师应该会注意到timer硬件的演化过程.在单 ...
- Zynq-7000 FreeRTOS(二)中断:Timer中断
总结Zynq-7000 这款器件中的Timer定时器中断,为FreeRTOS中断做准备.在 ZYNQ 的纯 PS 里实现私有定时器中断. 每隔一秒中断一次, 在中断函数里计数加 1, 通过串口打印输出 ...
随机推荐
- 《LINUX内核设计与实现》第五章学习总结
一.与内核通信 系统调用:用户控件进程和硬件设备之间添加了一个中间层 系统调用的三个主要作用: 为用户空间提供了一种硬件的抽象接口 系统调用保证了系统的稳定和安全 每个进程都运行在虚拟系统中,而在用户 ...
- 剑指offer:二叉树的深度
题目描述: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 解题思路: 这道题也是递归的思路,比较简单. 做的过程中遇到的一个 ...
- Alpha 冲刺一
团队成员 051601135 岳冠宇 051604103 陈思孝 031602629 刘意晗 031602248 郑智文 031602234 王淇 会议照片 项目燃尽图 项目进展 界面(简陋) 登录界 ...
- 用友时空KSOA功能挖掘之zl_func函数
问题日常开发中,需要对界面进行控制,不符合条件时禁用某些功能菜单.例如[采购订单填制]界面,要实现供应商资质证书效期提醒功能,即近效期提醒,超效期禁止采购,如何实现呢? 分析使用KSOA新增加的zl_ ...
- javascript面向对象系列第五篇——拖拽的实现
前面的话 在之前的博客中,拖拽的实现使用了面向过程的写法.本文将以面向对象的写法来实现拖拽 写法 <style> .test{height: 50px;width: 50px;backgr ...
- linux 命令大全,我去
系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS ...
- MySQL索引类型,优化,使用数据结构
工欲善其事必先利其器 半藏说道:“若你在路途中遇到上帝,上帝也会被割伤.” 一.mysql 索引分类(默认使用B树结构)在数据库表中,对字段建立索引可以大大提高查询速度.通过善用这些索引,可以令 My ...
- 【转】如何快速识别应用MOS管,几张图片就搞定了
三极管是流控型器件,MOS管是压控型器件,两者存在相似之处.三极管机可能经常用,但MOS管你用的可能较少.对于MOS管先抛出几个问题: 如何区分P-MOS和N-MOS: 如何区分MOS的G.D.S管脚 ...
- luogu2679 [NOIp2015]子串 (dp)
设f[i][j][k][b]表示在A串第i位.这是第j组.B串第k位.i号选不选(b=0/1) 那么就有$f[i][j][k][1]=(A[i]==B[k])*(f[i-1][j-1][k][0]+f ...
- python之旅:异常处理
一 什么是异常 异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止),在python中,错误触发的异常如下 一个异常分为三部分 ...