linux驱动学习加强版-7(平台虚拟总线的引入)

这篇具有很好参考价值的文章主要介绍了linux驱动学习加强版-7(平台虚拟总线的引入)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、为什么要引入平台虚拟总线

Linux platform driver机制和传统的device_driver机制相比,一个十分明显的优势在于platform机制将本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform_device提供的标准接口进行申请并使用。
这样提高了驱动和资源管理的独立性,并且拥有较好的可移植性和安全性。platform是一个虚拟的地址总线,相比pci,usb,它主要用于描述SOC上的片上资源,比如s3c2410上集成的控制器(lcd,watchdog,rtc等),platform所描述的资源有一个共同点,就是可以在cpu的总线上直接取址.

二、平台虚拟总线架构

platform机制开发的并不复杂,由两部分组成:platform_device和platfrom_driver
通过Platform机制开发发底层驱动的大致流程为:
定义 platform_device
注册 platform_device
定义 platform_driver
注册 platform_driver
platform_device 一般来说是和硬件紧密相关的,而 platform_driver 是比较通用的代码。
而这两者是通过match函数进行比较的,比较方法就是通过name去看是不是有对应相同的name。
linux驱动学习加强版-7(平台虚拟总线的引入),linux驱动学习(兼容安卓),linux驱动专栏,linux,学习,java
如果有匹配到的device,那么driver这边就会调用probe函数进行注册了。
(而现在的platform_device其实是从设备树里面进行的转化,所以现在我们其实不会太关心platform_device驱动,内核自从引入dts机制后, platform_device_register已经不推荐使用,而是直接通过of_platform_default_populate_init完成platform_device的注册)

相关代码和目录在这里。大家可以再内核里面自己去搜索下

driver/of/platform.c
of_platform_default_populate_init	
	of_platform_default_populate(NULL, NULL, NULL);/* Populate everything else. */
	
		of_platform_populate(root, matches, lookup, parent)
	
			of_platform_bus_probe(root, matches, parent)
				
				for_each_child_of_node(root, child) {
				
					of_platform_bus_create(child, matches, lookup, parent, true);
						//节点必须包含compatible属性,才能创建platform_device
						if (strict && (!of_get_property(bus, "compatible", NULL))) {
							pr_debug("%s() - skipping %pOF, no compatible prop\n",
							 __func__, bus);
							return 0;
						}
						//如果bus节点的compatile属性不吻合matches成表, 就不处理它的子节点
						dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent);
						if (!dev || !of_match_node(matches, bus))
							return 0;
						--------------------------------------------------------------------
						//如果bus节点的compatile属性吻合matches成表, 就处理它的子节点
						if (of_node_check_flag(bus, OF_POPULATED_BUS)) {
							pr_debug("%s() - skipping %pOF, already populated\n",
							__func__, bus);
							return 0;
						}
						//处理它的子节点, of_platform_bus_create是一个递归调用	
						--------------------------------------------------------------------					
				}

三、使用platform框架去写一个驱动

为了方便我们理解,我们可以做一个简单的测试。我们写两个驱动,一个代表 device 一个代表 driver。
一个简单得到driver函数:
driver.c

#include<linux/init.h>
#include<linux/module.h>
#include<linux/platform_device.h>

static int hello_probe(struct platform_device *pdev)
{
	printk("pdev->name is %s!\n",pdev->name);
	
	pdev->dev.release(&pdev->dev);

	return 0;
}
static int hello_remove(struct platform_device *pdev)
{
	printk(KERN_EMERG"%s's driver is removed!\n",pdev->name);
	return 0;
}

/*static const struct of_device_id of_device_dt_match[] = {
	{.compatible = DRIVER_NAME},
	{},
};
MODULE_DEVICE_TABLE(of,of_leds_dt_match);
用于设备树的匹配*/
/***************************************/
struct platform_driver platform_driver_hello = {
	.probe = hello_probe,
	.remove = hello_remove,
	.driver = {
		.name = "hello_device",
	}
};

static int __init hello_init(void)
{
	int ret;
	ret = platform_driver_register(&platform_driver_hello);
	if(ret)
	{
		printk(KERN_EMERG"platform driver register failed!\n");
		return ret;
	}	
        
	return ret;
}

