当应用程序需要调用内核的方法进行数据交互,
可以使用 ioctl 进行调用。
使用到这个交互方式是一次在我程序中需要对某个管脚进行拉高和拉低处理。
驱动部分程序
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#define MAJOR_SAMPLE 120
#define MINOR_SAMPLE 0
static dev_t dev_num = 0;
static struct cdev g_cdev;
static int sample_open (struct inode *inode, struct file *pfile)
{
printk("[%s]\n", __func__);
return 0;
}
long sample_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
printk("[%s]cmd:%d\n", __func__, cmd);
return 0;
}
static struct file_operations hello_ops = {
.open = sample_open,
.unlocked_ioctl = sample_ioctl,
};
static int sample_init(void)
{
int result;
int error;
dev_num = MKDEV(MAJOR_SAMPLE, MINOR_SAMPLE);
result = register_chrdev_region(dev_num, 1, "sample_ioctl");
if (result < 0){
printk("register_chrdev_region fail! \n");
return result;
}
printk("register_chrdev_region OK \n");
cdev_init(&g_cdev,&hello_ops);
error = cdev_add(&g_cdev,dev_num,1);
if(error < 0)
{
printk("cdev_add fail \n");
unregister_chrdev_region(dev_num,1);
return error;
}
return 0;
}
static void sample_exit(void)
{
printk("%s ...\n", __func__);
cdev_del(&g_cdev);
unregister_chrdev_region(dev_num, 1);
return;
}
module_init(sample_init);
module_exit(sample_exit);
MODULE_LICENSE("GPL");
使用测试程序打开驱动进行数据交互测试
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
// cat /proc/devices
// mknod /dev/sample_ctl c 120 0
int main()
{
int fd;
int ret;
fd = open("/dev/sample_ctl",O_RDWR);
if(fd<0)
{
perror("open fail \n");
return;
}
printf("open ok \n ");
ret = ioctl(fd, 10086, 1);
if (ret < 0)
{
perror("ioctl fail \n");
}
return ret;
return 1;
}
使用 insmod 安装驱动后没有设备节点
可以手动添加节点
cat /proc/devices
mknod /dev/sample_ctl c 120 0