天嵌 ARM开发社区

 找回密码
 注册
查看: 1661|回复: 1

兄弟们,帮我看看我写的代码,有段错误,急,谢谢大家!!

[复制链接]
txb20061012 发表于 2013-7-25 17:43:26 | 显示全部楼层 |阅读模式
小弟最近在写SPI的设备驱动。
我在板文件中添加完spi设备信息后,写好设备驱动,insmod驱动后,成功调用probe函数。我在probe函数里获取struct spi_device *spi之外,同时注册创建了字符设备,并创建了设备节点。
然后我在用户层的测试程序中打开该设备节点文件,write,成功调用驱动里的write函数。我在write函数里完成了spi_transfer, spi_message结构体的创建,调用spi_message_init(), spi_message_add_tail(), 然后spi_sync()。程序运行到spi_sync()时出现段错误。但是如果是在probe里调用write函数,做同样的操作,运行到spi_sync则没有问题。
下面是我的驱动代码和测试程序,以及错误信息。恳请各位兄弟姐妹帮我看看,是不是我少了什么操作还是代码有错误。

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>

#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/math64.h>
#include <linux/slab.h>
#include <linux/sched.h>

#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/mod_devicetable.h>

#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>

#define CDD_COUNT 1

struct adf4351_devs
{
    /*建立字符设备*/
    struct cdev cdev;
    /*将匹配的spi设备传递进来*/
    struct spi_device *spi_dev;
    struct device *dev_device;
    struct mutex lock;
    int data;
};
dev_t dev;
struct adf4351_devs *adf4351_devp = NULL;
struct class *dev_class = NULL;
/*test code*/
#if 1
static int my_write(struct adf4351_devs *devp, loff_t to, size_t len, const char *buf)
{
    printk("enter my_write\n");
    struct spi_transfer st;
    struct spi_message msg;

    spi_message_init(&msg);
    memset(&st,0,sizeof(st));

    st.tx_buf = buf;
    st.len = len;

    spi_message_add_tail(&st,&msg);
    spi_sync(devp->spi_dev,&msg);
    printk("exit my_write\n");

    return 0;
}
#endif
/*面向用户程序的接口函数*/
ssize_t adf4351_write(struct file *fp,const char __user *buf,
        size_t size, loff_t *offset)
{
    int i;
    struct spi_transfer st[2];
    struct spi_message msg;
    char buf_write[100];
    memset(buf_write,0x7,100);

    printk("enter adf4351_write\n");
    printk("matched device's name=%s\n",adf4351_devp->spi_dev->modalias);
#if 1
    spi_message_init(&msg);
    memset(st,0,sizeof(st));
    printk("sizeof(st)=%d,sizeof(st[0])=%d\n",sizeof(st),sizeof(st[0]));
    st[0].tx_buf = buf;
    st[0].len = size;
    spi_message_add_tail(&st[0],&msg);

    for(i=0;i<size;i++)
        printk("st.tx_buf[%d]=%d\n",i,*((char *)st[0].tx_buf+i));

#if 1
//    mutex_lock(&(adf4351_devp->lock));
    spi_sync(adf4351_devp->spi_dev,&msg);
//    mutex_unlock(&(adf4351_devp->lock));
#endif
#endif
//    spi_write(adf4351_devp->spi_dev,buf,size);
    printk("enter adf4351_device_0 write\n");

    return 0;
}
ssize_t adf4351_read(struct file *fp,const char __user *buf,
        size_t size, loff_t *offset)
{
    printk("enter adf4351_read\n");
    int i;
    /*定义transfer*/
    struct spi_transfer st[2];
    /*定义message*/
    struct spi_message message;
    /*初始化message*/
    spi_message_init(&message);

    memset(st,0,sizeof(st));
    st[0].rx_buf = buf;
    st[0].len = size;
    /*将st放到message队列的尾部*/
    spi_message_add_tail(&st[0],&message);
    /*原子锁*/
    mutex_lock(&adf4351_devp->lock);
    /*将message与spi_device关联,发送message*/
    spi_sync(adf4351_devp->spi_dev,&message);
    /*将读到的数据打印出来*/
    for(i=0;i<size;i++)
        printk("0x%02x\n",buf[i]);

    /*去锁*/
    mutex_unlock(&adf4351_devp->lock);

    return 0;
}
struct file_operations adf4351_fops =
{
    .owner = THIS_MODULE,
    .write = adf4351_write,
    .read = adf4351_read,
};
#if 1
static const struct spi_device_id adf4351_idtable[] =
{
    {"adf4351_a",1},
//    {"adf4351_b",1},
    {},
};
MODULE_DEVICE_TABLE(spi, adf4351_idtable);
#endif
static int __devinit adf4351_probe(struct spi_device *spi)
{
    int ret=0;
    int i;
    printk("enter probe\n");
    /*首先创建字符设备*/
    /*动态申请设备号*/
    ret = alloc_chrdev_region(&dev,0,CDD_COUNT,"adf4351");
    if(ret<0)
    {
        printk("apply dev number failed\n");
        goto failure_alloc_chrdev_region;
    }
    /*分配空间*/
    adf4351_devp = kzalloc(sizeof(struct adf4351_devs)*CDD_COUNT,GFP_KERNEL);
    if(IS_ERR(adf4351_devp))
    {
        ret = PTR_ERR(adf4351_devp);
        printk("kzalloc failed\n");
        goto failure_kzalloc;
    }
    /*创建设备类*/
    dev_class = class_create(THIS_MODULE,"adf4351_class");
    if(IS_ERR(dev_class))
    {
        ret = PTR_ERR(dev_class);
        printk("class_create failed\n");
        goto failure_class_create;
    }
    /*创建多个设备节点*/
    for(i=0;i<CDD_COUNT;i++)
    {
        /*将匹配的spi device传递进来*/
        char buf_test[100];
        memset(buf_test,0x7,100);
        adf4351_devp[i].spi_dev = spi;
        mutex_init(&(adf4351_devp[i].lock));
        spi_set_drvdata(spi,adf4351_devp);
        /*初始化cdev结构体*/
        cdev_init(&(adf4351_devp[i].cdev),&adf4351_fops);
        /*添加cdev设备*/
        cdev_add(&(adf4351_devp[i].cdev),dev+i,1);
        /*动态创建设备节点*/
        adf4351_devp[i].dev_device = device_create(dev_class,NULL,dev+i,NULL,"adf4351_device_%d",i);
        //*(adf4351_devp[i].dev_device->platform_data) = i;
        adf4351_devp[i].data = i;
        /*这么调用则没有问题*/
        my_write(adf4351_devp,0,20,buf_test);
    }

    return 0;
failure_class_create:
    kfree(adf4351_devp);
failure_kzalloc:
    unregister_chrdev_region(dev,CDD_COUNT);
failure_alloc_chrdev_region:
    return ret;
}
static int __devexit adf4351_remove(struct spi_device *spi)
{
    printk("enter remove\n");
    int i;
    for(i=0;i<CDD_COUNT;i++)
    {
        cdev_del(&(adf4351_devp[i].cdev));
        device_destroy(dev_class,dev+i);
    }
    class_destroy(dev_class);
    kfree(adf4351_devp);
    unregister_chrdev_region(dev,CDD_COUNT);
    return 0;
}
/*构建spi_driver*/
static struct spi_driver adf4351_driver =
{
    .driver =
    {
        .name = "adf4351_drv",
        .bus  = &spi_bus_type,
        .owner = THIS_MODULE,
    },
    .probe = adf4351_probe,
    .remove = __devexit_p(adf4351_remove),
    .id_table = adf4351_idtable,
};
int __init spi_init()
{
    printk("-----------------------\n");
    spi_register_driver(&adf4351_driver);
    return 0;
}
void __exit spi_exit()
{
    printk("............................\n");
    spi_unregister_driver(&adf4351_driver);
}
module_init(spi_init);
module_exit(spi_exit);
MODULE_LICENSE("GPL");


