Linux设备驱动程序设计(3)的特殊字符设备:混杂设备,依旧让LED闪烁起来

Linux设备驱动程序设计(3)的特殊字符设备:混杂设备,依旧让LED闪烁起来

Linux设备驱动程序设计(三)—-Linux的特殊字符设备:混杂设备,依旧让LED闪烁起来

看了上面的文章,大家也会觉得创建字符设备是一件很复杂的事情,步骤太多,对于初学者要摸好长时间才能慢慢熟悉,然后还要创建设备文件,虽然每一步不难,但是组合到一起就显得有些繁琐了,没办法,开发Linux的都是大牛,更多的精力放到了功能上,而忽略了用户体验与操作的便捷性。

Linux针对像LED这样的操作,有一种设备叫做混杂设备:是一种特殊的字符设备,它的主设备号为10,我们重新启动开发板,然后执行命令:cat /proc/devices ,可以看到:

root@at91sam9260ek:/# cat /proc/devices 
Character devices:
  1 mem
  2 pty
  3 ttyp
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  7 vcs
 10 misc
 13 input
 14 sound
 90 mtd
116 alsa
128 ptm
136 pts
153 spi
180 usb
189 usb_device
253 usb_endpoint
254 rtc

说明混杂设备早已经存在,是为了给开发者一个叫为简单的操作方式,因为不用再重新申请一个设备号了(misc就是混杂设备的意思),那么它和普通的字符设备有什么不同呢?其实是操作上方便了很多,然我们先看驱动程序,其实改变也不是很大:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <mach/gpio.h>

//定义命令
#define LED_ON _IOW('h',0x01,unsigned long) //LED开的命令
#define LED_OFF _IOW('h',0x02,unsigned long) //LED关的命令

int open_state = 0; //1为打开,0为关闭

/*-----------------------------------------
函数名: led_open
参数: struct inode *inode,struct file *filp
返回值: int
描述: open对应的驱动函数
*-----------------------------------------*/
int led_open(struct inode *inode,struct file *filp )
{
if(open_state == 0)
{
open_state = 1;
printk("Open file suc!n");
return 0;
}
else
{
printk("The file has opened!n");
return -1;
}
}
/*-----------------------------------------
函数名: led_release
参数: struct inode *inode,struct file *filp
返回值: int
描述: open对应的驱动函数
*-----------------------------------------*/
int led_release(struct inode *inode,struct file *filp )
{
if(open_state == 1)
{
open_state = 0;
printk("close file suc!n");
return 0;
}
else
{
printk("The file has closed!n");
return -1;
}
}
/*-----------------------------------------
函数名: led_ioctl
参数: struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg
返回值: int
描述: ioctl对应的驱动函数
*-----------------------------------------*/
int led_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
switch(cmd)
{
case LED_ON: printk("ON!n");
at91_set_gpio_value(AT91_PIN_PC0, 1); //灯亮起来
break;

case LED_OFF:printk("OFFn");
at91_set_gpio_value(AT91_PIN_PC0, 0); //灯灭掉
break;

default :printk("Error command!n");
}
return 0;
}

const struct file_operations led_fop =
{
.owner = THIS_MODULE,
.open = led_open,
.ioctl = led_ioctl,
.release = led_release,
};

struct miscdevice misc =
{
.minor = 30,
.fops = &led_fop,
.name = "led3"
};
/*-----------------------------------------
函数名: gpio_init
参数: void
返回值: int
描述: 模块初始化函数,在安装模块时候执行
*-----------------------------------------*/
static int __init gpio_init(void)
{
int ret;

printk("------GPIO misc test init-----n");

/**
* 混杂设备主设备号就是10,通过次设备号来区分
*/
ret = misc_register(&misc); //向内核注册设备号
if(ret < 0)
{
printk("Register Error!n");
return ret;
}

/**
* 初始化字符设备
*/

at91_set_gpio_output(AT91_PIN_PC0,1); //设置引脚为输出功能,且为高电平
return 0;
}

/*-----------------------------------------
函数名: gpio_exit
参数: void
返回值: void
描述: 模块卸载函数,在卸载模块时候执行
*-----------------------------------------*/
static void __exit gpio_exit(void)
{

Linux设备驱动程序设计(3)的特殊字符设备:混杂设备,依旧让LED闪烁起来

相关文章:

你感兴趣的文章:

标签云: