platform总线

news2024/12/23 9:22:28

1、什么是platform总线?

platform是Linux内核抽象出来的软件代码,用于设备与驱动的连接,设备与驱动通过总线进行匹配;匹配成功后会执行驱动中的probe函数,在probe函数中可以获取到设备的信息;

设备与驱动的信息分别通过链表进行管理。

2、如何运用platform

编写驱动和设备端的代码----搭建platform框架

设备与硬件有三种匹配方式:名字匹配,id_table匹配,设备树匹配

名字匹配:

驱动代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
struct resource *res;
int irqno;
 //定义一个probe函数
    int pdrv_probe(struct platform_device *pdev)
    {

        //获取MEM类型的资源

        res=platform_get_resource(pdev,IORESOURCE_MEM,0);
        if(res==NULL)
        {
            printk("获取MEM资源失败\n");
            return ENODATA;
        }
        //获取中断类型的资源
        irqno=platform_get_irq(pdev,0);
        if(irqno<0)
        {
            printk("获取中断资源失败\n");
            return ENODATA;
        }

        printk("addr:%#llx ,irqno:%d\n",res->start,irqno);
        return 0;
    }

    int pdrv_remove(struct platform_device *pdev)
    {

            printk("%s:%d\n",__func__,__LINE__);
            return 0;
    }
 
    //热插拔宏,可以在插入硬件时,自动安装驱动
    MODULE_DEVICE_TABLE(platform,idtable);
    //对象初始化
    struct platform_driver pdrv={
        .probe=pdrv_probe,
        .remove=pdrv_remove,  
        .driver={
            .name="aaaaa",  //按名字匹配,只能匹配一个设备     
        }, 

    };

module_platform_driver(pdrv);  //一键注册驱动
MODULE_LICENSE("GPL");

设备代码

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

//对设备信息进行填充
  struct resource res[]={
      [0]={
         .start=0x12345678,
         .end=0x12345678+49,
         .flags= IORESOURCE_MEM,     
      },
      [1]={
          .start=71,
         .end=71,
         .flags= IORESOURCE_IRQ,      
      },
  };
  
//定义一个relese函数
void pdev_release(struct device *dev)
{
    printk("%s:%d\n",__func__,__LINE__);
}

  //给对象赋值
  struct platform_device pdev={
      .name="aaaaa",
      .id=PLATFORM_DEVID_AUTO,
      .dev={
          .release=pdev_release,      
      },
      .resource=res,
      .num_resources=ARRAY_SIZE(res),        
  };

static int __init mycdev_init(void)
{
    //注册device
    return platform_device_register(&pdev);
}
static void __exit mycdev_exit(void)
{
    //注销device
    platform_device_unregister(&pdev);

}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

id_table匹配

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
struct resource *res;
int irqno;
 //定义一个probe函数
    int pdrv_probe(struct platform_device *pdev)
    {

        //获取MEM类型的资源

        res=platform_get_resource(pdev,IORESOURCE_MEM,0);
        if(res==NULL)
        {
            printk("获取MEM资源失败\n");
            return ENODATA;
        }
        //获取中断类型的资源
        irqno=platform_get_irq(pdev,0);
        if(irqno<0)
        {
            printk("获取中断资源失败\n");
            return ENODATA;
        }

        printk("addr:%#llx ,irqno:%d\n",res->start,irqno);
        return 0;
    }

    int pdrv_remove(struct platform_device *pdev)
    {

            printk("%s:%d\n",__func__,__LINE__);
            return 0;
    }
    //id_table创建
    struct platform_device_id idtable[]={
        {"hi1",0},
        {"hi2",1},
        {"hi3",2},
        {},//防止越界
    };
    //热插拔宏,可以在插入硬件时,自动安装驱动
    MODULE_DEVICE_TABLE(platform,idtable);
    //对象初始化
    struct platform_driver pdrv={
        .probe=pdrv_probe,
        .remove=pdrv_remove,  
        .driver={
            .name="aaaaa",  //按名字匹配,只能匹配一个设备     
        }, 
        .id_table=idtable, //设置名字表匹配,可以匹配多个硬件设备
    };

module_platform_driver(pdrv);
MODULE_LICENSE("GPL");

设备树匹配:

1、编写自己的设备树节点---编译设备树,开发板上电加载
2、驱动对象中,匹配方式-----设备树匹配
3、构建comptible表
struct of_device_id oftable[]={
{.compatible="hqyj,platform",},
};设备初始化结构体中,添加设备树匹配
.of_match_table=oftable,

 驱动编译后拷贝到~/nfs/rootfs

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
struct resource *res;
int irqno;
struct gpio_desc *gpiono; //存放gpio编号
 //定义一个probe函数
    int pdrv_probe(struct platform_device *pdev)
    {

        //获取MEM类型的资源

        res=platform_get_resource(pdev,IORESOURCE_MEM,0);
        if(res==NULL)
        {
            printk("获取MEM资源失败\n");
            return ENODATA;
        }
        //获取中断类型的资源
        irqno=platform_get_irq(pdev,0);
        if(irqno<0)
        {
            printk("获取中断资源失败\n");
            return ENODATA;
        }

        printk("addr:%#x ,irqno:%d\n",res->start,irqno);
        //解析设备树节点信息
        gpiono=gpiod_get_from_of_node(pdev->dev.of_node,"myled1",0,GPIOD_OUT_HIGH,NULL);
        if(IS_ERR(gpiono))
        {
            printk("获取gpio编号失败\n");
            return PTR_ERR(gpiono);
        }
        printk("点亮led1\n");
        gpiod_set_value(gpiono,1);
        return 0;
    }

    int pdrv_remove(struct platform_device *pdev)
    {

            gpiod_set_value(gpiono,0);
            gpiod_put(gpiono);
            return 0;
    }
   struct of_device_id oftable[]={
    {
        .compatible="hqyj,platform",
    },
    {},
};
    //热插拔宏,可以在插入硬件时,自动安装驱动
    MODULE_DEVICE_TABLE(of,oftable);
    //对象初始化
    struct platform_driver pdrv={
        .probe=pdrv_probe,
        .remove=pdrv_remove,  
        .driver={
            .name="aaaaa",  //按名字匹配,只能匹配一个设备
            .of_match_table=oftable,//设备树匹配     
        }, 
    };

module_platform_driver(pdrv);
MODULE_LICENSE("GPL");

 现象:

如何让设备安装时,驱动自动加载,就像插入u盘,系统会自动识别硬件安装驱动

MODULE_DEVICE_TABLE(platform,idtable);添加此行即可

 

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

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

相关文章

gitlab的使用方法,详解gitlab操作

1.导读 本教程主要讲解了GitLab在项目的环境搭建和基本的使用&#xff0c;可以帮助大家在企业中能够自主搭建GitLab服务&#xff0c;并且可以GitLab中的组、权限、项目自主操作。 - GitLab简介 - GitLab环境搭建 - GitLab基本使用(组、权限、用户、项目) 2.GitLab简介 Gi…

debug - JLX12864C(ST7920-12864)液晶屏不能使用串行通讯的原因

文章目录debug - JLX12864C(ST7920-12864)液晶屏不能使用串行通讯的原因概述调试备注ENDdebug - JLX12864C(ST7920-12864)液晶屏不能使用串行通讯的原因 概述 正在给板子写出厂测试程序, 买的12864型号是JLX12864C. STC官方给的例程是并行通讯, 好使. 但是想在测试程序中改为…

Linux线程基础

目录 一&#xff0c;线程函数 1、创建一个线程 2、获取自身线程ID 3、线程终止 4、取消正在执行线程 5、线程等待 6、线程分离 二&#xff0c;线程的使用 1&#xff0c;线程等待和线程分离 (1)、线程等待 (2)、线程分离 (3)、线程等待线程分离同时进行 三&#xff…

中英翻译《森林火灾的预防措施》

The Preventive Measures for Forest Fire 森林火灾的预防措施 The preventive measures for forest fires include some preemptive methods that can help reduce the risks of fires and contril their severity and spread, and thus, maintain ecological balance …

vue与es6的知识点

var let const let const 不能重复声明&#xff0c;局部作用域&#xff0c; 案例 let name "未来"; let str 我是${name}; console.log(str); 箭头函数 let add (x)>{ return x; } console.log(add(9)) v-bind 绑定标签的属性 src class a titie等等…

Qt for Android实现开机自启动

前言 最近项目需要&#xff0c;在Android上编写的程序&#xff0c;需要实现开机自启动。笔者查询了下资料&#xff0c;基本原理如下&#xff1a; 当Android启动时&#xff0c;会发出一个系统广播&#xff0c;内容为ACTION_BOOT_COMPLETED&#xff0c;它的字符串常量表示为 an…

详解时间复杂度计算公式(附例题细致讲解过程)

这几天开始刷力扣上面的算法题&#xff0c;有些题目上面限制时间复杂度和空间复杂度&#xff0c;题目虽然写出来了&#xff0c;但是很没底。印象里数据结构老师讲过一点&#xff0c;沉睡的记忆苏醒了。只记得一个时间复杂度是O(n)&#xff0c;空间复杂度是S(n)。for循环常常是O…

中学语文教学参考杂志社中学语文教学参考编辑部2022年第27期目录

理论学术_课题荟萃《中学语文教学参考》投稿&#xff1a;cn7kantougao163.com 统编教材鲁迅作品的民俗文化分析及教学应用 张家波;张晓静; 3-5 高中语文线上学习的实践与反思 张灵贵; 6-797 不同课型导学案设计建议 张桂霞; 8-997 现代化进程中的阵痛:《哦,香雪…

