本文主要是示例程序,描述一个简单的管道,废话少说,贴代码。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
static int major = 0, minor = 0;
module_param(major, int, 0400);
module_param(minor, int, 0400);
static dev_t devno;
static struct cdev cdev;
//=========================================================
#define SIZE 1024
struct mypipe_t {
char kstr[SIZE];
int in, out;
};
static struct mypipe_t mypipe = { .in = 0, .out = 0 };
static int is_empty(void)
{
return mypipe.in == mypipe.out;
}
static int is_full(void)
{
return (mypipe.in + 1) % SIZE == mypipe.out;
}
static int enqueue(char ch)
{
if (is_full()) return -1;
mypipe.kstr[mypipe.in] = ch;
mypipe.in = (mypipe.in + 1) % SIZE;
return 0;
}
static int dequeue(char *ch)
{
if (is_empty()) return -1;
*ch = mypipe.kstr[mypipe.out];
mypipe.out = (mypipe.out + 1) % SIZE;
return 0;
}
//================================================
static int myopen(struct inode *inode, struct file *filp)
{
printk("[KERN] %s %d\n", __func__, __LINE__);
return 0;
}
static ssize_t myread(struct file *filp,
char * __user buf, size_t len, loff_t *off)
{
int i, ret = 0;
char ch;
for (i = 0; i < len; ++i)
{
if (dequeue(&ch) == -1)
{
break;
}
// buf[i] = ch;
if (copy_to_user(&buf[i], &ch, 1) != 0)
{
enqueue(ch);
ret = -EINVAL;
goto OUT;
}
}
ret = i;
OUT:
return ret;
}
static ssize_t mywrite(struct file *filp,
const char * __user buf, size_t len, loff_t *off)
{
int i, ret = 0;
char ch;
for (i = 0; i < len; ++i)
{
if (copy_from_user(&ch, &buf[i], 1) == 1)
{
ret = -EINVAL;
goto OUT;
}
if (enqueue(ch) == -1)
{
break;
}
}
ret = i;
OUT:
return ret;
}
//================================================
static struct file_operations fops = {
.open = myopen,
.read = myread,
.write = mywrite,
};
static int __init test_init(void)
{
int ret;
if (major == 0)
{
ret = alloc_chrdev_region(&devno, minor, 2, "mydrv");
if (ret != 0)
{
goto ERR0;
}
major = MAJOR(devno);
}
else
{
devno = MKDEV(major, minor);
ret = register_chrdev_region(devno, 2, "mydrv");
if (ret != 0)
{
goto ERR0;
}
}
printk("[KERN] major = %d, minor = %d\n", major, minor);
cdev_init(&cdev, &fops);
ret = cdev_add(&cdev, devno, 2);
if (ret != 0)
{
goto ERR1;
}
return 0;
ERR1:
unregister_chrdev_region(devno, 2);
ERR0:
return ret;
}
static void __exit test_exit(void)
{
cdev_del(&cdev);
unregister_chrdev_region(devno, 2);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
App 测试程序
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int fd, ret;
if (argc < 2) return -1;
fd = open(argv[1], O_RDONLY);
printf("[APP] %s %d\n", __func__, __LINE__);
ret = read(fd, NULL, 100);
perror("read");
printf("[APP] %s %d, ret = %d\n", __func__, __LINE__, ret);
close(fd);
return 0;
}