文字駆動サンプルプログラム【駆動:例6-3.call_dev.c】【適用:例6-4.call_app】


文字駆動call_dev.c
 
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>

#define CALL_DEV_NAME "calldev"
#define CALL_DEV_MAJOR  240


int call_open(struct inode *inode, struct file *filp)
{	
	int num = MINOR(inode->i_rdev);

	printk("call open->minor : %d 
", num); return 0; } loff_t call_llseek(struct file *filp, loff_t off, int whence) { printk("call llseek->off: %08x, whence:%08x
", off, whence); return 0x23; } ssize_t call_read(struct file *filp, char *buf, size_t count, loff_t *fops) { printk("call read->buf:%08x, count:%08x
",buf, count); return 0x33; } ssize_t call_write(struct file *filp, const char *buf,size_t count, loff_t *f_ops) { printk("call write->buf:%08x, count:%08x
",buf, count); return 0x43; } int call_ioctl(struct file *filp,unsigned int cmd, unsigned long arg) { printk("call ioctl->cmd: %08x, arg:%08x
",cmd,arg); return 0x53; } int call_release(struct inode *inode,struct file *filp) { printk("call release
"); return 0; } struct file_operations call_fops = { .owner = THIS_MODULE, .llseek = call_llseek, .read = call_read, .write = call_write, .unlocked_ioctl = call_ioctl, .open = call_open, .release = call_release, }; int call_init(void) { int result; printk("call call_init
"); result = register_chrdev(CALL_DEV_MAJOR, CALL_DEV_NAME,&call_fops); if(result <0) return result; return 0; } void call_exit(void) { printk("call call_exit
"); unregister_chrdev(CALL_DEV_MAJOR, CALL_DEV_NAME); } module_init(call_init); module_exit(call_exit); MODULE_LICENSE("Dual BSD/GPL");

テスト用アプリケーションcall_app.c:
 
#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define DEVICE_FILENAME "/dev/calldev"

int main()
{
	int dev;
	char buff[128];
	int ret;

	printf("1) device file open 
"); dev = open(DEVICE_FILENAME, O_RDWR|O_NDELAY); if(dev >= 0) { printf("2) seek function call
"); ret = lseek(dev, 0x20, SEEK_SET); printf("ret = %08X
", ret); } printf("3) read function call
"); ret = read(dev, 0x30, 0x31); printf("ret = %08X
", ret); printf("4) write function call
"); ret = write(dev, 0x40, 0x41); printf("ret = 0x08X
",ret); printf("5) ioctl function call
"); ret = ioctl(dev, 0x51, 0x52); printf("ret = %08X
" , ret); printf("6) device file close
"); ret = close(dev); printf("ret = %08X
", ret); return 0; }

実行結果:
root@xiangpingli:/home/linux/study/6.4# insmod call_dev.ko root@xiangpingli:/home/linux/study/6.4# mknod/dev/calldev c 240 32 root@xiangpingli:/home/linux/study/6.4# ./call_app 1) device file open 2) seek function call ret = 00000023 3) read function call ret = 00000033 4) write function call ret = 00000043 5) ioctl function call ret = 00000053 6) device file close ret = 00000000 root@xiangpingli:/home/linux/study/6.4# dmesg [ 2309.523091] call call_init [ 2329.501102] call open->minor : 32 [ 2329.501113] call llseek->off: 00000020, whence:00000000 [ 2329.501151] call read->buf:00000030, count:00000031 [ 2329.501158] call write->buf:00000040, count:00000041 [ 2329.501170] call ioctl->cmd: 00000051, arg:00000052 [ 2329.501178] call release root@xiangpingli:/home/linux/study/6.4#