今天算是正式开始学习驱动开发了。
问题不少,网上的的教程不是讲乱七八糟的基础知识,要不就是应用层,驱动开发的教程少之又少。
驱动开发难度确实不低,最起码得满足两个要求:1.扎实的编程经验。2.相关硬件的理论知识。
满足这两个之后,需要做的就是学习在Linux下如何把[2]用[1]变成代码。
第一更——内核模块框架的搭建与led驱动模块开发。
首先,第一步是搭建内核模块的框架。
上图的内容就是一个内核模块的基本框架了。所有的内核模块都需要着一些内容。
接下来就是正式写led的驱动。led的驱动是最简单的了。首先,来看原理图。
如图,从原理图可以知道,当GPC0_3和GPC0_4为高电平是led会被点亮,为低电平是会被熄灭。
知识点小贴士:
1.led正向导通,图中为共阳极接法,因此当led阴极为低电平时会被点亮。
2.三极管为NPN型,因此,当基极为高电平时,三极管为为导通状态。
好了,现在我们来设计驱动程序。我们简单一些,只是控制两个led亮或者灭。
程序如下:
就是这样了,struct file_operations定义了可供应用程序调用的函数名。具体怎么实现函数,需要自己用Source Insight到内核源码中查看函数原型。搜索file_operations会得到下图:
这里,我们只用到了open和ioctl,因此,我们只需要把这两个函数原型拷贝出来,然后改装一下就可以了。
open函数主要用来配置寄存器,这里我们进行以下宏定义
#define LEDCON 0xE0200060 //这个是控制寄存器
#define LEDDAT 0xE0200064 //这个是数据寄存器
这两个值来自芯片手册。如图:
根据原理图我们知道控制led的是GPC0口,所以我们到芯片手册中找到了GPC0的地址。
拿到寄存器之后就是配置寄存器了,也就是给寄存器写相应的值。这里还是需要查看芯片手册。如下图:
可以看到,这里一共有五个口,从原理图中我们知道,控制led的是GPC0_3和GPC0_4,所以我们就可以将3和4置为输出(Output)其他还是默认值,,也就是0001 0001 0000 0000 0000,连起来就是00010001000000000000,然后将其转换为十六进制,也就是11000,不够的话就补全,最终就是0x00011000。
ioctl函数就是具体驱动的代码了,也就是给DAT寄存器中写值。前面说了,当GPC0_3和GPC0_4置为高电平时就是全部点亮,为低电平时就是全部熄灭。这里我们为了简单,就直接全部置0和置1了,也就是代码中的0x00和0xff.
ok,led的驱动开发就是这样了,欢迎回帖交流。
ps:驱动开发的教程太少了,全靠自己查资料,明天去图书馆找几本书去,明天还是周六,也不知道科技书的库开不开。。