免费注册 查看新帖 |

Chinaunix

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

Led驱动Platform设备注册后无法调用probe函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-03-09 17:04 |只看该作者 |倒序浏览
做了个简单的led驱动,网上和书上都说device和driver注册后,如果name匹配的话就会调用probe进行加载,可是当我注册了device和driver后没有调用probe,不知道为什么,请各位大大帮忙看看,感激不尽!:)

led.h
  1. #include <linux/device.h>
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/miscdevice.h>
  5. #include <linux/fs.h>
  6. #include <linux/slab.h>
  7. #include <linux/err.h>
  8. #include <asm/arch/regs-gpio.h>
  9. #include <asm/arch/hardware.h>
  10. #include <asm/hardware.h>
  11. #include <asm/delay.h>

  12. #define LED_MINOR 0
  13. #define LED_DRIVER "Led Driver For Test"
  14. #define DEV_NAME "LED"

  15. static int led_open (struct inode *node, struct file *filp);
  16. static int led_ioctl (struct inode *node, struct file *filp, unsigned int cmd, unsigned long arg);
  17. static ssize_t led_write (struct file *filp, const char __user *buf, size_t count, loff_t *f_ops);
  18. static int led_probe(struct device * dev);
  19. static int led_remove(struct device * dev);
  20. static int led_release (struct inode *node, struct file *filp);

  21. static struct file_operations led_fops = {
  22.     .owner  =   THIS_MODULE,
  23.     .open   =   led_open,
  24.     .write  =   led_write,
  25.     .ioctl  =   led_ioctl,
  26.     .release    =   led_release,
  27. };

  28. static struct miscdevice led_miscdev = {
  29.     MISC_DYNAMIC_MINOR,
  30.     DEV_NAME,
  31.     &led_fops,
  32. };

  33. struct platform_device *led_dev;
  34. static struct device_driver led_driver = {
  35.     .name   =   DEV_NAME,
  36.     .bus    =   &platform_bus_type,
  37.     .probe  =   led_probe,
  38.     .remove =   led_remove,
  39. };

  40. static unsigned long led_table[] = {
  41.     S3C2410_GPF4,
  42.     S3C2410_GPF5,
  43.     S3C2410_GPF6,
  44.     S3C2410_GPF7,
  45. };

  46. static unsigned long led_cfg_table[] = {
  47.     S3C2410_GPF4_OUTP,
  48.     S3C2410_GPF5_OUTP,
  49.     S3C2410_GPF6_OUTP,
  50.     S3C2410_GPF7_OUTP,
  51. };


复制代码
led.c
  1. #include "led.h"

  2. static void led_on_off(int led_num,int led_on_off){
  3.     //1 for on,2 for off
  4.     if (led_num>ARRAY_SIZE(led_table)-1)
  5.         return;

  6.     s3c2410_gpio_setpin(led_table[led_num],led_on_off );
  7. }

  8. static void all_led_on(void){
  9.     int i;
  10.     for(i=0;i<ARRAY_SIZE(led_table);i++){
  11.         s3c2410_gpio_setpin(led_table[i],0);
  12.     }
  13. }

  14. static void all_led_out(void){
  15.     int i;
  16.     for(i=0;i<ARRAY_SIZE(led_table);i++){
  17.         s3c2410_gpio_setpin(led_table[i],1);
  18.     }
  19. }

  20. static void leds_init(void){
  21.     int i;
  22.     for(i=0;i<ARRAY_SIZE(led_table);i++){
  23.         s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]);
  24.     }
  25. }
  26.    

  27. static ssize_t led_write (struct file *filp, const char __user *buf, size_t count, loff_t *f_ops){
  28.     return 0;
  29. }

  30. static int led_ioctl (struct inode *node, struct file *filp, unsigned int cmd, unsigned long arg){
  31.     return 0;
  32. }


  33. static int led_open (struct inode *node, struct file *filp){
  34.     printk("led driver is opened.\n");
  35.     return 0;
  36. }

  37. static int led_release (struct inode *node, struct file *filp){
  38.     printk("led driver is closed.\n");
  39.     return 0;
  40. }

  41. static int led_probe(struct device * dev){
  42.     misc_register(&led_miscdev);
  43.     printk("%s is installed.\n",LED_DRIVER);

  44.     all_led_on();
  45.    
  46.     printk("%s probe!\n",DEV_NAME);
  47.     return 0;
  48. }

  49. static int led_remove(struct device * dev){
  50.     all_led_out();
  51.    
  52.     if(misc_deregister(&led_miscdev))
  53.       printk("misc device is deregister!\n");

  54.     printk("%s remove!\n",DEV_NAME);
  55.     return 0;
  56. }

  57. static int __init led_init(void){
  58.     int ret;

  59.     led_dev = platform_device_register_simple(DEV_NAME,-1,NULL,0);
  60.     if(IS_ERR(led_dev)){
  61.         printk("failed to register device %s",DEV_NAME);
  62.         return -EINVAL;
  63.     }
  64.     printk("Device is sucessfully registered.\n");

  65.     ret = driver_register(&led_driver);
  66.     if(ret){
  67.         platform_device_unregister(led_dev);
  68.         printk("failed to register driver %s",LED_DRIVER);
  69.         return -EINVAL;
  70.     }
  71.     printk("Driver is sucessfully registered.\n");


  72.     leds_init();
  73.     return 0;
  74. }

  75. static void __exit led_exit(void){
  76.     driver_unregister(&led_driver);
  77.     platform_device_unregister(led_dev);

  78.     printk("led modules exit!\n");
  79. }


  80. module_init(led_init);
  81. module_exit(led_exit);

  82. MODULE_AUTHOR("Jackie Cheung");
  83. MODULE_LICENSE("GPL");
