Linux系统之Platform设备驱动

Linux platform 设备驱动实验 本篇文章主要介绍了总线--驱动----设备模型下的platform总线的初始化过程,如何进行设备和驱动的匹配和绑定的?以及从源码的角度解释了为什么会执行驱动中的probe函数。 阅读详情

Linux系统之Platform设备驱动https://mp.weixin.qq.com/s?__biz=Mzg3NDkwMjc2NA==&mid=2247483754&idx=1&sn=222dcdd1d30fa541b40bdf29c440f6c0&chksm=cec8e4e9f9bf6dffd6213094f1dee1d3a6bec6a8e08c4dedeff3dab6e4ba854d11d03898d2ca#rd

在Linux系统中,驱动的设计充分体现了“高内聚、低耦合”的软件设计思想。这种思想体现在驱动设计的分层、分离上,下文将简单介绍platform设备驱动的实现,让我们来感受一下驱动设计的哲学。

platform设备驱动包含platform总线、platform设备和platform驱动三个部分,下面将分别介绍这三个部分。

1 platform 设备

platform设备通常包含设备的硬件资源。

未引入设备树之前,片上外设的硬件资源通常在arch/arm/mach-xxx/board-xxx.c定义,并由内核自动注册为platform设备。

引入设备树后,硬件资源不再集成到Linux源码中,而是按照设备树语法编写成设备树文件,并进行单独编译(.dtb)。把板级的硬件信息从源码中分离出来,并对其使用统一的方式管理,我认为既降低了系统维护的难度,也有利于保持代码的干净。

在内核启动的过程中,会对设备树进行解析,把对应的设备节点转换成platform设备。

flatform设备在Linux系统中的抽象如下:

//linux-4.1.15/include/linux/platform_device.h
struct platform_device {
	const char	*name;
	int		id;
	bool		id_auto;
	struct device	dev;
	u32		num_resources;
	struct resource	*resource;

	const struct platform_device_id	*id_entry;
	char *driver_override; /* Driver name to force a match */

	/* MFD cell pointer */
	struct mfd_cell *mfd_cell;

	/* arch specific additions */
	struct pdev_archdata	archdata;
};

其中resource结构体就是用于登记相关的硬件资源信息,如资源的类型、资源的地址空间等等,这里将不展开叙述,有兴趣的朋友可以查阅注册platform设备的相关代码。

2 platform 驱动

platform驱动一般由驱动工程师编写。当我们把platform驱动注册到platform总线时,platform总线会根据platform驱动的参数,查找与之匹配的设备。当存在与驱动匹配的设备时,总线将会把设备和驱动绑定。驱动可调用相关的接口获取设备资源,并驱动设备。

flatform设备在Linux系统中的抽象如下:

//linux-4.1.15/include/linux/platform_device.h
struct platform_driver {
	int (*probe)(struct platform_device *);
	int (*remove)(struct platform_device *);
	void (*shutdown)(struct platform_device *);
	int (*suspend)(struct platform_device *, pm_message_t state);
	int (*resume)(struct platform_device *);
	struct device_driver driver;
	const struct platform_device_id *id_table;
	bool prevent_deferred_probe;
};

将在示例中详细说明这个结构体的各个元素的作用。

3 platform 总线

platform总线是Linux系统发明的虚拟总线。如同I2C、SPI等总线,其作用是建立主机和从机通信的通道。platform总线的作用是根据相关规则匹配设备和驱动,使驱动与对应的设备建立联系。

flatform总线在Linux系统中的抽象如下:

//linux-4.1.15/drivers/base/platform.c
struct bus_type platform_bus_type = {
	.name		= "platform",
	.dev_groups	= platform_dev_groups,
	.match		= platform_match,
	.uevent		= platform_uevent,
	.pm		= &platform_dev_pm_ops,
};
EXPORT_SYMBOL_GPL(platform_bus_type);

其中 platform_match 就是负责设备与驱动的匹配工作。

/** -> linux-4.1.15/drivers/base/platform.c
 * platform_match - bind platform device to platform driver.
 * @dev: device.
 * @drv: driver.
 *
 * Platform device IDs are assumed to be encoded like this:
 * "<name><instance>", where <name> is a short description of the type of
 * device, like "pci" or "floppy", and <instance> is the enumerated
 * instance of the device, like '0' or '42'.  Driver IDs are simply
 * "<name>".  So, extract the <name> from the platform_device structure,
 * and compare it against the name of the driver. Return whether they match
 * or not.
 */
