免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 40121 | 回复: 31
打印 上一主题 下一主题

加载驱动出错:No such device(已解决,谢谢各位大侠) [复制链接]

论坛徽章:
8
2015年辞旧岁徽章
日期:2015-03-03 16:54:15午马
日期:2015-02-04 12:00:07羊年新春福章
日期:2015-02-04 11:57:56双子座
日期:2014-12-02 11:44:59金牛座
日期:2014-10-08 16:47:08狮子座
日期:2014-08-29 13:37:46巳蛇
日期:2014-08-26 17:32:29NBA常规赛纪念章
日期:2015-05-04 22:32:03
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-29 15:05 |只看该作者 |倒序浏览
小弟编译一个AT91RM9200的外接时钟ds1302的驱动,编译没有问题。下载到开发板,执行命令:
#insmod rtc-ds1302.ko
出现如下错误:
insmod: cannot insert 'rtc-ds1302.ko': No such device


请问,大虾,出现这个问题是怎么回事??? 谢谢

[ 本帖最后由 zhj1011 于 2009-5-4 08:59 编辑 ]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
2 [报告]
发表于 2009-04-29 15:26 |只看该作者
开发板上相应的硬件已经有了吗

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
3 [报告]
发表于 2009-04-29 15:26 |只看该作者
提示应该很明确,驱动找不到对应的设备

论坛徽章:
8
2015年辞旧岁徽章
日期:2015-03-03 16:54:15午马
日期:2015-02-04 12:00:07羊年新春福章
日期:2015-02-04 11:57:56双子座
日期:2014-12-02 11:44:59金牛座
日期:2014-10-08 16:47:08狮子座
日期:2014-08-29 13:37:46巳蛇
日期:2014-08-26 17:32:29NBA常规赛纪念章
日期:2015-05-04 22:32:03
4 [报告]
发表于 2009-04-29 15:35 |只看该作者

回复 #3 Godbach 的帖子

硬件连接都没有问题的

论坛徽章:
8
2015年辞旧岁徽章
日期:2015-03-03 16:54:15午马
日期:2015-02-04 12:00:07羊年新春福章
日期:2015-02-04 11:57:56双子座
日期:2014-12-02 11:44:59金牛座
日期:2014-10-08 16:47:08狮子座
日期:2014-08-29 13:37:46巳蛇
日期:2014-08-26 17:32:29NBA常规赛纪念章
日期:2015-05-04 22:32:03
5 [报告]
发表于 2009-04-29 15:37 |只看该作者

回复 #3 Godbach 的帖子

这是我的驱动代码,请大侠指点下迷津啊
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/time.h>
#include <linux/rtc.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/bcd.h>
#include <asm/rtc.h>

#include "/home/linux-2.6.27/arch/arm/mach-at91/include/mach/gpio.h"
#include "/home/linux-2.6.27/arch/arm/mach-at91/include/mach/at91rm9200.h"

#define DRV_NAME        "rtc-ds1302"
#define DRV_VERSION        "0.1.0"

#define        RTC_CMD_READ        0x81                /* Read command */
#define        RTC_CMD_WRITE        0x80                /* Write command */

#define RTC_ADDR_RAM0        0x20                /* Address of RAM0 */
#define RTC_ADDR_TCR        0x08                /* Address of trickle charge register */
#define        RTC_ADDR_YEAR        0x06                /* Address of year register */
#define        RTC_ADDR_DAY        0x05                /* Address of day of week register */
#define        RTC_ADDR_MON        0x04                /* Address of month register */
#define        RTC_ADDR_DATE        0x03                /* Address of day of month register */
#define        RTC_ADDR_HOUR        0x02                /* Address of hour register */
#define        RTC_ADDR_MIN        0x01                /* Address of minute register */
#define        RTC_ADDR_SEC        0x00                /* Address of second register */

#define        RTC_RESET        0x00800000
#define        RTC_IODATA        0x00000040
#define        RTC_SCLK        0x00400000

//#ifdef CONFIG_SH_SECUREEDGE5410
//#include <asm/snapgear.h>
//#define set_dp(x)        SECUREEDGE_WRITE_IOPORT(x, 0x1c00)
//#define get_dp()        SECUREEDGE_READ_IOPORT()
//#else
//#error "Add support for your platform"
//#endif

struct ds1302_rtc {
        struct rtc_device *rtc_dev;
        spinlock_t lock;
};

