两个相同的设备(只有基地址不同)怎么共用一个驱动啊?

freetime-wxj 2012-12-15 03:50:47
两个字符设备或者混杂设备,只有基地址不同。
要是按照字符设备去注册,要调用class_create函数,这样的话第二个设备初始化时就会再次调用class_create,这样就报错了 就是无法创建相同名字的类。
要是按照misc设备注册,miscdevice结构体里的.name = DEVICE_NAME,又会重名,又会导致失败。
到底怎么办才可以呀???[/size]
...全文
1393 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
wfy1008 2013-01-24
  • 打赏
  • 举报
回复
我的理解是不能两个硬件使用同一个驱动,因为每一个都是一个实例,系统一次装一个,怎么可能装两个呢,但是这个与两个设备共用一份驱动程序并不矛盾,就像一个可执行文件可以同时在主机内运行是一样的。 另外我对这个问题的理解是,如果两个设备的地址不同,就不应该使用同一个驱动,也不应该使用同样的设备ID,只有同样功能的设备才应该用同一个驱动。
li32768 2013-01-20
  • 打赏
  • 举报
回复
13楼,uart是只有一个驱动啊,一个驱动并不意味着只有一个节点,就跟网卡一样,usbstorage 驱动也是一个,并且有些平台底层硬件有多个控制器不同地址
kickxxx 2013-01-18
  • 打赏
  • 举报
回复
引用 11 楼 budongjiuwenha 的回复:
引用 5 楼 guomeng198613 的回复:创建一个字符设备数组,两个设备注册时使用相同的主设备号,不同的从设备号。 能举个例子么,比如驱动两个led??
uart mmc 都是啊
kickxxx 2013-01-18
  • 打赏
  • 举报
回复
引用 3 楼 li32768 的回复:
我理解是,仅注册一个,内部包含一个分支,可用id标记,上层调用对应传递id,这样维护方便简洁
我的理解是,必须注册两个,因为物理设备存在两个啊,如果这里值注册一个,那么上层应用的逻辑就不对了,因为从上层应用角度看到两个设备,但是只能打开相同的设备;另外还要为上层提供接口区分这个设备(传入id);使用两个不同id打开设备后,导致这个设备节点被打开了两次,由此带来很多问题。逻辑更混乱。 很明显的两个设备,系统的uart设备和楼主的情况不是完全一样吗,都是reg地址不同
RedWolf1999 2013-01-18
  • 打赏
  • 举报
回复
共用一个驱动的话,两个设备就不能同时使用了
zhoujiawen 2013-01-17
  • 打赏
  • 举报
回复