static int platform_match(struct device *dev, struct device_driver *drv)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct platform_driver *pdrv = to_platform_driver(drv);

	/* When driver_override is set, only bind to the matching driver */
	if (pdev->driver_override)
		return !strcmp(pdev->driver_override, drv->name);

	/* Attempt an OF style match first */
	if (of_driver_match_device(dev, drv)) /* --> 匹配设备树的compatible属性和设备驱动的compatible属性 */
		return 1;

	/* Then try ACPI style match */
	if (acpi_driver_match_device(dev, drv))
		return 1;

	/* Then try to match against the id table */
	if (pdrv->id_table) 
		return platform_match_id(pdrv->id_table, pdev) != NULL;/* --> 匹配设备和驱动的id table */

	/* fall-back to driver name match */
	return (strcmp(pdev->name, drv->name) == 0); /* --> 匹配设备和驱动的名字 */
}

可以看到这个接口根据struct platform_device和struct platform_driver的信息进行匹配绑定。

4 示例

在这个示例中,

  • 调用<late_initcall>接口,

    注册一个module:<pwm_backlight_init>

    在Linux启动过程中将会加载这个module

  • 在这个module中注册一个platform设备驱动

    (这个驱动抽象为<pwm_backlight_driver>结构体)

    <platform_driver_register(&pwm_backlight_driver); >

  • 在<pwm_backlight_driver>中可以看到该驱动的名字<.name= "pwm-backlight",>和设备树的匹配属性<{ .compatible = "pwm-backlight" },>

    platform总线将会根据这两个参数匹配已注册的设备

  • 当我们的platform驱动注册后,platform总线将驱动与总线上的设备进行匹配,当匹配属性一致时,驱动将与该设备进行绑定,并执行<pwm_backlight_driver>中的<pwm_backlight_probe>函数

  • 在probe函数中,我们将解析设备节点的资源,并以此初始化相关的硬件外设(GPIO、PWM等)

  • 完成初始化的外设可以通过系统调用的方式供上层应用使用,也可以导出符号表供其他驱动模块使用

  • 当我们卸载驱动(insmod加载,rmmod卸载)后

    将会执行<pwm_backlight_driver>中的

    <pwm_backlight_remove>函数,这个函数将会释放驱动所占用的硬件和内存资源,如注销pwm,释放申请的内存空间等

/linux-4.1.15/drivers/video/backlight/pwm_bl.c
/*
 * linux/drivers/video/backlight/pwm_bl.c
 *
 * simple PWM based backlight control, board code has to setup
 * 1) pin configuration so PWM waveforms can output
 * 2) platform_data being correctly configured
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
......

struct pwm_bl_data {
	struct device		*dev;
	......
};

static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness)
{
	......
}

static void pwm_backlight_power_off(struct pwm_bl_data *pb)
{
	......
}

static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness)
{
	......
}

static int pwm_backlight_update_status(struct backlight_device *bl)
{

	......
}

static int pwm_backlight_check_fb(struct backlight_device *bl,
				  struct fb_info *info)
{
	......
}
}

static const struct backlight_ops pwm_backlight_ops = {
	.update_status	= pwm_backlight_update_status,
	.check_fb	= pwm_backlight_check_fb,
};

#ifdef CONFIG_OF
static int pwm_backlight_check_fb_name(struct device *dev, struct fb_info *info)
{
	struct backlight_device *bl = dev_get_drvdata(dev);
	struct pwm_bl_data *pb = bl_get_data(bl);

	if (strcmp(info->fix.id, pb->fb_id) == 0)
		return true;

	return false;
}

static int pwm_backlight_parse_dt(struct device *dev,
				  struct platform_pwm_backlight_data *data)
{
	struct device_node *node = dev->of_node;
	struct property *prop;
	int length;
	u32 value;
	const char *names;
	......
	/* determine the number of brightness levels */
	prop = of_find_property(node, "brightness-levels", &length);
	......

	/* read brightness levels from DT property */
	if (data->max_brightness > 0) {	
		......
		ret = of_property_read_u32_array(node, "brightness-levels",
						 data->levels,
						 data->max_brightness);
		......

		ret = of_property_read_u32(node, "default-brightness-level",
					   &value);
		......
	}

	if (!of_property_read_string(node, "fb-names", &names)){
		strcpy(data->fb_id, names);
		......
	}
	......
	return 0;
}

