目录
copy_from_user改为用ioctl接口
将以前的beep杂项设备中的copy_from_user改为用ioctl接口,修改的代码是 linux驱动:(8)实战:用杂项设备完成蜂鸣器驱动 中的代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#define GPIO5_DR 0x020AC00
unsigned int *vir_gpio5_dr;
int misc_open(struct inode * inode,struct file * file)
{
printk("hello misc_open\n");
return 0;
}
int misc_read(struct file *file,char _user *ubuf,size_t size,loff_t *loff_t)
{
char kbuf[64] = "heheh";
if( copy_to_user(ubuf,kbuf,strlen(kbuf))!=0)
{
printk("copy_to_user error\n");
return -1;
}
return 0;
}
int misc_write(struct file *file,const char _user *ubuf,size_t size,loff_t *loff_t)
{
char kbuf[64] = {0};
if( copy_from_user(kbuf,ubuf,size)!=0)
{
printk("copy_from_user error\n");
return -1;
}
printk("kbuf is %s\n",kbuf);
if(kbuf[0]==1)
{
*vir_gpio5_dr |= (1<<1);
}
else if
{
*vir_gpio5_dr &= ~(1<<1);
}
return 0;
}
struct const file_operation misc_fops = {
.owner = THIS_MODULE,
.open = misc_open,
.write= misc_write,
.read = misc_read
};
struct miscdevice misc_dev = {
.minor = MISC_DYNAMIC_MINOR,//动态分配
.name ="hellomisc",//设备节点名字
.fops =&misc_fops
};
static int misc_init(void)
{
int ret;
ret = misc_register(&misc_dev);
if(ret<0)
{
printk("misc registe is error\n");
return -1;
}
vir_gpio5_dr = ioremap(GPIO5_DR,4);
if(vir_gpio5_dr ==NULL)
{
printk("GPIO5_DR ioremap error\n");
return -EBUSY;
}
printk("GPIO5_DR ioremap ok\n");
return 0;
}
static void misc_exit(void)
{
misc_deregister(&misc_dev);
iounmap(vir_gpio5_dr );
printk("misc goodbye");
}
module_init(misc_init);
module_exit(misc_exit);
MODULE_LICENSE("GPL");
修改为ioctl读取无参数命令
- 先把关于GPIO5_DR 的部分删掉
- 编写测试.c,定义发送两个无参数命令
- ioctl函数中的参数对应驱动中的函数中的参数
- 在驱动.c中也要定义两个一样的无参数命令
- 在文件操作集中定义unlocked_ioctl函数
- 在函数中判断cmd命令是否等于我们自己定义的两个命令
测试.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unis