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