频 道 直 达 - 新闻 - 培训 - 软件 - 教程 - 前沿 - 组网 - 系统应用 - 安全 - 编程 - 存储 - 操作系统 - 数据库 - 服务器 - 专题 - 产品 - 案例库 - 读书 - 博客 - BBS
51CTO.COM_中国最大的网络技术网站
找资料:

5.3.4.1 设备驱动模板

作者: 苏东 出处:电子工业出版社易飞思公司  2007-08-16 09:37    砖    好    评论   进入论坛
阅读提示:《主流ARM嵌入式系统设计技术与实例精解》第5章重点介绍了基于ARM处理器的底层驱动设计以及ARM处理器的汇编语言编程。本节主要介绍的是设备驱动程序模板与实现.
5.3.4  设备驱动程序模板与实现
Linux下的驱动程序虽然复杂,但是总结下来还是有很多的规律可寻。Linux下的设备驱动开始编程时显得比较容易,可以轻松地开始驱动编写,但是要把驱动写好也的确需要花一定的时间去研究。
1.设备驱动模板
设备驱动模板代码如例程5-4所示。
例程5 4  Mydriver.c
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
#include <linux/ioctl.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/arch/irqs.h>
#include <asm/irq.h>
#include <asm/signal.h>
#include <asm/uaccess.h>
/*定义设备的从设备号*/
#define MYDRIVER_MINOR  174
/*定义设备相关数据结构*/
typedef struct _MYDRIVER_DEV
{
spinlock_t            dev_lock;
wait_queue_head_t     oWait;     
int                  open_count;

}MYDRIVER_DEV, *PMYDRIVER_DEV;
/*定义设备状态数据结构*/
typedef struct _MYDRIVER_DEV_STATS
{
unsigned long         rx_intrs;
unsigned long         rx_errors;
unsigned long         rx_blocks;
unsigned long         rx_dropped;
unsigned long         tx_intrs;
unsigned long         tx_errors;
unsigned long         tx_missed;
unsigned long         tx_blocks;
unsigned long         tx_dropped;
}MYDRIVER_DEV_STATS, * MYDRIVER_DEV_STATS;
unsigned int IntInit=0;
/*定义设备open接口函数*/
static int mydriver_open(struct inode *inode, struct file * filp)
{
int  minor;
DBGPRINT("mydriver_open\n");
minor = MINOR(inode->i_rdev);
if ( minor != MYDRIVER_MINOR )  { return -ENODEV; }

#ifdef MODULE
MOD_INC_USE_COUNT;    /*打开使用次数累加*/
#endif

mydriver_dev.open_count++;
if ( mydriver_dev.open_count == 1 )
{
DBGPRINT("mydriver_open: first opne\n");
/*第一次打开设备,在这里可以放些设备初始化代码*/
}
return 0;
}
/*定义设备close接口函数*/
static int mydriver_release(struct inode *inode, struct file *filp)
{
DBGPRINT("mydriver_release\n");
mydriver_dev.open_count--;
if ( mydriver_dev.open_count == 0 )
{
DBGPRINT("mydriver_release: last close\n");
/*设备彻底关闭,这里可以放一些使设备休眠,或者poweroff的代码*/
}
#ifdef MODULE
MOD_DEC_USE_COUNT;    /*打开次数递减*/
#endif
return 0;
}
/*定义设备read接口函数*/
static ssize_t mydriver_read(struct file *filp, char *buf, size_t size,
                   loff_t *offp)
{
if(size> 8192) size = 8192;
/* copy_to_user()*/
/*copy kernel space to user space. */
/*把数据从内核复制到用户空间的代码,可以根据实际添加*/
return size;                      /*返回字节数*/
}
/*定义设备write接口函数*/
static ssize_t mydriver_write(struct file *filp, const char *buf, size_t
                   size, loff_t *offp)
{
lock_kernel();
DBGPRINT("mydriver_write\n");
if(size> 8192)  size = 8192;
/*copy_from_user()*/
/*copy user space to kernel space. */   /*把数据从用户空间复制到内核空间*/
unlock_kernel();        
return size;                      /*返回字节数*/
}
/*定义设备ioctl接口函数*/
static int mydriver_ioctl(struct inode *inode, struct file *filp, unsigned
                   int cmd, unsigned long arg)
{
int  ret = 0;
DBGPRINT("mydriver_ioctl: cmd: 0x%x\n", cmd);
switch(cmd)
{
case cmd1:      /*命令字,注意幻数的使用*/
…..
break;
…..
case cmd3:
…..
break;
default:
DBGPRINT("mydriver_ioctl: bad ioctl cmd\n");
ret = -EINVAL;
break;
}
return ret;
}
/*定义设备select函数接口*/
static unsigned int mydriver_poll(struct file *filp, poll_table *wait)
{
poll_wait(filp,&mydriver_dev.oWait,wait);
if(IntInit)

IntInit=0;
return POLLIN|POLLRDNORM;  //可以写
}
else {  return POLLOUT;      //可以读 }
}
/*定义设备的file_operations*/
static struct file_operations  mydriver_fops =
{
owner:      THIS_MODULE,
open:       mydriver_open,
release:     mydriver_release,
read:       mydriver_read,
write:      mydriver_write,
ioctl:       mydriver_ioctl,
poll:       mydriver_poll,
};
/*定义设备结构体*/
static struct miscdevice  mydriver_miscdev =
{
MYDRIVER_MINOR,
" mydriver ",
& mydriver_fops
};
/*定义设备init函数*/
int __init mydriver_init(void)
{
int  ret;
DBGPRINT("mydriver_init\n");
ret =misc_register(&mydriver_miscdev); //注意这里调用misc_register()来注册
if ( ret )
{
 DBGPRINT("misc_register failed: 0x%x\n", ret);
return ret;
}
memset(&mydriver_dev, 0, sizeof(mydriver_dev));
init_waitqueue_head(&mydriver_dev.oWait);
spin_lock_init(&mydriver_dev->dev_lock);
/*这里可以放一些硬件初始化的函数*/   
return 0;
}
/*定义设备exit函数*/
void __exit mydriver_exit(void)
{
DBGPRINT("mydriver_exit\n");
misc_deregister(&mydriver_miscdev);  //注销misc dev
}
module_init(mydriver_init);
module_exit(mydriver_exit);
MODULE_LICENSE("GPL");
从上面的模板代码可以看出,设备驱动主要给上层提供file_operation和ioctl功能,实现上层对于底层设备的管理和读、写操作等。另外不同的设备调用的设备注册和注销函数有所不同,大家可以区分一下:misc_register()函数、register_chardev()函数、register_netdev()函数及misc_deregister()函数。也可以去分析一下deregister_chardev()函数和deregister_netdev() 函数的不同之处。
通常的设备驱动参照上面的模板就可以实现基本的框架了,当然还需要注意有关硬件的一些操作,包括初始化、参数设置、中断服务等。这些代码可以根据系统的设计放在driver_init里面,或者放在第一次打开的时候。
【责任编辑:雪花 TEL:(010)68476606-8007】

