#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;
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的函数,根据工程需要,可选用不同的接口函数。
*
*/
#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的函数,根据工程需要,可选用不同的接口函数。
*
*/