linux 中断程序设计,linux gpio做中断源

一、linux系统介绍

Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。它主要用于基于Intel x86系列CPU的计算机上。

Linux以它的高效性和灵活性著称,Linux模块化的设计结构,使得它既能在价格昂贵的工作站上运行,也能够在廉价的PC机上实现全部的Unix特性,具有多任务、多用户的能力。Linux是在GNU公共许可权限下免费获得的,是一个符合POSIX标准的操作系统。Linux操作系统软件包不仅包括完整的Linux操作系统,而且还包括了文本编辑器、高级语言编译器等应用软件。它还包括带有多个窗口管理器的X-Windows图形用户界面,如同我们使用Windows NT一样,允许我们使用窗口、图标和菜单对系统进行操作。

二、linux启动流程

1、读取MBR的信息,启动Boot Manager ,Windows使用NTLDR作为Boot Manager,如果您的系统中安装多个版本的Windows,您就需要在NTLDR中选择您要进linux系统入的系统。Linux通常使用功能强大,配置灵活的GRUB作为Boot Manager,将在启动管理章节中向您介绍它的使用方式。

2、加载系统内核,启动init进程 ,init进程是Linux的根进程,所有的系统进程都是它的子进程。

3、init进程读取“/etc/inittab”文件中的信息,并进入预设的运行级别,按顺序运行该运行级别对应文件夹下的脚本。脚本通常以“start”参数启动,并指向一个系统中的程序。 通常情况下,“/etc/rcS.d/”目录下的启动脚本首先被执行,然后是“/etc/rcN.d/”目录。例如您设定的运行级别为3,那么它对应的启动目录为“/etc/rc3.d/”。

4、根据“/etc/rcS.d/”文件夹中对应的脚本启动Xwindow服务器“xorg”,Xwindow为Linux下的图形用户界面系统。

5、启动登录管理器,等待用户登录 ,Ubuntu系统默认使用GDM作为登录管理器,您在登录管理器界面中输入用户名和密码后,便可以登录系统。

三、Linux Zynq GPIO中断源

注册中断:对每个pin进行循环遍历for (pin_num = 0; pin_num 《 min_t(int, ZYNQ_GPIO_NR_GPIOS, (int)chip-》ngpio); pin_num++)

gpio_irq = irq_find_mapping(irq_domain, pin_num); 将GPIO号映射为Linux系统中断号。

在Linux中断系统中,一个irq_domain表示一个中断控制器,其内中断由0开始编号(尚存在疑问)

unsigned int irq_find_mapping(struct irq_domain *domain, irq_hw_number_t hwirq)

将一个中断控制器上的某个硬件中断映射为某个Linux系统中断。

[cpp] view plain copy/**

* struct irq_domain - Hardware interrupt number translaTIon object

* @link: Element in global irq_domain list.

* @name: Name of interrupt domain

* @ops: pointer to irq_domain methods

* @host_data: private data pointer for use by owner. Not touched by irq_domain

* core code.

*

* OpTIonal elements

* @of_node: Pointer to device tree nodes associated with the irq_domain. Used

* when decoding device tree interrupt specifiers.

* @gc: Pointer to a list of generic chips. There is a helper funcTIon for

* setTIng up one or more generic chips for interrupt controllers

* drivers using the generic chip library which uses this pointer.

*

* Revmap data, used internally by irq_domain

* @revmap_direct_max_irq: The largest hwirq that can be set for controllers that

* support direct mapping

* @revmap_size: Size of the linear map table @linear_revmap[]

* @revmap_tree: Radix map tree for hwirqs that don‘t fit in the linear map

* @linear_revmap: Linear table of hwirq-》virq reverse mappings

*/

struct irq_domain {

struct list_head link;

const char *name;

const struct irq_domain_ops *ops;

void *host_data;

/* Optional data */

struct device_node *of_node;

struct irq_domain_chip_generic *gc;

/* reverse map data. The linear map gets appended to the irq_domain */

irq_hw_number_t hwirq_max;

unsigned int revmap_direct_max_irq;

unsigned int revmap_size;

struct radix_tree_root revmap_tree;

unsigned int linear_revmap[];

};

revmap_direct_max_irq: 小于该值的中断,Linux中断号和硬件中断号相同,直接返回。

revmap_size: 线性反向映射(似乎要求域内IRQ从零开始,有点矛盾),小于该值的hwirq直接利用linear_revmap做查找。

否则用radix tree来查找映射。

irq_set_chip_and_handler(gpio_irq, &zynq_gpio_irqchip, handle_simple_irq);

调用irq_get_desc_lock(irq, &flags, 0);,获取irq对应的irq_desc。并设定irq_desc的chip:desc-》irq_data.chip = chip;

调用irq_reserve_irq(irq);,将allocated_irqs中断位图中相应的中断标识为已占用。

调用__irq_set_handler,将irq_desc中的handle_irq设定:desc-》handle_irq = handle;

irq_set_chip_data(gpio_irq, (void *)gpio);

这个比较简单,将要用私有的变量关联到irq,desc-》irq_data.chip_data = data;

set_irq_flags(gpio_irq, IRQF_VALID);

总体调用:

irq_set_handler_data(irq_num, (void *)gpio);

这里的irq_num是通过irq_num = platform_get_irq(pdev, 0);获取的系统配置文件里面的irq配置。这个函数也简单,实质为:desc-》irq_data.handler_data = data;

irq_set_chained_handler(irq_num, zynq_gpio_irqhandler);

这个函数实质为:desc-》handle_irq = handle;

最终调用关系为:调用zynq_gpio_irqhandler,然后在该函数中通过调用generic_handle_irq来调用最终的handle_simple_irq。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值