用户层的测试程序:
#include <stdio.h>
#include <fcntl.h>

int main()
{
    int fd = open("/dev/adf4351_device_0",O_RDWR);
    if(fd<0)
    {
        printf("device node open failed\n");
        return -1;
    }
    printf("enter operation code, 'w'=write,'r'=read\n");
    char buf[100];
    int i;
    for(i=0;i<100;i++)
        buf[i]=i;
    write(fd,buf,10);
    sleep(1);

    close(fd);
    return 0;
}

 楼主| txb20061012 发表于 2013-7-25 17:43:55 | 显示全部楼层
调试时出现的错误打印信息:
/ko # ./a.out
enter operation code, 'w'=write,'r'=readenter adf4351_write
matched device's name=adf4351_a
sizeof(st)=72,sizeof(st[0])=36
st.tx_buf[0]=0
st.tx_buf[1]=1
st.tx_buf[2]=2
st.tx_buf[3]=3
st.tx_buf[4]=4
st.tx_buf[5]=5
st.tx_buf[6]=6
st.tx_buf[7]=7
st.tx_buf[8]=8
st.tx_buf[9]=9
kernel BUG at arch/arm/mm/dma-mapping.c:409!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 817 [#1] PREEMPT
last sysfs file: /sys/devices/virtual/adf4351_class/adf4351_device_0/dev
Modules linked in: spi_drv [last unloaded: spi_drv]
CPU: 0    Not tainted  (2.6.35.7-EmbedSky #15)
PC is at __bug+0x20/0x2c
LR is at schedule+0x2e8/0x36c
pc : [<c003ce40>]    lr : [<c05edbcc>]    psr: 60000013
sp : f3fa7ef0  ip : f3fa7df0  fp : f3fa7efc
r10: f3fa6000  r9 : f3563eec  r8 : f3f7c400
r7 : f3563f0c  r6 : 1ef70af4  r5 : f3563ea4  r4 : f3f864c8
r3 : 00000000  r2 : 00000000  r1 : 00000002  r0 : 00000033
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 10c5387d  Table: 534dc019  DAC: 00000017

PC: 0xc003cdc0:
cdc0  e89da800 c07a1c40 e1a0c00d e92dd800 e24cb004 e1a0c001 e1a03002 e1a01000
cde0  e1a0200c e59f0004 eb16c26a e89da800 c07a1c57 e1a0c00d e92dd800 e24cb004
ce00  e1a0c001 e1a03002 e1a01000 e1a0200c e59f0004 eb16c25f e89da800 c07a1c6e
ce20  e1a0c00d e92dd800 e24cb004 e1a02001 e1a01000 e59f000c eb16c256 e3a03000
ce40  e5833000 eafffffe c07a1c85 e1a0c00d e92dd800 e24cb004 e59f0014 e30022e1
ce60  e59f1010 eb16c24b e3a03000 e5833000 eafffffe c07a1c85 c07a1c9e e1a0c00d
ce80  e92dd800 e24cb004 e1a01000 e59f001c eb16c240 e59f0018 e59f1018 e30022c5
cea0  eb16c23c e3a03000 e5833000 eafffffe c07a1cb6 c07a1c85 c07a1c9e e1a0c00d

LR: 0xc05edb4c:
db4c  ebf21ab8 e3500000 0a000001 e1590008 0a000011 e59f30e4 e5932000 e5983150
db6c  e0223003 e1b03423 0a000001 e1a00008 ebe952d9 e5982154 e59a3154 e1520003
db8c  0a000001 e1a00008 ebe94a7c e5980024 e1a01008 e2800206 ebe9534b e59530d8
dbac  e1a00005 e3530000 058530dc 05869420 e5972004 e5951004 ebe92cea ebe9bf2a
dbcc  ea000007 f1080080 e5943004 e2433001 e5843004 e5943000 e3130002 0a000000
dbec  eb000091 e594300c e5933014 e3530000 ba000003 eb00089c e3500000 b5965414
dc0c  baffff46 e5942000 e5943004 e3120002 e2433001 e5843004 089daff8 eaffff34
dc2c  e3a02000 e5852000 eaffff66 c085bbb8 c0868fa4 c05f1c00 c0898fa0 c0898fb0

SP: 0xf3fa7e70:
7e70  f3fa7e94 f3fa7e80 c004a5c8 c004a5ac c0851c54 f3d01a40 ffffffff f3fa7edc
7e90  1ef70af4 f3563f0c f3fa7efc f3fa7ea8 c0038a6c c00382ac 00000033 00000002
7eb0  00000000 00000000 f3f864c8 f3563ea4 1ef70af4 f3563f0c f3f7c400 f3563eec
7ed0  f3fa6000 f3fa7efc f3fa7df0 f3fa7ef0 c05edbcc c003ce40 60000013 ffffffff
7ef0  f3fa7f0c f3fa7f00 c003ef0c c003ce2c f3fa7f74 f3fa7f10 c03196bc c003eedc
7f10  00000000 f3fa7f20 f3fac01c f3f11500 f3fa7f44 f3f864f8 c0856a8c c00895c0
7f30  f3f8650c f3f11500 f3fa7f74 c0855750 c0856ab0 c0856aa8 f3dc91c0 f3fa6000
7f50  f3dc91c0 f3fa7f90 f3f864ec f3f864e8 c0319470 c0899400 f3fa7fc4 f3fa7f78

IP: 0xf3fa7d70:
7d70  c07bdba7 00000000 f3fa7ea8 00000000 00000817 00000000 20000113 00000817
7d90  f3fa7dc4 f3fa7da0 c003f88c c003d2a0 f3f11500 f3fa7ea8 00000000 00000000
7db0  00000000 20000113 f3fa7dfc f3fa7dc8 c003fa78 c003f82c f3fa7dec f3fa7dd8
7dd0  c0089634 00000817 c0850408 00000000 f3fa7ea8 f3f7c400 20000113 f3fa6000
7df0  f3fa7ea4 f3fa7e00 c00382dc c003f8b8 c085c130 f3fa7e38 60000013 00000000
7e10  f3fa7e34 f3fa7e20 c05ede78 c05ed8f0 00000000 0000002d f3fa7ec4 f3fa7e38
7e30  c006833c c05ede44 c085213c 00000033 f3fa7e64 f3fa7e50 c004a5c8 c004a5ac
7e50  00000032 60000013 f3fa7e7c f3fa7e68 c004a5c8 c004a5ac c0851c24 f3d01a40

FP: 0xf3fa7e7c:
7e7c  c004a5ac c0851c54 f3d01a40 ffffffff f3fa7edc 1ef70af4 f3563f0c f3fa7efc
7e9c  f3fa7ea8 c0038a6c c00382ac 00000033 00000002 00000000 00000000 f3f864c8
7ebc  f3563ea4 1ef70af4 f3563f0c f3f7c400 f3563eec f3fa6000 f3fa7efc f3fa7df0
7edc  f3fa7ef0 c05edbcc c003ce40 60000013 ffffffff f3fa7f0c f3fa7f00 c003ef0c
7efc  c003ce2c f3fa7f74 f3fa7f10 c03196bc c003eedc 00000000 f3fa7f20 f3fac01c
7f1c  f3f11500 f3fa7f44 f3f864f8 c0856a8c c00895c0 f3f8650c f3f11500 f3fa7f74
7f3c  c0855750 c0856ab0 c0856aa8 f3dc91c0 f3fa6000 f3dc91c0 f3fa7f90 f3f864ec
7f5c  f3f864e8 c0319470 c0899400 f3fa7fc4 f3fa7f78 c007f4dc c031947c c085bbb8

R4: 0xf3f86448:
6448  00000000 00000000 00000000 00000001 f3f7c458 f3f0f298 7fffffff f3f86464
6468  f3f86464 00000000 00000000 00000000 00000000 f3f8647c f3f8647c 00000000
6488  00000000 f3f8648c f3f8648c f3c5e1b0 f3f86898 f3c5e1b0 00000001 c087e1cc
64a8  00000000 00000000 00010000 00070008 00000000 c03191b8 c0319f48 00000000
64c8  f489a000 c0851744 c0859ad8 c0856aa8 f3f86400 f3dc9180 c0856a8c 00000000
64e8  f3dc91c0 f3f864ec f3f864ec c0319470 f3f864f8 f3f864f8 00000016 00000017
6508  e1300000 00000000 f3f86510 f3f86510 00000002 00000000 00000008 007f385c
6528  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

R5: 0xf3563e24:
3e24  c006240c f3563e78 f3563e78 f3563eec f3563eec f3563e74 f3f7c400 f3563ec0
3e44  bef70af4 f3562000 00000000 f3563e6c f3563e60 c05ee278 c05ee020 f3563e9c
3e64  f3563e70 c0318454 c05ee26c c05ed7c0 00000000 f3563e28 f3563e28 f3563f3c
3e84  bf00c850 f3563eec 0000000a f3563f3c f3563ea0 bf00c1a8 c0318400 f34a1000
3ea4  bef70af4 00000000 0000000a ffffffff ffffffff 00000000 00000000 f3563eec
3ec4  f3563eec 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3ee4  00000000 00000000 f3563ec0 f3563ec0 f3f7c400 00000000 c031866c f3563e74
3f04  00000000 ffffff8d f3563f0c f3563f0c 00000000 00000000 0000000a f34c4f80

R7: 0xf3563e8c:
3e8c  0000000a f3563f3c f3563ea0 bf00c1a8 c0318400 f34a1000 bef70af4 00000000
3eac  0000000a ffffffff ffffffff 00000000 00000000 f3563eec f3563eec 00000000
3ecc  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3eec  f3563ec0 f3563ec0 f3f7c400 00000000 c031866c f3563e74 00000000 ffffff8d
3f0c  f3563f0c f3563f0c 00000000 00000000 0000000a f34c4f80 bef70af4 f3563f70
3f2c  0000000a f3563f6c f3563f40 c00ef604 bf00c0dc 00000000 00000000 00001000
3f4c  f34c4f80 bef70af4 00000000 00000000 0000000a f3563fa4 f3563f70 c00ef774
3f6c  c00ef558 00000000 00000000 00000022 00000000 ffffffff 0000853c 00000000

R8: 0xf3f7c380:
c380  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
c3a0  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
c3c0  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
c3e0  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
c400  c0856ab0 f3f7ad80 f3dc94c0 f3f8680c f3f8640c c0856ab8 f3c1f140 c087bdb8
c420  f3dc86f0 00000003 00000007 00000000 00000000 00000001 f3f7c438 f3f7c438
c440  c087e198 bf00c6c8 00000000 00000000 00000000 00000001 f3f86858 f3f86458
c460  7fffffff f3f7c464 f3f7c464 00000000 00000000 00000000 00000000 f3f7c47c

R9: 0xf3563e6c:
3e6c  c05ee26c c05ed7c0 00000000 f3563e28 f3563e28 f3563f3c bf00c850 f3563eec
3e8c  0000000a f3563f3c f3563ea0 bf00c1a8 c0318400 f34a1000 bef70af4 00000000
3eac  0000000a ffffffff ffffffff 00000000 00000000 f3563eec f3563eec 00000000
3ecc  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3eec  f3563ec0 f3563ec0 f3f7c400 00000000 c031866c f3563e74 00000000 ffffff8d
3f0c  f3563f0c f3563f0c 00000000 00000000 0000000a f34c4f80 bef70af4 f3563f70
3f2c  0000000a f3563f6c f3563f40 c00ef604 bf00c0dc 00000000 00000000 00001000
3f4c  f34c4f80 bef70af4 00000000 00000000 0000000a f3563fa4 f3563f70 c00ef774

R10: 0xf3fa5f80:
5f80  f3fa4000 f3f11200 f3dbf860 f3f7aa10 c05edbcc c005d884 00000000 f3c37ce8
5fa0  f3fa5fcc c030f63c f3f7aa00 00000000 00000000 00000000 f3fa5ff4 f3fa5fc8
5fc0  c008317c c030f648 00000000 00000000 f3fa5fd0 f3fa5fd0 f3c37ce8 c00830f8
5fe0  c006ad24 00000013 00000000 f3fa5ff8 c006ad24 c0083104 ffffffea fb5eefff
6000  00000000 00000002 00000000 f3f11500 c085c080 00000000 00000017 f3fa6000
6020  f3f11500 c085bbb8 f34e2600 f34b0180 f34b0180 c0868fa4 f3fa7e1c f3fa7df0
6040  c05edbc8 00000000 00000000 00000000 00000000 00000000 00000000 00000000
6060  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Process s3c64xx-spi.0 (pid: 39, stack limit = 0xf3fa62f0)
Stack: (0xf3fa7ef0 to 0xf3fa8000)
7ee0:                                     f3fa7f0c f3fa7f00 c003ef0c c003ce2c
7f00: f3fa7f74 f3fa7f10 c03196bc c003eedc 00000000 f3fa7f20 f3fac01c f3f11500
7f20: f3fa7f44 f3f864f8 c0856a8c c00895c0 f3f8650c f3f11500 f3fa7f74 c0855750
7f40: c0856ab0 c0856aa8 f3dc91c0 f3fa6000 f3dc91c0 f3fa7f90 f3f864ec f3f864e8
7f60: c0319470 c0899400 f3fa7fc4 f3fa7f78 c007f4dc c031947c c085bbb8 f3dc91c8
7f80: f3f11684 00000000 f3f11500 c0083604 f3fa7f90 f3fa7f90 00000000 f3c37d78
7fa0: f3fa7fcc c007f2d0 f3dc91c0 00000000 00000000 00000000 f3fa7ff4 f3fa7fc8
7fc0: c008317c c007f2dc 00000000 00000000 f3fa7fd0 f3fa7fd0 f3c37d78 c00830f8
7fe0: c006ad24 00000013 00000000 f3fa7ff8 c006ad24 c0083104 5fb7d7ee fbfffbff
Backtrace:
[<c003ce20>] (__bug+0x0/0x2c) from [<c003ef0c>] (___dma_single_cpu_to_dev+0x3c/0x6c)
[<c003eed0>] (___dma_single_cpu_to_dev+0x0/0x6c) from [<c03196bc>] (s3c64xx_spi_work+0x24c/0xad8)
[<c0319470>] (s3c64xx_spi_work+0x0/0xad8) from [<c007f4dc>] (worker_thread+0x20c/0x2c4)
[<c007f2d0>] (worker_thread+0x0/0x2c4) from [<c008317c>] (kthread+0x84/0x8c)
[<c00830f8>] (kthread+0x0/0x8c) from [<c006ad24>] (do_exit+0x0/0x6f4)
r7:00000013 r6:c006ad24 r5:c00830f8 r4:f3c37d78
Code: e1a01000 e59f000c eb16c256 e3a03000 (e5833000)
s3cfb s3cfb: change blank mode
s3cfb s3cfb: [fb0] win map off
s3cfb s3cfb: [fb0] turn on
s3cfb s3cfb: [fb0] yoffset for pan display: 0
s3cfb s3cfb: [fb0] start_addr: 0x465ab000, end_addr: 0x46722000
---[ end trace f8c0262e5ccfd0b0 ]---
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号-2 )

GMT+8, 2025-6-19 21:32 , Processed in 2.041889 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表