static struct of_device_id pwm_backlight_of_match[] = {
	{ .compatible = "pwm-backlight" },
	{ }
};

MODULE_DEVICE_TABLE(of, pwm_backlight_of_match);
#else
static int pwm_backlight_parse_dt(struct device *dev,
				  struct platform_pwm_backlight_data *data)
{
	return -ENODEV;
}
#endif

static int pwm_backlight_probe(struct platform_device *pdev)
{
	struct platform_pwm_backlight_data *data = dev_get_platdata(&pdev->dev);
	struct platform_pwm_backlight_data defdata;
	struct backlight_properties props;
	struct backlight_device *bl;
	struct pwm_bl_data *pb;
	int ret;

	if (!data) {
		ret = pwm_backlight_parse_dt(&pdev->dev, &defdata);
		......
		data = &defdata;
	}

	if (data->init) {
		ret = data->init(&pdev->dev);
		......
	}

	......
	if (data->levels) {
		unsigned int i;

		for (i = 0; i <= data->max_brightness; i++)
			if (data->levels[i] > pb->scale)
				pb->scale = data->levels[i];

		pb->levels = data->levels;
	} else
		pb->scale = data->max_brightness;

	......
	pb->dev = &pdev->dev;
	......

	pb->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable");
	......

	/*
	 * Compatibility fallback for drivers still using the integer GPIO
	 * platform data. Must go away soon.
	 */
	if (!pb->enable_gpio && gpio_is_valid(data->enable_gpio)) {
		ret = devm_gpio_request_one(&pdev->dev, data->enable_gpio,
					    GPIOF_OUT_INIT_HIGH, "enable");
		......
		pb->enable_gpio = gpio_to_desc(data->enable_gpio);
	}

	if (pb->enable_gpio)
		gpiod_direction_output(pb->enable_gpio, 1);

	pb->power_supply = devm_regulator_get(&pdev->dev, "power");
	......

	pb->pwm = devm_pwm_get(&pdev->dev, NULL);
	......

	dev_dbg(&pdev->dev, "got pwm for backlight\n");

	/*
	 * The DT case will set the pwm_period_ns field to 0 and store the
	 * period, parsed from the DT, in the PWM device. For the non-DT case,
	 * set the period from platform data if it has not already been set
	 * via the PWM lookup table.
	 */
	pb->period = pwm_get_period(pb->pwm);
	if (!pb->period && (data->pwm_period_ns > 0)) {
		pb->period = data->pwm_period_ns;
		pwm_set_period(pb->pwm, data->pwm_period_ns);
	}

	pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale);

	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_RAW;
	props.max_brightness = data->max_brightness;
	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
				       &pwm_backlight_ops, &props);
	if (IS_ERR(bl)) {
		dev_err(&pdev->dev, "failed to register backlight\n");
		ret = PTR_ERR(bl);
		goto err_alloc;
	}

	if (data->dft_brightness > data->max_brightness) {
		dev_warn(&pdev->dev,
			 "invalid default brightness level: %u, using %u\n",
			 data->dft_brightness, data->max_brightness);
		data->dft_brightness = data->max_brightness;
	}

	bl->props.brightness = data->dft_brightness;
	backlight_update_status(bl);

	platform_set_drvdata(pdev, bl);
	return 0;

......
	return ret;
}

static int pwm_backlight_remove(struct platform_device *pdev)
{
	struct backlight_device *bl = platform_get_drvdata(pdev);
	struct pwm_bl_data *pb = bl_get_data(bl);

	backlight_device_unregister(bl);
	pwm_backlight_power_off(pb);

	if (pb->exit)
		pb->exit(&pdev->dev);
	if (pb->legacy)
		pwm_free(pb->pwm);

	return 0;
}

static void pwm_backlight_shutdown(struct platform_device *pdev)
{
	......
}

#ifdef CONFIG_PM_SLEEP
static int pwm_backlight_suspend(struct device *dev)
{
	......
	return 0;
}

static int pwm_backlight_resume(struct device *dev)
{
	......
	return 0;
}
#endif

static const struct dev_pm_ops pwm_backlight_pm_ops = {
#ifdef CONFIG_PM_SLEEP
	.suspend = pwm_backlight_suspend,
	.resume = pwm_backlight_resume,
	.poweroff = pwm_backlight_suspend,
	.restore = pwm_backlight_resume,
#endif
};