static void ds1302_sendbits(unsigned int val)
{
        int i;
   
    at91_set_gpio_output(AT91_PIN_PA23,0);

        for (i = 8; (i); i--, val >>= 1) {
//                set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ?
//                        RTC_IODATA : 0));
//                set_dp(get_dp() | RTC_SCLK);        /* clock high */
//                set_dp(get_dp() & ~RTC_SCLK);        /* clock low */
        
                at91_set_gpio_value(AT91_PIN_PA23,((val & 0x1)?1:0));
        at91_set_gpio_value(AT91_PIN_PA22,1);
        at91_set_gpio_value(AT91_PIN_PA22,0);
        }
}

static unsigned int ds1302_recvbits(void)
{
        unsigned int val;
        int i;
   
    at91_set_gpio_input(AT91_PIN_PA23,1);
   
        for (i = 0, val = 0; (i < ; i++) {
//                val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i);
//                set_dp(get_dp() | RTC_SCLK);        /* clock high */
//                set_dp(get_dp() & ~RTC_SCLK);        /* clock low */

        val |=( ( (at91_get_gpio_value(AT91_PIN_PA23))?1:0 ) << i );
        at91_set_gpio_value(AT91_PIN_PA22,1);
        at91_set_gpio_value(AT91_PIN_PA22,0);
    }

        return val;
}

static unsigned int ds1302_readbyte(unsigned int addr)
{
        unsigned int val;

//        set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));

//        set_dp(get_dp() | RTC_RESET);

    at91_set_gpio_value( AT91_PIN_PA6,0);
    at91_set_gpio_value( AT91_PIN_PA22,0);
    at91_set_gpio_value( AT91_PIN_PA23,0);
   
    at91_set_gpio_value( AT91_PIN_PA6,1);

        ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ);
        val = ds1302_recvbits();
    at91_set_gpio_value( AT91_PIN_PA6,0);

//        set_dp(get_dp() & ~RTC_RESET);

        return val;
}

static void ds1302_writebyte(unsigned int addr, unsigned int val)
{
//        set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
//        set_dp(get_dp() | RTC_RESET);

    at91_set_gpio_value( AT91_PIN_PA6,0);
    at91_set_gpio_value( AT91_PIN_PA22,0);
    at91_set_gpio_value( AT91_PIN_PA23,0);

    at91_set_gpio_value( AT91_PIN_PA6,1);
        ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE);
        ds1302_sendbits(val);
    at91_set_gpio_value( AT91_PIN_PA6,0);
//        set_dp(get_dp() & ~RTC_RESET);
}

static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
        struct ds1302_rtc *rtc = dev_get_drvdata(dev);

        spin_lock_irq(&rtc->lock);

        tm->tm_sec        = BCD2BIN(ds1302_readbyte(RTC_ADDR_SEC));
        tm->tm_min        = BCD2BIN(ds1302_readbyte(RTC_ADDR_MIN));
        tm->tm_hour        = BCD2BIN(ds1302_readbyte(RTC_ADDR_HOUR));
        tm->tm_wday        = BCD2BIN(ds1302_readbyte(RTC_ADDR_DAY));
        tm->tm_mday        = BCD2BIN(ds1302_readbyte(RTC_ADDR_DATE));
        tm->tm_mon        = BCD2BIN(ds1302_readbyte(RTC_ADDR_MON)) - 1;
        tm->tm_year        = BCD2BIN(ds1302_readbyte(RTC_ADDR_YEAR));

        if (tm->tm_year < 70)
                tm->tm_year += 100;

        spin_unlock_irq(&rtc->lock);

        dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
                "mday=%d, mon=%d, year=%d, wday=%d\n",
                __func__,
                tm->tm_sec, tm->tm_min, tm->tm_hour,
                tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);

        if (rtc_valid_tm(tm) < 0)
                dev_err(dev, "invalid date\n";

        return 0;
}

static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
        struct ds1302_rtc *rtc = dev_get_drvdata(dev);

        spin_lock_irq(&rtc->lock);

        /* Stop RTC */
        ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);

        ds1302_writebyte(RTC_ADDR_SEC, BIN2BCD(tm->tm_sec));
        ds1302_writebyte(RTC_ADDR_MIN, BIN2BCD(tm->tm_min));
        ds1302_writebyte(RTC_ADDR_HOUR, BIN2BCD(tm->tm_hour));
        ds1302_writebyte(RTC_ADDR_DAY, BIN2BCD(tm->tm_wday));
        ds1302_writebyte(RTC_ADDR_DATE, BIN2BCD(tm->tm_mday));
        ds1302_writebyte(RTC_ADDR_MON, BIN2BCD(tm->tm_mon + 1));
        ds1302_writebyte(RTC_ADDR_YEAR, BIN2BCD(tm->tm_year % 100));

        /* Start RTC */
        ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);

        spin_unlock_irq(&rtc->lock);

        return 0;
}

