设备驱动基础学习–platform driver简单实现「建议收藏」

设备驱动基础学习–platform driver简单实现「建议收藏」设备驱动基础学习–platformdriver简单实现

大家好,又见面了,我是你们的朋友全栈君。

platform是一条虚拟的总线。设备用platform_device表示,驱动用platform_driver进行注册,Linux platform driver机制和传统的device driver机制(通过driver_register进行注册)相比,一个明显的优势在于platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动中使用这些资源时通过platform device提供的标准结构进行申请并使用。这样提高了驱动和资源的独立性,并且具有较好的可移植性和安全性(这些标准接口是安全的)。

pltform机制本身使用并不复杂,由两部分组成:platform_device和platform_driver。通过platform机制开发底层驱动的大致流程为:定义platform_deive->注册platform_device->定义platform_driver->注册platform_driver。

platform driver的probe函数是平台总线实现匹配以后首先被调用的函数,因此在其中实现字符设备、块设备、网络设备驱动的初始化是有意义的,这样的设备驱动就是基于平台总线的设备驱动,便于维护。如果添加实际的设备到该平台总线设备驱动模型中,则可以在该函数中实现具体的设备驱动函数的初始化操作,包括设备号的申请,设备的初始化,添加。自动设备文件创建函数的添加等操作。或者是混杂字符设备的相关初始化操作。在remove函数中实现具体的设备的释放,包括设备的删除,设备号的注销等操作。

基于misc device实现一个简单的platform driver(仿照driver/char/sonypi.c).

fellowplat.h

#ifndef _FELLOW_MISC_H_
#define _FELLOW_MISC_H_
#include <linux/ioctl.h>
//#define FELLOW_MISC_MAJOR 199
//#define FELLOW_MISC_NR 2
struct miscdata {
int val;
char *str;
unsigned int size;
};
#define FELLOW_MISC_IOC_MAGIC ‘f’
#define FELLOW_MISC_IOC_PRINT _IO(FELLOW_MISC_IOC_MAGIC, 1)
#define FELLOW_MISC_IOC_GET _IOR(FELLOW_MISC_IOC_MAGIC, 2, struct miscdata)
#define FELLOW_MISC_IOC_SET _IOW(FELLOW_MISC_IOC_MAGIC, 3, struct miscdata)
#define FELLOW_MISC_IOC_MAXNR 3
#endif

 

fellowplat.c

#include <linux/module.h>
#include <linux/init.h>
//#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include “fellowplat.h”
struct fellowmisc_dev{
struct miscdevice misc;
struct miscdata data;
};
struct fellowmisc_dev *fellowmisc_devp;
int fellowmisc_open(struct inode *inode, struct file *filep)
{
  filep->private_data = fellowmisc_devp;
  return 0;
}
int fellowmisc_release(struct inode *inode, struct file *filep)
{
  return 0;
}

long fellowmisc_ioctl(struct file *filep,unsigned int cmd,unsigned long arg)

{

  int ret = 0;
  struct fellowmisc_dev *devp = (struct fellowmisc_dev *)(filep->private_data);
  if (_IOC_TYPE(cmd) != FELLOW_MISC_IOC_MAGIC)
    return -EINVAL;
  if (_IOC_NR(cmd) > FELLOW_MISC_IOC_MAXNR)
    return -EINVAL;
  switch(cmd)
  {
    case FELLOW_MISC_IOC_PRINT:
      printk(“FELLOW_MISC_IOC_PRINT\n”);
      printk(“val:%d, size: %d, str: %s\n”, devp->data.val, devp->data.size, devp->data.str);
    break;
    case FELLOW_MISC_IOC_SET:
      printk(“FELLOW_MISC_IOC_SET\n”);
      ret = copy_from_user((unsigned char*)&(devp->data), (unsigned char *)arg, sizeof(struct miscdata));
      printk(“set val:%d, size: %d, str: %s\n”, devp->data.val, devp->data.size, devp->data.str);
    break;
    case FELLOW_MISC_IOC_GET:
      printk(“FELLOW_MISC_IOC_GET\n”);
      ret = copy_to_user((unsigned char*)arg,(unsigned char*)&(devp->data), sizeof(struct miscdata));
    break;
    default:
      return -EINVAL;

  }
  return ret;
}
static const struct file_operations fellowmisc_fops ={
.owner = THIS_MODULE,
.open = fellowmisc_open,
.release = fellowmisc_release,
.unlocked_ioctl = fellowmisc_ioctl,
};
static struct miscdevice fellow_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = “fellowplat”,
.fops = &fellowmisc_fops,
};
static struct platform_device *fellow_platform_device;
static int fellow_plat_drv_probe(struct platform_device *dev)
{
  int error;
  printk(“fellow_plat_drv_probe\n”);
  fellowmisc_devp = kmalloc(sizeof(struct fellowmisc_dev), GFP_KERNEL);
  if (!fellowmisc_devp)
  {
    error = -ENOMEM;
    return error;
  }
  memset(&(fellowmisc_devp->data), 0, sizeof(fellowmisc_devp->data));
  fellowmisc_devp->misc = fellow_misc;
  error = misc_register(&fellow_misc);
  return error;
}
static int fellow_plat_drv_remove(struct platform_device *dev)
{
  int error;
  if (fellowmisc_devp)
    kfree(fellowmisc_devp);
  error = misc_deregister(&fellow_misc);
  return error;
}
static struct platform_driver fellow_platform_driver = {
.driver = {
.name = “fellow”,
},
.probe = fellow_plat_drv_probe,
.remove = fellow_plat_drv_remove,
};