/*
仅做参考:原是一个SPI口扩展了两路mcp2515,一个驱动注册两个设备,mcp251x_count=2
*/
static int __init mcp251x_init(void)
{
    int ret,i;
    struct mcp251x *chip=NULL;
    
    DEBUGMSG(DRIVER_NAME" init\n");
    
    mcp251x_dev = kmalloc(sizeof(struct mcp251x)*mcp251x_count,GFP_KERNEL);
    if (!mcp251x_dev) {
        printk(KERN_WARNING "mcp251x_CAN: cannot allocate memmory for mcp251x_dev");
        ret = -1;
        goto err_kmalloc_mcp251x_dev;
    }

	alloc_chrdev_region(&mcp251x_dev_major,0, mcp251x_count, DRIVER_NAME);
	cclass = class_create(THIS_MODULE, DRIVER_NAME);
	
    for (i=0; i< mcp251x_count; i++) {
        chip = &mcp251x_dev[i];
        chip->dev = i;//minor device number
        chip->f_osc = CANFOSC;

    	cdev_init(&chip->cdev, &mcp251x_fops);
    	chip->cdev.owner = THIS_MODULE;
    	chip->cdev.ops = &mcp251x_fops;
    	ret = cdev_add (&chip->cdev, MKDEV(MAJOR(mcp251x_dev_major), i), 1);
    	if (ret)
    		printk (KERN_NOTICE "Error %d adding can_lpc2xxx\n", ret);

		sprintf(chip->name, DRIVER_NAME"%d", i+1);
		if (device_create(cclass, NULL,	MKDEV(MAJOR(mcp251x_dev_major), i),
							chip, DRIVER_NAME"%d",i+1) == NULL) {
			printk(KERN_WARNING "fail to create device %s %d \n",__FILE__,__LINE__);
		}

        chip->can_available = (atomic_t)ATOMIC_INIT(1);
        chip->spi_transfer_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL);
        if (!chip->spi_transfer_buf) {
            ret = -ENOMEM;
            goto error_buf;
        }
        
        /*init receive FIFO*/
        //chip->RxFIFO.fadd    = 0;
        //chip->RxFIFO.fremove = 0;
        (chip->RxFIFO).count = 0;
        (chip->RxFIFO).wp = 0;
        (chip->RxFIFO).rp = 0;
        (chip->RxFIFO).buf = kmalloc(sizeof(struct canmsg_t)*CAN_CIRBUF_SIZE,GFP_KERNEL);
        
        spin_lock_init(&chip->RxFIFO.flock);
        if ( !(chip->RxFIFO).buf) {
            printk(KERN_WARNING "mcp251x_CAN: cannot allocate memmory for receive FIFO buffer");
            ret = -1;
            goto err_kmalloc_buf;
        }
        
        /*init Transimit FIFO*/
        //chip->TxFIFO.fadd    = 0;
        //chip->TxFIFO.fremove = 0;
        (chip->TxFIFO).count = 0;
        (chip->TxFIFO).wp = 0;
        (chip->TxFIFO).rp = 0;
        (chip->TxFIFO).buf = kmalloc(sizeof(struct canmsg_t)*CAN_TXDBUF_SIZE,GFP_KERNEL);
        spin_lock_init(&chip->lock);
        spin_lock_init(&chip->TxFIFO.flock);
        if ( !(chip->TxFIFO).buf) {
            printk(KERN_WARNING "mcp251x_CAN: cannot allocate memmory for transimit FIFO buffer");
            ret = -1;
            goto err_kmalloc_buf;
        }
        
        if (i == 0) {
            set_irq_type(IRQ0_GPIO_NAME, IRQ_TYPE_EDGE_FALLING);
            __raw_writel(PIO_DIR_GPIO(IRQ0_GPIO), GPIO_P2_DIR_CLR(GPIO_IOBASE));//GPIO_00 as input
            chip->irq=IRQ0_GPIO_NAME;
            
            ret = request_irq(chip->irq, mcp251x_can1_irq, IRQF_DISABLED|IRQF_TRIGGER_FALLING,DRIVER_NAME, NULL);
            if (ret < 0) {
                dev_err(&chip->sdev, "request irq %d failed (ret = %d)\n", chip->irq, ret);
                goto error_irq;
            }
        } else if (i ==  1) {
            set_irq_type(IRQ1_GPIO_NAME, IRQ_TYPE_EDGE_FALLING);
            __raw_writel(PIO_DIR_GPIO(IRQ1_GPIO), GPIO_P2_DIR_CLR(GPIO_IOBASE));//GPIO_01 as input
            chip->irq=IRQ1_GPIO_NAME;
            
            ret = request_irq(chip->irq, mcp251x_can2_irq, IRQF_DISABLED|IRQF_TRIGGER_FALLING,DRIVER_NAME, NULL);
            if (ret < 0) {
                dev_err(&chip->sdev, "request irq %d failed (ret = %d)\n", chip->irq, ret);
                goto error_irq;
            }
        } else {
            goto error_irq;
        }
        
        lpc32xx_gpio_irq_set(i,Disable);
    }
	

    mcp251x_hw_init();
    for (i=0; i<mcp251x_count; i++) {
        mcp251x_set_bit_rate(i, 20000);
    }
    DEBUGMSG("%s init sucess", DRIVER_NAME);
    return 0;