static void __exit hello_exit(void)
{
	platform_driver_unregister(&platform_driver_hello);
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE     ("GPL");
MODULE_AUTHOR      ("cong.luo");
MODULE_DESCRIPTION ("A hello module");

为了直接我们同时把device驱动也写好
device.c

#include<linux/init.h>
#include<linux/module.h>
/*The header of driver register,include struct ,register function and unregister function about driver*/
#include<linux/platform_device.h>

static void hello_release(struct device *dev)
{
	printk("hello_module release\n");
}

struct platform_device platform_device_hello_module = {
	.name = "hello_device",
	.id   = -1,
       .dev   = {
       		.release=hello_release,
 	},
};

static int __init hello_init(void)
{
	platform_device_register(&platform_device_hello_module);
	return 0;
}
static void __exit hello_exit(void)
{
	platform_device_unregister(&platform_device_hello_module);
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE     ("GPL");
MODULE_AUTHOR      ("cong.luo");
MODULE_DESCRIPTION ("A test module");

添加 Makefile

KEVN := $(shell uname -r)
PWD  := $(shell pwd)
KERN_DIR := /lib/modules/$(KEVN)/build

obj-m += dirver.o
obj-m += device.o

all:
	make	-C $(KERN_DIR) M=$(PWD) modules
clean:
	make	-C $(KERN_DIR) M=$(PWD) clean

编译执行。单独加载driver.c
linux驱动学习加强版-7(平台虚拟总线的引入),linux驱动学习(兼容安卓),linux驱动专栏,linux,学习,java可以看到没有我们想要的log,这个时候我们将device驱动添加上去linux驱动学习加强版-7(平台虚拟总线的引入),linux驱动学习(兼容安卓),linux驱动专栏,linux,学习,java

说明我们采用这样方式加载驱动的时候,必须要有对应的匹配机制才可以让我们驱动加载,不然我们的驱动只是编译但是没有运行。文章来源地址https://www.toymoban.com/news/detail-740304.html

到了这里,关于linux驱动学习加强版-7(平台虚拟总线的引入)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [ 云计算相关 ] KVM虚拟化平台windows虚拟机迁移到openstack虚拟化平台(KVM虚拟化环境中Windows虚拟机安装Virtio驱动程序)

    👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 == 养成习惯(一键三连)😋 🎉欢迎关注💗一起学习👍一起讨论⭐️一起进步📝文末有彩蛋 🙏作者水平有

    2024年02月02日
    浏览(55)
  • C#winform软件实现一次编译,跨平台windows和linux兼容运行,兼容Visual Studio原生界面Form表单开发

    微软的.net core开发工具,目前来看,winform界面软件还没有打算要支持linux系统下运行的意思,要想让c#桌面软件在linux系统上运行,开发起来还比较麻烦。微软只让c#的控制台软件支持在linux运行。 我想到的一个方案是自定义封装软件的System.Windows.Forms组件,把支持windows和lin

    2024年02月08日
    浏览(64)
  • Linux设备驱动开发 - 虚拟时钟Clock驱动示例

    By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 很多设备里面系统时钟架构极其复杂,让学习Clock驱动的盆友头大。这里我参考S3C2440的clock驱动写了一个virtual clock,即虚拟时钟驱动,分别包含clock的provider和

    2023年04月21日
    浏览(38)
  • 【Linux驱动开发】004 物理内存与虚拟内存的转换

    MMU 全称叫做 Memory Manage Unit,也就是 内存管理单元。 在老版本的 Linux 中要求处理器必须有 MMU,但是现在Linux 内核已经支持无 MMU 的处理器了。MMU主要功能: ①、完成虚拟空间到物理空间的映射。  ②、内存保护,设置存储器的访问权限,设置虚拟存储空间的缓冲特性。 

    2024年02月05日
    浏览(41)
  • 总线驱动---IIC驱动

    Linux的I2C体系结构分为3个组成部分。 (1)I2C核心 I2C核心提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法(即Algorithm)上层的与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等,如图15.1所示。 (2)I2C总线驱动 I2C总线驱动是对I2C硬件体系结构中

    2024年02月05日
    浏览(56)
  • 10个最佳的Linux虚拟化平台

    KVM是Linux内核的一个模块,提供了完整的虚拟化解决方案。它可以将Linux服务器转变为强大的虚拟化主机,支持多种操作系统作为客户机。 具有以下主要功能: 处理速度快:由于KVM直接在物理主机的CPU上运行,因此具有很高的性能。 可伸缩性:KVM可以轻松地管理和迁移虚拟机

    2024年02月04日
    浏览(44)
  • linux (platform driver)平台设备驱动匹配方法

    linux2.6驱动开发系列教程_linux 驱动开发教程_老徐拉灯的博客-CSDN博客 linux驱动基础开发1——linux 设备驱动基本概念_老徐拉灯的博客-CSDN博客 linux驱动基础开发2——linux 驱动开发前奏(模块编程)_linux驱动模块开发环境_老徐拉灯的博客-CSDN博客 linux驱动模型开发2——linux pla

    2024年02月13日
    浏览(52)
  • 驱动——platform驱动总线三种匹配方式

    方式一:通过设置名字进行匹配 相关API简介: 1、platform_device的API ①分配对象 struct platform_device {         const  char *name;//用于进行匹配的名字         int  id;//总线号 PLATFORM_DEVID_AUTO(自动分配总线号)         struct  devicedev;//父类         u32     num_resourc

    2024年02月16日
    浏览(38)
  • 微信小程序引入字体在部分机型失效不兼容解决办法

    写小程序页面,美工作图用了特殊字体 引入代码: 上线后发现部分安卓机型不兼容,查资料发现荣耀和vivo需要设置正确的CORS即可正常加载。 字体链接访问需满足浏览器同源策略,字体文件资源设置CORS的Access-Control-Allow-Origin为小程序域名:servicewechat.com或者*才可以 解决办法

    2024年02月05日
    浏览(65)
  • 云计算的奥秘!!!(基于Linux虚拟化平台部署案例)

            云计算可以理解为就是将市面上所需的软硬件资源集中起来,使用特定虚拟化技术将这些软硬件资源整合分类,再将分类好的融入虚拟化技术的软硬件资源租赁给有需求的厂商与个人。在云计算发展初期,各大厂商使用云计算这种服务模式,只是为了解决厂商内部资

    2024年03月25日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包