static struct platform_driver pwm_backlight_driver = {
	.driver		= {
		.name		= "pwm-backlight",
		.pm		= &pwm_backlight_pm_ops,
		.of_match_table	= of_match_ptr(pwm_backlight_of_match),
	},
	.probe		= pwm_backlight_probe,
	.remove		= pwm_backlight_remove,
	.shutdown	= pwm_backlight_shutdown,
};

static int __init pwm_backlight_init(void) 
{ 
        return platform_driver_register(&pwm_backlight_driver); 
} 
//module_init(pwm_backlight_init); 
late_initcall(pwm_backlight_init); 

static void __exit pwm_backlight_exit(void) 
{ 
        platform_driver_unregister(&pwm_backlight_driver); 
} 
module_exit(pwm_backlight_exit);

//module_platform_driver(pwm_backlight_driver);

MODULE_DESCRIPTION("PWM based Backlight Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pwm-backlight");

5 结束语

至此,Platform设备驱动已介绍完毕,希望本文可以帮助到大家!

欢迎大家通过后台与我交流学习心得,水平有限,如有错漏的地方请不吝指出,谢谢!

Linux驱动开发之platform驱动 本文通过设计使用platform架构的ds18b20程序驱动,来介绍如何编写platform驱动。 阅读详情

相关推荐

Linux·platform驱动框架

驱动框架-platform驱动框架

m0_64560763的博客 1843

一张图掌握 Linux platform 平台设备驱动框架!【建议收藏】

嵌入式系统中有很多的物理总线:I2c、SPI、USB、uart、PCIE、APB、AHB。像这样的总线很多,而 Linux 系统要考虑到驱动的可重用性,因此提出了驱动的分离与分层这样的软件思路,于是 Linux从2.6起就加入了 platform 设备驱动,也叫做平台设备驱动。它是一条虚拟的总线, 并不是一个物理的总线。如下图所示:(本文不考虑设备树的情况):

火山上的企鹅 3万+

Linux设备驱动开发-platform总线

在嵌入式系统里面,SoC系统中集成的独立的外设控制器、挂接在SoC内存空间的外设等确不依附于总线。也就是说在嵌入式CPU中,访问外设跟访问内存是一样的。基于这一背景,Linux发明了一种虚拟的总线,称为platform总线,相应的设备称为platform_device,而驱动成为 platform_driver。物理总线:芯片与各个功能外设之间传送信息的公共通信干线,其中又包括数据总线、地址总线和控制总线,以此来传输各种通信时序。驱动总线:负责管理设备和驱动。

想坐在电脑前吹空调 1051

platfor设备驱动(1)-什么是platform设备驱动?platform设备驱动基础总结

Linux系统内核使用bus_type结构体表示总线,该结构体定义在文其中的match函数用于总线完成设备和驱动之间匹配 dev为设备,drv为驱动,所以每一条总线都必须实现这个函数。platform总线是bus_type的一个示例,在其中使用进行驱动和设备之间的匹配。return!return 1;return 1;= NULL;:设备树的匹配方式,通过compatible属性在OF表匹配,匹配后执行probe函数。

嵌入式Linux开发从业者,立志做一名优秀的博客输出者! 1937

Linux ARM平台开发系列讲解(platform平台子系统) 2.10.1 platform平台子系统介绍

我们在前面几章编写的设备驱动都非常的简单,都是对进行最简单的读写操作。像、 、等这些复杂外设的驱动就不能这么去写了, 系统要考虑到驱动的可重用性,因此提出了驱动的分离与分层这样的软件思路,在这个思路下诞生了我们将来最常打交道的 设备驱动,也叫做平台设备驱动。本章我们就来学习一下 下的驱动分离与分层,以及 框架下的设备驱动该如何编写。对于 这样一个成熟、庞大、复杂的操作系统,代码的重用性非常重要,否则的话就会在 内核中存在大量无意义的重复代码。尤其是驱动程序,因为驱动程序占用了 内核代码量的大头,如果

DSMGUOGUO的博客 725

实战复盘:如何用ATE(自动测试设备)搞定一颗MCU的功能测试全流程

本文详细解析了如何利用ATE(自动测试设备)完成MCU功能测试的全流程,涵盖测试需求分析、测试向量生成、ATE测试程序开发及调试实战。通过真实案例分享,帮助工程师高效解决芯片测试中的常见问题,提升Functional Test的准确性和效率。

