User Application除了透過read()、write()跟驅動程式傳送資料之外,也可以使用以控制為主的ioctl()去跟驅動程式溝通
main.c
#include <linux/cdev.h> #include <linux/init.h> #include <linux/device.h> #include <linux/module.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Steward Fu"); MODULE_DESCRIPTION("Linux Driver"); static int base = 0; static struct cdev mycdev; static struct class *myclass = NULL; static int myopen(struct inode *inode, struct file *file) { printk("%s\n", __func__); return 0; } static int myclose(struct inode *inode, struct file *file) { printk("%s\n", __func__); return 0; } static long myioctl(struct file *filp, unsigned int cmd, unsigned long arg) { printk("%s, 0x%x\n", __func__, cmd); return 0; } static const struct file_operations myfops = { .owner = THIS_MODULE, .open = myopen, .release = myclose, .unlocked_ioctl = myioctl, }; int ldd_init(void) { alloc_chrdev_region(&base, 0, 1, "myfile"); myclass = class_create(THIS_MODULE, "myfile"); device_create(myclass, NULL, base, NULL, "myfile"); cdev_init(&mycdev, &myfops); cdev_add(&mycdev, base, 1); return 0; } void ldd_exit(void) { cdev_del(&mycdev); device_destroy(myclass, base); class_destroy(myclass); unregister_chrdev_region(base, 1); } module_init(ldd_init); module_exit(ldd_exit);
ldd_init: 建立字元驅動程式
myopen: 僅列印字串
myioctl: 僅列印字串
myclose: 僅列印字串
ldd_exit: 刪除字元驅動程式
app.c
#include <stdio.h> #include <stdint.h> #include <sys/fcntl.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h> #include <linux/ioctl.h> #define MY_IOCTL _IOWR(0x100, 0, unsigned long) int main(int argc, char **argv) { int fd = 0; fd = open("/dev/myfile", O_RDWR); ioctl(fd, MY_IOCTL, 0); close(fd); return 0; }
編譯App
$ arm-linux-gnueabihf-gcc app.c -o app -static
測試
# insmod /boot/main.ko # /boot/app myopen myioctl, 0xc0050000 myclose