linux device driver —— ioctl

实现了应用程序和设备驱动通过ioctl通信。还是对设备驱动没什么感觉,贴一下代码吧。

在Ubuntu 16.04 64bit中测试通过

ioctldemo.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/stat.h>
#include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/moduleparam.h>
#include <linux/cdev.h>
#include <asm-generic/uaccess.h>
#include <asm-generic/ioctl.h>
#include <asm-generic/current.h>

#define IOCTLDEMO_MAJOR 0
#define MODULE_NAME "ioctldemo"

#define DEMO_MAGIC ‘m‘
#define DEMO_SIZE  int
#define DEMO_NR_MAX    1
#define MY_IOCTL_READ _IOR(DEMO_MAGIC,1,DEMO_SIZE);

static int ioctldemo_major = IOCTLDEMO_MAJOR;

void ioctldemo_exit(void);
int  ioctldemo_init(void);
long my_unlocked_ioctl(struct file*, unsigned int, unsigned long);
int  my_cdev_open(struct inode*, struct file*);
int  my_cdev_release(struct inode*,struct file*);

MODULE_LICENSE("Dual BSD/GPL");
module_param(ioctldemo_major,int,S_IRUGO);
module_init(ioctldemo_init);
module_exit(ioctldemo_exit);

struct cdev *my_cdev;

static struct file_operations cdev_ops =
{
    .owner          = THIS_MODULE,
    .open           = my_cdev_open,
    .release        = my_cdev_release,
    .unlocked_ioctl = my_unlocked_ioctl,
};

int __init ioctldemo_init(void)
{
    int ret;
    dev_t devno;
    printk(KERN_NOTICE "=== ioctldemo_init start");
    devno = MKDEV(ioctldemo_major,0);
    if(ioctldemo_major)
    {
        printk(KERN_NOTICE "=== ioctldemo_init try register");
        ret = register_chrdev_region(devno,1,MODULE_NAME);
    }else
    {
        printk(KERN_NOTICE "=== ioctldemo_init auto register");
        ret = alloc_chrdev_region(&devno,0,1,MODULE_NAME);
        ioctldemo_major = MAJOR(devno);
    }
    if(ret < 0)
    {
        printk(KERN_NOTICE "=== ioctldemo_init register fail");
        return ret;
    }

    my_cdev = cdev_alloc();
    my_cdev->owner = THIS_MODULE;
    my_cdev->ops   = &cdev_ops;
    ret = cdev_add(my_cdev,MKDEV(ioctldemo_major,0),1);

    if(ret < 0)
    {
        printk(KERN_NOTICE "=== ioctldemo_init add cdev fail");
        return ret;
    }

    printk(KERN_NOTICE "=== ioctldemo_init finish");
    return 0;
}

void __exit ioctldemo_exit(void)
{
    printk (KERN_NOTICE "=== ioctldemo_exit");
    cdev_del(my_cdev);
    unregister_chrdev_region(MKDEV(ioctldemo_major,0),1);
}

long my_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    int err = 0;
    if(_IOC_TYPE(cmd) != DEMO_MAGIC)
        return -ENOTTY;
    if(_IOC_NR(cmd) > DEMO_NR_MAX)
        return -ENOTTY;
    if(_IOC_DIR(cmd) & _IOC_READ)
        err = !access_ok(VERIFY_WRITE,(void __user*)arg, _IOC_SIZE(cmd));
    if(err)
        return -EFAULT;

    printk(KERN_NOTICE "=== ioctldemo_ioctl current process is: %s, pid is: %d\n",current->comm,current->pid);

    return __put_user(666,(int *)arg);
}

int my_cdev_open(struct inode *node, struct file *filp)
{
    return 0;
}

int my_cdev_release(struct inode *node, struct file *filp)
{
    return 0;
}

Makefile

ifneq ($(KERNELRELEASE),)
mymodule-objs := ioctldemo
obj-m := ioctldemo.o
else
PWD  := $(shell pwd)
KVER ?= $(shell uname -r)
KDIR := /lib/modules/$(KVER)/build
all:
    $(MAKE) -C $(KDIR) M=$(PWD)
clean:
    rm -rf *.cmd *.o *.mod.c  .tmp_versions *.order *.symvers
endif

install.sh

#!/bin/bash

module="ioctldemo"
device="ioctldemo"
name="ioctldemo"

insmod $module.ko

if [ $? == 1 ]
then
    exit
fi
major=$(awk "{if(\$2==\"$name\"){print \$1}}"  /proc/devices)

mknod /dev/$device c $major 0

chmod 666 /dev/$device

uninstall.sh

#!/bin/bash
module="ioctldemo"
device="ioctldemo"

file="/dev/$device"

if [ -e $file ]
then
    rm -rf /dev/$device
    echo ‘rm device‘
fi

echo ‘rm module‘
/sbin/rmmod $module

测试程序:

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <asm-generic/ioctl.h>
#include <error.h>

#define CMD _IOR(‘m‘,1,int)

int main()
{
    int fd, ret, arg;
    fd = open("/dev/ioctldemo",O_RDWR);
    if(fd < 0)
    {
        puts("open fail");
        return fd;
    }
    ret = ioctl(fd,CMD,&arg);
    if(ret == 0)
        printf("ioctl result :%d",arg);
    else
        perror("ioctl fail");
    close(fd);
    return 0;
}
时间: 2024-11-04 01:17:10

linux device driver —— ioctl的相关文章

linux platform device/driver(三)--Platform Device和Platform_driver注册过程之代码对比

转自:http://blog.csdn.net/thl789/article/details/6723350 Linux 2.6的设备驱动模型中,所有的device都是通过Bus相连.device_register() / driver_register()执行时通过枚举BUS上的Driver/Device来实现绑定,本文详解这一过程.这是整个LINUX设备驱动的基础,PLATFORM设备,I2C上的设备等诸设备的注册最终也是调用本文讲述的注册函数来实现的. Linux Device的注册最终都

linux platform device/driver(二)--Platform Device和Platform_driver注册过程

从 Linux 2.6 起引入了一套新的驱动管理和注册机制 :Platform_device 和 Platform_driver . Linux 中大部分的设备驱动,都可以使用这套机制 ,  设备用 Platform_device 表示,驱动用 Platform_driver 进行注册. Linux platform driver 机制和传统的 device driver  机制 ( 通过 driver_register 函数进行注册 ) 相比,一个十分明显的优势在于 platform 机制将设

I.MX6 Linux I2C device&amp; driver hacking

/******************************************************************************************* * I.MX6 Linux I2C device& driver hacking * 声明: * 1. 本文主要是对Linux I2C驱动进行代码跟踪,主要是为了能够对I2C驱动框架有个全面的了解: * 2. 本文源代码来自myzr_android4_2_2_1_1_0.tar.bz2: * 3. 如果你有兴趣,

Device driver testing framework for OMAP Linux kernel

unit test on android kernel: OMAP DDT(Device Driver Test) Part of Linux OMAP Project code: git://gitorious.org/omap-ddt/omap-ddt.git

Samsung_tiny4412(驱动笔记10)----mdev,bus,device,driver,platform

/*********************************************************************************** * * mdev,bus,device,driver,platform * * 声明: * 1. 本系列文档是在vim下编辑,请尽量是用vim来阅读,在其它编辑器下可能会 * 不对齐,从而影响阅读. * 2. 由于本人水平有限,很难阐述清楚bus device driver platform的关系 * 所以强烈要求您详细参考本次

linux device driver3 读书笔记(一)

一:机制与策略(转) http://www.51hei.com/bbs/dpj-29441-1.html 机制mechanism,策略policy.如果你看过<linux device drivers>,里面给出了大概的介绍.机制提供了干什么(do what),策略提供如何做(how to do).驱动程序完成机制的功能,把策略的实现留给用户的应用程序. 通常在机制中,驱动程序要完成打开,关闭,读写,控制等功能.这些都是设备使用时最基本的操作.而策略中就要实现一些高级的数据处理或界面功能.通过

Program for Linux USB-devices driver step by step (ONE)

Program for Linux USB-devices driver 开始啃硬骨头~ 这里我打算一步步给出USB device driver 的demo,希望有心能能够共同交流学习. 希望认识更多对Linux有兴趣的geek. 目前由于环境和自身能力方面原因还没能做实物的测试,篇章的最后打算给出一个在x86上模拟USB读写的driver,以后能够做实物测试之后再更新this blog 我的联系方式: [email protected](由于偶不能登QQ,所以thunder bird的邮件只要

char device driver

概览:    第一步:注册设备号                                              信息#tail -f /var/log/message        注册函数:            register_chrdev_region() 或                             查看#lsmod            alloc_chrdev_region()    或                             查看#cat

I.MX6 Linux、Jni ioctl 差异

/*********************************************************************** * I.MX6 Linux.Jni ioctl 差异 * 声明: * 在使用Jni的ioctl()的过程中,发现不能像普通的Linux函数那样使用, * 必须使用3各参数的ioctl()函数. * * 2015-12-20 深圳 南山平山村 曾剑锋 ****************************************************