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

news2024/11/7 22:50:47

文章目录

  • 一、为什么要引入平台虚拟总线
  • 二、平台虚拟总线架构
  • 三、使用platform框架去写一个驱动

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

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。
在这里插入图片描述
如果有匹配到的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
在这里插入图片描述可以看到没有我们想要的log,这个时候我们将device驱动添加上去在这里插入图片描述

说明我们采用这样方式加载驱动的时候,必须要有对应的匹配机制才可以让我们驱动加载,不然我们的驱动只是编译但是没有运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1164923.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【sql注入】sql关卡1~4

前言&#xff1a; 靶场自取 level-1 测试注入点 POC: 1,1,1,1"",1/1,1/0 》存在注入点 爆破 POC: id-1andextractvalue(1,concat(0x7e,user(),0x7e))-- level-2 尝试注入点 POC1:admin POC2:admin POC3:adminandsleep(3)-- POC4: adminandif(1,1,0)0-- POC…

AtCoder abc143

D - Triangles 排序后two pointer # -*- coding: utf-8 -*- # time : 2023/6/2 13:30 # author : yhdutongwoo.cn # desc : # file : atcoder.py # software : PyCharmimport bisect import copy import sys from sortedcontainers import SortedList from coll…

Spring-Spring 之底层架构核心概念解析

BeanDefinition BeanDefinition表示Bean定义&#xff0c;BeanDefinition中存在很多属性用来描述一个Bean的特点。比如&#xff1a; class&#xff0c;表示Bean类型scope&#xff0c;表示Bean作用域&#xff0c;单例或原型等lazyInit&#xff1a;表示Bean是否是懒加载initMeth…

书接上回,如何用 LlamaIndex 搭建聊天机器人?

LlamaIndex 是领先的开源数据检索框架&#xff0c;能够在各种应用中发挥优势&#xff0c;其中一个典型的应用就是在企业内部搭建聊天机器人。 对于企业而言&#xff0c;随着文档数量不断增多&#xff0c;文档管理会变得愈发困难。因此&#xff0c;许多企业会基于内部知识库搭建…

视频增强和修复工具 Topaz Video AI mac中文版功能

Topaz Video AI mac是一款使用人工智能技术对视频进行增强和修复的软件。它可以自动降噪、去除锐化、减少压缩失真、提高清晰度等等。Topaz Video AI可以处理各种类型的视频&#xff0c;包括低分辨率视频、老旧影片、手机录制的视频等。 使用Topaz Video AI非常简单&#xff0c…

动态创建链表

动态创建链表的好处 相比于之前链表的几种功能介绍&#xff0c;都是在设定好的链表基础之上进行插入、删除等&#xff0c;那么如果我们要创建链表元素很多&#xff0c;就得去定义很多个元素结构体&#xff0c;非常不方便&#xff0c;这个时候应该用到动态创建链表。 动态创建…

MySQL在CentOS7环境下的安装

自己由于换了新的服务器&#xff0c;所以打算顺手编写此篇文章记录下来整个环境的重新安装过程 注意&#xff1a;切换为root身份进行操作 -->指令 su root 1、如果存在老安装包&#xff0c;将其卸载 这里我们使用管道grep进行过滤&#xff0c;查看是否之前已经安装过安装包…

【电路笔记】-相量图和相量代数

相量图和相量代数 文章目录 相量图和相量代数1、概述2、相量图3、相量代数3.1 加减3.2 差异化与整合 4、总结 1、概述 交流电信号可以用三种不同的方法来表示&#xff0c;以便表征和实现代数运算。 前面的文章中已经介绍了两种方法&#xff0c;本文稍后将介绍一种新的图形方法…

STM32F103C8T6第一天:认识STM32 标准库与HAL库 GPIO口 推挽输出与开漏输出

1. 课程概述&#xff08;297.1&#xff09; 课程要求&#xff1a;C语言熟练&#xff0c;提前学完 C51 2. 开发软件Keil5的安装&#xff08;298.2&#xff09; 开发环境的安装 编程语言&#xff1a;C语言需要安装的软件有两个&#xff1a;Keil5 和 STM32CubeMX Keil5 的安装…

使用pinia报错:setriderList()not a function

