利用udev、sys动态创建linux设备结点

news/2024/7/4 1:40:05 标签: linux, struct, class, module, file, null
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

在Linux 2.6内核中,devfs被认为是过时的方法,并最终被抛弃,udev取代了它。Devfs的一个很重要的特点就是可以动态创建设备结点。那我们现在如何通过udev和sys文件系统动态创建设备结点呢?

  下面通过一个实例,说明udev、sys动态创建设备结点的方法。注意代码中红色的部分是为了实现动态创建设备结点添加的。

利用udev、sys动态创建<a <a class=class="tags" href="/tags/LINUX.html" title=linux>linux设备结点" /> 

#include <class="tags" href="/tags/LINUX.html" title=linux>linux/module.h>
#include <class="tags" href="/tags/LINUX.html" title=linux>linux/kernel.h>
#include <class="tags" href="/tags/LINUX.html" title=linux>linux/init.h>
#include <class="tags" href="/tags/LINUX.html" title=linux>linux/fs.h>
#include <class="tags" href="/tags/LINUX.html" title=linux>linux/cdev.h>
#include <asm/uaccess.h>
#include <class="tags" href="/tags/LINUX.html" title=linux>linux/device.h>
MODULE_LICENSE ("GPL");
  
int hello_major = 252;
int hello_minor = 0;
int number_of_devices = 1;
char data[50]="foobar not equal to barfoo";
  
class="tags" href="/tags/STRUCT.html" title=struct>struct cdev cdev;
dev_t dev = 0;
static int hello_open (class="tags" href="/tags/STRUCT.html" title=struct>struct inode *inode, class="tags" href="/tags/STRUCT.html" title=struct>struct file *file)
{
printk (KERN_INFO "Hey! device openedn");
return 0;
}
  
static int hello_release (class="tags" href="/tags/STRUCT.html" title=struct>struct inode *inode, class="tags" href="/tags/STRUCT.html" title=struct>struct file *file)
{
printk (KERN_INFO "Hmmm... device closedn");
return 0;
}
ssize_t hello_read (class="tags" href="/tags/STRUCT.html" title=struct>struct file *filp, char *buff, size_t count, loff_t *offp)
{
ssize_t result = 0;
if (copy_to_user (buff, data, sizeof(data)-1))
  result = -EFAULT;
else
  printk (KERN_INFO "wrote %d bytesn", count);
  return result;
}
  
ssize_t hello_write (class="tags" href="/tags/STRUCT.html" title=struct>struct file *filp, const char*buf, size_t count, loff_t *f_pos)
{
ssize_t ret = 0;
printk (KERN_INFO "Writing %d bytesn", count);
if (count>127) return -ENOMEM;
if (count<0) return -EINVAL;
if (copy_from_user (data, buf, count)) {
  ret = -EFAULT;
}
else {
  data[127]='';
  printk (KERN_INFO"Received: %sn", data);
  ret = count;
}
return ret;
}
class="tags" href="/tags/STRUCT.html" title=struct>struct file_operations hello_fops = {
.owner = THIS_MODULE,
.open= hello_open,
.release = hello_release,
.read= hello_read,
.write = hello_write
};
class="tags" href="/tags/STRUCT.html" title=struct>struct class *my_class;
static void char_reg_setup_cdev (void)
{
int error, devno = MKDEV (hello_major, hello_minor);
cdev_init (&cdev, &hello_fops);
cdev.owner = THIS_MODULE;
cdev.ops = &hello_fops;
error = cdev_add (&cdev, devno , 1);
if (error)
   printk (KERN_NOTICE "Error %d adding char_reg_setup_cdev", error);
    /* creating your own class */
my_class =class_create(THIS_MODULE, "farsight_class");//add by lht
if(IS_ERR(my_class)) {
     printk("Err: failed in creating class.n");
     return ;
}
  /* register your own device in sysfs, and this will cause udevd to create corresponding device node */
class_device_create(my_class,NULL, devno, NULL,"farsight_dev");
  //device_create(my_class,NULL, devno,"farsight_dev");
}
  
