beep.c
#include<linux/init.h>
#include<linux/module.h>
#include<linux/miscdevice.h>
#include<linux/fs.h>
#include<linux/uaccess.h>
#include<linux/io.h>
#include <linux/ioctl.h>
#include<linux/gpio.h>
#include<linux/of_gpio.h>
#define CMD_TEST0 _IO('L',0)
#define CMD_TEST1 _IO('L',1)
#define CMD_TEST2 _IOW('L',2,int)
#define CMD_TEST3 _IOW('L',3,int)
#define CMD_TEST4 _IOR('L',4,int)
struct device_node *test_device_node;
int ret;
int beep_gpio=0;
int misc_open(struct inode *inode,struct file *file)
{
printk("hello misc_open\n");
return 0;
}
int misc_release(struct inode *inode,struct file *file)
{
printk("hello misc_release bye bye\n");
return 0;
}
ssize_t 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;
}
ssize_t misc_write(struct file *file,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);
return 0;
}
long misc_ioctl(struct file *file,unsigned int cmd,unsigned long value)
{
int val;
switch(cmd)
{
case CMD_TEST0:
gpio_set_value(beep_gpio,1);
printk("LED ON!!\n");
break;
case CMD_TEST1:
gpio_set_value(beep_gpio,0);
printk("LED OFF!!\n");
break;
case CMD_TEST4:
val=12;
if(copy_to_user((int *)value,&val,sizeof(val))!=0)
{
printk("copy_from_user error\n");
return -1;
}
break;
}
return 0;
}
struct file_operations misc_fops=
{
.owner=THIS_MODULE,
.open = misc_open,
.release = misc_release,
.read = misc_read,
.write = misc_write,
.unlocked_ioctl = misc_ioctl
};
struct miscdevice misc_dev=
{
.minor=MISC_DYNAMIC_MINOR,
.name="hello_misc",
.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;
}
printk("msic registe is succeed\n");
printk("beep_probe\n");
test_device_node=of_find_node_by_path("/test");
if(test_device_node==NULL)
{
printk("of_find_node_by_path is error\n");
return -1;
}
beep_gpio=of_get_named_gpio(test_device_node,"beep-gpio",0);
if(beep_gpio<0){
printk("of_get_named_gpio is error\n");
return -1;
}
printk("beep_gpio is %d\n",beep_gpio);
ret=gpio_request(beep_gpio,"beep");
if(ret<0){
printk("gpio_request is error\n");
return -1;
}
gpio_direction_output(beep_gpio,0);
return 0;
}
static void misc_exit(void)
{
misc_deregister(&misc_dev);
printk("misc byb byb\n");
}
module_init(misc_init);
module_exit(misc_exit);
MODULE_LICENSE("GPL");
ioctl.c
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/ioctl.h>
#define CMD_TEST0 _IO('L',0)
#define CMD_TEST1 _IO('L',1)
#define CMD_TEST2 _IOW('L',2,int)
#define CMD_TEST3 _IOW('L',3,int)
#define CMD_TEST4 _IOR('L',4,int)
int main(int argc,char *argv[])
{
int fd;
int value;
fd=open("/dev/hello_misc",O_RDWR);
if(fd<0)
{
perror("open error\n");
return fd;
}
while(1)
{
ioctl(fd,CMD_TEST0);
sleep(2);
ioctl(fd,CMD_TEST1);
sleep(2);
}
return 0;
}
执行效果图: