zwxhehehe2012 发表于 2012-9-13 15:28:18

自己写的linux系统中spi驱动问题

自己写了一个SPI设备的驱动,加载驱动后已经成功调用probe函数并创建了设备文件,问题是现在应用程序打开设备文件后就出现以下错误:将驱动中的open函数与release函数中其它删除只留下打印信息,应用程序中只留下打开和关闭设备文件代码,还是会出现如下错误,麻烦大侠帮忙解决以下该问题(已经调试好久了还没解决)


Unable to handle kernel NULL pointer dereference at virtual address 0000002fe driver uvcv
usbcore:
LR is at sys_close+0xa0/0xcc
pc : [<c0cde7c0>] lr : [<c0cde8d0>] psr: 80000013
sp : c082bf68 ip : c082bf88 fp : c082bf84
r10: 00000000 r9 : c082a000 r8 : c0c80008
r7 : 00000006 r6 : 0000001b r5 : c2b01cc0 r4 : 00000003
r3 : 00000007 r2 : 00000004 r1 : c2b01cc0 r0 : 0000001b
Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: c000717f Table: 32b84000 DAC: 00000015
Process app_gp21 (pid: 504, stack limit = 0xc082a268)
Stack: (0xc082bf68 to 0xc082c000)
bf60: 00000003 c2b01cc0 0000001b 00000006 c082bfa4 c082bf88
bf80: c0cde8d0 c0cde7c4 0000b494 00000000 0000b450 00000006 00000000 c082bfa8
bfa0: c0c7fe60 c0cde840 0000b494 00000000 00000003 00000000 00084f2c 00000001
bfc0: 0000b494 00000000 0000b450 00000006 00000000 00000000 00000000 be851b94
bfe0: 00000000 be851b78 00008278 0001522c 60000010 00000003 e5803008 e542c001
Backtrace:
[<c0cde7b4>] (filp_close+0x0/0x7c) from [<c0cde8d0>] (sys_close+0xa0/0xcc)
r7:00000006 r6:0000001b r5:c2b01cc0 r4:00000003
[<c0cde830>] (sys_close+0x0/0xcc) from [<c0c7fe60>] (ret_fast_syscall+0x0/0x2c)
r7:00000006 r6:0000b450 r5:00000000 r4:0000b494
Code: e89da800 e1a0c00d e92dd8f0 e24cb004 (e5903014)
---[ end trace d982a507971a8f45 ]---
Segmentation fault


驱动程序主要代码如下:#define ARRYSIZE(x) ( sizeof(x)/ sizeof(x))
#define EINT3_IRQ 7
#define SPI_MAJOR 252
#define HIGH 1
#define LOW 0


extern int spi_register_driver(struct spi_driver *sdrv);
extern int spi_write_then_read(struct spi_device *spi,const u8 *txbuf,unsigned n_tx,u8 *rxbuf,unsigned n_rx);
extern int spi_sync(struct spi_device *spi,struct spi_message *message);
extern struct class *__class_creat(struct module *owner ,const char *name,struct lock_class_key *key);
extern int register_chrdev(unsigned int major,const char *name,const struct file_operations *fops);




static char ev_irq = 0; // 定义表示中断发生的变量

static DECLARE_WAIT_QUEUE_HEAD(measure_waitq); //定义一个等待队列




struct spidev_data
{
dev_t devt;
struct spi_device *spi ;
};



irqreturn_t mp_interrupt (int irq ,void *dev_id)
{
unsigned char value ;
value = s3c2410_gpio_getpin(S3C2410_GPF3);   
if (!value)
{
ev_irq = 1 ;
wake_up_interruptible (&measure_waitq);
}
   
}



        int Mp_Open (struct inode *inode ,struct file *file)
{
/* struct spidev_data *data_spi ;
file->private_data = data_spi ;   
if (request_irq(EINT3_IRQ,mp_interrupt,IRQF_DISABLED|IRQF_TRIGGER_LOW,"mp",NULL)) //申请中断
{
printk ("request_irq error\n");

} */
   
printk("kernel open device success\n");
}


   
int Mp_Release (struct inode *inode ,struct file *filp)
{
printk("close device\n");



}
struct file_operations mp_fops =
{
.owner = THIS_MODULE ,
.open = Mp_Open ,
.release = Mp_Release ,
   
};

static struct class *spi_class ;



static int Mp_Probe (struct spi_device *spi_dev)
{
int ret ;
struct spidev_data *data_spi ;
data_spi= kzalloc (sizeof(*data_spi),GFP_KERNEL);
if(!data_spi)
return -ENOMEM ;
printk("kzalloc success\n");
data_spi->spi = spi_dev ;
data_spi->devt = MKDEV(SPI_MAJOR,0);
device_create(spi_class,&spi_dev->dev,data_spi->devt,data_spi,"mp");
spi_set_drvdata(spi_dev,data_spi);
printk ("probe mp \n ");
return 0 ;
   
}


static int Mp_Remove (struct spi_device *spi_dev)
{

struct spidev_data *data_spi ;
cdev_del (&data_spi->spi);//注销字符设备
return 0 ;


}


static struct spi_driver mp_driver =
{
.probe = Mp_Probe ,
.remove = Mp_Remove ,
.driver =
{
.name = "mp" ,
.owner = THIS_MODULE ,
}

} ;



static int __init Mp_init (void)
{
unsigned int ret ;
ret = register_chrdev(SPI_MAJOR,"spi",&mp_fops);
if (ret<0)
{
printk ("cdev add error\n");
return ret;
}
spi_class = class_create (THIS_MODULE,"mp");
if (IS_ERR(spi_class))
{
return PTR_ERR(spi_class);
}
return spi_register_driver (&mp_driver);

}

static void __exit Mp_exit (void)
{
spi_unregister_driver (&mp_driver);
}



module_init(Mp_init);
module_exit(Mp_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("mp for EmbedSky SKY2440/TQ2440 Board");


应用程序如下:

void main (int argc ,char **argv)
{
int fd ;
fd = open("/dev/mp" ,O_RDWR);   

if (fd<0)
{
printf ("open device error\n");
return ;
}

printf ("open seccuss\n");   
close(fd);
}

xi_liang 发表于 2012-9-13 15:50:08

估计是地址错误 ,内核里用到的都是虚拟地址,检查下是否有用了物理地址

zwxhehehe2012 发表于 2012-9-13 17:38:42

用到物理地址的代码全部删掉了,只剩下上面的代码,上面代码中没有使用到物理地址,但还是出现以上问题,奇怪的是我应用程序中最后不加 close(fd);这句代码的话,就会出现以下错误:

CPU: 0    Not tainted(2.6.30.4 #1)   4,10 Jan1 00:00 tty10transf
PC is at filp_close+0xc/0x7cram (eg: uCOS-II or TQ2440
c
LR is at put_files_struct+0xbc/0xe0,11 Jan1 00:00 tty11b] Download
pc : [<c0cde7c0>]    lr : [<c0c93b74>]    psr: 20000013w----    1 root   root       4,12 Jan1 00:00 tty1
sp : c2ab3f08ip : c2ab3f28fp : c2ab3f24FlashUTC0 00000000
crw-rw----    1 root   
r10: 00000000r9 : c2ab2000r8 : c2b01cc0 Image (zImage)d)                        
r3 : c2b01cfcr2 : c2ab2000r1 : c2b01cc0r0 : 0000001e:00 tty15Verifying Ch
Press Space key to Download Mode !
Flags: nzCvIRQs onFIQs onMode SVC_32ISA ARMSegment user00 tty16#####
3f40: c2ab3f5c c2ab3f50 c0c93bc0 c0c93ac8 c2ab3f7c c2ab3f60 c0c954c8 c0c93ba8
3f60: c2ab2000 00000001 00084ef4 000864a0 c2ab3f94 c2ab3f80 c0c95680 c0c9502c
3f80: 0006eea8 0006ee84 c2ab3fa4 c2ab3f98 c0c95718 c0c9564c 00000000 c2ab3fa8
3fa0: c0c7fe60 c0c95710 0006eea8 0006ee84 0000000d 0000000d 00084f1c 0000d844
3fc0: 0006eea8 0006ee84 0007a4c8 000000f8 00000000 00000000 00000000 00000000
3fe0: 0002bd2c bed1fbb8 0000b888 00015070 60000010 0000000d 00000910 0000e102
Backtrace:
[<c0cde7b4>] (filp_close+0x0/0x7c) from [<c0c93b74>] (put_files_struct+0xbc/0xe0
)
r7:0000000c r6:c2b01cc8 r5:00000001 r4:00000000
[<c0c93ab8>] (put_files_struct+0x0/0xe0) from [<c0c93bc0>] (exit_files+0x28/0x2c
)
[<c0c93b98>] (exit_files+0x0/0x2c) from [<c0c954c8>] (do_exit+0x4ac/0x620)
[<c0c9501c>] (do_exit+0x0/0x620) from [<c0c95680>] (do_group_exit+0x44/0xc4)
[<c0c9563c>] (do_group_exit+0x0/0xc4) from [<c0c95718>] (sys_exit_group+0x18/0x2
4)
r5:0006ee84 r4:0006eea8
[<c0c95700>] (sys_exit_group+0x0/0x24) from [<c0c7fe60>] (ret_fast_syscall+0x0/0
x2c)
Code: e89da800 e1a0c00d e92dd8f0 e24cb004 (e5903014)
---[ end trace acb6c7765998076f ]---
Fixing recursive fault but reboot is needed!

加了close(fd)后就出现原题中的错误,不知道怎么回事
页: [1]
查看完整版本: 自己写的linux系统中spi驱动问题