Led驱动Platform设备注册后无法调用probe函数
做了个简单的led驱动,网上和书上都说device和driver注册后,如果name匹配的话就会调用probe进行加载,可是当我注册了device和driver后没有调用probe,不知道为什么,请各位大大帮忙看看,感激不尽!:)led.h#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/hardware.h>
#include <asm/hardware.h>
#include <asm/delay.h>
#define LED_MINOR 0
#define LED_DRIVER "Led Driver For Test"
#define DEV_NAME "LED"
static int led_open (struct inode *node, struct file *filp);
static int led_ioctl (struct inode *node, struct file *filp, unsigned int cmd, unsigned long arg);
static ssize_t led_write (struct file *filp, const char __user *buf, size_t count, loff_t *f_ops);
static int led_probe(struct device * dev);
static int led_remove(struct device * dev);
static int led_release (struct inode *node, struct file *filp);
static struct file_operations led_fops = {
.owner= THIS_MODULE,
.open = led_open,
.write= led_write,
.ioctl= led_ioctl,
.release = led_release,
};
static struct miscdevice led_miscdev = {
MISC_DYNAMIC_MINOR,
DEV_NAME,
&led_fops,
};
struct platform_device *led_dev;
static struct device_driver led_driver = {
.name = DEV_NAME,
.bus = &platform_bus_type,
.probe= led_probe,
.remove = led_remove,
};
static unsigned long led_table[] = {
S3C2410_GPF4,
S3C2410_GPF5,
S3C2410_GPF6,
S3C2410_GPF7,
};
static unsigned long led_cfg_table[] = {
S3C2410_GPF4_OUTP,
S3C2410_GPF5_OUTP,
S3C2410_GPF6_OUTP,
S3C2410_GPF7_OUTP,
};
led.c#include "led.h"
static void led_on_off(int led_num,int led_on_off){
//1 for on,2 for off
if (led_num>ARRAY_SIZE(led_table)-1)
return;
s3c2410_gpio_setpin(led_table,led_on_off );
}
static void all_led_on(void){
int i;
for(i=0;i<ARRAY_SIZE(led_table);i++){
s3c2410_gpio_setpin(led_table,0);
}
}
static void all_led_out(void){
int i;
for(i=0;i<ARRAY_SIZE(led_table);i++){
s3c2410_gpio_setpin(led_table,1);
}
}
static void leds_init(void){
int i;
for(i=0;i<ARRAY_SIZE(led_table);i++){
s3c2410_gpio_cfgpin(led_table,led_cfg_table);
}
}
static ssize_t led_write (struct file *filp, const char __user *buf, size_t count, loff_t *f_ops){
return 0;
}
static int led_ioctl (struct inode *node, struct file *filp, unsigned int cmd, unsigned long arg){
return 0;
}
static int led_open (struct inode *node, struct file *filp){
printk("led driver is opened.\n");
return 0;
}
static int led_release (struct inode *node, struct file *filp){
printk("led driver is closed.\n");
return 0;
}
static int led_probe(struct device * dev){
misc_register(&led_miscdev);
printk("%s is installed.\n",LED_DRIVER);
all_led_on();
printk("%s probe!\n",DEV_NAME);
return 0;
}
static int led_remove(struct device * dev){
all_led_out();
if(misc_deregister(&led_miscdev))
printk("misc device is deregister!\n");
printk("%s remove!\n",DEV_NAME);
return 0;
}
static int __init led_init(void){
int ret;
led_dev = platform_device_register_simple(DEV_NAME,-1,NULL,0);
if(IS_ERR(led_dev)){
printk("failed to register device %s",DEV_NAME);
return -EINVAL;
}
printk("Device is sucessfully registered.\n");
ret = driver_register(&led_driver);
if(ret){
platform_device_unregister(led_dev);
printk("failed to register driver %s",LED_DRIVER);
return -EINVAL;
}
printk("Driver is sucessfully registered.\n");
leds_init();
return 0;
}
static void __exit led_exit(void){
driver_unregister(&led_driver);
platform_device_unregister(led_dev);
printk("led modules exit!\n");
}
module_init(led_init);
module_exit(led_exit);
MODULE_AUTHOR("Jackie Cheung");
MODULE_LICENSE("GPL");
顶上去~!:roll: 对着例子模仿下吧,要不多加点printk看看跑了哪些,多调一下就明白了~
(不愿仔细看代码,:lol::lol:) 你从内核拷贝个led.c的驱动,然后把所有的都删掉。
然后留下注册,和probe然后一步一步加你想要的功能.
不愿意这样做,你可以在你所有的函数里加printk,像这样贴一篇代码上来,大多数人只看个驱动名称,是led,愿意再看的就几乎没有了。 我觉得你应该用platform_driver_register()注册相对应的平台驱动结构体,使他们属于platform总线下。而不是driver_register(),使用driver_register()后他们不是属于同一总线下,是不会匹配的吧? 首先,你应该定义的是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等都是继承的该类。 而且最好将device和driver分开编写成两个模块,然后先insmod device 然后再insmod driver。写在一起的这种做法貌似不是很推荐。 如果是arm核的话,那要在/arch/arm/mach-xxxx/devs.c中添加struct platform_devicemy_device_led,, 然后在/arch/arm/mach-xxxx/mach-xxxx.c中的static struct platform_device *smdkxxx_devices[] __initdata = {中添加&my_device_led
请参考可以否 看来楼主的麻烦还是比较多的 。。最好多加点打印信息哦。。看走到哪里去了。还有 我不明白的是 楼主是把这个驱动编译成模块的 还是直接编进内核的呢? 非常感谢各位!
原来Linux设备模型只适用于编译进内核么?就是说platform_device和platform_driver的形式来写驱动不适用于编译成模块再insmod加载?
另外我用的是FS2410开发板,预装Linux2.6.8,所以我懒得移植新版内核就用这个了,而这个内核是没有Platform_driver的,所以就用device_driver了。
页:
[1]
2