|
我自己做了一个ADC的驱动程序,不知道怎么回事,总是读不到数据,程序如下
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#define READ_START (0<<1)
#define ADC_START (1)
#define ADC_READY (1<<15)
#define PRSCEN (1<<14)
#define PRSCVL (24<<6)
#define SEL_MUX (0<<3)
#define ADCCON (READ_START|PRSCEN|PRSCVL|SEL_MUX)
#define AUTO_PST (~(1<<2))
#define DLY (5000)
#define rADCCON_PA 0x58000000
#define rADCTSC_PA 0x58000004
#define rADCDLY_PA 0x58000008
#define rADCDAT0_PA 0x5800000c
#define rADCDAT1_PA 0x58000010
#define rADCUPDN_PA 0x58000014
#define rADCCON (*(volatile unsigned long *)ioremap(rADCCON_PA,4))
#define rADCTSC (*(volatile unsigned long *)ioremap(rADCTSC_PA,4))
#define rADCDLY (*(volatile unsigned long *)ioremap(rADCDLY_PA,4))
#define rADCDAT0 (*(volatile unsigned long *)ioremap(rADCDAT0_PA,4))
#define rADCDAT1 (*(volatile unsigned long *)ioremap(rADCDAT1_PA,4))
#define rADCUPDN (*(volatile unsigned long *)ioremap(rADCUPDN_PA,4))
#define irq_adc 80
#define dev_name "adc"
#define dev_major 202
static DECLARE_WAIT_QUEUE_HEAD(adc_waitq);
static irqreturn_t adc_interrupt(int irq,void *dev_id);
static int adcready=0 ;
unsigned int adc_dat;
static int open_adc(struct inode *inode,struct file *filp) {
int err;
rADCCON = ADCCON;
rADCTSC &=AUTO_PST;
rADCDLY =DLY;
err= request_irq(irq_adc , adc_interrupt ,IRQF_SHARED , "adc",&err);
if(err!=0) {
printk("adc_int request fail");
return err; }
printk("adc_initialized ");
return 0;
}
static ssize_t read_adc(struct file *filp, char __user *buff,size_t count,loff_t * offp ){
int err;
//int value;
printk("\n NOW IS IN READ_ADC");
rADCCON |=ADC_START;
while(rADCCON & ADC_START);
printk("\n adc is on ");
//while(rADCCON & ADC_READY);
//printk("\n adc is finished ");
//value = rADCDAT0;
//value &= 0x3ff;
//adc_dat=value;
if(adcready==0)
{
printk("\n adc is going to sleep");
wait_event_interruptible(adc_waitq, adcready);
}
printk("adc value is(this message is from kernel) :%4d",adc_dat);
err = copy_to_user(buff, (const void *)&adc_dat, sizeof(adc_dat));
if(err!=sizeof(adc_dat))
return -1;
//memset((void *)adc_dat, 0, sizeof(adc_dat));
return 0;
}
static int close(struct inode *inode,struct file *filp) {
free_irq (irq_adc,NULL);
return 0;
}
static irqreturn_t adc_interrupt(int irq, void *dev_id )
{
unsigned int value;
value = rADCDAT0;
value &= 0x3ff;
printk("\nadc ready :%u",value);
adc_dat=value;
adcready=1;
wake_up_interruptible(&adc_waitq);
return 0;
}
static struct file_operations adc_ops={
owner : THIS_MODULE,
open : open_adc,
read : read_adc,
release : close
};
static int __init adc_int(void)
{
int err;
err=register_chrdev(dev_major,dev_name,& adc_ops);
if(err)
{
printk("\ncan't register adc device");
return err;
}
printk("\n adc device register success");
return 0;
}
static void __exit adc_exit(void )
{
unregister_chrdev(dev_major,dev_name);
}
module_init(adc_int);
module_exit(adc_exit);
MODULE_AUTHOR("yuziqiang");
MODULE_DESCRIPTION("S3C2410/S3C2440 ADC Driver");
MODULE_LICENSE("GPL");
问题是按照上面的代码来的话中断不会发生,我把中断相关代码注销掉的话,在read里面改用查询的话每一回读到的数据都是0,
按理来说应该有一个数据值才对,因为我用关盘里面测试程序试过,是有值的,
我的内核版本为2.6.32.9
谢谢指教
当我去掉中断的部分,在read中采用查询的时候,运行测试程序后,等待1分钟左右,出现上面的错误代码
当我采用中断的话中断就不会发生,也不会有结果, |
|