版本2在加载驱动的时候自动的添加设备节点,不用再执行的版本1中的
在目标机上面查看led的设备号使用命令
cat /proc/devices
使用mknod /dev/led c 设备号 0
直接insmod led_dev_read_write.ko 就OK了
//代码如下:
//版本2
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define CMD_NO 1
#define CMD_OFF 0
//static struct cdev led_dev;
struct led_resources
{
unsigned
long gpio;//gpio 软件编号
char
*name;
};
struct class *cls;//设备类
static struct led_resources led_inf[]={
[0]={
.gpio =S3C2410_GPB5,
.name ="led1"
},
[1]={
.gpio = S3C2410_GPB6,
.name ="led2"
},
[2]={
.gpio = S3C2410_GPB8,
.name ="led3"
},
[3]={
.gpio = S3C2410_GPB10,
.name ="led4"
}
};
static int major; //设备号
static void led_cmd(struct led_resources led_inf, unsigned long
value)
{
//配置gpio
为输出
gpio_direction_output(led_inf.gpio,0);
gpio_set_value(led_inf.gpio,value);
//
配置输出值
}
static int led_open(struct inode *inode , struct file
*file)
{
return
0;
}
static int led_close(struct inode *inode , struct file *file)
{
int i
;
for( i = 0;
i < ARRAY_SIZE(led_inf); ++i)
{
led_cmd(led_inf[i],CMD_OFF);
gpio_free(led_inf[i].gpio);
}
return
0;
}
static int led_ioctl(struct inode *inode,struct file *
file,unsigned int cmd,unsigned long arg)
{
if(cmd >3||cmd <0)
return -1;
led_cmd(led_inf[cmd], arg);
return
0;
}
static struct file_operations led_file=
{
.owner =
THIS_MODULE,
.open
=led_open,
.ioctl=
led_ioctl,
.release =
led_close
};
static struct cdev led_dev;
static int led_init(void)
{
int i = 0,
flag ;
dev_t
dev_nu;
if(major)
{
dev_nu = MKDEV(major,0);
register_chrdev_region(dev_nu,1,"led");
printk("static major\n");
}
else
{
printk("alloc major\n");
alloc_chrdev_region(&dev_nu,0,1,"led");
major = MAJOR(dev_nu);
}
//sys/class/leds/leds产生资料
cls =
class_create(THIS_MODULE,
"leds");
//产生dev/led
节点
device_create(cls,NULL,dev_nu,NULL,"led");
cdev_init(&led_dev, &led_file);
//初始化cdev
flag =
cdev_add(&led_dev,dev_nu,1);//添加cdev设备
if(flag
< 0)
printk("cdev add error");
printk("major nu is %d \n",
major);
//申请申请GPIO 资源
for(i = 0; i
< ARRAY_SIZE(led_inf); ++i)
{
gpio_request(led_inf[i].gpio,led_inf[i].name);
}
//配配置GPIO 为输出
//
printk("init succesfukk");
return
0;
}
static void led_exit(void)
{
dev_t dev_nu
= MKDEV(major,0);
device_destroy(cls,dev_nu);
class_destroy(cls);
cdev_del(&led_dev);
//删除cdev
unregister_chrdev_region(dev_nu, 1);//删除设备号
printk("exit
sucessfull\n");
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");