回书目   上一节   下一节
专题
Linux——从菜鸟到高手
二手仿冒设备与思科再营销谁更火
Linux/Solaris服务器的安全配置
双机热备技术
Linux 集群技术专题
我也说两句

匿名发表

(如果看不清请点击图片进行更换)


中 国 最 大 的 网 络 技 术 网 站 ·
技 术 成 就 梦 想
订阅技术快讯
电子杂志下载
名称:SQL Server数据库管理精品黄皮书
简介:书中文章经过精挑细选,便于用户能根据自己的实际工作和学习,快速在本书寻找到相关资料。内容涵盖了SQL Server的安装与升级、语句查询、数据备份和恢复、自动化任务、数据同步、数据字典、安全和预防、性能和优化、集群等各方面应用信息,以及DBA管理人员在数据库管理工作中
名称:2007路由技术大全
简介:《2007路由技术大全》由51CTO.com网站特别策划制作,该书包括路由器技术、路由器产品、路由器配置、安全设置、路由器故障处理、路由器密码恢复,以及广大网友在实践使用中的心得经验和技巧文章,内容注重实用性,适用于初学者入门,也适合多年从业者提高,是一本实践和理论完
名称:网络安全精品应用黄皮书
简介:《2007精品网络安全黄皮书》包括了9个大类24个小类, 800余篇文章,内容包含了熊猫烧香病毒、DDOS攻击、ARP病等热点问题的介绍及解决方案。从病毒查杀、防范、系统、数据等各方面的安全设置到黑客技术的了解、防范,涉及到了安全应用的全部领域, 由浅至深内容全面。
浏览器的战国时代
浏览器的战国时代
ARP攻击防范与解决方案
ARP攻击防范与解决方案
NAC安全访问控制
NAC安全访问控制
· NAC安全访问控制
· 网络布线测试仪器
· Windows Server 2008专..
· Windows远程桌面应用
· 网络故障排除宝典
· 运营商封堵ADSL共享 中..
· 解析35岁技术人的价值..
· 世纪枭雄比尔盖茨的王..
· 主流品牌防火墙配置
· ASP.NET开发教程
· 超级计算机TOP500专题
· Vista SP1对决XP SP3
· SQL Server 2008/2005..
· 程序员如何成长?
· C#技术开发指南
· 虚拟化技术还有点“虚”
ARP攻击防范与解决方案
ARP攻击防范与解决方案
SQL Server 2008/2005全解
SQL Server 2008/2005全解
SOA 面向服务架构
SOA 面向服务架构
· SOA 面向服务架构
· SQL Server 2008/2005..
· Apache技术专题
· 三层交换技术专题
· SQL Server入门到精通
· Windows远程桌面应用
· C#技术开发指南
· Apache技术专题
· Windows集群服务应用
· C#技术开发指南
· 国际文档格式标准开战
· 路由器设置与口令恢复
· Linux 集群技术专题
· PHP开发应用手册
· SOA 面向服务架构
· 企业数据恢复指南
ARP攻击防范与解决方案
ARP攻击防范与解决方案
SQL Server 2008/2005全解
SQL Server 2008/2005全解
SQL Server入门到精通
SQL Server入门到精通
· SQL Server入门到精通
· SQL Server 2008/2005..
· SOA 面向服务架构
· Apache技术专题
· C#技术开发指南
· 三层交换技术专题
· Apache技术专题
· C#技术开发指南
· Windows远程桌面应用
· 企业数据恢复指南
· Windows集群服务应用
· 路由器设置与口令恢复
· Linux 集群技术专题
· SOA 面向服务架构
· 了解统一威胁管理(UTM)..
· 反垃圾邮件技术应用