static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd,
                            unsigned long arg)
{
        switch (cmd) {
#ifdef RTC_SET_CHARGE
        case RTC_SET_CHARGE:
        {
                struct ds1302_rtc *rtc = dev_get_drvdata(dev);
                int tcs_val;

                if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int)))
                        return -EFAULT;

                spin_lock_irq(&rtc->lock);
                ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf));
                spin_unlock_irq(&rtc->lock);
                return 0;
        }
#endif
        }

        return -ENOIOCTLCMD;
}

static struct rtc_class_ops ds1302_rtc_ops = {
        .read_time        = ds1302_rtc_read_time,
        .set_time        = ds1302_rtc_set_time,
        .ioctl                = ds1302_rtc_ioctl,
};

static int __devinit ds1302_rtc_probe(struct platform_device *pdev)
{
        struct ds1302_rtc *rtc;
        int ret;

    printk("rtc-ds1302.c line 226\n";

        /* Reset */
//        set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
    at91_set_gpio_value( AT91_PIN_PA6,0);
    at91_set_gpio_value( AT91_PIN_PA22,0);
    at91_set_gpio_value( AT91_PIN_PA23,0);

        /* Write a magic value to the DS1302 RAM, and see if it sticks. */
        ds1302_writebyte(RTC_ADDR_RAM0, 0x42);
        if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42)
                return -ENODEV;

        rtc = kzalloc(sizeof(struct ds1302_rtc), GFP_KERNEL);
        if (unlikely(!rtc))
                return -ENOMEM;

        spin_lock_init(&rtc->lock);
        rtc->rtc_dev = rtc_device_register("ds1302", &pdev->dev,
                                           &ds1302_rtc_ops, THIS_MODULE);
        if (IS_ERR(rtc->rtc_dev)) {
                ret = PTR_ERR(rtc->rtc_dev);
                goto out;
        }

        platform_set_drvdata(pdev, rtc);

        return 0;
out:
        kfree(rtc);
        return ret;
}

