本文主要描述了GPIO口的申请和高低电平输出、输入,以及中断的申请和调用等
Linux Kernel 中使用GPIO,不能直接引用和操作GPIO的物理地址,而需要把物理地址映射为内存中的虚拟地址,然后对映射的虚拟地址进行操作。
大致情况是这样的,以下通过实际代码分析linux GPIO的简单的驱动分析。
一、一种情况的GPIO驱动和IRQ中断服务申请
1.1、源码实例:
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <plat/regs-serial.h>
#include "samsung.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-bank.h>
#include <plat/s5pv210.h>
#include <plat/gpio-cfg.h>
#include <linux/gpio.h>
struct scan_button_irq_desc
{
int irq;
int pin;
int pin_setting;
// int number;
char *name;
};
static struct scan_button_irq_desc scan_button_irq[] =
{
{IRQ_EINT7,S5PV210_GPH0(7),IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"scan_trig"},
};
static irqreturn_t s3c_gpio_scan_isr(int irq,void* dev_id)
{
unsigned int key_status;
u32 cfg;
//void __iomem *base = S5PV210_GPG1DAT;
cfg = readl(S5PV210_GPG1CON);
cfg &= (0xf<<20); //clear gpg1_5 con
cfg |= (1 << 20); //out put cfg
writel(cfg,S5PV210_GPG1CON);
printk("scanmodule pwr ctrl con: %d",readl(S5PV210_GPG1CON));
cfg = readl(S5PV210_GPG1DAT);
cfg |= (1 << 5);
writel(cfg,S5PV210_GPG1DAT);
printk("scanmodule pwr ctrl dat: %d",readl(S5PV210_GPG1DAT));
key_status = (readl(S5PV210_GPH0DAT)) & (1 << 7);
printk("scan_button,keyval:%d : %s\n", GPIO_KEY, key_status?"released":"pressed");
return IRQ_HANDLED;
}
static int s3c_gpio_scan_isr_setup(void)
{
int ret;
~~~~
s3c_gpio_cfgpin(S5PV210_GPH0(7), S3C_GPIO_SPECIAL(0xf)); //配置gpio为中断输出,Eint7
s3c_gpio_setpull(S5PV210_GPH0(7), S3C_GPIO_PULL_UP); //S3C_GPIO_PULL_NONE
set_irq_wake(scan_button_irq[0].irq, 1);
ret = request_irq(scan_button_irq[0].irq, s3c_gpio_scan_isr,
IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING,
scan_button_irq[0].name, (void *)&scan_button_irq);
if (ret) {
printk("request IRQ for scan triger failed\n");
ret = -EIO;
}
~~~~
return ret;
}
static int __init XXX_init(void)
{
~~~~
//中断申请
ret = s3c_gpio_scan_isr_setup();
if(!ret)
printk("IRQ request successfully\n");
else
printk("IRQ request failed");
~~~~
return 0;
}
static void __exit XXX_exit(void)
{
~~~~
//IRQ srv free
free_irq(scan_button_irq[0].irq,(void *)&scan_button_irq);
~~~~
}
1.2、中断申请函数原型及分析:
1.2.1、原型
int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *,struct pt_regs *),unsigned long flags, const char *dev_name, void *dev_id);
void free_irq(unsigned int irq, void *dev_id);
1.2.2、分析
1)、unsigned int irq:所要注册的中断号
2)、irqreturn_t (*handler)(int, void *, struct pt_regs *):中断服务程序的入口地址。
3)、unsigned long flags:与中断管理有关的位掩码选项,有三组值:
SA_INTERRUPT : 快速中断处理程序,当使用它的是后处理器上所有的其他中断都被禁用;
SA_SHIRQ : 该中断是在设备之间可共享的;
SA_SAMPLE_RANDOM :

本文深入探讨了Linux内核中GPIO接口的使用,包括GPIO的申请、高电平和低电平输出、输入操作,以及中断的申请和处理。通过源码分析,解析了request_irq函数的各个参数及其作用,并提供了查看中断号的命令示例。同时,讨论了/proc/interrupts和/proc/stat文件在监控中断活动中的作用。
最低0.47元/天 解锁文章
4940

被折叠的 条评论
为什么被折叠?



