先看代码:
1、驱动程序:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#define TIMER_DEV_NAME "test"
#define TIMER_DEV_COUNT 1
#define CMD_RUN (_IO('T', 0x54))
#define CMD_STOP (_IO('T', 0x53))
struct timer_dev_type {
dev_t dev_id;
struct cdev cdev;
struct class *class;
struct device *device;
int major;
};
struct timer_dev_type timer_dev;
static int timer_dev_open(struct inode *inode, struct file *file)
{
return 0;
}
long timer_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
case CMD_RUN:
printk("Running!\n");
break;
case CMD_STOP:
printk("Stopped!\n");
break;
}
return 0;
}
static struct file_operations timer_dev_ops = {
.owner = THIS_MODULE,
.open = timer_dev_open,
.unlocked_ioctl = timer_dev_ioctl,
};
static int __init timer_dev_init(void)
{
int err = 0;
/* 1、创建设备号 */
if(timer_dev.major)
{
timer_dev.dev_id = MKDEV(timer_dev.major, 0);
register_chrdev_region(timer_dev.dev_id, TIMER_DEV_COUNT, TIMER_DEV_NAME);
}
else
{
alloc_chrdev_region(&timer_dev.dev_id, 0, TIMER_DEV_COUNT, TIMER_DEV_NAME);
timer_dev.major = MAJOR(timer_dev.dev_id);
}
/* 2、初始并添加字符设备 */
timer_dev.cdev.owner = THIS_MODULE;
cdev_init(&timer_dev.cdev, &timer_dev_ops);
cdev_add(&timer_dev.cdev, timer_dev.dev_id, TIMER_DEV_COUNT);
/* 3、创建类 */
timer_dev.class = class_create(THIS_MODULE, TIMER_DEV_NAME);
if(IS_ERR(timer_dev.class))
{
printk("Error: Failed to create timer class!\n");
return -EINVAL;
}
/* 4、创建设备 */
timer_dev.device = device_create(timer_dev.class, NULL, timer_dev.dev_id, NULL, TIMER_DEV_NAME);
if(IS_ERR(timer_dev.device))
{
printk("Error: Failed to create device!\n");
return -EINVAL;
}
return err;
}
static void __exit timer_dev_exit(void)
{
/* 1、删除设备 */
device_destroy(timer_dev.class, timer_dev.dev_id);
/* 2、删除类 */
class_destroy(timer_dev.class);
/* 3、注销字符设备 */
cdev_del(&timer_dev.cdev);
/* 4、释放设备号 */
unregister_chrdev_region(timer_dev.dev_id, TIMER_DEV_COUNT);
}
module_init(timer_dev_init);
module_exit(timer_dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("LSW");
2、应用程序:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define CMD_RUN (_IO('T', 0x54))
#define CMD_STOP (_IO('T', 0x53))
int main(int argc, char const *argv[])
{
int err = 0;
int fd;
const char *filename = argv[1];
unsigned char cmd;
/* 打开文件 */
fd = open(filename, O_RDWR);
if(fd < 0)
{
printf("Error: Could not open file: %s\n", filename);
return -1;
}
#if 0 /* 代码1:直接调用ioctl */
/* 能成功实现 */
ioctl(fd, CMD_RUN);
ioctl(fd, CMD_STOP);
#else /* 代码2:通过键盘输入命令,再通过命令调用ioctl */
/* 不能实现 */
printf("Please input cmd:");
err = scanf("%d", &cmd);
if(err != 1) // 防止卡死
{
while(getchar() != '\n');
}
if(cmd == 1)
{
err = ioctl(fd, CMD_RUN);
if(err != 0)
{
printf("ioctl error: %d\n", err);
}
printf("cmd1 executed!\n");
}
else if(cmd == 2)
{
err = ioctl(fd, CMD_STOP);
if(err != 0)
{
printf("ioctl error: %d\n", err);
}
printf("cmd2 executed!\n");
}
#endif
/* 关闭文件 */
err = close(fd);
if(err < 0)
{
printf("Error: Could not close file: %s\n");
return -1;
}
return 0;
}
问题描述
在应用程序中,如果直接调用ioctl函数(代码1)时,驱动程序中的ioctl能成功打印,
但是,如果应用程序中,用代码2来调用时,虽然没有报错,但是就是没有代用到驱动程序的ioctl
|