在上一个hello模块的安装卸载后,我们来实行一下ioctl。最终的目的是实现控制继电器的开启和关闭
hello.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h> // cdev_add cdev_init
#include <linux/kdev_t.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h> // struct file_operations
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/ioport.h>
#include <linux/gpio.h>
#include "msg.h"
#define HELLO_MAJOR 10
#define HELLO_MINJOR 99
MODULE_LICENSE("Dual BSD/GPL");
//MODULE_LICENSE("GPL2");
int open(struct inode *inode1, struct file *filep) {
printk(KERN_ALERT "open success\n");
gpio_direction_output(4,0);
mdelay(500);
gpio_direction_output(4,1);
return 0;
}
int release(struct inode *inode, struct file *filep) {
printk(KERN_ALERT "release success\n");
return 0;
}
int ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{
switch(cmd)//对命令进行判定
{
case MODLD:
printk(KERN_ALERT"LOW\n");
break;
case CMD_LEVEL:
break;
}
return 0;
}
struct file_operations myfops = {
.owner = THIS_MODULE, .open = open, .release = release,.unlocked_ioctl=ioctl, };
struct cdev c_dev;
struct class *myclass=NULL;
void cleanup(int a, int b) {
dev_t devno;
devno = MKDEV(HELLO_MAJOR, HELLO_MINJOR);
if (b == 1) {
device_destroy(myclass, devno);
}
if (a == 1) {
cdev_del(&c_dev);
}
unregister_chrdev_region(devno, 1);
}
static int hello_init(void) {
int ret;
int device_creat;
int dev_add;
int devno;
gpio_request(4,"JDQ");
//c_dev=cdev_alloc();
// myclass = class_create(THIS_MODULE, "hello");
printk(KERN_ALERT "hello world\n");
devno = MKDEV(HELLO_MAJOR, HELLO_MINJOR);
ret = register_chrdev_region(0, 1, "hello");
if (ret < 0) {
printk(KERN_ALERT "chardev_region filed\n");
return -1;
}
// cdev_add(c_dev,devon,1);
if (NULL == device_create(myclass, NULL, HELLO_MAJOR, NULL, "hello")) {
goto cleanup1;
}
device_creat = 1;
cdev_init(&c_dev, &myfops);
c_dev.owner = THIS_MODULE;
c_dev.ops = &myfops;
ret = cdev_add(&c_dev, devno, 1);
if (ret < 0) {
printk(KERN_ALERT "cdev_add filed\n");
return -1;
}
dev_add = 1;
return 0;
cleanup1:
cleanup(dev_add, device_creat);
return -1;
}
static void hello_exit(void) {
printk(KERN_ALERT "goodbay world\n");
cleanup(1, 1);
}
module_init(hello_init);
module_exit(hello_exit);
msg。h
#ifndef MSG_H
#define MSG_H
#include <linux/ioctl.h>
#define MAGIC 'c'
#define CMD_PIN_LOW 0
#define CMD_PIN_HIGH 1
#define CMD_PIN_INPUT 1
#define CMD_PIN_OUTPUT 0
#define MODLD _IOW(MAGIC,0,int)
#define CMD_LEVEL _IOW(MAGIC,1,int)
#endif