- 论坛徽章:
- 0
|
我写了个简单的中断程序:
#define IRQ_ADC_FIQ AT91_PIN_PB29
#define ADS_CHANNEL_COUNT 4
#define NAME "gpiotest"
#define TS_PB29 1<<29
static struct cdev ads7852_cdev;
static int major=0;
static DECLARE_WAIT_QUEUE_HEAD(wq);
static struct semaphore sem;
static int flag = 0;
void pio_init(void)
{
((AT91PS_SYS)AT91C_VA_BASE_SYS)->PIOB_IER=TS_PB29;
((AT91PS_SYS)AT91C_VA_BASE_SYS)->PIOB_PER=TS_PB29;
((AT91PS_SYS)AT91C_VA_BASE_SYS)->PIOB_ODR=TS_PB29;
((AT91PS_SYS)AT91C_VA_BASE_SYS)->PIOB_PPUER=TS_PB29;
}
/******************************************************************************/
static irqreturn_t ads7852_int_handler(int irq, void *dev_id, struct pt_regs *reg)
{
printk(KERN_ERR"AD_DATA ch0: %x\n",data);
flag = 1;
wake_up_interruptible(&wq);
printk("Interrupted: The %u channel data: %u\n", cur_ch, data);
return IRQ_HANDLED;
}
/******************************************************************************/
static ssize_t ads7852_read(struct file *file,char *buf,
size_t count, loff_t *ppos)
{
//进入临界区
if(down_interruptible(&sem)) return -ERESTARTSYS;
//让读进程先睡觉,一直到中断发生时中断来唤醒它
printk( "process %i (%s) going to sleep\n",
current->pid, current->comm);
wait_event_interruptible(wq, flag != 0);
flag = 0;
printk("awoken %i (%s)\n", current->pid, current->comm);
up(&sem);
}
/******************************************************************************/
static ssize_t ads7852_open(struct inode *inode, struct file *file)
{
int retval= request_irq( IRQ_ADC_FIQ, ads7852_int_handler,
SA_INTERRUPT, NAME, NULL );
if(retval==0)
printk(KERN_WARNING"request_irq result success\n");
else {
if(retval==-EBUSY)
printk(KERN_WARNING"request_irq result BUSY\n");
else
printk(KERN_WARNING"request_irq result BUSYING\n");
return -EFAULT;
}
printk(KERN_WARNING"init interrupte\n");
}
/******************************************************************************/
static ssize_t ads7852_release(struct inode *inode, struct file *flip)
{
free_irq(IRQ_ADC_FIQ,NULL);
return 0;
}
/******************************************************************************/
struct file_operations ads7852_fops=
{
.owner = THIS_MODULE,
.read = ads7852_read,
.open = ads7852_open,
.release = ads7852_release
};
/******************************************************************************/
static int __init ads7852_init(void)
{
int retval = 0;
dev_t dev_id;
pio_init();
at91_set_deglitch(AT91_PIN_PB29,1);
set_irq_type(AT91_PIN_PB29,IRQT_RISING);
if(major) {
//注册主设备号
dev_id = MKDEV(major,0);
retval = register_chrdev_region( dev_id, ADS_CHANNEL_COUNT, NAME);
if(retval < 0) printk(KERN_WARNING"can't register major number\n");
} else {
//分配主设备号
retval = alloc_chrdev_region(&dev_id, 0 ,ADS_CHANNEL_COUNT, NAME);
if (retval <0 )printk(KERN_WARNING"can't alloc major number\n");
m
}
printk(KERN_WARNING"major=%d\n", major);
//向内核注册设备
cdev_init(&ads7852_cdev, &ads7852_fops);
ads7852_cdev.owner = THIS_MODULE;
ads7852_cdev.ops = &ads7852_fops;
if( cdev_add(&ads7852_cdev, dev_id, ADS_CHANNEL_COUNT) ) {
printk(KERN_WARNING"cdev_add error!\n");
}
//初始化互斥锁
init_MUTEX(&sem);
printk(KERN_WARNING"module load sucess\n");
return 0;
}
/******************************************************************************/
static void __exit ads7852_exit(void)
{
dev_t dev_id = MKDEV(major,0);
cdev_del(&ads7852_cdev);
unregister_chrdev_region(dev_id,ADS_CHANNEL_COUNT);
}
/******************************************************************************/
module_init(ads7852_init);
module_exit(ads7852_exit);
但是我发现程序运行到:
request_irq result success
init interrupte
process 828 (testgpio) going to sleep
然后程序就死在这里了,说明根本就没有唤醒中断服务程序,我仔细检查了所写的程序,没有发现什么问题,各位能给指导下吗?为什么中断服务程序就是唤醒不了 |
|