首页 >> 大全

❤️⭐万字长文玩转总线设备驱动platform_device与platform_

2023-10-14 大全 31 作者:考证青年

文章目录 二、总线设备里面含有什么结构体? 1.2与结合1.与 如何进行关联1.3.1比对规则1.4 匹配成功后 三.代码示范

前言

总线设备驱动的引入是主要解决资源和驱动的问题,简称分离的思想,如果我们在开发引脚时,只需要更换资源就行了,驱动方面则不需要太大的变动,Linux内核提供了/这个个结构体来进行关联,一个是平台设备,一个是平台驱动,本文章的目的是深究资源与驱动具体是如何进行关联的。

一、Linux总线的重要函数 1.1注册与销毁函数

首先,要先了解有什么函数去进行连接之后才能一步步的进行分析

int ster( *pdev)

void ( *pdev)

这是两个注册与销毁的函数,我们使用总线设备时需要先进行注册,使用完毕后在进行销毁

1.2获得资源

truct resource *platform_get_resource(struct platform_device *dev,unsigned int type, unsigned int num)

该函数的作用是返回该dev(平台资源)中某类型(type)资源中的第几个(num):

1.3获得中断

int platform_get_irq(struct platform_device *dev, unsigned int num)

功能:获取该dev用到的第几个中断

1.4通过名字获得资源或者中断

struct resource *platform_get_resource_byname(struct platform_device *dev,unsigned int type,const char *name)int platform_get_irq_byname(struct platform_device *dev, const char *name)

顾名思义,可以通过名字来获取到你想要的那个资源或者中断,至于name是什么,可以后面在介绍

1.5同时注册多个dev

int platform_add_devices(struct platform_device **devs, int num)

通过二维数组存储多个dev,然后一一进行注册

二、总线设备里面含有什么结构体? 1.1从 开始

可以看到,里面有很多属性,重点关注上面几个,这个就是存储资源的结构体,那么,他的结构体存储在哪里呢,在 里面。

1.1.2 资源存储

比如我们可以把引脚号放在start里,中断放在flags里面

static struct resource resources[] = {{.start = GROUP_PIN(3,1),.flags = IORESOURCE_IRQ,},{.start = GROUP_PIN(5,8),.flags = IORESOURCE_IRQ,},
}

1.2与结合

1.与 如何进行关联

可以说上面这个结构体是连接他们两个的桥梁,通过这个函数来进行比对,继续深入

看到了把,回到我们熟悉的C语言逻辑了,通过这几个变量来进行对比

在这之前要先关注平台驱动里的 结构体

1.3.1比对规则

最先比较:. 和..name

可以设置的,强制选择某个

然后比较:. name和.[i].name

.是“”指针,表示该drv支持若干个,它里面列出了各个的{.name, .},其中的“name”表示该drv支持的设备的名字,是些提供给该的私有数据。

最后比较.name和..name

.可能为空,

这时可以根据..name来寻找同名的。

1.4 匹配成功后

当有匹配的时,它的probe函数就会被调用。

当进行设备卸载后函数则会被调用,我们可以在里面做自己想多的事

三.代码示范 3.1平台设备案例

#include #include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include #include "led_opr.h"
#include "leddrv.h"
#include "led_resource.h"static int g_ledpins[100];
static int g_ledcnt = 0;static int board_demo_led_init (int which) /* 初始化LED, which-哪个LED */       
{   //printk("%s %s line %d, led %d\n", __FILE__, __FUNCTION__, __LINE__, which);printk("init gpio: group %d, pin %d\n", GROUP(g_ledpins[which]), PIN(g_ledpins[which]));switch(GROUP(g_ledpins[which])){case 0:{printk("init pin of group 0 ...\n");break;}case 1:{printk("init pin of group 1 ...\n");break;}case 2:{printk("init pin of group 2 ...\n");break;}case 3:{printk("init pin of group 3 ...\n");break;}}return 0;
}static int board_demo_led_ctl (int which, char status) /* 控制LED, which-哪个LED, status:1-亮,0-灭 */
{//printk("%s %s line %d, led %d, %s\n", __FILE__, __FUNCTION__, __LINE__, which, status ? "on" : "off");printk("set led %s: group %d, pin %d\n", status ? "on" : "off", GROUP(g_ledpins[which]), PIN(g_ledpins[which]));switch(GROUP(g_ledpins[which])){case 0:{printk("set pin of group 0 ...\n");break;}case 1:{printk("set pin of group 1 ...\n");break;}case 2:{printk("set pin of group 2 ...\n");break;}case 3:{printk("set pin of group 3 ...\n");break;}}return 0;
}static struct led_operations board_demo_led_opr = {.init = board_demo_led_init,.ctl  = board_demo_led_ctl,
};struct led_operations *get_board_led_opr(void)
{return &board_demo_led_opr;
}static int chip_demo_gpio_probe(struct platform_device *pdev)
{struct resource *res;int i = 0;while (1){res = platform_get_resource(pdev, IORESOURCE_IRQ, i++);if (!res)break;g_ledpins[g_ledcnt] = res->start;led_class_create_device(g_ledcnt);g_ledcnt++;}return 0;}static int chip_demo_gpio_remove(struct platform_device *pdev)
{struct resource *res;int i = 0;while (1){res = platform_get_resource(pdev, IORESOURCE_IRQ, i);if (!res)break;led_class_destroy_device(i);i++;g_ledcnt--;}return 0;
}static struct platform_driver chip_demo_gpio_driver = {.probe      = chip_demo_gpio_probe,.remove     = chip_demo_gpio_remove,.driver     = {.name   = "100ask_led",},
};static int __init chip_demo_gpio_drv_init(void)
{int err;err = platform_driver_register(&chip_demo_gpio_driver); register_led_operations(&board_demo_led_opr);return 0;
}static void __exit lchip_demo_gpio_drv_exit(void)
{platform_driver_unregister(&chip_demo_gpio_driver);
}module_init(chip_demo_gpio_drv_init);
module_exit(lchip_demo_gpio_drv_exit);MODULE_LICENSE("GPL");

3.2资源设备案例


#include #include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include #include "led_resource.h"static void led_dev_release(struct device *dev)
{
}static struct resource resources[] = {{.start = GROUP_PIN(3,1),.flags = IORESOURCE_IRQ,.name = "100ask_led_pin",},{.start = GROUP_PIN(5,8),.flags = IORESOURCE_IRQ,.name = "100ask_led_pin",},
};static struct platform_device board_A_led_dev = {.name = "100ask_led",.num_resources = ARRAY_SIZE(resources),.resource = resources,.dev = {.release = led_dev_release,},
};static int __init led_dev_init(void)
{int err;err = platform_device_register(&board_A_led_dev);   return 0;
}static void __exit led_dev_exit(void)
{platform_device_unregister(&board_A_led_dev);
}module_init(led_dev_init);
module_exit(led_dev_exit);MODULE_LICENSE("GPL");

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了