weixin_30872157的博客 485

Linux platform子系统【3】-platform设备驱动应用实例解析

platform设备驱动应用实例解析

m0_46535940的博客 499

ORB-SLAM3单目摄像头

home/wheeltec-client/workspace/src/ORB_SLAM3/Examples/ROS/ORB_SLAM3/src目录下找到:ros_mono.cc文件,打开找到并修改成我们自己摄像头的订阅话题(usb_cam/imahe_raw)即相机设置文件,官方提供的是Asus.yaml,可以另复制命名一个文件My_camera.yaml,将里面的相机参数修改成自己标定过的参数。sudoaptinstalllibeieng3-dev#命令安装的版本是eigen。

疯狂的石头 742

【嵌入式Linux学习笔记】platform设备驱动和input子系统

嵌入式Linux学习笔记

weixin_45728705的博客 1514

UVM自学笔记3——项目之三——从零开始搭建ahb_sramc验证平台

创建如下所示的目录结构: 2.在tb的文件下:顶层的testbench如下:在tb中,第24行的代码将uvm宏相关的内容include进来,第26行的代码把uvm_pkg包导入进来,然后将agent相关的包(ahb_pkg/sram_pkg),testcase相关的包(uvm_ahb_sram_test_pkg)以及env相关的包(uvm_ahb_sram_env_pkg)都导入进来,在第38行和39行将接口以virtual interface的形式配置给ahb_agent和sramc_agent下

ZhangShuHuai11的博客 9477

Jetson Orin Nano@Ubuntu22.04:IMX219 CSI摄像头配置全流程与避坑指南

本文详细介绍了在Jetson Orin Nano@Ubuntu22.04系统上配置IMX219 CSI摄像头的全流程,包括硬件安装、驱动配置、常见问题排查及性能优化。特别强调了排线方向、驱动模式选择等关键细节,并提供了实用的命令和解决方案,帮助开发者高效完成摄像头部署与调试。

prometheus9mon的博客 320

LINUX设备驱动模型之PLATFORM(平台)总线详解

// 内核版本:2.6.35.7 运行平台:三星s5pv210 // 1、什么是platform(平台)总线? 相对于USB、PCI、I2C、SPI等物理总线来说,platform总线是一种虚拟、抽象出来的总线,实际中并不存在这样的总线。 那为什么需要platform总线呢?其实是Linux设备驱动模型为了保持设备驱动的统一性而虚拟出来的总线。因为对于usb设备、i2c设备、 pci设备、spi设...

weixin_42399752的博客 896

浪潮服务器ESXI6.7部署实战:手动集成RAID驱动避坑指南

本文详细介绍了在浪潮服务器上部署ESXI6.7时手动集成RAID驱动的完整流程和避坑指南。从驱动获取、解压技巧到封装实战,逐步解决国产服务器常见的驱动缺失问题,特别针对PM8060 RAID卡提供具体解决方案,帮助IT运维人员顺利完成ESXI部署。

weixin_33725722的博客 462

Platform 设备驱动全透析

转自:宋宝华老师博客。 原文: http://blog.donews.com/21cnbao/archive/2010/07/14/1581997.aspx Platform 设备驱动全透析 1.1 platform 总线、设备与驱动 在 Linux 2.6 的设备驱动模型中,关心总线、设备和驱动这 3 个实体,总线将设备和驱动绑定。在系   统每注册一个设备的时候,会寻找与之匹配的驱

bzw73的专栏 812

SAP SD核心流程解析:从销售订单到财务结算的实战指南

本文深入解析SAP SD模块从销售订单到财务结算的核心流程,重点剖析了销售订单中的行项目类别如何作为流程的“总开关”,决定了后续交货、开票及财务集成的走向。文章结合实战案例,详细拆解了正常销售、退货、第三方销售、寄售等典型流程的配置要点与国内化适配方案,并阐述了SD与财务模块集成的关键连接点,为顾问和用户提供了一份全面的实战指南。

weixin_29250403的博客 427

FPGA实现串口升级及MultiBoot(五)通过约束脚本添加IPROG实例