error_irq:
DEBUGMSG("error_irq");
error_buf:
DEBUGMSG("error_buf");
err_kmalloc_buf:
DEBUGMSG("err_kmalloc_buf");
    while (i > 0) {
    	i--;
    	kfree((mcp251x_dev[i].RxFIFO).buf);
    	kfree((mcp251x_dev[i].TxFIFO).buf);
    }
    kfree(mcp251x_dev);
err_kmalloc_mcp251x_dev:
DEBUGMSG("err_kmalloc_mcp251x_dev");
    printk(KERN_WARNING "mcp251x_can init FAILURE\n");
    return ret;
}
budongjiuwenha 2013-01-14
  • 打赏
  • 举报
回复
引用 4 楼 gongyf1977 的回复:
你的驱动得要按照能够驱动多个的设备来编写,内部用一个设备数组来保存多个设备对象,应用程序在调用驱动的时候,驱动程序需要判别是对哪个设备进行操作。
您好,我最近也在学习简单的字符设备驱动,但是在设备号这里卡住了。如果两个设备共用一个驱动,网上说是通过次设备号来区分的,但是次设备号又是通过设么来实现的呢?两个设备虽然可以通用一个驱动,但是至少它们的IO端口是不一样的,内核怎么知道你是要操作哪个端口呢?你提到的设备数组是什么意思,能说的详细点么,在编程时怎么体现,这一思路呢,能举个例子么?谢谢啦
budongjiuwenha 2013-01-14
  • 打赏
  • 举报
回复
引用 5 楼 guomeng198613 的回复:
创建一个字符设备数组,两个设备注册时使用相同的主设备号,不同的从设备号。
能举个例子么,比如驱动两个led??
swq1982 2013-01-14
  • 打赏
  • 举报
回复
主次设备号的定义都是内核已经按照一套规则编写好的,你可以参考内核里的代码文档/Documentation/devices.txt里面都有定义的。至少操作时,由于设备注册的时候分配的次设备号不一样的就对应到不同的两个设备来对待了。
HuaiShuShuV 2013-01-13
  • 打赏
  • 举报
回复
注册两个名字不同的,然后上层可以分别调用。
jiangbei_lengyu 2013-01-11
  • 打赏
  • 举报
回复
可以在id_table中定义一个platform_device_id结构体数组,使用不同的name和不同的driver_data。这样你可是尝试一下……
swq1982 2013-01-10
  • 打赏
  • 举报
回复
字符设备本来就是相同的主设备号应用的是相同的驱动,既然两个设备的基址不同,你得区别开,可以参考像i2c设备那样可以在/dev/i2c-x(x=0,1,2...)下建立不同的设备接口。还有就是网卡,例如两个相同的pcie网卡可以使用相同的驱动,但是在注册到内核的eth0和eth1两者是不同的。
大脸猫_Mars 2013-01-10
  • 打赏
  • 举报
回复
创建一个字符设备数组,两个设备注册时使用相同的主设备号,不同的从设备号。
gongyf1977 2013-01-07
  • 打赏
  • 举报
回复
你的驱动得要按照能够驱动多个的设备来编写,内部用一个设备数组来保存多个设备对象,应用程序在调用驱动的时候,驱动程序需要判别是对哪个设备进行操作。
li32768 2012-12-16
  • 打赏
  • 举报
回复
我理解是,仅注册一个,内部包含一个分支,可用id标记,上层调用对应传递id,这样维护方便简洁
freetime-wxj 2012-12-15
  • 打赏
  • 举报
回复
俩设备除了基地址不同其他的都是一模一样的 寄存器也是各自独立的 ,在probe函数里 他们俩资源得每人保存一份吧? 不然后注册的会把先注册的资源覆盖掉???
Wenxy1 2012-12-15
  • 打赏
  • 举报
回复
注册两个设备就OK。

1,318

社区成员

发帖
与我相关
我的任务
社区描述
主要是开发驱动技术
社区管理员
  • 驱动程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