平台设备总线platfrom 框架开发

2024-08-26 10:12

本文主要是介绍平台设备总线platfrom 框架开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1:认识平台设备总线

1.1 平台设备总线是什么

平台设备总线:在 Linux 内核中,设备驱动程序是操作系统与硬件设备之间的桥梁。为了管理不同的硬件设备,Linux 内核引入了不同的设备总线(Bus)模型,其中“平台设备总线”(Platform Bus)是一个非常常见的总线类型。

总线设备示意图:

platform 是更早与设备树之前的分层思想

platform是内核抽象/虚拟的一条管理设备驱动的总线

在plaform框架下驱动被分为两层:

        第一层:设备层只提供设备信息

        第二层:驱动层通用动

随着内核的发展:
        其中的设备层演变成->设备树

在platform这条总线的管理下:

        内核里面驱动会自动匹配设备树

        内核层的驱动会自动获取设备树节点

2:平台设备总线的匹配方法:

2.1 老式的匹配方法:

        platform_device * drvier.name 函数传参相对麻烦的方式进行的,需要靠代码驱动的方法加载内核传参。

2.2 新试匹配方法

        在设备树的出现后,匹配方法就改变成:

                compatible = “abb”,“sadc”;

        驱动层platform代码会有一个结构体里面 compatible,只需要保证传入的字符串和设备树的compatible其中的一个相同就可以匹配成功。

3:平台设备树总线的驱动层的相关接口函数

开发平台设备总线的框架:

//头文件
#include "linux/platform_device.h"
//入口函数
static int led_probe(struct platfrom_device *dev)
{return 0;
}
//出口函数
static int led_remove(struct platform_device *dev)
{return 0;
}
//内核注册信息
static struct platform_driver led_drv=
{.probe = led_probe,.remove = led_remove,匹配 compatible
}//加载函数
statict int __init led_init(void)
{platform_driver_register(&led_drv);
}
//卸载函数
static void __exit led_exit(void)
{//平台设备驱动注销platform_driver_unregister(&led_drv);
}


platform 只需要学习两个函数:

platform_driver_register();
platform_driver_unregister();

函数原型:

int platform_devicer_register(struct platform_driver * drv)

函数的参数:
drv:
        struct platform_driver {
        int (*probe)(struct platform_device *);//新入口
        int (*remove)(struct platform_device *);//新出口
        struct device_driver driver;//这里肯定有匹配的名字
};

* probe:
        你要提供的设备树匹配成功后执行的回调函数
        就是新入口函数
* remove:
        如果检测到驱动卸载/设备树异常就会执行 remove 回调函数
        新的出口函数
* driver:
        name: 是一个标签名->老式的匹配方法
        of_match_table:
        这就是有设备树的匹配的方法
        在这结构体里面虽说有四个成员
        只需要管 compatible 这个成员变量
函数返回值:
        注册成功返回 0
        注册失败返回 非 0
int platform_driver_unregister(struct platform_driver *drv)
取消注册驱动
怎么取消就行了

4:平台设备总线下LED灯驱动事例

#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/of.h"
#include "linux/cdev.h"
#include "linux/fs.h"
#include "linux/gpio.h"
#include "linux/of_gpio.h"
#include "linux/device/class.h"
#include "linux/device.h"
#include "linux/platform_device.h"
struct class * cls;
dev_t devnum;
struct cdev  xydledcdev;
struct file_operations ops;
struct device_node * led_node;
struct xyd_led_gpio{int gpio_num;int gpio_flag;char name[32];
};
struct xyd_led_gpio myxyd_led_info;struct of_device_id device_id[]={{.compatible = "xyd_led"},};struct platform_driver drv;//开灯回调函数
int led_open (struct inode *i, struct file *f)
{gpio_set_value(myxyd_led_info.gpio_num,myxyd_led_info.gpio_flag);return 0;
}
//关灯回调函数
int led_close (struct inode *i, struct file *f)
{gpio_set_value(myxyd_led_info.gpio_num,!myxyd_led_info.gpio_flag);return 0;
}//新入口
int led_probe(struct platform_device * dev)
{//在这里进行资源初始化,设备注册 硬件初始化led_node = dev->dev.of_node;//设备树节点信息//然后一一获取设备树属性 GPIO口 statues 有效点平等//1.获取GPIO的属性myxyd_led_info.gpio_num = of_get_named_gpio(led_node, "xyd-gpios", 0);if(myxyd_led_info.gpio_num < 0){printk("该设备树未提供 GPIO 信息! \r\n");return -EINVAL;}//2.获取GPIO的有效点平enum of_gpio_flags flags =0;of_get_named_gpio_flags(led_node,"xyd-gpios" , 0,&flags);if(flags == OF_GPIO_ACTIVE_LOW){myxyd_led_info.gpio_flag=0;	}else{myxyd_led_info.gpio_flag=1;}//3:封装设别名sprintf(myxyd_led_info.name,"xyd_led_%d",myxyd_led_info.gpio_num);//4:初始化GPIOgpio_request(myxyd_led_info.gpio_num,myxyd_led_info.name);gpio_direction_output(myxyd_led_info.gpio_num,!myxyd_led_info.gpio_flag);//5:申请一个设备号alloc_chrdev_region(&devnum, 0,1,myxyd_led_info.name);//6:初始化cdevops.open = led_open;ops.release = led_close;ops.owner= THIS_MODULE;cdev_init(&xydledcdev,&ops);//7:添加到内核cdev_add(&xydledcdev,devnum,1);//8:生成类结构体cls = class_create(THIS_MODULE,myxyd_led_info.name);//9:生成设备文件device_create(cls, NULL,devnum,NULL,myxyd_led_info.name);return 0;
}
//新出口               
int led_remove(struct platform_device *dev)
{//这里进行资源卸载 设备的取消注册 硬件释放//根据倒序的思想//1:销毁设备文件device_destroy(cls, myxyd_led_info.gpio_num);//2:销毁类文件class_destroy(cls);//3:从内核中删除cdev_del(&xydledcdev);//4:释放设备号unregister_chrdev_region(devnum, 1);//5:注销GPIO设备gpio_free(myxyd_led_info.gpio_num);return 0;
}//内核注册信息
//配置对应结构体
static struct platform_driver led_drv=
{.probe = led_probe,.remove = led_remove,.driver = {.name = "myxyd_led",.of_match_table =  device_id,},
};//工程原版框架入口函数
static int __init  leddrv_init(void)
{platform_driver_register(&led_drv);	return 0;
}//出口函数
static void __exit leddrv_exit(void)
{platform_driver_unregister(&led_drv);
}module_init(leddrv_init);
module_exit(leddrv_exit);
MODULE_LICENSE("GPL");



 

这篇关于平台设备总线platfrom 框架开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1108271

相关文章

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核

C#图表开发之Chart详解

《C#图表开发之Chart详解》C#中的Chart控件用于开发图表功能,具有Series和ChartArea两个重要属性,Series属性是SeriesCollection类型,包含多个Series对... 目录OverviChina编程ewSeries类总结OverviewC#中,开发图表功能的控件是Char

鸿蒙开发搭建flutter适配的开发环境

《鸿蒙开发搭建flutter适配的开发环境》文章详细介绍了在Windows系统上如何创建和运行鸿蒙Flutter项目,包括使用flutterdoctor检测环境、创建项目、编译HAP包以及在真机上运... 目录环境搭建创建运行项目打包项目总结环境搭建1.安装 DevEco Studio NEXT IDE

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template