复制代码

论坛徽章:
0
2 [报告]
发表于 2011-03-09 19:00 |只看该作者
顶上去~!

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
3 [报告]
发表于 2011-03-10 08:32 |只看该作者
对着例子模仿下吧,要不多加点printk看看跑了哪些,多调一下就明白了~

(不愿仔细看代码,)

论坛徽章:
0
4 [报告]
发表于 2011-03-10 12:59 |只看该作者
你从内核拷贝个led.c的驱动,然后把所有的都删掉。


然后留下注册,和probe然后一步一步加你想要的功能.


不愿意这样做,你可以在你所有的函数里加printk,像这样贴一篇代码上来,大多数人只看个驱动名称,是led,愿意再看的就几乎没有了。

论坛徽章:
0
5 [报告]
发表于 2011-03-10 15:24 |只看该作者
我觉得你应该用platform_driver_register()注册相对应的平台驱动结构体,使他们属于platform总线下。而不是driver_register(),使用driver_register()后他们不是属于同一总线下,是不会匹配的吧?

论坛徽章:
0
6 [报告]
发表于 2011-03-10 15:53 |只看该作者
首先,你应该定义的是struct platform_device 结构体对象,而不是指针,并把把它的name赋值
其次你应该定义的是   struct platform_driver 结构体对象,而不是device_driver的对象,且要对其中的.driver.name赋值一样的名字,或者为id_table赋值。
第三,应该是在init函数中用platform_device_register以及platform_driver_register进行注册。device和device_driver只是虚基类,一般不会直接引用的,像platform, PCI USB等都是继承的该类。

论坛徽章:
0
7 [报告]
发表于 2011-03-10 15:55 |只看该作者
而且最好将device和driver分开编写成两个模块,然后先insmod device 然后再insmod driver。写在一起的这种做法貌似不是很推荐。

论坛徽章:
0
8 [报告]
发表于 2011-03-11 10:53 |只看该作者
如果是arm核的话,那要在/arch/arm/mach-xxxx/devs.c中添加struct platform_device  my_device_led,, 然后在/arch/arm/mach-xxxx/mach-xxxx.c中的static struct platform_device *smdkxxx_devices[] __initdata = {中添加&my_device_led

请参考可以否

论坛徽章:
0
9 [报告]
发表于 2011-03-11 13:08 |只看该作者
看来楼主的麻烦还是比较多的 。。最好多加点打印信息哦。。看走到哪里去了。还有 我不明白的是 楼主是把这个驱动编译成模块的 还是直接编进内核的呢?

论坛徽章:
0
10 [报告]
发表于 2011-03-11 13:41 |只看该作者
非常感谢各位!
原来Linux设备模型只适用于编译进内核么?就是说platform_device和platform_driver的形式来写驱动不适用于编译成模块再insmod加载?

另外我用的是FS2410开发板,预装Linux2.6.8,所以我懒得移植新版内核就用这个了,而这个内核是没有Platform_driver的,所以就用device_driver了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP