在最近的工程中,需要用到PS/2键盘和鼠标作为控制输入,所以在网上找了一些相关的资料,内容很丰富,看来已经有很多人做过了这方面的编程。本篇Blog算是实践总结,为以后的开发积累一些基础知识。

MicroBlaze支持重启(reset),中断( interrupt), 暂停(break)和异常(

exception)。这里粗略的介绍:

reset当

外部按键发出reset信号或者XMD通过MDM(MicroBlaze Debug

module)发出reset信号,这些信号都会被proc_sys_reset模块接收,然后该模块产生一个16周期长的高电平信号至

MicroBlaze的MB_RESET管脚。MicroBlaze响应reset, PC

寄存器指向0x0地址,依照向量表中代码执行。

exception异常是MicroBlaze对内部运行发生错误的情况发做出的响应,这些情况包括:非法指令,指令和数据总线错误和未对齐的访问(unaligned

access)。如除0操作,非法操作码异常,数据总线异常等。

breakbreak 分为software break和hardware

break。hardware

break,这时MDM模块的输出端口Ext_BRK和Ext_NM_BRK跟MicroBlaze对应的输入端口相连。一旦break响应,暂停返回地址(break

return address)自动装入R16寄存器中。而software

break通过brk和brki指令来完成。

interruptMicroBlaze

只支持一个外部中断源(连接于Interrupt

端口),所以需要多个中断输入的话,就得添加中断控制器(xps_intc)了。只有当机器状态寄存器(Machine Status

Register,MSR)中的中断使能位(interrupt

enable)置'1',MicroBlaze才能响应中断。MicroBlaze响应中断,PC指向中断向量(地址:0x10),R14存储了中断返回地址。

注:具体细节问题,请见参考1。

注:该表格来自于MicroBlaze参考手册,见参考1

下面具体介绍如何对MicroBlaze进行中断编程。

中断信号的物理连接

system.mhs文件定义了物理硬件的相关信息,包括总线架构、外围设备、处理器、系统内部信号互连和地址空间等。所以这里就通过MHS定义文件给出关于中断信号互连的信息。

当然MicroBlaze的中断输入,可以配置成电平触发或者边沿触发,在配置MicroBlaze的GUI或者在MicroBlaze.mpd中通过设置

C_INTERRUPT_IS_EDGE

,C_EDGE_IS_POSITIVE来完成对中断的触发的配置。

BEGIN microblaze

. . .PORT MB_RESET = mb_reset

PORT Interrupt =

InterruptEND

BEGIN xps_uartlite

. . . PORT Interrupt =

RS232_Uart_1_InterruptEND

BEGIN xps_intc

. . .

PORT Irq =

Interrupt PORT

Intr =

RS232_Uart_1_Interrupt&plb_ps2_controller_0_IP2INTC_IrptEND

BEGIN plb_ps2_controller

. . .

PORT IP2INTC_Irpt =

plb_ps2_controller_0_IP2INTC_IrptPORT

mouse_clk = plb_ps2_controller_0_mouse_clk

PORT mouse_data = plb_ps2_controller_0_mouse_data

PORT key_clk = plb_ps2_controller_0_key_clk

PORT key_data = plb_ps2_controller_0_key_data

END

EDK提供的驱动以及相关函数的介绍

void

microblaze_enable_interrupts(void)该函数使MicroBlaze可以响应中断,即MSR中的“interrupt

enable”位置’1’;

void

microblaze_disable_interrupts(void)该函数使MicroBlaze不能响应中断,即MSR中的“interrupt

enable”位置 ’0’;

这几个函数都定义包含在$EDK_project/microblaze_0/include/mb_interface.h头文件中

XIntc_Initialize(&InterruptController,

(Xuint16)INTC_DEVICE_ID);该函数用于初始化中断控制器,主要包括初始化XIntc的结构体,初始化向量列表,以及所有中断源输入禁用,中断输出禁用。

int XIntc_Connect(XIntc * InstancePtr, u8 Id,

XInterruptHandler Handler, void

*CallBackRef)中断源的标示和相关中断处理程序的连接。

XIntc_Start(XIntcInstancePtr,

XIN_REAL_MODE);该函数使得中断控制器输出的中断信号启用。XIN_REAL_MODE

意思是只允许硬件中断(hardware interrupt)

void XIntc_Enable(XIntc * InstancePtr, u8

Id)该函数使得对应ID的中断源输入启用

这几个函数定义在$EDK_project/microblaze_0/libsrc/intc_v1_11_a/src/xintc.c需要包含的头文件:xintc.h

C语言编程实例

#include

#include

#include "xparameters.h"

#include "xutil.h"

#include "xintc.h"

#include "plb_ps2_controller.h"

#include "mb_interface.h"

#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID

int init_input(void);

