刚接触platform bus,学习的时候遇到一个问题。我现在想用1个led的driver驱动4个led的device。我的想法是先注册driver,然后注册device,每匹配上一个device就新建一个/dev/ledx(x 从0到3),然后在应用程序里打开不同的/dev/ledx来控制不同的led。但是我在实验的时候发现,不管我用应用程序打开哪个/dev/ledx,控制的永远是我最后一个注册的led device。led driver的代码在下面(只保留了platform相关内容)。我觉得是不是因为我的led的设备描述符只有一个(led_dev),所以最后注册的led device会覆盖以前注册的设备的信息,导致这种现象?那不知道一般对于这种问题的做法是什么?谢谢struct led_dev_t
{
const char * dev_name;
unsigned long major;
struct class * cls;
struct device * dev;
void * reg_virt_base;
int led_gpio_bit;
};static struct led_dev_t * led_dev;
int led_dev_release(struct inode *inode, struct file *filp)
{
return 0;
}
int pdrv_probe(struct platform_device * pdev)
{
struct resource * rsc; int ret;
unsigned int gpio_base_addr;
unsigned int gpio_base_addr_size;
unsigned int gpio_conf_val;
// Apply resources
printk("------------%s------------\n", __FUNCTION__);
// malloc memory for led description
led_dev = (struct led_dev_t *)kzalloc(sizeof(struct led_dev_t), GFP_KERNEL);
// get resource from device
rsc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
gpio_base_addr = (unsigned int)rsc->start;
gpio_base_addr_size = (unsigned int)resource_size(rsc);
led_dev->led_gpio_bit = *((int *)pdev->dev.platform_data);
led_dev->dev_name = pdev->dev.kobj.name; // register device number
led_dev->major = register_chrdev(0,led_dev->dev_name, &dev_fops); led_dev->cls = led_cls;
// create device node
led_dev->dev = device_create(led_dev->cls, NULL, MKDEV(led_dev->major, 1), NULL, led_dev->dev_name); // io remap
led_dev->reg_virt_base = ioremap(gpio_base_addr, gpio_base_addr_size); // config gpio as output
gpio_conf_val = readl(led_dev->reg_virt_base);
gpio_conf_val &= ~(0xf<<(led_dev->led_gpio_bit*4));
gpio_conf_val |= (0x1<<(led_dev->led_gpio_bit*4));
writel(gpio_conf_val, led_dev->reg_virt_base); return 0;
}int pdrv_remove(struct platform_device * pdev)
{
printk("-----------------------%s---------------------\n", __FUNCTION__);
device_destroy(led_dev->cls, MKDEV(led_dev->major, 1));
printk("devie destroyed!\n"); unregister_chrdev(led_dev->major, led_dev->dev_name);
printk("char dev unregistered!\n");
kfree(led_dev);
return 0;
}struct platform_device_id led_id_table[] = {
{"4412-led", 1},
};struct platform_driver pdrv = {
.probe = pdrv_probe,
.remove = pdrv_remove,
.driver = {
.name = "4412_led_driver",
},
.id_table = led_id_table,
};static int __init led_drv_init(void)
{
int ret; printk("-----------------------%s---------------------\n", __FUNCTION__); // construct /sys/bus/mybus/devices/...
ret = platform_driver_register(&pdrv);
if(ret != 0) {
printk("device register error!\n");
return ret;
} // create device class
led_cls = class_create(THIS_MODULE, "led");
if (IS_ERR(led_dev->cls))
{
printk(KERN_ERR "create class error\n");
kfree(led_dev);
return PTR_ERR(led_dev->cls);
} return 0;
}static void __exit led_drv_exit(void)
{
printk("-----------------------%s---------------------\n", __FUNCTION__);
class_destroy(led_dev->cls);
platform_driver_unregister(&pdrv);
}
module_init(led_drv_init);
module_exit(led_drv_exit);
MODULE_LICENSE("GPL");
{
const char * dev_name;
unsigned long major;
struct class * cls;
struct device * dev;
void * reg_virt_base;
int led_gpio_bit;
};static struct led_dev_t * led_dev;
int led_dev_release(struct inode *inode, struct file *filp)
{
return 0;
}
int pdrv_probe(struct platform_device * pdev)
{
struct resource * rsc; int ret;
unsigned int gpio_base_addr;
unsigned int gpio_base_addr_size;
unsigned int gpio_conf_val;
// Apply resources
printk("------------%s------------\n", __FUNCTION__);
// malloc memory for led description
led_dev = (struct led_dev_t *)kzalloc(sizeof(struct led_dev_t), GFP_KERNEL);
// get resource from device
rsc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
gpio_base_addr = (unsigned int)rsc->start;
gpio_base_addr_size = (unsigned int)resource_size(rsc);
led_dev->led_gpio_bit = *((int *)pdev->dev.platform_data);
led_dev->dev_name = pdev->dev.kobj.name; // register device number
led_dev->major = register_chrdev(0,led_dev->dev_name, &dev_fops); led_dev->cls = led_cls;
// create device node
led_dev->dev = device_create(led_dev->cls, NULL, MKDEV(led_dev->major, 1), NULL, led_dev->dev_name); // io remap
led_dev->reg_virt_base = ioremap(gpio_base_addr, gpio_base_addr_size); // config gpio as output
gpio_conf_val = readl(led_dev->reg_virt_base);
gpio_conf_val &= ~(0xf<<(led_dev->led_gpio_bit*4));
gpio_conf_val |= (0x1<<(led_dev->led_gpio_bit*4));
writel(gpio_conf_val, led_dev->reg_virt_base); return 0;
}int pdrv_remove(struct platform_device * pdev)
{
printk("-----------------------%s---------------------\n", __FUNCTION__);
device_destroy(led_dev->cls, MKDEV(led_dev->major, 1));
printk("devie destroyed!\n"); unregister_chrdev(led_dev->major, led_dev->dev_name);
printk("char dev unregistered!\n");
kfree(led_dev);
return 0;
}struct platform_device_id led_id_table[] = {
{"4412-led", 1},
};struct platform_driver pdrv = {
.probe = pdrv_probe,
.remove = pdrv_remove,
.driver = {
.name = "4412_led_driver",
},
.id_table = led_id_table,
};static int __init led_drv_init(void)
{
int ret; printk("-----------------------%s---------------------\n", __FUNCTION__); // construct /sys/bus/mybus/devices/...
ret = platform_driver_register(&pdrv);
if(ret != 0) {
printk("device register error!\n");
return ret;
} // create device class
led_cls = class_create(THIS_MODULE, "led");
if (IS_ERR(led_dev->cls))
{
printk(KERN_ERR "create class error\n");
kfree(led_dev);
return PTR_ERR(led_dev->cls);
} return 0;
}static void __exit led_drv_exit(void)
{
printk("-----------------------%s---------------------\n", __FUNCTION__);
class_destroy(led_dev->cls);
platform_driver_unregister(&pdrv);
}
module_init(led_drv_init);
module_exit(led_drv_exit);
MODULE_LICENSE("GPL");
解决方案 »
- 求助两个文件匹配关键词并替换字段
- 服务器占用cpu过高,怎么回事,如何解决
- 关于echo 问题
- Ubuntu16下安装NS-3.29编译问题~~~~~~~~
- 初学者在Openfoam安装过程中遇到了难题!求大神帮忙,以解燃眉之急!。
- dns服务器无法ping
- 求助domino认证
- 双网卡设备如何设置路由转发?
- 使用html,css,js,xul开发Linux GUI桌面应用
- 初学gobject,写了一个小demo但是编译不过去,未定义符号问题
- java -Djava.awt.headless=true怎么用???
- linux socket网络 绑定失败 bind errorInvalid argument
还是说在驱动注册的某个环节出错了,导致硬件IO信息被覆盖了?