// This file for explain how to use interrupt .
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// KEY DEVICE MAJOR
#define SIMPLE_INT_MAJOR 98
//#define SIMPLE_INT_IRQ MAINSTONE_USIM_IRQ
//key
#define SIMPLE_INT_IRQ MAINSTONE_PEN_IRQ
//int 166
//#define OURS_KEY_DEBUG
//static long *ioremap_addr;
#define VERSION "PXA270RP_int-V1.00-090224"
static int SimpleINT_temp_count = 0;
DECLARE_WAIT_QUEUE_HEAD (wq);
struct key_dev
{
struct cdev cdev;
unsigned char value;
};
struct key_dev *key_devp;
static int key_major=SIMPLE_INT_MAJOR;
void showversion(void)
{
printk("*********************************************\n");
printk("\t %s \t\n", VERSION);
printk("*********************************************\n\n");
}
// ------------------- READ ------------------------
ssize_t SIMPLE_INT_read (struct file * file ,char * buf, size_t count, loff_t * f_ops)
{
int tmp[0];
#ifdef OURS_KEY_DEBUG
printk ("SIMPLE_INT_read [ --kernel--]\n");
#endif
interruptible_sleep_on(&wq);
SimpleINT_temp_count++;
printk("Now interrupt %d occur.......................!!!\n",SimpleINT_temp_count);
tmp[0]=SimpleINT_temp_count;
// tmp[0] +=1;
copy_to_user(buf,tmp,1);
return count;
}
// ------------------- WRITE -----------------------
ssize_t SIMPLE_INT_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops)
{
#ifdef OURS_KEY_DEBUG
printk ("SIMPLE_INT_write [ --kernel--]\n");
#endif
return count;
}
// ------------------- IOCTL -----------------------
ssize_t SIMPLE_INT_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, unsigned long data)
{
#ifdef OURS_KEY_DEBUG
printk ("SIMPLE_INT_ioctl [ --kernel--]\n");
#endif
return 0;
}
// ------------------- OPEN ------------------------
ssize_t SIMPLE_INT_open (struct inode * inode ,struct file * file)
{
#ifdef OURS_KEY_DEBUG
printk ("SIMPLE_INT_open [ --kernel--]\n");
#endif
return 0;
}
// ------------------- RELEASE/CLOSE ---------------
ssize_t SIMPLE_INT_release (struct inode * inode ,struct file * file)
{
#ifdef OURS_KEY_DEBUG
printk ("SIMPLE_INT_release [ --kernel--]\n");
#endif
// free_irq(SIMPLE_INT_IRQ,NULL);
// disable_irq_nosync(SIMPLE_INT_IRQ);
cdev_del(&key_devp->cdev);
kfree(key_devp);
unregister_chrdev_region(MKDEV(key_major,0),1);
return 0;
}
static irqreturn_t SIMPLE_INT_interrupt(int nr, void *devid, struct pt_regs *regs)
{
// SimpleINT_temp_count++;
//printk("Now interrupt %d occur.......................!!!\n",SimpleINT_temp_count);
wake_up_interruptible(&wq);
return IRQ_HANDLED;
}
// -------------------------------------------------
struct file_operations key_fops ={
.open= SIMPLE_INT_open,
.read= SIMPLE_INT_read,
.write= SIMPLE_INT_write,
.ioctl= SIMPLE_INT_ioctl,
.release= SIMPLE_INT_release,
};
static void key_setup_cdev(struct key_dev *dev,int index)
{
int err, devno=MKDEV(key_major,index);
cdev_init(&dev->cdev,&key_fops);
dev->cdev.owner=THIS_MODULE;
dev->cdev.ops=&key_fops;
err=cdev_add(&dev->cdev,devno,1);
if(err)
printk(KERN_NOTICE "Error %d adding key%d",err,index);
}
// ------------------- INIT ------------------------
static int key_init(void)
{
int result;
dev_t dev=MKDEV(key_major,0);
if(key_major)
result=register_chrdev_region(dev,1,"int_ctl");
else
{
result=alloc_chrdev_region(&dev,0,1,"int_ctl");
key_major=MAJOR(dev);
}
if(result<0)
return result;
key_devp =kmalloc (sizeof(struct key_dev),GFP_KERNEL);
if (!key_devp)
{ result= - ENOMEM;
goto fail_malloc;
}
memset(key_devp,0,sizeof(struct key_dev));
key_setup_cdev(key_devp,0);
printk("key_init\n");
showversion();
return 0;
fail_malloc: unregister_chrdev_region(dev,1);
return result;
}
static int __init pxa270_KEY_CTL_init(void)
{
int ret = -ENODEV;
#ifdef OURS_KEY_DEBUG
printk ("pxa270_KEY_CTL_init [ --kernel--]\n");
#endif
key_init();
ret=request_irq(SIMPLE_INT_IRQ, SIMPLE_INT_interrupt, SA_INTERRUPT, "int_ctl", NULL);
if(ret){
printk("IRQ:could not register interrupt\n");
}
/*
#ifdef CONFIG_DEVFS_FS
devfs_mk_cdev(MKDEV(key_major,0)S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP,"key");
#endif
*/
return 0;
}
static void __exit cleanup_KEY_ctl(void)
{
#ifdef OURS_KEY_DEBUG
printk ("cleanup_INT_ctl [ --kernel--]\n");
#endif
free_irq(SIMPLE_INT_IRQ,NULL);
cdev_del(&key_devp->cdev);
kfree(key_devp);
unregister_chrdev_region(MKDEV(key_major,0),1);
printk("key_cleanup\n");
}
MODULE_DESCRIPTION("simple int driver module");
MODULE_AUTHOR("guliangzeng");
MODULE_LICENSE("GPL");
module_init(pxa270_KEY_CTL_init);
module_exit(cleanup_KEY_ctl);
#include
#include
#include
#include // open() close()
#include // read() write()
#define DEVICE_NAME "/dev/int_ctl"
//------------------------------------- main ----------------------------------------------------------------
int main(void)
{
int fd;
int fd1;
int ret;
int i;
char tmp[30];
char buf[1];
printf("\nstart KEY test\n");
printf ("\nYou may use \" Ctrl + c\" to quit the function\n");
printf("\nPress KEY on the board and you will see how many interrupt occured\n\n");
fd = open(DEVICE_NAME, O_RDWR);
fd1= open("/dev/tty1",O_RDWR);
printf("fd = %d\n",fd);
if (fd == -1)
{
printf("open device %s error\n",DEVICE_NAME);
}
else
{
while(1)
{
read(fd,buf,1);
sprintf(tmp,"now interrupt %d occur\n",buf[0]);
write(fd1,tmp,strlen(tmp));
}
ret = close(fd);
printf ("ret=%d\n",ret);
printf ("close interrupt driver test\n");
}
return 0;
}// end main
阅读(777) | 评论(0) | 转发(0) |