- 论坛徽章:
- 0
|
还是没有办法wake up进程。下面是我的程序代码,请帮忙解决~~
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <asm/hardware.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
MODULE_LICENSE("GPL");
#define IOPORT_MAJOR 220
#define START_ADC_AIN(x) \
{ \
ADCCON = PRESCALE_EN | PRSCVL(255) | ADC_INPUT((x)) ; \
ADCCON |= ADC_START; \
}
static struct semaphore adc_lock;
static wait_queue_head_t adc_wait;
static int flag=0;
static ssize_t adcdrv_read(struct file*,char*,size_t,loff_t*);
static int adcdrv_open(struct inode*,struct file*);
struct file_operations adcdrv_fops=
{
open:adcdrv_open,
read:adcdrv_read,
};
//adcdone中断处理函数
static void adcdone_int_handler(int irq, void *dev_id, struct pt_regs *reg)
{
printk("will wake up\n");
flag=1;
wake_up_interruptible(&adc_wait);
}
int s3c2410_adc_read(int ain)
{
int ret = 0;
if (down_interruptible(&adc_lock))
return -ERESTARTSYS;
START_ADC_AIN(ain); //设置ADC的参数
//当AD转换结束后会触发adcdone中断,在中断中唤醒adc_wait
wait_event_interruptible(adc_wait,(flag!=0));
printk("wake up\n");
flag=0;
ret = ADCDAT0 ;
up(&adc_lock);
printk("AIN[%d] = 0x%04x, %d\n", ain, ret, ADCCON & 0x80 ? 1:0);
return (ret & 0x3ff);
}
static int adcdrv_open(struct inode*inode,struct file*filp)
{
printk("open the adc device\n");
return 0;
}
static ssize_t adcdrv_read(struct file* file,char* buffer,size_t count,loff_t* ppos)
{
int ret=0;
printk("in adcdrv_read function\n");
ret=s3c2410_adc_read(6);
printk("the data is %d\n",ret);
copy_to_user(buffer,(char*)&ret,sizeof(int));
return (sizeof(int));
}
static int __init adcdrv_init(void)
{
if(register_chrdev(IOPORT_MAJOR,"adc",&adcdrv_fops))
{
printk("adc driver register failure\n");
return -1;
}
else
{
printk("adc driver register success\n");
if(request_irq(IRQ_ADC_DONE, adcdone_int_handler, SA_INTERRUPT,
"ADC", NULL) < 0)
{
printk("request irq failure\n");
return 1;
}
else
{
printk("request irq success\n");
init_MUTEX(&adc_lock);
init_waitqueue_head(&adc_wait);
ADCTSC = 0;
return 0;
}
return 0;
}
}
static void __exit adcdrv_exit(void)
{
free_irq(IRQ_ADC_DONE, NULL);
ret=unregister_chrdev(IOPORT_MAJOR,"adc");
if(ret)
{
printk("adc unregister failure\n");
}
else
{
printk("adc unregister success\n");
}
}
module_init(adcdrv_init);
module_exit(adcdrv_exit);
|
|
|