linux驱动开发-字符设备初级应用(管道)

本文主要是示例程序,描述一个简单的管道,废话少说,贴代码。

#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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值