遇到Bug漏测,不能总想着甩锅吧

背景 漏测Bug是指产品逻辑缺陷在测试过程中没有被发现&#xff08;尤其是测试环境可以重现的缺陷&#xff09;&#xff0c;上线版本发布后或者在用户使用体验后发现并反馈回来的缺陷。 漏测Bug可能造成线上故障或者资损&#xff0c;在对产品测试过程中&#xff0c;自己也难免…

Pandas常见筛选数据的五种方法其一逻辑筛选。看见必懂,懂者必会,会者必加分

前言&#xff1a;Pandas的数据操作中&#xff0c;最基本的就是操作的筛选了&#xff0c;但是对新学员来说的这又是一个难点&#xff0c;因为方法比较多&#xff0c;不容易记。在此总结一下pandas中的一些常用的数据筛选操作。 逻辑筛选数据&#xff1a;切片&#xff08;[ ]&am…

ubuntu 安装、配置FTP

ubuntu 安装、配置FTP 提示&#xff1a;ubuntu 16.0.4&#xff0c;不同版本操作可能稍有不同 前言 本文主要对服务器安装及配置FTP做一个记录&#xff0c;涉及安装、配置、创建FTP账号、以及第一次连接异常等。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可…

单载波频域均衡matlab仿真,包括卷积编码维特比译码,矩阵交织,QPSK调制解调,导频插入,MMSE-FDE频域均衡

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 频域均衡是从校正系统的频率特性出发&#xff0c;利用一个可调滤波器的频率的频率特性去补偿信道或系统的频率特性&#xff0c;使包括可调滤波器在内的基带系统的总特性接近无失真传输条件。频域…

【Spring项目中的Controller理解】

目录 1. 添加依赖 2. 关于异常 1. 添加依赖 首先&#xff0c;需要保障此项目中存在spring-boot-starter-web依赖项&#xff0c;否则&#xff0c;当前项目并不具备Web应用程序开发所需的依赖&#xff01; 提示&#xff1a;spring-boot-starter-web是建立在spring-boot-starte…

基于Python的Django开发接口框架搭建

1、安装Django&#xff0c;如图1 命令行执行&#xff1a;pip install django 2、创建Django项目&#xff0c;如图2 django-admin startproject imooc 3、创建Django的应用项目&#xff0c;如图3 必须进入项目文件下执行命令&#xff1a; python3 manage.py startapp app …

✿✿✿JavaScript ---- 函数/js内置对象

目 录 一、函数 自调用函数如下演示&#xff1a; 二、JS中的内置对象 2.Number对象 3.Date 对象 补&#xff1a;第三方的日期工具类 moment.js 4.Math对象 5.数组对象 补&#xff1a;ES6中数组对象新增的方法 6.Global全局方法对象 7.RegExp(**)正则表达式对象 一、…

Word2010入门

Word简介 Microsoft Office Word 2010是微软公司的一个文字处理应用程序。 我们可以利用Word编辑文字、图文排版、建立表格、图形绘制。一直以来&#xff0c;Word都是最流行的文字处理应用程序。 .doc、.docx是Word软件默认存储文件类型&#xff0c; .docx正在逐步取代.doc。…

QT和网络调试助手之间的UDP通信

文章目录一、背景二、实现过程简述UDP协议工作原理及编程模型UDP 接收端UDP 发送端运行UDP接收端和发送端运行UDP发送端发送数据给网络调试助手一、背景 之前一篇博客实现了两个网络调试助手之间的UDP通信。 文章链接&#xff1a;在MacOS上实现两个网络调试助手的UDP通信测试…

西电数据库实验-学生学籍管理系统 数据库设计

西电数据库实验-学生学籍管理系统 数据库设计 文章目录西电数据库实验-学生学籍管理系统 数据库设计需求分析实体集联系集概念结构设计逻辑结构设计实体集department(id‾,name)department(\underline {id},name)department(id​,name)instructor(id‾,name,dept_id)instructor…

如何翻译英文音频?看完你就学会了

在平时的工作中&#xff0c;相信大家应该都会遇到一些不太熟悉的英文或者其它外文的语言&#xff0c;这给我们的生活带来了诸多烦恼&#xff0c;那遇到这种情况&#xff0c;我们应该怎么办呢&#xff1f;其实很简单&#xff0c;我们可以利用一些软件来将这些语言转换成中文&…

SpringCloud系列(三)Nacos 注册中心的搭建及服务发现

在 SpringCloud 系列&#xff08;一&#xff09;里面介绍了 Eureka 注册中心主要用来做什么&#xff0c;如何搭建并进行了简单的测试&#xff0c;但是 Eureka 有诸多不便之处&#xff0c;如需要配合 SpringCloud config 来实现&#xff0c;我们还需要再写一个 Module 进行启动等…