碰到一个问我怎么写驱动的师弟,其实我也不懂,更不懂怎么和他说了。要学的还有很多,具体的驱动框架需要他去看了,理解内核机制我也需要抽时间去琢磨。由于前面做过,就整理一下前面做过的文档,从头到尾演示一下,步骤而已,简单的说,就是操作演示,至于调试啊,那是代码的事情了。直接贴出以前的文档如下:
********************************************************
由于近段时间还要继续创新试验项目,这个不是很喜欢做,哎,一言难尽。还好,我可以搞USB模块。不说了,说说我的开发板吧。今天拿起,启动不得,一阵子没摸她,倒是给我发脾气了。没有供电,还以为电源坏了。后来一查,按钮开关坏了。小CASE,换好,今晚,跑跑板。
系统配置:
虚拟机上,操作系统是Fedora9,内核看看。
#uname -r
2.6.25-14.fc9.i686
开发板FL2440:
# uname -r
2.6.12-h1940
首先,到虚拟机上确定两个编译器,gcc和arm-linux-gcc。
# gcc -v 然后就跟着就出来了,
gcc 版本 4.3.0 20080428 (Red Hat 4.3.0-8) (GCC)
______________________________________________________
| 使用toolchain的开发方式,我当时使用的是别人做好的交叉编译器,解压后,直接到配置文
| 件夹下配置
| #cd /etc
| 把编译器路径告诉内核,这叫做环境变量设置,即在bashrc中的后面加入
| export PATH=/usr/local/arm/3.4.1/bin:$PATH
_______________________________________________________
所以, 这里就可以这样继续看交叉编译器了
# arm-linux-gcc
gcc version 3.4.1
其次,目的:写个流水灯的驱动,其实就是写个对led的操作罢了。命名led.c
具体板子具体分析,这就不贴出来了,接下来,写个很简单的Makefile,贴码如下:
—————————————————————————————————————
ARCH= arm # 说明平台
MVTOOL_PREFIX = /usr/local/arm/3.4.1/bin/arm-linux- #指定编译器,本机或者交叉编译器:绝对路径
CROSS_COMPILE= $(MVTOOL_PREFIX)
KDIR := /usr/src/linux-2.6.12 #告诉使用的内核编译
EXEC = led #文件名
obj-m := led.o #-m编译成模块,注意参数 -y -名称
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
—————————————————————————————————————
#mkdir led //建个文件夹,将led.c和makefile这两个源文件cp过来,很简单了。
#make
#ls
led.c led.mod.c led.o led.ko led.mod.o
看见了吧,make给干了很过工作,结果完成任务是带给我led.ko和其他的咚咚(中间文件),
看准了,led.ko是所需模块(2.4内核以前是.o文件),其他都不用关注。虚拟机和本机设置了共
享,所以我直接拷贝过来,通过UART发送到FL2440,然后在板子操作
#insmod led.ko //insmod 会调用module_init,这个放心
最后,驱动一切都弄好了,写个测试程序看看吧!这里贴出ledshow.c
————————————————————————————————————
#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/ioctl.h"
#include "stdlib.h"
#include "termios.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "sys/time.h"
int main(void)
{
int on=1;
int led;
int fd;
fd=open("/dev/led",0);
if(fd<0)
{
perror("open device led");
exit(1);
}
printf("leds test show,press ctrl+c to exit /n");
while(1)
{
for(led=0;led<4;led++)
{
ioctl(fd,on,led);
usleep(50000);
}
on=!on;
}
close(fd);
return 0;
}
——————————————————————————————————————
同样,我拷贝到led文件夹下,这个很简单了,不用写makefile或用自动生成makefile文件了。文
件这么少,我们就省事点吧,花最少的时间完成最多的动作嘛。呵呵
#arm-linux-gcc -o ledshow ledshow.c //交叉编译器设置好,就是方便
#ls
led.c led.mod.c led.o ledshow.c
led.ko led.mod.o ledshow Makefile
程序出炉了,将测试程序ledshow通过串口传到开发板上。然后,
#chmod +x ledshow //修改一下文件权限,可读可写可执行去。
#./ledshow
结果,OK!(开发板只有我看见哈哈)
对了,说明,我的内核源码树是在/usr/src/linux-2.6.12,随便在任意目录下干像上面的事情,
得在源码树顶层目下配置过内核,编译一下就好,否则好像会出错,还没研究怎么回事。