linux chrdev字符设备驱动程序示例

简介

下面代码是一个linux内核模块,用于实现一个简单的字符设备驱动程序示例。示例代码实现了一个简单的字符设备驱动程序,可以读取和写入内核缓冲区中的数据。

代码说明

头文件包含该代码包含了一些Linux内核头文件,这些头文件提供了与Linux内核功能和API相关的定义和声明。

前面的代码段定义了一些用于内核模块的全局变量,包括一个表示设备打开次数的变量和一个用于存储数据的缓冲区。

simple_open()函数和simple_release()函数分别用于处理设备的打开和释放操作。在simple_open()函数中,会检查设备是否已经被打开,若已经打开则返回错误码。在simple_release()函数中,会将设备打开次数减1。

simple_read()函数和simple_write()函数分别用于处理从设备读取数据和向设备写入数据的操作。在simple_read()函数中,会将数据从内核空间拷贝到应用程序空间。在simple_write()函数中,会将数据从应用程序空间拷贝到内核空间。

代码定义了一个struct file_operations结构体变量simple_fops,用于指定文件操作的回调函数。这些回调函数会在对设备进行读、写、打开、释放等操作时被调用。

simple_init_module()函数通过调用register_chrdev()函数来注册字符设备,设备号为simple_MAJOR。simple_cleanup_module()函数用于注销字符设备,并在终端打印一条消息。

代码

cpp 复制代码
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/cdev.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/ctype.h>
#include <linux/pagemap.h>

#include "demo.h"

MODULE_AUTHOR("fgj");
MODULE_LICENSE("Dual BSD/GPL");

static unsigned char simple_inc=0;
static unsigned char demoBuffer[256];

int simple_open(struct inode *inode, struct file *filp)
{
	if(simple_inc>0)return -ERESTARTSYS;
	simple_inc++;
	return 0;
}

int simple_release(struct inode *inode, struct file *filp)
{
	simple_inc--;
	return 0;
}

ssize_t simple_read(struct file *filp, char __user *buf, size_t count,loff_t *f_pos)
{
	/* 把数据拷贝到应用程序空间 */
	if (copy_to_user(buf,demoBuffer,count))
	{
	   count=-EFAULT; 
	}
	return count;
}

ssize_t simple_write(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)
{
	/* 把数据拷贝到内核空间 */
	if (copy_from_user(demoBuffer+*f_pos, buf, count))
	{
		count = -EFAULT;
	}
	return count;
}

struct file_operations simple_fops = {
	.owner =    THIS_MODULE,
	.read =     simple_read,
	.write =    simple_write,
	.open =     simple_open,
	.release =  simple_release,
};

/*******************************************************
                MODULE ROUTINE
*******************************************************/
void simple_cleanup_module(void)
{
    unregister_chrdev(simple_MAJOR,  "simple"); 
	printk("simple_cleanup_module!\n");
}

int simple_init_module(void)
{
	int ret;
	ret = register_chrdev(simple_MAJOR, "simple", &simple_fops);//注册设备号231,设备名 
	if (ret < 0)
	{
		printk("Unable to register character device %d!\n",simple_MAJOR);
		return ret;
	}
	return 0;
}

module_init(simple_init_module);
module_exit(simple_cleanup_module);

头文件

cpp 复制代码
#ifndef _simple_H_
#define _simple_H_

#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */

/********************************************************
 * Macros to help debugging
 ********************************************************/
#undef PDEBUG             /* undef it, just in case */
#ifdef simple_DEBUG
#ifdef __KERNEL__
#    define PDEBUG(fmt, args...) printk( KERN_DEBUG "DEMO: " fmt, ## args)
#else//usr space
#    define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
#endif
#else
#  define PDEBUG(fmt, args...) /* not debugging: nothing */
#endif

#undef PDEBUGG
#define PDEBUGG(fmt, args...) /* nothing: it's a placeholder */

//设备号
#define simple_MAJOR 224

//设备结构
struct simple_dev 
{
	struct cdev cdev;	  /* Char device structure		*/
};

//函数申明
ssize_t simple_read(struct file *filp, char __user *buf, size_t count,
                   loff_t *f_pos);
ssize_t simple_write(struct file *filp, const char __user *buf, size_t count,
                    loff_t *f_pos);
loff_t  simple_llseek(struct file *filp, loff_t off, int whence);
int     simple_ioctl(struct inode *inode, struct file *filp,
                    unsigned int cmd, unsigned long arg);


#endif /* _simple_H_ */
相关推荐
知北游天4 分钟前
Linux:多线程---深入互斥&&浅谈同步
linux·运维·服务器
Gappsong8746 分钟前
【Linux学习】Linux安装并配置Redis
java·linux·运维·网络安全
try2find39 分钟前
移动conda虚拟环境的安装目录
linux·运维·conda
码农101号1 小时前
Linux中容器文件操作和数据卷使用以及目录挂载
linux·运维·服务器
PanZonghui1 小时前
Centos项目部署之Nginx 的安装与卸载
linux·nginx
PanZonghui1 小时前
Centos项目部署之安装数据库MySQL8
linux·后端·mysql
PanZonghui1 小时前
Centos项目部署之运行SpringBoot打包后的jar文件
linux·spring boot
PanZonghui1 小时前
Centos项目部署之Java安装与配置
java·linux
程序员弘羽2 小时前
Linux进程管理:从基础到实战
linux·运维·服务器
PanZonghui2 小时前
Centos项目部署之常用操作命令
linux