static int fellowplat_init(void)
{
  int error;
  printk(“fellowplat_init\n”);
  printk(“fellow register driver\n”);
  error = platform_driver_register(&fellow_platform_driver);//注册platform driver
  if (error)
    return error;

  fellow_platform_device = platform_device_alloc(“fellow”, -1);//名字与platform driver相同。
  if (!fellow_platform_device) {
    error = -ENOMEM;
    goto err_driver_unregister;
  }

  printk(“fellow register device\n”);
  error = platform_device_add(fellow_platform_device);//添加platform device
  if (error)
    goto err_free_device;

  return 0;

err_free_device:
  platform_device_put(fellow_platform_device);
err_driver_unregister:
  platform_driver_unregister(&fellow_platform_driver);
  return error;
}

static void fellowplat_exit(void)
{
  platform_device_unregister(fellow_platform_device);
  platform_driver_unregister(&fellow_platform_driver);
}

MODULE_AUTHOR(“fellow”);
MODULE_LICENSE(“GPL”);
module_init(fellowplat_init);
module_exit(fellowplat_exit);

 

app.c

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include “fellowplat.h”
int main(void)
{
  int fd = open(“/dev/fellowplat”, O_RDWR);
  if (fd < 0)
  {
    printf(“open fail:%s\n”, strerror(errno));
    return -1;
  }
  int ret = 0;
  struct miscdata data;
  data.val = 18;
  data.str = “fellow platform device”;
  data.size = sizeof(“fellow platform device”);
  if ((ret = ioctl(fd, FELLOW_MISC_IOC_SET, &data)) < 0)
  {
    printf(“ioctl set fail:%s\n”, strerror(errno));
  }
  struct miscdata getdata;
  if ((ret = ioctl(fd, FELLOW_MISC_IOC_GET, &getdata)) < 0)
  {
    printf(“ioctl get fail:%s\n”, strerror(errno));
  }
  printf(“get val:%d, str:%s, size: %d\n”, getdata.val, getdata.str, getdata.size);
  if ((ret = ioctl(fd, FELLOW_MISC_IOC_PRINT, NULL)) < 0)
  {
    printf(“ioctl print fail:%s\n”, strerror(errno));
  }
  close(fd);
  return ret;
}

运行结果如下

设备驱动基础学习--platform driver简单实现「建议收藏」

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/154964.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • iocomp入门教程-以MFC中iplotx为例

    iocomp入门教程-以MFC中iplotx为例最近要做一个项目需要绘制曲线,为了节省时间,就选用了iocomp控件,可网上相关的教程极少,官方给的文档还是比较详尽,但缺少具体的前期准备步骤,在初次接触这个控件很容易蒙,所以我写下这篇,给入门者以便利。用到的材料:              iocomp激活成功教程版(目前常见的为V3和V4,两个版本按喜好选择吧~            

    2022年7月17日
    15
  • 电商网站商品价格获取方法_电商网站

    电商网站商品价格获取方法_电商网站电商网站商品价格获取本文以苏宁易购,京东,两个电商网站,模仿说明电商网站商品价格的两种获取方法。json形式存放,京东商品的价格以json形式存放,以以下页面为例https://item.jd.com/100000287133.html明显价格数据并非放在前端页面里,搜索找到以下数据查看当前的url在浏览器中请求https://p.3.cn/prices/mgets?cal…

    2022年10月1日
    3
  • 服务器加网站防盗链,网站防盗链的设置方法介绍(适用于IIS和Apache)[通俗易懂]

    服务器加网站防盗链,网站防盗链的设置方法介绍(适用于IIS和Apache)[通俗易懂]这篇文章主要为大家详细介绍了网站防盗链的设置方法介绍(适用于IIS和Apache),具有一定的参考价值,感兴趣的小伙伴们可以参考一下,有需要的朋友可以收藏方便以后借鉴。做网站的朋友一般都会遇到这样的一种情况,就是别人的网站经常会调用我们自己网站的图片或者文件,这无形之中会增加我们的服务器的压力,尤其是对于一些服务器带宽并不是十分富裕的网站来说就更是雪上加霜。因此我们需要学会设置防盗链来应对或者说来…

    2022年7月23日
    25
  • Oracle中文全文索引[通俗易懂]

    环境Oracle9.0.2 Oracle全文索引的基本知识一、历史背景Oracle数据库的全文检索技术已经非常完美,OracleText使Oracle9i具备了强大的文本检索能力和智能化的文本管理能力。OracleText是Oracle9i采用的新名称,在Oracle8/8i中它被称作OracleinterMediaText,在Oracle8以前它的名称是Oracle

    2022年4月11日
    38
  • PS2手柄遥控控制灯开关(arduino)

    PS2手柄遥控控制灯开关(arduino)PS2手柄遥控控制灯开关(arduino)使用的材料arduino板子:ps2遥控手柄;一个5V供电的LDE;连线首先按照遥控手柄底座上的英文,你会发现一共有六根线,分别是GND,VCC,DAT,CMD,CS,CL。GND连接arduino板子上的gnd,vcc连接5V或者3.3v,其他四根线可以按照代码中的引脚设置连接,也可以自己更改。代码部分#include<PS…

    2022年6月3日
    88
  • Linux chmod命令及权限含义

    Linux chmod命令及权限含义

    2021年10月15日
    56

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号