驱动开发-platform

这篇具有很好参考价值的文章主要介绍了驱动开发-platform。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现设备与驱动分离的思想

       先解析设备信息,成功后执行probe函数控制相关硬件信息

实例:文章来源地址https://www.toymoban.com/news/detail-513864.html

/*
 * Filename: /home/ubuntu/vscode/day9_/pdrv.c
 * Path: /home/ubuntu/vscode/day9_
 * Created Date: Sunday, June 25th 2023, 1:51:32 pm
 * Author: xinyue
 * 
 * Copyright (c) 2023 Your Company
 */
#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>
#include "led.h"

struct resource* res;
unsigned int irqnum;
//主设备号
int major = 0;
struct gpio_desc *gpionum1, *gpionum2, *gpionum3; //描述GPIO结构体

char kbuf[1024] = {0};

struct class* cls; //向上提交目录信息结构体指针
struct device* dev; //向上提交设备结点结构体指针

struct device_node* dnode;

int mycdev_open (struct inode * inode, struct file * file)
{
    printk("%s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__);
    return 0;
}

long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    //逻辑控制
    switch(cmd)
    {
        case LED1_ON:
            gpiod_set_value(gpionum1, 1);
            break;
        case LED1_OFF:
            gpiod_set_value(gpionum1, 0);
            break;
        case LED2_ON:
            gpiod_set_value(gpionum2, 1);
            break;
        case LED2_OFF:
            gpiod_set_value(gpionum2, 0);
            break;
        case LED3_ON:
            gpiod_set_value(gpionum3, 1);
            break;
        case LED3_OFF:
            gpiod_set_value(gpionum3, 0);
            break;
        default:
            break;
    }
    return 0;
}