XStatus SetUpInterruptSystem(XIntc *XIntcInstancePtr);

static XIntc InterruptController;

void PS2_InterruptHandler(void *CallbackRef)

{

u32

mouse_state, keybd_state, flags;

Xuint32

baseaddr = (Xuint32) XPAR_PLB_PS2_CONTROLLER_0_BASEADDR;

keybd_state

= ((u32 *)baseaddr)[0];

mouse_state

= ((u32 *)baseaddr)[1];

flags = PLB_PS2_CONTROLLER_mReadReg(baseaddr,

PLB_PS2_CONTROLLER_INTR_IPISR_OFFSET);

if (flags

& EVENT_FROM_MOUSE)

handle_mouse_event(mouse_state);

if (flags

& EVENT_FROM_KEYBD)

handle_keybd_event(keybd_state);

PLB_PS2_CONTROLLER_mWriteReg(baseaddr,

PLB_PS2_CONTROLLER_INTR_IPISR_OFFSET, flags);

}

XStatus init_input(void)

{

XStatus

Status;

Xuint32

baseaddr = (Xuint32) XPAR_PLB_PS2_CONTROLLER_0_BASEADDR;

PLB_PS2_CONTROLLER_mWriteReg(baseaddr,

PLB_PS2_CONTROLLER_INTR_DIER_OFFSET, 0);

PLB_PS2_CONTROLLER_mWriteReg(baseaddr,

PLB_PS2_CONTROLLER_INTR_DGIER_OFFSET, 0xFFFFFFFF);

PLB_PS2_CONTROLLER_mWriteReg(baseaddr,

PLB_PS2_CONTROLLER_INTR_IPIER_OFFSET, 0xFFFFFFFF);

PLB_PS2_CONTROLLER_mWriteReg(baseaddr,

PLB_PS2_CONTROLLER_INTR_IPISR_OFFSET, 0);

Status =

XIntc_Initialize(&InterruptController,

(Xuint16)INTC_DEVICE_ID);

if (Status

!= XST_SUCCESS)

{ return

XST_FAILURE; }

Status =

XIntc_SelfTest(&InterruptController);

if (Status

!= XST_SUCCESS)

{ return

XST_FAILURE; }

Status =

XIntc_Connect(XIntcInstancePtr,

XPAR_XPS_INTC_0_PLB_PS2_CONTROLLER_0_IP2INTC_IRPT_INTR,

(XInterruptHandler)PS2_InterruptHandler,

(void *)0);

if (Status

!= XST_SUCCESS)

{ return XST_FAILURE;}

Status =

XIntc_Start(XIntcInstancePtr, XIN_REAL_MODE);

if (Status

!= XST_SUCCESS)

{

return XST_FAILURE;

}

XIntc_Enable(XIntcInstancePtr,

XPAR_XPS_INTC_0_PLB_PS2_CONTROLLER_0_IP2INTC_IRPT_INTR);

microblaze_enable_interrupts();

return

XST_SUCCESS;

}

int main(void){

init_input();

while(1);

return 1;

}

汇编代码详解

使用mb-objdump工具对实例进行了反汇编,想看看到底是个什么情况

Disassembly of section .vectors.reset:

00000000 <_start>:

0: b0009000 imm -28672

4: b8080000 brai 0 #main()程序起始地址是0x90000000

Disassembly of section .vectors.sw_exception:

00000008

<_vector_sw_exception>:

8: b0009000 imm -28672

c: b8080438 brai 1080

Disassembly of section .vectors.interrupt:

00000010 <_vector_interrupt>:

10: b0009000 imm -28672

14: b8080474 brai 1140 #中断处理程序起始地址是0x90000474

Disassembly of section .vectors.hw_exception:

00000020

<_vector_hw_exception>:

20: b0009000 imm -28672

24: b8080450 brai 1104

90000474

<__interrupt_handler>: #中断处理程序起始地址和汇编代码

90000474: 3021ffb0 addik r1, r1, -80

90000478: f9e10000 swi r15, r1, 0

9000047c: f8610020 swi r3, r1, 32

90000480: f8810024 swi r4, r1, 36

90000484: f8a10028 swi r5, r1, 40

90000488: f8c1002c swi r6, r1, 44

9000048c: f8e10030 swi r7, r1, 48

90000490: f9010034 swi r8, r1, 52

90000494: f9210038 swi r9, r1, 56

90000498: f941003c swi r10, r1, 60

9000049c: f9610040 swi r11, r1, 64

900004a0: f9810044 swi r12, r1, 68

900004a4: fa210048 swi r17, r1, 72

总结

主要描述了MicroBlaze的中断的基本原理,以及编程。

参考文献:

ps 2c语言程序,MicroBlaze中断编程——以PS/2键盘输入为例相关推荐

  1. ps 2键盘代码 c语言,MicroBlaze中断编程——以PS/2键盘输入为例

    /* *Date      2010-12-27 *author    Qi Yao *decription main function code for interrupt program *    ...

  2. ps 2c语言程序,C语言基础(二)

    ## #ifdef的形式 预处理程序提供了条件编译的功能.条件编译有三种形式,下面分别介绍. 第一种形式 第一种形式的格式为: ```#ifdef 标识符 程序段1 #else 程序段2 #endif ...

  3. 6.19 C语言练习(编程判断以从键盘输入的三个数为边长,是否能构成三角形。)

    [练习] 题目要求:编程判断以从键盘输入的三个数为边长,是否能构成三角形. #include <stdio.h>int main() {float a,b,c;printf("请 ...

  4. c语言程序实际问题,《编程解决问题之程序规划语言(c语言)》.doc

    <编程解决问题之程序规划语言(c语言)> <编程解决问题之程序设计语言(c语言)> 课程内容介绍: 本课程主要是介绍如何利用c程序设计语言,编写程序,解决实际问题.目的是提高学 ...

  5. linux 中断 应用程序,Linux中断编程

    本文转载自[微信公众号:机械猿,ID:on_ourway]经微信公众号授权转载,如需转载与原文作者联系 基本概念 中断是指CPU在执行程序时,由于内外部事件或由程序预先安排的事件,导致CPU 暂停当前 ...

  6. c语言程序第一章编程,c语言程序的设计第一章 C语言编程入门.ppt

    c语言程序的设计第一章 C语言编程入门 第1章 C语言编程入门 本章是本书的入门篇,专为初学者熟悉编程过程.掌握程序结构而准备的. 本章学习目标 ? 1)? 能够通过模仿与改变来构造带有测试函数的C语 ...

  7. matlab怎么与c语言接口,Matlab与C语言程序的应用编程接口 (2)

    三.C语言程序MEX文件实例 MATLAB 5 API提供了一系列程序来处理MATLAB所支持的各种数据类型,每一种数据类型都有对应函数共你使用来处理对应的数据.下面给出一个简单的C语言程序和与之对应 ...

  8. C语言 数据结构 图的邻接矩阵存储 基本操作(附输入样例和讲解)

    代码参照了严蔚敏.吴伟民编写的数据结构(C语言版). 部分内容参考了这位大佬: https://blog.csdn.net/jeffleo/article/details/53326648 所有代码采 ...

  9. 编写c语言程序的可视化编程环境有哪些,C语言可视化编程环境设计及实现.pdf

    T 6YR&D c语言可视化编程环境设计及实现 李丽萍 (云南经济管理职业学院 ,云南昆明 650106) 摘 要 在计算机语言的使用过程中 ,对于语言的模式采取不断深化的实施方式 ,通过不断 ...

最新文章

  1. 使用PowerShell deprovision O365 资源
  2. Android中通过ImageSwitcher实现相册滑动查看照片功能(附代码下载)
  3. tomcat占用cpu比较多
  4. VS2013中CUDA的配置
  5. sdram trp_TRP的完整形式是什么?
  6. windows 2003 iis 360防黑加固后不能使用
  7. 华为机试HJ8:合并表记录
  8. fiddler注释_FIDDLER的使用方法及技巧总结
  9. (day 53 - 动态规划 ) 剑指 Offer 63. 股票的最大利润
  10. mysql5.6跳过密码登录_mysql-配置与使用(跳过原始密码登陆)
  11. 【教学类-07-02】20220330 5以内加减法不重复题 及生成word打印docx纸(方法二)(Python VS)
  12. excel转txt后导入mysql 20211207
  13. 湘潭大学c语言大作业难过吗,C语言程序设计参考答案(湘大出版社)
  14. Shapely——基础操作汇总
  15. 网络状态测试程序(基于ping命令)
  16. HDOJ题目分类大全
  17. Web前端是什么?主要是干什么的
  18. 简明解释算法中的大O符号
  19. 怎么通过助记词登录MetaMask和通过私钥登录
  20. php汉字转拼音库,汉字转拼音的PHP库

热门文章

  1. 【OpenGL学习笔记②】——OpenGL基础【渲染管线 顶点着色器 片元着色器 VAO VBO 万字总结】
  2. 湖南师范大学 C语言考试操作题汇总。
  3. Oracle函数篇 - pivot行转列函数
  4. PHP浮点数运算精度
  5. 【饥荒mod制作吧第二篇】mod制作工具下载资源!
  6. 用美国主机空间的内容管理系统建站的优点
  7. 因误删文件导致CentOS7开机卡死无法进入图形登录界面
  8. 回归分析预测世界大学综合得分
  9. 机械阻抗法与频响分析
  10. win11关闭快速启动