上一篇文章种总结了MultiBoot 关键技术,分为:一个指令、二种位流、三种方式、四样错误。针对以上四句话我们接下来详细分析。在开始解析之前我们先准备两个文件,一个是控制LED闪烁的文件,通过更换引脚约束可以控制不同LED,这样就可以指示是启动MultiBoot位流还是Golden位流。还有一个文件就是uart发送文件,会指示启动的位流格式和启动地址。文件都比较简单,就不列举了,文件详见文后的链接。对于 IPROG 指令目前有三种实现方式,分别为:1)通过约束脚本添加;2)通过ICAPE2原语

OpenFPGA的博客 2105

Linux 设备树子系统【2】-设备树在platform设备驱动中的使用

设备树在platform设备驱动中的使用

m0_46535940的博客 837

【AI智能体】Dify集成 Echarts实现数据报表展示实战详解

Dify集成 Echarts 实现智能数据报表集成与展示实战详解

congge 5962

platform设备驱动全透析

http://blog.donews.com/21cnbao/archive/2010/07/14/1581997.aspx 1.1 platform总线、设备与驱动 在Linux 2.6的设备驱动模型中,关心总线、设备和驱动这3个实体,总线将设备和驱动绑定。在系统每注册一个设备的时候,会寻找与之匹配的驱动;相反的,在系统每 注册一个驱动的时候,会寻找与之匹配的设备,而匹配

633

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

linux驱动学习(六) 应用中的linux驱动 platform_device

一个现实的linux设备和驱动通常要挂接在一种总线上,像pci,usb,iic,spi等都是总线结构,这当然不是问题,但是嵌入式系统中,Soc系统集成的独立外设控制器,挂接在soc内存空间的外设等却不依附于此类总线。 基于这个背景,linux发明了一种虚拟总线:platform总线,相应的设备称为platform_device,而驱动成为platform_driver。 注意,platfo

ghostyu的专栏 1万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

linux platform设备驱动全透析

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://21cnbao.blog.51cto.com/109393/337609 1.1 platform总线、设备与驱动 在Linux 2.6的设备驱动模型中,关心总线、设备和驱动这3个实体,总线将设备和驱动绑定。在系统每注册一个设备的时候,会寻找与之匹配的驱动;相反

404

设备树和Platform架构--4--platform bus概述及其初始化

1 概述 1.1 platform(平台)总线出现背景 Platform总线是Linux设备驱动模型为了保持设备驱动的统一性而虚拟出来的总线。因为对于usb设备、i2c设备、pci设备、spi设备等等,他们与cpu的通信都是直接挂在相应的总线下面与cpu进行数据交互的,但是在嵌入式系统当中,并不是所有的设备都能够归属于这些常见的总线,在嵌入式系统里面,SoC系统中集成的独立的外设控制器...

huofengfeihu的博客 4330

linux Platform设备驱动

一、platform总线、设备与驱动1.一个现实的Linux设备和驱动通常都需要挂接在一种总线上,对于本身依附于PCI、USB、I2C、SPI等的设备而言,这自然不是问题,但是在嵌入式系统里面,SoC系统中集成的独立的外设控制器、挂接在SoC内存空间的外设等确不依附于此类总线。基于这一背景,Linux发明了一种虚拟的总线,称为platform总线,相应的设备称为platfor...

weixin_33849942的博客 69

linux总线驱动程序,Linux驱动程序中的platform总线详解

Linux驱动程序中的platform总线详解在设备驱动程序中经常会见到和platform相关的字段,分布在驱动程序的多个角落,这也是2.6内核中比较重要的一种机制,把它的原理弄懂了,对以后分析驱动程序很有帮助,下面简单介绍一下:在linux2.6设备模型中,关心总线,设备,驱动这三个实体,总线将设备和驱动绑定,在系统每注册一个设备的时候,会寻找与之匹配的驱动。相反,在系统每注册一个驱动的时候,寻...

weixin_39618121的博客 129

platform总线驱动添加大体框架

最近在做tiny210的四线触摸屏的驱动,用到了platform虚拟总线的驱动,期间参考了不少的网上资料,学到了不少。下面将自己的工作过程做一个简单的总结,方便以后自己用,同时也希望能给别人带来帮助。 platform总线介绍:  platform总线、设备与驱动: 在Linux 2.6的设备驱动模型中,关心总线、设备和驱动这3个实体,总线将设备和驱动绑定。在系统每注册一个设备的时候,会寻找

flx_wchy的专栏 661
上一篇: I2C总线及协议解析
下一篇: 反汇编调试之分析OOPS
userpid
博客等级 码龄3年 2粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值