加载驱动出错:No such device(已解决,谢谢各位大侠)

发布于 2022-09-18 18:04:10 字数 254 浏览 17 评论 0

小弟编译一个AT91RM9200的外接时钟ds1302的驱动,编译没有问题。下载到开发板,执行命令:
#insmod rtc-ds1302.ko
出现如下错误:
insmod: cannot insert 'rtc-ds1302.ko': No such device

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

人生戏 2022-09-25 18:04:10

开发板上相应的硬件已经有了吗

懵少女 2022-09-25 18:04:10

提示应该很明确,驱动找不到对应的设备

想你只要分分秒秒 2022-09-25 18:04:10

硬件连接都没有问题的

oО清风挽发oО 2022-09-25 18:04:10

这是我的驱动代码,请大侠指点下迷津啊
#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";

淡淡離愁欲言轉身 2022-09-25 18:04:10

在函数
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

梦过后 2022-09-25 18:04:10

在函数
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内核中统一采用设备模型的方式管理了。

望喜 2022-09-25 18:04:10
  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了。

遗忘曾经 2022-09-25 18:04:10

原帖由 Godbach 于 2009-4-29 15:49 发表

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

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

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

终止放荡 2022-09-25 18:04:10

原帖由 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函数,这是怎么回事啊???

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文