linux中,一切皆文件
我们在用户层用一些系统函数(如:fopen等等)时,会进入内核,内核会在字符注册了的设备号链表中查找。如果找到就运行我们写的设备文件的(驱动)函数
我们在前面已经讲了怎么创建一个内核程序,我们在驱动文件的目录下创建我们自己的驱动程序
比如我们创建一个test.c,代码如下
其实都是套模版,可以看到用不同颜色标出来的三个部分。
绿色(设备号):主设备号(最大值4095)与次设备号。(框选失误,52-54行为其他东西)
系统给我们定一个一个宏,如下。我们只需要调用它
蓝色(方法):
系统给我们定义了以下函数指针
我们只需要去重定义他们,就可以在用户层调用它。
方法结构体里的.open = open是结构体的一种特殊用法。我们只需要生命我们要调用的方法。类似于部分赋值。
红色:这是最基础的两个函数,缺一不可,一个初始化函数,一个注销函数。
来看看里面的一些东西
1.struct cdev结构体(链式)
操作系统给我们,方便管理维护驱动程序的结构体
2.cdev_add 添加设备号到cdev结构体
3.cdev_init 把方法结构体file_operations添加进cdev结构体
4.register_chrdev_region 注册设备驱动到操作系统
最后demo_exit就是一些注销的函数, 我们可以看到,这两个函数开始有一些不一样的东西
这是我们在编写内核驱动代码时特别的写法,目的就是告诉操作系统这个函数是内核的初始化以及追销的函数。在编写内核驱动代码时,很多函数都和用户层不一样,这时的代码编写更为谨慎。
出错处理
由于每一步出错都需要把前面产生的新空间全部释放,所以越后面的错误需要释放的就越多,使用goto语句把错误处理都放在后面,看起来没那么冗余
添加下载驱动
1.在同层目录(linux-2.6.32.2/drivers/char)下修改Kconfig文件
按模版修改即可
2.Makefile添加新建驱动文件
2.menuconfig(不懂的可以去搜一下)
它被称为内核活地图,可以根据可视化图形修改我们的驱动开关
我们直接在linux-2.6.32.2(解压出来的顶层目录)下make menuconfig 如图
根据以上路径找到我们的test
也可以直接 / 进入搜索我们的搜索。
上图 * 代表开启,可以通过Tab键或者 y/n选择是否开启,相应的在我们的顶层Makefile里就会改变
接下来直接Makefile编译就行了
还是和以前的步骤一样
到这里我们的内核就添加了一个我们自己的驱动,但这个驱动文件里只有一些打印,我们想要实现硬件功能怎么办呢。
其实还是对寄存器的操作,然后把这些操作再移植到之前提到的系统给我们提供的函数(指针),最后去调用这些函数就行了。这里就不多说了,直接上代码。
在与板子挂载的nfs目录下创建程序
另一端链接板子,还是通过tftp下载,bootm命令运行uImage内核
然后在创建设备结点
就会发现我们/dev/目录下多了一个led的设备
我们在电脑客户端编译arm版可执行程序,此时板子也共享了这个程序,然后就可以直接运行了