字符驱动,希望对大家有帮助
#include <linux/module.h>
#if defined(CONFIG_SMP)
#define __SMP__
#endif
#if defined(CONFIG_MODVERSIONS)
#define MODVERSIONS
#include <linux/modversions.h>
#endif
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/timer.h>/* for timers */
#include <linux/fs.h>/* file modes and device registration */
#include <linux/poll.h>/* for poll */
#include <linux/wrapper.h>/* mem_map_reserve,mem_map_unreserve */
#include <linux/proc_fs.h>
#include <linux/sysctl.h>
#include <linux/init.h>
#include <asm/io.h>
#include "schar.h"
/* forward declarations for _fops */
static ssize_t schar_read(struct file *file, char *buf, size_t count, loff_t *offset);
static ssize_t schar_write(struct file *file, const char *buf, size_t count, loff_t *offset);
static int schar_open(struct inode *inode, struct file *file);
static int schar_release(struct inode *inode, struct file *file);
static struct file_operations schar_fops = {
schar_read,
schar_write,
schar_open,
schar_release,
};
/* data */
static long schar_pool, schar_data_read, schar_data_written;
static char *schar_buffer;
static struct wait_queue *schar_wq = NULL;
static struct wait_queue *schar_poll_read = NULL;
static char *schar_name;
/* module parameters and descriptions */
MODULE_PARM(schar_name, "s");
MODULE_PARM_DESC(schar_name, "Name of device");
MODULE_DESCRIPTION("schar, Sample character driver");
MODULE_AUTHOR("zz");
static ssize_t schar_read(struct file *file, char *buf, size_t count,
loff_t *offset)
{
/* if less data than requested is here, put reading process to sleep */
while (count > schar_pool) {
/* if the device is opened non blocking satisfy what we
can of the request and don't put the process to sleep. */
if (file->f_flags & O_NONBLOCK) {
if (schar_pool > 0) {
file->f_pos += schar_pool;
schar_data_read += file->f_pos;
if(copy_to_user(buf, schar_buffer, schar_pool))
return -EFAULT;
count = schar_pool;
schar_pool = 0;
return count;
} else {
return -EAGAIN;
}
}
MSG("putting process with pid %u to sleep\n", current->pid);
/* go to sleep, but wake up on signals */
interruptible_sleep_on(&schar_wq);
if (signal_pending(current)) {
MSG("pid %u got signal\n", (unsigned)current->pid);
/* tell vfs about the signal */
return -EINTR;
}
}
/* copy the data the our buffer */
if (copy_to_user(buf, schar_buffer, count))
return -EFAULT;
schar_pool -= count;
schar_data_read += count;
MSG("want to read %u bytes, %ld bytes in queue\n", (unsigned)count,
schar_pool);
/* return data written */
file->f_pos += count;
return count;
}
static ssize_t schar_write(struct file *file, const char *buf, size_t count,
loff_t *offset)
{
schar_pool += count;
schar_data_written += count;
/* if we were really writing - modify the file position to
reflect the amount of data written */
file->f_pos += count;
if (copy_from_user(schar_buffer, buf, count))
return -EFAULT;
/* wake up reading processes, if any */
if (schar_pool > 0) {
wake_up_interruptible(&schar_wq);
wake_up_interruptible(&schar_poll_read);
}
MSG("trying to write %u bytes, %ld bytes in queue now\n",
(unsigned)count, schar_pool);
/* return data written */
return count;
}
static int schar_open(struct inode *inode, struct file *file)
{
/* increment usage count */
MOD_INC_USE_COUNT;
if (file->f_mode & FMODE_READ) {
MSG("opened for reading\n");
} else if (file->f_mode & FMODE_WRITE) {
MSG("opened for writing \n");
}
MSG("major: %d minor: %d\n", MAJOR(inode->i_rdev), MINOR(inode->i_rdev));
return 0;
}
static int schar_release(struct inode *inode, struct file *file)
{
MOD_DEC_USE_COUNT;
MSG("schar_release\n");
return 0;
}
int init_module(void)
{
int res;
if (schar_name == NULL)
schar_name = "schar";
/* register device with kernel */
res = register_chrdev(SCHAR_MAJOR, schar_name, &schar_fops);
if (res) {
MSG("can't register device with kernel\n");
return res;
}
MSG("module loaded\n");
return 0;
}
void cleanup_module(void)
{
/* unregister device and proc entry */
unregister_chrdev(SCHAR_MAJOR, "schar");
if (schar_root_header)
unregister_sysctl_table(schar_root_header);
MSG("unloaded\n");
return;
}
本站以服务广大智能设备爱好者和开发者为立站之本.是你在此交流提高的乐园,本站不做任何形式的广告,不发布任何无意义帖子,论坛靠大家,希望大家踊跃交流,给大家一片洁净的天地!只有大家的支持才是本站生存的根本