嵌入式linux下,简单的misc设备驱动框架

来源:互联网 发布:虚拟专用网络是免费的 编辑:程序博客网 时间:2024/06/05 16:29
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/semaphore.h>
#include <asm/io.h>


//#include <xxx.h>        /*工程相关,平台相关的头文件*/


struct
{
struct miscdevice dev;
struct semaphore sem;
char data;
}led_st;


static int 

led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

{
int status = 0;


        /*申请信号量*/
if (down_interruptible(&led_st.sem))
return - ERESTARTSYS;
switch(cmd)
{
case CMD_SET_CASE1:
/*code1*/
break;
case CMD_SET_CASE1:
/*code2*/
break;
case CMD_SET_CASE1:
/*code3*/
break;
case CMD_SET_CASE1:
/*code3*/
break;
default:
status = -ENOTTY;
}

        /*释放信号量*/
up(&led_st.sem);
return status;
}


static const struct file_operations led_fops = {
.owner  = THIS_MODULE,
.open   = NULL,
.release= NULL,
.read   = NULL,
.write  = NULL,
.ioctl  = led_ioctl,
};


/*设备装载函数,在insmod led.ko 时,将调用该函数*/
static int __init led_init(void)
{
int status = 0;


// 初始化设备结构体
memset(&led_st, 0, sizeof(led_st));
        //初始化信号量(互斥)
init_MUTEX(&led_st.sem);
        //填充设备结构成员
led_st.dev.minor = MISC_DYNAMIC_MINOR;
led_st.dev.name = "led";
led_st.dev.fops = &led_fops;


// 注册设备
status = misc_register(&led_st.dev);


if (status)
printk(" %s fail to registe device\n", __FUNCTION__);
else
printk("LED driver installed\n");


return status;
}


/*设备卸载函数,在rmmod led 时,将调用该函数*/
static void __exit led_exit(void)
{
misc_deregister(&led_st.dev);
printk("LED driver removed\n");
}


module_init(led_init); 
module_exit(led_exit);


MODULE_AUTHOR("se7en_days, <se7en_days@163.com>");
MODULE_DESCRIPTION("LED");
MODULE_LICENSE("GPL");


/*
 *简单总结一下:
 *第一步,定义设备结构体,成员包括:misc设备结构体,信号量结构体,其他由工程需要添加
 *第二部,设备装载函数,里面主要做了:
         1.初始化结构体,也就是开辟空间,
         2.初始化信号量
         3.初始化misc设备结构体
         4.注册
 *第三步,模块卸载函数,主要就是调用misc_deregister(&led_st.dev)
 *第四步,填充file_operations结构体,这个是应用层与内核驱动的结构
 *第五部,具体的操作函数,可以是read,write,ioctl,这个简单的写了一个IOCTL的函数,根据工程需要,可选用不同的接口函数。
 *
 */
0 0