天天看點

Linux裝置驅動中的ioctl

memdev.h

#ifndef _MEMDEV_H
#define _MEMDEV_H

#define MEM_MAGIC 'm'
#define MEM_RESTART _IO(MEM_MAGIC, 0)//使用核心提供的宏産生指令,
#define MEM_SET     _IOW(MEM_MAGIC, 1, int)//改指令向核心傳遞一個整形的參數

#endif
           

驅動程式memdev.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "memdev.h"

struct cdev mdev;
dev_t devno;

static long mem_ioctl(struct file* filp, unsigned int cmd, unsigned long arg)
{
	switch(cmd)
	{
		case MEM_RESTART:
			printk("memdev restart.\n");
			break;
		case MEM_SET:
			printk("arg is %ld\n", arg);//将使用者傳遞下來的參數列印出來看是否一緻
			break;
		default:
			return -EINVAL;
			break;
	}
	return 0;
}

struct file_operations memfops = {
	.llseek = mem_lseek,
	.unlocked_ioctl = mem_ioctl,//在2.6.36之前核心中為ioctl,2.6.36之後為unlocked_ioctl,函數參數也有變化
};

static __init int memdev_init(void)
{
	cdev_init(&mdev, &memfops);

	alloc_chrdev_region(&devno, 0, 2, "memdev");
	cdev_add(&mdev, devno, 2);
	printk("memdev_init success\n");

	return 0;
}

static void __exit memdev_exit(void)
{
	cdev_del(&mdev);
	unregister_chrdev_region(devno, 2);
	printk("memdev_exit success\n");
}

module_init(memdev_init);
module_exit(memdev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("liuwei");
MODULE_DESCRIPTION("char driver");
           

應用程式mem_read.c

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "memdev.h"


int main(int argc, char *argv[])
{
	int fd = open("/dev/memdev", O_RDWR);
	if (fd ==  -1)
	{
		perror("open");
		return -1;
	}
	ioctl(fd, MEM_RESTART);//發送兩個控制指令,一個不帶參數,一個帶一個整形的參數
	ioctl(fd, MEM_SET, 10);
	close(fd);

	return 0;
}
           

驅動程式中動态配置設定裝置号,通過cat /proc/devices 檢視系統為memdev配置設定的裝置号。

使用指令mknod /dev/memdev c 252 0建立裝置節點。其中252系統配置設定的裝置号。

驅動簡單的Makefile

ifeq ($(KERNELRELEASE),)

PWD := $(shell pwd)
KERNELDIR ?= /home/farsight/samba/linux-2.6.36
INSTALLDIR ?= /nfs/rootnfs/

modules:
		$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

install:
	cp *.ko /nfs/rootnfs/
clean:
		rm -rf *.o *.ko *.mod.c .*.cmd modules.order Module.symvers .tmp_versions

else

obj-m := memdev.o 

endif
           

繼續閱讀