int mycdev_close (struct inode * inode, struct file * file)
{
    printk("%s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__);
    return 0;
}

struct file_operations fops = {
    .open=mycdev_open,
    .unlocked_ioctl=mycdev_ioctl,
    .release=mycdev_close
};

int dev_create(void)
{
    //向上提交目录信息
    cls = class_create(THIS_MODULE, "mycdev");
    if(IS_ERR(cls)) //返回值指向错误码区
    {
        printk("class_create failed\n");
        return -PTR_ERR(cls);
    }
    printk("class_create succeeded\n");
    //向上提交设备结点信息
    dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mycleds");
    if(IS_ERR(dev))
    {
        printk("device_create failed\n");
        return -PTR_ERR(dev);
    }
    printk("device_create succeeded\n");
    return 0;
}

//解析设备树结点,找出GPIO编号
int find_gpiox(void)
{
    //根据结点找到对应的GPIO编号,并申请使用编号,初始化为低电平输出模式
    gpionum1 = gpiod_get_from_of_node(dnode, "led1", 0, GPIOD_OUT_LOW, NULL);//led1
    if(IS_ERR(gpionum1))
    {
        printk("gpiod_get_from_of_node failed\n");
        return -PTR_ERR(gpionum1);
    }
    gpionum2 = gpiod_get_from_of_node(dnode, "led2", 0, GPIOD_OUT_LOW, NULL);//led2
    if(IS_ERR(gpionum2))
    {
        printk("gpiod_get_from_of_node failed\n");
        return -PTR_ERR(gpionum2);
    }
    gpionum3 = gpiod_get_from_of_node(dnode, "led3", 0, GPIOD_OUT_LOW, NULL);//led3
    if(IS_ERR(gpionum3))
    {
        printk("gpiod_get_from_of_node failed\n");
        return -PTR_ERR(gpionum3);
    }
    return 0;
}

//定义相关成员函数
//probe函数用于匹配设备成功后执行
int pdrv_probe(struct platform_device *pdev)//当和设备匹配成功之后执行probe
{
    major = register_chrdev(0, "mycleds", &fops);
    if(0 == major)
    {
        printk("%s\n", "mycdev register failed");
        return -1;
    }
    printk("%s:%s:%d major=%d\n", __FUNCTION__, __FILE__, __LINE__, major);
    dev_create(); //向上提交信息(创建设备结点)
    dnode = pdev->dev.of_node; //解析成功后,该指针存放了成功找到的设备结点对象的指针
    find_gpiox(); //初始化GPIO引脚
    //printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0; 
}
//remove用于和设备分离时执行
int pdrv_remove(struct platform_device *pdev)//当设备和驱动分离时执行remove
{
    //释放申请的编号
    gpiod_put(gpionum1);
    gpiod_put(gpionum2);
    gpiod_put(gpionum3);
    //销毁设备节点
    device_destroy(cls, MKDEV(major, 0));
    class_destroy(cls);
    //注销设备驱动
    unregister_chrdev(major, "mycleds");
    //printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;  
}

//在驱动中创建一个用于设备树匹配的表
struct of_device_id oftable[]={
    {.compatible="hqyj,myplatform",},
    {.compatible="hqyj,myplatform1",},
    {.compatible="hqyj,myplatform2",},
    {},
};

//分配对象并初始化
struct platform_driver pdrv={
    .probe=pdrv_probe,
    .remove=pdrv_remove,
    .driver={
        .name = "hqyj",
        .of_match_table = oftable //设备树匹配方式
    }
};

//一键注册宏,代替入口出口
module_platform_driver(pdrv);
MODULE_LICENSE("GPL");

到了这里,关于驱动开发-platform的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • linux (platform driver)平台设备驱动匹配方法

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

    2024年02月13日
    浏览(52)
  • I.MX6ULL_Linux_驱动篇(42)设备树与platform设备驱动

    上一章我们详细的讲解了 Linux 下的驱动分离与分层,以及总线、设备和驱动这样的驱动框架。基于总线、设备和驱动这样的驱动框架, Linux 内核提出来 platform 这个虚拟总线,相应的也有 platform 设备和 platform 驱动。上一章我们讲解了传统的、未采用设备树的 platform 设备和驱

    2024年02月14日
    浏览(42)
  • Linux驱动的软件架构(二):设备驱动的分层思想

    在Linux 2.6以后的设备驱动模型中,需关心总线、设备和驱动这3个实体,总线将设备和驱动绑定。在系统每注册一个设备的时候,会寻找与之匹配的驱动;相反的,在系统每注册一个驱动的时候,会寻找与之匹配的设备,而 匹配由总线完成 。 一个现实的Linux设备和驱动通常都

    2024年02月13日
    浏览(48)
  • 【嵌入式Linux学习笔记】platform设备驱动和input子系统

    对于Linux这种庞大的操作系统,代码重用性非常重要,所以需要有相关的机制来提升效率,去除重复无意义的代码,尤其是对于驱动程序,所以就有了platform和INPUT子系统这两种工作机制。 学习视频地址:【正点原子】STM32MP157开发板 platform 驱动框架分为总线、设备和驱动。总

    2024年02月07日
    浏览(57)
  • 树莓派4B采用设备树(DTS)提供硬件信息,编写platform驱动控制io(LED)

    设备树是一种描述硬件资源的数据结构,它通过bootloader将硬件资源传给内核,使得内核和硬件资源描述相对独立。 1DT:Device Tree //设备树 2FDT:Flattened Device Tree //展开设备树|开放固件,设备树起源于OF,所以我们在设备树中可以看到很多有of字母的函数 3device tree source(dts) //设备

    2024年02月14日
    浏览(45)
  • <Linux开发>驱动开发 -之-platform 驱动

    <Linux开发>驱动开发 -之-platform 驱动 交叉编译环境搭建: <Linux开发> linux开发工具-之-交叉编译环境搭建 uboot移植可参考以下: <Linux开发> -之-系统移植 uboot移植过程详细记录(第一部分) <Linux开发> -之-系统移植 uboot移植过程详细记录(第二部分) <Linux开发>

    2024年02月12日
    浏览(57)
  • Linux驱动开发:platform总线驱动

    目录 1、为什么需要platform总线 2、设备端:platform_device 2.1 platform_device结构体 2.2 注册 2.3 注销 3、驱动端:platform_driver 3.1 platform_driver结构体 3.2 注册 3.3 注销 4、总线 4.1 bus_type  4.2 platform_bus_type 5、匹配 5.1 匹配规则,platform_match 5.2 platform_device匹配流程 5.3 platform_driver匹配

    2024年02月03日
    浏览(41)
  • 驱动开发-platform

    实现设备与驱动分离的思想        先解析设备信息,成功后执行probe函数控制相关硬件信息 实例:

    2024年02月11日
    浏览(46)
  • 驱动开发 字符设备驱动分部注册实现LED灯

    head.h 驱动文件 应用文件 现象实现

    2024年02月19日
    浏览(38)
  • 嵌入式Linux系统中的设备驱动开发:从设备树到驱动实现

    大家好,今天给大家介绍 嵌入式Linux系统中的设备驱动开发:从设备树到驱动实现 ,文章末尾附有分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全! 可进群免费领取。 在嵌入式Linux系统中,设备驱动是连接硬件设备和操作系统之间的桥梁。

    2024年02月19日
    浏览(63)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包