/* cli(), *_flags */
#include #define DEVICE_NAME "demo"
#define led_MAJOR 212
#define led_MINOR 0
static int MAX_BUF_LEN=1024;
static char drv_buf[1024];
static int WRI_LENGTH=0;
static char combuf[2];
char base = 0x70;
char off = 0x07;
/*************************************************************************************/
static ssize_t led_write(struct file *filp,const char *buffer, size_t count, loff_t *ppos)
{
copy_from_user(drv_buf , buffer, count);
combuf[0]=drv_buf[0];
combuf[1]=drv_buf[1];
WRI_LENGTH = count;
printk("user write data to driver\n");
IIC_WriteSerial(base, off, combuf, 2);
return count;
}
/*************************************************************************************/
static ssize_t led_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
return count;
}
/*************************************************************************************/
static int led_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
printk("ioctl runing\n");
switch(cmd){
case 1:printk("runing command 1 \n");break;
case 2:printk("runing command 2 \n");break;
default:
printk("error cmd number\n");break;
}
return 0;
}
/*************************************************************************************/
static int led_open(struct inode *inode, struct file *file)
{
sprintf(drv_buf,"device open sucess!\n");
printk("device open sucess!\n");
return 0;
}
/*************************************************************************************/
static int led_release(struct inode *inode, struct file *filp)
{
MOD_DEC_USE_COUNT;
printk("device release\n");
return 0;
}
/*************************************************************************************/
static struct file_operations demo_fops = {
owner: THIS_MODULE,
write: led_write,
read: led_read,
ioctl: led_ioctl,
open: led_open,
release: led_release,
};
/*************************************************************************************/
#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_demo_dir, devfs_demoraw;
#endif
/*************************************************************************************/
static int __init led_init(void)
{
int result;
SET_MODULE_OWNER(&demo_fops);
result = register_chrdev(led_MAJOR, "demo", &demo_fops);
if (result < 0) return result;
printk(DEVICE_NAME " initialized\n");
return 0;
}
/*************************************************************************************/
static void __exit led_exit(void)
{
unregister_chrdev(led_MAJOR, "demo");
//kfree(demo_devices);
printk(DEVICE_NAME " unloaded\n");
}
/*************************************************************************************/
module_init(led_init);
module_exit(led_exit);
//
下面是程序说明,不是代码部分:
重要的数据结构
struct file数据结构
定义位于include/fs.h
struct file结构与驱动相关的成员
mode_t f_mode 标识文件的读写权限
loff_t f_pos 当前读写位置
unsigned int_f_flag 文件标志,主要进行阻塞/非阻塞型操作时检查
struct file_operation * f_op 文件操作的结构指针
void * private_data 驱动程序一般将它指向已经分配的数据
struct dentry* f_dentry 文件对应的目录项结构
设备驱动程序接口( struct file_operations), 标记化方法:
static struct file_operations demo_fops = {
owner: THIS_MODULE,
write: demo_write,
read: demo_read,
ioctl: demo_ioctl,
open: demo_open,
release: demo_release,
};
设备驱动程序接口( struct file_operations )
通常所说的设备驱动程序接口是指struct file_operations{ },它的定义位于include/linux/fs.h中。
在嵌入式系统的开发中,通常只要实现如下几个接口函数就能完成系统所需要的功能
init 加载驱动程序(insmod)时,内核自动调用
read 从设备中读取数据
write 向字符设备中写数据
ioctl 控制设备,实现除读写操作以外的其他控制命令
open 打开设备并进行初始化
release 关闭设备并释放资源
exit 卸载驱动程序(rmmod)时,内核自动调用
驱动程序注册过程(动态分配主设备号)
insmod module_name ;加载驱动程序,运行init函数(register_chrdev(dev_Major, “module_name”, * fs ))
查看/proc/devices
mknod /dev/module_name c/b 主设备号 次设备号
rmmod module_name ;卸载驱动,运行 exit函数(unregister_chrdev(dev_Major, “module_name”, * fs ))