基于mini2440的linux驱动程序模块编译测试笔记
wtt @ USST
2010-4-6
原创文章,转载请注明出处。
1.引言
当我们编写好驱动程序后,保存成*.c文件,那这个文件如何编译,如何添加到内核中,又如何测试该驱动是否正常运行呢?下面,我以led驱动为例来说明整个过程.
2.准备工作
注意:"()"中的内容是我安装的版本,其他版本亦可.
首先要有一台主机,装好发行版linux操作系统(fedora 9),安装好交叉编译器(arm-linux-gcc),将mini2440源光盘中的linux内核源码解压到/opt/FriendlyARM/mini2440/目录下.
进入/opt/FriendlyARM/mini2440/linux-2.6.32.2目录,执行cp config_mini2440_t35 .config
注意:t35 后面有个空格,然后有个“.”开头的config 这个是配置好的内核配置文件,也可以自己建立.
将led驱动保存成leds_name.c(leds_wtt.c),并且要存入目录opt/FriendlyARM/mini2440/linux-2.6.32.2/drivers/char下.
准备好mini2440开发板,预装linux操作系统,内核要同PC上的版本相同(linux-2.6.32.2).
3.配置(配置三步 顺序不可颠倒错乱!)
3.1 改写Kconfig文件
cd 到opt/FriendlyARM/mini2440/linux-2.6.32.2/drivers/char目录,打开Kconfig文件,在文件中添加几行语句并保存,如下:
config LEDS_NAME #(LEDS_WTT)
tristate"LED Support for Mini2440 GPIO LEDs (name)"
#((wtt)) 上一行主要是为了在配置内核编译模式时提供选择目标驱动所用的显示文字
dependson MACH_MINI2440 #基于mini2440
defaulty if MACH_MINI2440 #默认编译入内核 稍后会更改成编译为module形式
help #帮助信息
This option enables support for LEDsconnected to GPIO lines
on Mini2440 boards.
添加位置大致如图:
3.2 配置.config文件
cd 到opt/FriendlyARM/mini2440/linux-2.6.32.2/目录,执行make menuconfig,出现如下界面:
找到
DeviceDrivers ---> (回车)
Characterdevices --->(回车)
用方向键选中 “LED Supportfor Mini2440 GPIO LEDs (wtt) (NEW)”,按空格键使该行最前面的符号变为<M>(表示为编译成Module形式,默认<*>为编译入内核)。(该行即为3.1中所添加第二行),配置最后结果见图:
配置完成后,一直按Exit,直到出现
按YES(回车保存)。
3.3更改Makefile文件
cd 到opt/FriendlyARM/mini2440/linux-2.6.32.2/drivers/char目录,打开Makefile文件,在文件中添加如下语句并保存:
obj-$(CONFIG_LEDS_NAME) += leds_wtt.o
(obj-$(CONFIG_LEDS_WTT) +=leds_wtt.o)
#其中CONFIG_LEDS_NAME应该和3.1中的config LEDS_NAME相同.
添加大致位置见图:
4.编译驱动
之前做了很多工作,到了编译环节了,编译就很容易了。
cd 到opt/FriendlyARM/mini2440/linux-2.6.32.2/目录下,执行make modules
显示如下:
编译成功!
编译好的module在驱动程序同一目录下。
5.装载模块
编译好的驱动需要装载到目标板才能发挥作用。
将opt/FriendlyARM/mini2440/linux-2.6.32.2/drivers/char目录下的leds_name.ko(leds_wtt.ko)文件拷到mini2440开发板的为/lib/modules/2.6.32.2-FriendlyARM目录下,必须这样才可以!
然后在目标板上执行modprobe leds_wtt
我在驱动程序的init函数中添加了输出语句,所以我装载好之后目标板输出显示:
leds_wtt initialized
装载完成。
6.测试驱动
测试驱动,比较简单的话,可以采用编写应用程序调用驱动的方式来测试。
我的测试程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
int main(int argc, char **argv)
{
int fd;
fd =open("/dev//dev/leds_wtt", 0);
if (fd < 0) {
fd =open("/dev/leds_wtt", 0);
}
if (fd < 0) {
perror("open device leds");
exit(1);
}
/*通过系统调用 ioctl 和输入的参数控制 led*/
ioctl(fd,1, 0); //第二个参数是开1|关0,第三个参数是led标号 从0~3
ioctl(fd,0, 1);
ioctl(fd,1, 2);
ioctl(fd, 0, 3);
close(fd);
return 0;
}
将上述程序保存成led_test.c,用arm-linux-gcc编译,如下:
arm-linux-gcc –o run led_test.c
编译得到的目标程序run,拷到mini2440开发板下,执行该程序,如下:
./run
可以看到开发板上的1和3号发光二极管亮,其他两个不亮。
注:mini2440预装的linux+qtopia上电后,led自动以0~16的二进制形式在4个led上变化,需要运行qtopia上的led_test,关掉该演示功能才能正常测试led驱动。
7.卸载模块
在目标板上执行
rmmod leds_wtt
我在驱动程序的exit函数中添加了输出语句,所以我卸载好之后目标板输出显示:
leds_wtt removed
卸载完成。
wtt
USST
2010-04-06