static int __init hello_2_init (void)
{
int result;
dev = MKDEV (hello_major, hello_minor);
result = register_chrdev_region (dev, number_of_devices, "test");
if (result<0) {
  printk (KERN_WARNING "hello: can't get major number %dn", hello_major);
  return result;
}
char_reg_setup_cdev ();
printk (KERN_INFO "char device registeredn");
return 0;
}
static void __exit hello_2_exit (void)
{
 dev_t devno = MKDEV (hello_major, hello_minor);
 cdev_del (&cdev);
 unregister_chrdev_region (devno, number_of_devices);
  class_device_destroy(my_class, devno);
  class_destroy(my_class);
}
module_init (hello_2_init);
module_exit (hello_2_exit);

 

 

在编译了驱动后,可以查看/dev/farsight_dev设备结点,和/sys/class/farsight_class/farsight_dev/

本代码的测试环境是Ubantu7.04,内核版本是2.6.20-15-generi。在不同版本的内核中,有些系统函数的参数可能不太一样

 


http://www.niftyadmin.cn/n/1748487.html

相关文章

php连接sql_server数据库

1.编译安装FreeTDS从官网下载最新的版本 ftp://ftp.freetds.org/pub/freetds/stable/freetds-patched.tar.gz#wget ftp://ftp.freetds.org/pub/freetds/stable/freetds-patched.tar.gz#tar -zxvf freetds-patched.tar.gz#cd freetds-0.95.95#./configure --prefix/usr/local/fr…

[Docker入门系列教程] 目录索引

Docker是一个开源平台&#xff0c;使开发者和系统管理员可以构建、发布和运行分布式应用。Docker包括Docker引擎、可移植的轻量级运行环境和打包工具&#xff0c;Docker Hub提供了分享应用和自动化工作流的云服务&#xff0c;Docker可以使应用由多个组件快速装配起来&#xff0…

盒子模型理解

HTML CSS DIV实现整体布局 1、技术目标&#xff1a; 开发符合W3C标准的Web页面理解盒子模型实现DIVCSS整体布局2、什么是W3C标准&#xff1f; W3C&#xff1a;World Wide Web Consortium&#xff0c;万维网联盟 W3C的职能&#xff1a;负责制定和维护Web行业标准 W3C标…

udev轻松上路

第一、什么是udev&#xff1f; 这篇文章UDEV Primer给我们娓娓道来&#xff0c;花点时间预习一下是值得的。当然&#xff0c;不知道udev是什么也没关系&#xff0c; 把它当个助记符好了&#xff0c;有了下面的上路指南&#xff0c;可以节省很多时间。我们只需要树立一个信念&…

.Net开发笔记(十) “容器-组件-服务”模型

我前面一篇博客讲了自定义窗体设计器&#xff0c;其实功能太简单&#xff0c;主要想阐述的是底层原理&#xff08;虽然我不保证VS IDE设计器确实是那样去实现的&#xff09;。编程讲究的是刨根问底&#xff0c;刨到祖坟最好&#xff0c;这篇或者可能以后几篇博客我想说一下VS I…

vi的复制粘贴命令

vi编辑器有3种模式&#xff1a;命令模式、输入模式、末行模式。掌握这三种模式十分重要&#xff1a;  命令模式&#xff1a;vi启动后默认进入的是命令模式&#xff0c;从这个模式使用命令可以切换到另外两种模式&#xff0c;同时无论在任何模式下只要按一下[Esc]键都可以返回…

电枢控制直流电动机的数学模型

1. 时域模型 1.1 电枢控制直流电机 这种电机好像有两个绕组需分别供电&#xff1a;励磁绕组和电枢绕组。 1.1.1 反电势 对于给定的反电势系数&#xff0c;反电势只和电机角速度有关。这个反过来想就可以了&#xff1a;负载不变时&#xff0c;永磁式直流电机角速度只和供电电压…

浏览器与web客户端的HTTP交互过程

未经许可谢绝以任何形式对本文内容进行转载&#xff01; HTTP协议是常见的几种应用层协议之一&#xff0c;当我们用浏览器和web客户端进行交互时html页面等内容的传输都是依靠该协议完成的。值得注意的是&#xff0c;HTTP使用的是TCP而非UDP作为其底层的传输层协议&#xff0c;…