下面代码是一个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()函数用于注销字符设备,并在终端打印一条消息。
-
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- #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);
- #ifndef _simple_H_
- #define _simple_H_
-
- #include
/* 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_ */