1、前言
其实说是最简单,但依然费了些工夫,正所谓知易行难,看着网上和书上寥寥数语就把最简单的Hello串口驱动linux,LinuxDriver讲完,本以为能手到擒来,半小时搞定,做出来却花了半天多。
2、学习目标及被撞倒的点
简单了解驱动开发流程
怎么编译驱动程序
怎么加载和卸载驱动程序
重启后,未重新配置系统环境变量,编译驱动时并没有提示找不到编译器
要步入root后再编译(不晓得为什么,这个可能是由于编译器装在root路径下)
编译报错时,过分苦恼代码所在路径问题
对Makefile的规则不了解
3、驱动程序概述
设备驱动程序,顾名思义,用于驱动设备,实现设备的操作和控制。与中间件类似,坐落应用软件和硬件之间,为应用软件屏蔽底层硬件细节,提供了设备管理的插口linux课程,应用开发人员毋须在硬件细节花太大精力。
4、一个完整的最简化的“Hello,LinuxDriver”模块
————————————hello.c————————————-
#include
#include
MODULE_LICENSE(“DualBSD/GPL”);
staticinthello_init(void)
printk(“Moduleinitcomplete!nHello,LinuxDriver!n”);
return0;

staticvoidhello_exit(void)
printk(“Moduleexit!nBye,LinuxDriver!n”);
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR(“Cuter@ChinaAET”);
MODULE_DESCRIPTION(“HelloLinuxDriver”);
MODULE_ALIAS(“It’sonlyatest”);
——————————————end—————————————-
编程人精典的“Helloworld”,只要有一定的基础,上述程序一眼就看个明白了。针对Linux驱动开发须要非常强调的是:
MODULE_LICENSE宏,用于告知内核,该模块带有一个自由的许可证,如缺乏linux多线程编程,加载时会报错。
module_init,在模块加载到内核时被调用;

module_exit,在模块从内核中移除时调用;
printk,内核用复印函数,与printf类似;
5、程序的编译&编撰Makefile
编译的关键在于makefile的编撰,最终的makefile如下:
————————————————-makefile——————————————--
obj-m:=hello.o
#currentpath
CURRENT_PATH:=$(shellpwd)
#linuxkernelpath
LINUX_KERNEL_PATH:=/home/cucter/Documents/linux-digilent-3.6
#complieobject
all:

make-C$(LINUX_KERNEL_PATH)ARCH=armM=`pwd`modules
#clean
clean:
make-C$(LINUX_KERNEL_PATH)ARCH=armM=$(CURRENT_PATH)clean
—————————————————-end———————————————--
这块遇到的错误:
Commandscommencebeforefirsttarget.Stop
Missingseparatorstop
Makefile规则:每位执行行要以Tab开头,Tab厚度为4


注意CURRENT_PATH是否在上义民义了。网上有用PWD的文章(digilent一份PDF也是),但都未定义串口驱动linux,会报该错误。
注意`pwd`,不是用的单冒号,而是1右侧键盘上的那种符号。
6、测试
在并口终端中借助tftp指令,将驱动程序从PC下载至系统,使用insmod指令加载驱动,结果如下:
使用lsmod指令再度确认加载成功:

卸载驱动:由上图可以看出,直接使用rmmod卸载是不成功的,缘由是BusyBox和发行的Linux,在加载驱动时,并没有生成相应的目录。我们首先步入/lib/modules目录,创建3.6.0-digilent-13.01文件夹(由上图错误提示可知),之后运行rmmod指令,卸载驱动,结果如右图所示。