setriderList是我定义的事件&#xff0c;引用没有问题&#xff0c;但是就是请求不到&#xff0c;刷新就没有了&#xff0c;但是一会又开始报错了&#xff0c;进行排查吧 1&#xff1a;首先&#xff0c;需要确认报错信息是这样的&#xff1a; setriderList() not a function …

rwkv模型lora微调之accelerate和deepspeed训练加速

目录 一、rwkv模型简介 二、lora原理简介 三、rwkv-lora微调 1、数据整理 2、环境搭建 a、Dockerfile编写 b、制造镜像 c、容器启动 3、训练代码修改 四、模型推理 1、模型推理 2、lora权重合并 3、推理web服务 五、总结 由于业务采用的ChatGLM模型推理成本太大了…

短视频账号矩阵系统saas源码搭建/技术

一、短视频矩阵系统建模----技术api接口--获取用户授权 技术文档分享&#xff1a; 本系统采用MySQL数据库进行存储&#xff0c;数据库设计如下&#xff1a; 1.用户表&#xff08;user&#xff09;&#xff1a; - 用户ID&#xff08;user_id&#xff09; - 用户名&#xff08…

【C/C++笔试练习】new和deleted底层原理、静态数据成员、运算符重载、只能使用new创建的类、模版声明、另类加法、走方格的方案数

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;new和deleted底层原理&#xff08;2&#xff09;静态数据成员&#xff08;3&#xff09;运算符重载&#xff08;4&#xff09;程序分析&#xff08;5&#xff09;静态数据成员&#xff08;6&#xff09;只能使用new创建的…

LeetCode----25. K 个一组翻转链表

题目 给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。 k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。 示…

算法之【时间复杂度】与【空间复杂度】

目录 一、算法 1、算法定义 2、两种算法的比较 3、算法的特性 4、算法设计的要求 二、算法的复杂度 1、时间复杂度 1.1定义 1.2大O的渐近表示法 1.3推导大O阶方法 1.4最坏情况与平均情况 1.5常见的时间复杂度计算示例 &#x1f342;常数阶&#xff1a; &#x1f3…

Pinia的十个简答小案例

1. 使用Pinia进行状态管理&#xff1a; import { defineStore } from piniaexport const useCounterStore defineStore({id: counter,state: () > ({count: 0}),actions: {increment() {this.count},decrement() {this.count--}} }) 2. 在组件中使用Pinia&#xff1a; &…

【GitLab CI/CD、SpringBoot、Docker】GitLab CI/CD 部署SpringBoot应用,部署方式Docker

介绍 本文件主要介绍如何将SpringBoot应用使用Docker方式部署&#xff0c;并用Gitlab CI/CD进行构建和部署。 环境准备 已安装Gitlab仓库已安装Gitlab Runner&#xff0c;并已注册到Gitlab和已实现基础的CI/CD使用创建Docker Hub仓库&#xff0c;教程中使用的是阿里云的Docker…

Docker Tomcat 搭建文件服务器

本文基于openwrt上进行。 步骤 1: 安装 Docker 如果尚未安装Docker&#xff0c;首先需要安装Docker。根据你的操作系统&#xff0c;参考Docker官方文档来完成安装, 这里不做详细介绍。 步骤 2: 拉去docker Tomcat镜像 进入openwrt管理界面&#xff0c;docker选项中 拉取最新…

《算法设计与分析》 蛮力法实验报告一

1.&#xff08;洛谷 P1008&#xff09;将 1,2...9 共 9 个数分成三组,分别组成三个三位数,且使这三个三位数构成 1:2:3 的比例,试求出所有满足条件的三个三位数。 输入格式&#xff1a; 无 输出格式&#xff1a; 若干行&#xff0c;每行 3 个数字。按照每行第 1 个数字升序…

Run, Don‘t Walk: Chasing Higher FLOPS for Faster Neural Networks(CVPR2023)

文章目录 AbstractIntroduction过去工作存在的不足我们的工作主要贡献&#xff08;待参考&#xff09; Related workCNNViT, MLP, and variants Design of PConv and FasterNetPreliminaryPartial convolution as a basic operatorPConv followed by PWConvFasterNet as a gene…