要写pxa270上的GPIO中断,迟迟没有进展,无奈,从基础开始,先连个按键做简单的中断,但是因为中断号方面的问题,始终看不出效果,没办法,先做个简单的GPIO驱动吧,就让GPIO9号引脚隔两秒变成低电平,再隔两秒变成高电平,很快实现。
没什么难度,就是终于有一点可视的效果了(示波器),记录结果,做个基础的滚回点吧。代码如下:
(1)驱动程序irq_driver.c
#include<linux/config.h>
#include<linux/module.h>
#include<linux/devfs_fs_kernel.h>
#include<linux/interrupt.h>
#include<linux/kernel.h>
#include<linux/fs.h>
#include<linux/init.h>
#include<linux/unistd.h>
#include<linux/signal.h>
#include<linux/jiffies.h>
#include<asm/param.h>
#include<linux/miscdevice.h>
#include<linux/sched.h>
#include<linux/delay.h>
#include<linux/poll.h>
#include<linux/spinlock.h>
#include<linux/delay.h>
#include<asm/system.h>
#include<asm/hardware.h>
#include<asm/arch/pxa-regs.h>
#include<asm/arch/irqs.h>
#define DEVICE_NAME "irq_270"
#define IRQ_MAJOR 0
staticint irq_major=IRQ_MAJOR;
staticvoid GPIO_init()
{
GPDR0|=(0x1<<9); //GPIO第9位置,表输出
GPSR0|=(0x1<<9); //置高
printk("GPIO_init ok!\n");
}
staticvoid GPIO_low()
{
GPCR0|=(0x1<<9);
}
staticvoid GPIO_heigh()
{
GPSR0|=(0x1<<9);
}
staticint irq_open(struct inode *inode ,struct file *file)
{
printk(DEVICE_NAME"open success!\n");
return 0;
}
staticint irq_release(struct inode *inode ,struct file *filp)
{
printk(DEVICE_NAME "release!\n");
return 0;
}
static ssize_t irq_read(struct file *filp, char *buff, size_t count, loff_t *ppos)
{
printk("user read data from driver\n");
return count;
}
staticint gpio_ioctl(struct inode *inode,struct file *file,unsignedint cmd,unsignedlong arg)
{
switch(cmd){
case 0:
{
GPIO_low();
printk("GPIO to low level!\n");
}break;
case 1:
{
GPIO_heigh();
printk("GPIO to high level!\n");
}break;
default:
printk("error cmd number\n");break;
}
return 0;
}
staticstruct file_operations irq_fops={
owner: THIS_MODULE,
read: irq_read,
ioctl: gpio_ioctl,
open: irq_open,
release: irq_release,
};
staticint __init irq_init(void)
{
int ret=-1;
int flags;
ret=register_chrdev(irq_major,DEVICE_NAME,&irq_fops);
if(ret<0)
{
printk("pxa270:init_irq failed with %d.\n[--kernel--]",ret);
return ret;
}
GPIO_init();
printk(DEVICE_NAME "initialized\n");
return 0;
}
staticvoid __exit irq_exi(void)
{
unregister_chrdev(irq_major,"GPIO9");
printk(DEVICE_NAME "unload!\n");
}
module_init(irq_init);
module_exit(irq_exi);
MODULE_DESCRIPTION("IRQ module");
MODULE_LICENSE("GPL");
(2)测试程序irq_test.c
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/ioctl.h>
int main()
{
int fd;
int r_buf[1024];
fd=open("/dev/irq",O_RDONLY);
if(fd !=-1);
else
printf("Device open failure!\n");
while(1)
{
ioctl(fd,0,NULL);
sleep(2);
ioctl(fd,1,NULL);
sleep(2);
}
close(fd);
return 0;
}
(3)Makefile文件
PWD=$(shell pwd)
KERNEL:= /up-techpxa270/kernel/linux-2.6.9
obj-m := irq_driver.o
module-objs:=irq_driver.o
all:
$(MAKE) -C$(KERNEL) M=$(PWD) modules
clean:
rm *.mod.c
rm *.ko
rm *.o
运行:
insmod irq_driver.ko
mknod /dev/irq c 253 0
./test
卸载:
rmmod irq_driver.ko
rm /dev/irq