Linux驱动编程 - platform平台设备驱动总线

Linux平台设备驱动总线及设备树解析

目录

简介:

一、初识platform平台设备驱动

1、platform_driver驱动代码框架

2、platform_device设备代码框架

3、测试结果

3.1 Makefile编译

3.2 加载驱动

二、platform框架分析

1、注册platform总线

1.1 创建platform平台总线函数调用流程

1.2 platform_bus_init() 函数

2、注册platform_driver

2.1 platform_driver_register函数流程

2.2 匹配过程

2.3 调用probe函数

3、注册platform_device

3.1 platform_device_register函数流程

三、dts设备树

1、设备树的匹配过程

2、设备树与platform_driver匹配示例

2.1 dts设备树文件

​编辑

2.2 platform_driver 驱动代码


简介:


        Linux系统为了驱动的可重用性,提出驱动的分离与分层的软件思路,为了保持设备驱动的统一性,platform平台设备驱动模型就此诞生。相对于USB、PCI、I2C、SPI等物理总线来说,platform总线是虚拟、抽象出来的总线,实际中并不存在这样的总线。

说明:本文基于Linux版本为4.1.15

一、初识platform平台设备驱动


        platform平台总线下有驱动链表设备链表,当调用 platform_driver_register() 注册platform驱动,或调用 platform_device_register() 注册platform设备时,都会执行match匹配函数。当链表中有platform驱动和platform设备匹配上,就会调用platform驱动probe() 函数。

图解platform_driver和platform_device匹配过程:

比较 platform_driver 的 driver->name 与 platform_device 的 name 相同都为 "myled",就会执行 platform_driver 的 probe函数,这里为 led_probe。led_probe函数由我们自己定义实现注册字符设备等功能。

platform 总线设备驱动大概有以下步骤:

  • platform_device_register() 注册平台设备
  • platform_driver_register() 注册平台驱动
  • platform总线自动匹配name,匹配上就调用 driver 的 .probe
  • probe中注册字符设备等操作

1、platform_driver驱动代码框架


#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>

/* 当驱动driver->name和设备name相同, 则调用驱动的.probe函数, .probe函数可以做任何事情 */
static int led_probe(struct platform_device *pdev)
{
	/* 注册字符设备等操作 */
	printk("platform_driver probe run!\n");
	return 0;
}

static int led_remove(struct platform_device *pdev)
{
	/* 卸载字符设备等操作 */
	printk("platform_driver remove run!\n");
	return 0;
}

/* 定义平台drv,通过.name来比较dev */
struct platform_driver led_drv = {
	.probe		= led_probe,
	.remove		= led_remove,
	.driver		= {
		.name	= "myled",
	}
};

static int led_drv_init(void)
{
	platform_driver_register(&led_drv);			//注册驱动,最终调用driver_register()
	return 0;
}

static void led_drv_exit(void)
{
	platform_driver_unregister(&led_drv);
}

module_init(led_drv_init);
module_exit(led_drv_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("dongao");

platform_get_resource()可以从platform_device中获取资源。linux支持设备树后,platform_get_resource() 就不常用了。

2、platform_device设备代码框架


#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>

static void led_release(struct device * dev)		//构造一个release函数,防止报错
{
}

/* platform_device结构体.name与platform_driver的driver->name比较 */
static struct platform_device led_dev = {
    .name         = "myled",
    .id       = -1,
    //.num_resources    = ARRAY_SIZE(led_resource), //可以将device的资源传给driver使用
    //.resource     = led_resource,
    .dev = { 
    	.release = led_release, 
	},
};

static int led_dev_init(void)
{
	platform_device_register(&led_dev);				//注册1个平台设备,最终调用device_add()
	return 0;
}

static void led_dev_exit(void)
{
	platform_device_unregister(&led_dev);			//卸载1个平台设备
}

module_init(led_dev_init);
module_exit(led_dev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("dongao");

3、测试结果


3.1 Makefile编译

KERN_DIR = /home/linux-imx-rel_imx_4.1.15_2.1.0
 
all:
	make -C $(KERN_DIR) M=`pwd` modules
 
clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order
 
obj-m   += led_drv.o
obj-m   += led_dev.o

3.2 加载驱动


加载编译出来的2个ko文件。

$ insmod led_dev.ko               # 加载 platform_device 驱动

$ insmod led_drv.ko                # 加载 platform_driver 驱动

结果: 

结果,运行probe 打印 "platform_driver remove run!"

查看在系统中的驱动:

$ ls  /sys/bus/platform/devices 

$ ls  /sys/bus/platform/drivers/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值