
知道这个硬件是怎么工作的
否则 没法写驱动
懂这个之后
准备好相应芯片的技术手册。
根据技术手册,配置对应时钟寄存器
如需要中断,配置中断相关寄存器。完成对应的ISR中断服务程序。
实现对外接口。jsp中加载jdbc驱动:
Java加载JDBC的实现方法:
通过调用ClassforName()方法可以显式地加载一个驱动程序。该方法的入口参数为要加载的驱动程序。例如:ClassforName("sunjdbcodbcJdbcOdbcDriver")语句加载了SUN 公司开发的JDBC-ODBC 桥接器。对数据库进行连接的时候,驱动管理器(DriverManager)会使用这个被加载的驱动程序。通过DriverManager 的getDriver()方法可以获得已经加载的驱动程序信息。程序代码要求:
1.编写useDBDriver 类的基本框架,在该类中仅包括main()方法,在main()方法中加载驱动程序。
2.程序代码如下:
public class useDBDriver
{
public static void main(String arg[])}; //IO功能选项,硬件上拉输出 static unsigned int gpio_cfg_table[] = { S3C2410_GPB5_OUTP, S3C2410_GPB6_OUTP, S3C2410_GPB7_OUTP, S3C2410_GPB8_OUTP, }; //编写一个ioctl函数,这个函数提供给用户端使用(也就是用户态使用) static int my_ioctl(struct inode inode,struct file file,unsigned int cmd, unsigned long arg) { if (arg > 4) { return -EINVAL; } if (cmd == 1) //led ON { s3c2410_gpio_setpin(gpio_table[arg],0); return 0; } if (cmd == 0) //led OFF { s3c2410_gpio_setpin(gpio_table[arg],1); return 0; } else { return -EINVAL; } } //一个和文件设备相关的结构体。 static struct file_operations dev_fops = { owner = THIS_MODULE, ioctl = my_ioctl, //read = my_read, //这个暂时屏蔽,一会我们再加入一个读 *** 作的函数 }; //linux中设备的注册结构体 static struct miscdevice misc =
{ minor = MISC_DYNAMIC_MINOR, name = DEVICE_NAME, fops = &dev_fops, }; //设备初始化(包括注册)函数 static int __init dev_init(void) { int ret; int i; for (i=0;i<4;i++) { s3c2410_gpio_cfgpin(gpio_table[i],gpio_cfg_table[i]); s3c2410_gpio_setpin(gpio_table[i],0); mdelay(500); s3c2410_gpio_setpin(gpio_table[i],1); } ret = misc_register(&misc); printk(DEVICE_NAME"MY_LED_DRIVER init ok\n"); return ret; } //设备注销函数 static void __exit dev_exit(void) { misc_deregister(&misc); } //与模块相关的函数 module_init(dev_init); module_exit(dev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("blogednchinacom/itspy");
MODULE_DESCRIPTION("MY LED DRIVER"); 到此,上面就完成了一个简单的驱动(别急,下面我们再会稍微增加点复杂的东西),以上代码的可以简单概括为:像自己写51单片机或者ARM的裸奔程序一样 *** 作IO函数,然后再linux系统中进行相关必须的函数关联和注册。 为什么要关联呢,为什么注册呢? 因为这是必须的,从以下这些结构体就知道了。 stuct file_operations{ struct module owner; loff_t (llseek) (struct file , loff_t, int); ssize_t (read) (struct file , char __user , size_t, loff_t ); ssize_t (write) (struct file , const char __user , size_t, loff_t ); ssize_t (aio_read) (struct kiocb , const struct iovec , unsigned long, loff_t); ssize_t (aio_write) (struct kiocb , const struct iovec , unsigned long, loff_t); int (readdir) (struct file , void , filldir_t);
unsigned int (poll) (struct file , struct poll_table_struct ); int (ioctl) (struct inode , struct file , unsigned int, unsigned long); long (unlocked_ioctl) (struct file , unsigned int, unsigned long); … } file_operations 结构体中包括了很多与设备相关的函数指针,指向了驱动所提供的函数。 struct inode{ struct hlist_node i_hash; struct list_head i_list; struct list_head i_sb_list; struct list_head i_dentry; unsigned long i_ino; atomic_t i_count; unsigned int i_nlink; uid_t i_uid; gid_t i_gid; dev_t i_rdev; u64 i_version; loff_t i_size; … } inode 是 UNIX *** 作系统中的一种数据结构,它包含了与文件系统中各个文件相关的一些重要信息。在 UNIX 中创建文件系统时,同时将会创建大量的 inode 。通常,文件系统磁盘空间中大约百分之一空间分配给了 inode 表。 大略了解以上信息之后,我们只需把我们所要实现的功能和结构体关联起来。上例中已经完成IO写 *** 作的函数,现在我们再添加一个读的函数。基于这种原理,我们想实现各种功能的驱动也就很简单了。 //添加读函数示意, 用户层可以通过 read函数来 *** 作。 static int my_read(struct file fp, char __user dat,size_t cnt) { size_t i; printk("now read the hardware\n"); for(i=0;i<cnt;i++) dat[i] = 'A'; dat[i] = '\0'; return cnt; } 这样,完成驱动编写。编译之后,本驱动可以通过直接嵌入内核中,也可以以模块的嵌入的形式加载到linux内核中去。 完成了驱动,写个应用程序了验证一下吧: int main(int argc,char argv) {
int on; int led_no; int fd; char str[10]; int cnt =0; fd = open("/dev/MY_LED_DRIVER",0); if (fd < 0) { printf("can't open dev\n"); exit(1); } printf("read process\n"); cnt = read(fd,str,10); printf("get data from driver:\n%s\ncount = %d\n",str,cnt); printf("read process end \n"); cnt = 0; printf("running\n"); while(cnt++<1000) { ioctl(fd,0,0); //led off ioctl(fd,0,1); ioctl(fd,0,2); ioctl(fd,0,3); sleep(1); //printf("sdfdsfdsfdsfds\n"); ioctl(fd,1,0); //led on ioctl(fd,1,1); ioctl(fd,1,2); ioctl(fd,1,3); sleep(1); printf("%d\b",cnt); } close(fd); return 0; }Linux是Unix *** 作系统的一种变种,在Linux下编写驱动程序的原理和思想完全类似于其他的Unix系统,但它dos或window环境下的驱动程序有很大的区别。在Linux环境下设计驱动程序,思想简洁, *** 作方便,功能也很强大,但是支持函数少,只能依赖kernel中的函数,有些常用的 *** 作要自己来编写,而且调试也不方便。本人这几周来为实验室自行研制的一块多媒体卡编制了驱动程序,获得了一些经验,愿与Linux fans共享
一、Linux device driver 的概念系统调用是 *** 作系统内核和应用程序之间的接口,设备驱动程序是 *** 作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件, 应用程序可以象 *** 作普通文件一样对硬件设备进行 *** 作。设备驱动程序是内核的一部分,它完成以下的功能:
1对设备初始化和释放。
2把数据从内核传送到硬件和从硬件读取数据。
3读取应用程序传送给设备文件的数据和回送应用程序请求的数据。
4检测和处理设备出现的错误。
二、实例剖析我们来写一个最简单的字符设备驱动程序。虽然它什么也不做,但是通过它可以了解Linux的设备驱动程序的工作原理。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)