static int __devexit ds1302_rtc_remove(struct platform_device *pdev)
{
        struct ds1302_rtc *rtc = platform_get_drvdata(pdev);

        if (likely(rtc->rtc_dev))
                rtc_device_unregister(rtc->rtc_dev);

        platform_set_drvdata(pdev, NULL);

        kfree(rtc);
    printk("rtc-ds1302.c line 269";
        return 0;
}

static struct platform_driver ds1302_platform_driver = {
        .driver                = {
                .name        = DRV_NAME,
                .owner        = THIS_MODULE,
        },
        .probe                = ds1302_rtc_probe,
        .remove                = __devexit_p(ds1302_rtc_remove),
};

static int __init ds1302_rtc_init(void)
{
    printk("rtc-ds1302.c line 284\n";
        return platform_driver_register(&ds1302_platform_driver);
//        return platform_driver_probe(&ds1302_platform_driver,ds1302_rtc_probe);

}

static void __exit ds1302_rtc_exit(void)
{
        platform_driver_unregister(&ds1302_platform_driver);
}

module_init(ds1302_rtc_init);
module_exit(ds1302_rtc_exit);

MODULE_DESCRIPTION("Dallas DS1302 RTC driver";
MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR("aul Mundt, David McCullough";
MODULE_LICENSE("GPL v2";

论坛徽章:
8
2015年辞旧岁徽章
日期:2015-03-03 16:54:15午马
日期:2015-02-04 12:00:07羊年新春福章
日期:2015-02-04 11:57:56双子座
日期:2014-12-02 11:44:59金牛座
日期:2014-10-08 16:47:08狮子座
日期:2014-08-29 13:37:46巳蛇
日期:2014-08-26 17:32:29NBA常规赛纪念章
日期:2015-05-04 22:32:03
6 [报告]
发表于 2009-04-29 15:40 |只看该作者

回复 #3 Godbach 的帖子

在函数
static int __init ds1302_rtc_init(void)
{
    printk("rtc-ds1302.c line 284\n");
        return platform_driver_register(&ds1302_platform_driver);
//        return platform_driver_probe(&ds1302_platform_driver,ds1302_rtc_probe);

}
中,使用platform_driver_register(&ds1302_platform_driver);来注册驱动,则加载驱动后,只打印出提示信息:
rtc-ds1302.c line 284
但是参照,rtc-at91rm9200.c驱动中的注册方式,使用platform_driver_probe注册驱动,则加载时,打印提示信息:
rtc-ds1302.c line 284
并报错:
insmod: cannot insert 'rtc-ds1302.ko': No such device

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
7 [报告]
发表于 2009-04-29 15:49 |只看该作者
在函数
static int __init ds1302_rtc_init(void)
{
    printk("rtc-ds1302.c line 284\n");
        return platform_driver_register(&ds1302_platform_driver);
//        return platform_driver_probe(&ds1302_platform_driver,ds1302_rtc_probe);

}
中,使用platform_driver_register(&ds1302_platform_driver);来注册驱动,则加载驱动后,只打印出提示信息:
rtc-ds1302.c line 284
但是参照,rtc-at91rm9200.c驱动中的注册方式,使用platform_driver_probe注册驱动,则加载时,打印提示信息:
rtc-ds1302.c line 284
并报错:
insmod: cannot insert 'rtc-ds1302.ko': No such device


你的驱动是在什么内核下使用的?
        return platform_driver_register(&ds1302_platform_driver);
//        return platform_driver_probe(&ds1302_platform_driver,ds1302_rtc_probe);

第二行的注册中,应该是先probe设备,如果能够找到对应的设备,才会注册driver,否则会提示找不到设备。这是老式的probe方法。2.6内核中统一采用设备模型的方式管理了。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
8 [报告]
发表于 2009-04-29 15:52 |只看该作者
  1.         /* Write a magic value to the DS1302 RAM, and see if it sticks. */
  2.         ds1302_writebyte(RTC_ADDR_RAM0, 0x42);
  3.         if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42)
  4.                 return -ENODEV;
复制代码


调试一下你的probe函数。如果找不到设备的话,应该是是在上面的程序段中return -NODEV了。

论坛徽章:
8
2015年辞旧岁徽章
日期:2015-03-03 16:54:15午马
日期:2015-02-04 12:00:07羊年新春福章
日期:2015-02-04 11:57:56双子座
日期:2014-12-02 11:44:59金牛座
日期:2014-10-08 16:47:08狮子座
日期:2014-08-29 13:37:46巳蛇
日期:2014-08-26 17:32:29NBA常规赛纪念章
日期:2015-05-04 22:32:03
9 [报告]
发表于 2009-04-29 16:03 |只看该作者
原帖由 Godbach 于 2009-4-29 15:49 发表


你的驱动是在什么内核下使用的?

第二行的注册中,应该是先probe设备,如果能够找到对应的设备,才会注册driver,否则会提示找不到设备。这是老式的probe方法。2.6内核中统一采用设备模型的方式管理了。


驱动是在2.6内核下使用的。这个针对ds1302的驱动,是通过对2.6内核下drivers/rtc/rtc-ds1302.c代码进行修改的。目标板芯片是AT91RM9200。

论坛徽章:
8
2015年辞旧岁徽章
日期:2015-03-03 16:54:15午马
日期:2015-02-04 12:00:07羊年新春福章
日期:2015-02-04 11:57:56双子座
日期:2014-12-02 11:44:59金牛座
日期:2014-10-08 16:47:08狮子座
日期:2014-08-29 13:37:46巳蛇
日期:2014-08-26 17:32:29NBA常规赛纪念章
日期:2015-05-04 22:32:03
10 [报告]
发表于 2009-04-29 16:07 |只看该作者
原帖由 Godbach 于 2009-4-29 15:52 发表
        /* Write a magic value to the DS1302 RAM, and see if it sticks. */
        ds1302_writebyte(RTC_ADDR_RAM0, 0x42);
        if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42)
                re ...

我在probe函数中添加了打印信息。
static int __devinit ds1302_rtc_probe(struct platform_device *pdev)
{
        struct ds1302_rtc *rtc;
        int ret;

    printk("rtc-ds1302.c line 226\n)";

        /* Reset */
//        set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
    at91_set_gpio_value( AT91_PIN_PA6,0);
    at91_set_gpio_value( AT91_PIN_PA22,0);
    at91_set_gpio_value( AT91_PIN_PA23,0);

        /* Write a magic value to the DS1302 RAM, and see if it sticks. */
        ds1302_writebyte(RTC_ADDR_RAM0, 0x42);
        if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42)
                return -ENODEV;
....................
}
但是加载驱动时,没有打印出这个提示信息。说明系统没有调用这个probe函数,这是怎么回事啊???
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP