文字駆動サンプルプログラム【駆動:例6-3.call_dev.c】【適用:例6-4.call_app】
文字駆動call_dev.c
テスト用アプリケーションcall_app.c:
実行結果:
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#
#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#