1.在上次的设备中我们使用IOCTL进行控制2.我们将一些自定义的信息封装在了结构体内
3.我们使用filp->private_data 对正在使用的模块进行传参
4.增加APP 对驱动程序进行控制
下面上代码:
led_test.h
#ifndef _LED_TEST_H
#define _LED_TEST_H
#define LED_CLEAN 0
#define LED_MAGIC 'B'
#define LED_MAX_NR 1
#define LED_ON _IO(LED_MAGIC,1)
#define LED_OFF _IO(LED_MAGIC,0)
#endif
led.c
#include
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include timer.h>
#include
#include
#include
#include
#include "led_test.h"
#define GPIO_TO_PIN(bank,gpio) bank*32+gpio
struct _led_test{
struct cdev t_cdev;
char kbuf[100];
};
ssize_t led_write(struct file *filp , const char __user *ubuf, size_t count, loff_t lof)
{
struct _led_test *dev = filp->private_data;
if(copy_from_user(dev->kbuf, ubuf, count))
return EFAULT;
return 0;
}
int led_open(struct inode *node, struct file *filp)
{
struct _led_test *dev;
dev = container_of(node->i_cdev, struct _led_test, t_cdev);
filp->private_data = dev;
return 0;
}
long led_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
{
struct _led_test *dev = filp->private_data;
if (_IOC_TYPE(cmd) != LED_MAGIC)
return EINVAL;
if (_IOC_NR(cmd) > LED_MAX_NR)
return EINVAL;
switch (cmd)
{
case LED_CLEAN :
memset(dev->kbuf, 0 ,sizeof(dev->kbuf));
break;
case LED_ON :
gpio_set_value(GPIO_TO_PIN(1,22),1);
break;
case LED_OFF :
gpio_set_value(GPIO_TO_PIN(1,22),0);
break;
default :
printk("EINVAL ");
break;
}
return 0;
}
static const struct file_operations led_ops = {
.owner = THIS_MODULE,
.open = led_open,
//.release = led_release,
.unlocked_ioctl = led_ioctl,
};
static struct miscdevice led_dev = {
.name = "users_led",
.fops = &led_ops,
};
static int __init led_test_init(void)
{
misc_register(&led_dev);
if (gpio_request(GPIO_TO_PIN(1,22),"myled")){
printk("gpio is fail n");
}
else{
gpio_direction_output(GPIO_TO_PIN(1,22),0);
printk("gpio is success n");
}
//gpio_set_value(GPIO_TO_PIN(1,22),1);
return 0;
}
static void __exit led_test_exit(void)
{
gpio_free(GPIO_TO_PIN(1,22));
misc_deregister(&led_dev);
}
module_init(led_test_init);
module_exit(led_test_exit);
MODULE_LICENSE("GPL");
app.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "led_test.h"
#define LED "/dev/users_led"
int main(void)
{
int fd = -1;
fd = open(LED, O_RDWR);
if (fd < 0)
{
perror("open is failn");
return -1;
}
ioctl(fd,LED_ON);
sleep(4);
ioctl(fd,LED_OFF);
return 0;
}
这个应用程序实现了LED 的亮->灭的过程,到此我们基础的驱动模型已经搭建好了。
下面我们将讲解如何把它写入到内核中
|