实验七 嵌入式系统驱动实验资料Word文档格式.docx
《实验七 嵌入式系统驱动实验资料Word文档格式.docx》由会员分享,可在线阅读,更多相关《实验七 嵌入式系统驱动实验资料Word文档格式.docx(16页珍藏版)》请在冰豆网上搜索。
我们采用第一种,即静态编译的方式添加驱动程序。
驱动程序的开发步骤如下:
1)首先,用户在自己的驱动程序源文件中定义file_operations结构,并编写出设备需要的各种操作函数,对于设备不需要的操作函数用NULL初始化,这些操作函数将被注册到内核。
当应用程序对相应的设备文件进行操作时,内核会找到相应的操作函数,并进行调用。
如果操作函数使用NULL,操作系统就进行默认的处理。
2)设备驱动程序编写完成后,就可将其添加到linux内核中,这需要修改linux的源码,然后重新配置编译linux内核。
3)编写相应的驱动测试程序,下载到ARM板进行相应驱动的测试。
【实验步骤】
1.打开桌面上的虚拟机软件VMwareWorkstation,用户名为root,密码为123456,即以超级用户的身份登录。
打开终端,学习一下Linux常用命令:
#cd/切换到根目录
#cddir切换到当前目录下的dir目录下
#cd..切换到上一级目录
#ls显示当前目录下的文件列表
#vifile编辑文件file
#tarxzvffile.tgz将文件file解压
#rmfile删除文件
#rm–frdir删除当前目录下叫dir的整个目录
#cpsourcetarget将文件source复制为target,可以指定文件路径
#catfile查看file的内容
#mvfile/dir将当前目录下的file文件移动到dir目录下
还有一些命令会在后面的使用中具体讲解。
2.在终端里进入/opt/FriendlyARM/Nano2410V2目录下,其中有一个kernel文件夹,这就是我们要操作的LINUX的内核。
进入kernel/drivers/char,即内核驱动的字符型设备驱动文件夹,然后ls查看里面的文件列表,其中有一个super2410-leds.c文件,这是一个led驱动程序,但此程序需要修改才能适用于我们的ARM板。
3.输入visuper2410-leds.c,对此文件进行编辑。
在vi编辑器里面默认的是命令模式,键入i就进入了编辑模式。
程序里led_table中定义了四个端口,我们将GPIO_E13改为GPIO_F7,即我们只对板子上的LED2进行操作。
修改之后按Esc回到命令模式,然后输入:
wq保存退出。
4.打开kernel/drivers/char目录下的Makefile文件,即输入viMakefile。
切换到编辑模式,在第199行里输入obj-$(CONFIG_SUPER2410_LEDS)+=super2410-leds.o。
按Esc键,输入:
这一步操作时为了在编译内核时将super2410-leds.c编译成super2410-leds.o文件。
5.打开kernel/drivers/char目录下的Config.in文件,即输入viConfig.in。
切换到编辑模式,在第89行里输入dep_tristate‘SupportSuper2410Leds’CONFIG_SUPER2410_LEDS,然后按Esc键,输入:
这样在运行menuconfig配置字符设备时就会出现SupportSuper2410Leds的字样,如果选中并编译通过,驱动程序就加到内核中了。
6.返回到/kernel目录下面,输入makemenuconfig,进行内核的配置。
首先找到Characterdevices,回车进入,找到SupportSuper2410Leds(NEW),键入空格选中此项。
然后返回上一级,进入Generalsetup,在TimerandCPUusageLEDS上键入空格,取消选中。
如果选中则两个LED分别用于Timer和CPU,我们的测试程序将看不到效果,故在此处将其取消。
然后保存退出,这时可以进行LINUX内核的编译了。
7.在终端里输入makedep,这一步仅仅在第一次编译时需要,为的是编译时内核知道文件之间的依赖关系;
输入makeclean,该命令用于清除以前编译内核时生成的所有目标文件、模块文件和临时文件;
输入makezImage,即将内核编译成gzip压缩形式的image。
编译通过后会在目录kernel/arch/arm/boot下生成zImage内核文件。
8.编译好之后,我们查看kernel/drivers/char目录会看到super2410-leds.o文件,如果没有则我们的LED驱动程序没有加入到内核。
另一种方法是在终端里kernel目录下输入catSystem.map|grepleds,如果有matrix4_leds_init、matrix4_leds_ioctl、matrix4_leds_fops(这几个是super2410-leds.c文件里的函数)等,则表明驱动已经正确地加入到了内核。
9.将zImage文件拷贝到/mnt/hgfs/share文件夹里,则在windows下我们可以获得此文件。
下面进行驱动测试程序的操作。
10.在虚拟机的/opt/FrindlyARM/Nano2410V2/examples找到leds文件夹,里面有两个文件,main.c是led的测试程序,Makefile是用来指明编译main.c文件时要用的编译器。
在终端里进入此文件夹,输入make后在该文件下生成一个二进制程序led。
将其重命名为ledtest,拷贝到/opt/FriendlyARM/Nano2410V2/root_qtopia_tp/sbin下。
这个root_qtopia_tp文件夹是我们板子所使用的文件系统。
11.将root_qtopia_tp文件夹拷贝到/opt/FriendlyARM/Nano2410V2/mkyaffs文件夹下,在终端里进入此文件夹,输入命令./mkyaffsimageroot_qtopia_tptest.img。
执行完后在mkyaffs文件夹下会生成test.img文件,这是我们要下载到ARM板子上的文件系统映像文件。
12.将前面的zImage和test.img文件下载到ARM板,然后重新启动,通过windows主机的超级终端进行驱动程序的测试。
13.在windows主机下,打开开始-程序-附件-通讯-超级终端,输入自定义的名称,选择COM口(默认COM1即可),端口设置如下图:
将ARM板上面的COM0和主机的串口用串口线连接,上电后会在超级终端里看到启动信息,当出现“PleasepressEntertoactivethisconsole”时键入回车进入操作系统,如下图
此时可以通过超级终端控制我们的ARM板了。
14.这时候可以看到LED2在闪烁,其控制程序是/etc/rC.d/init.d下面的leds。
输入./ledsstop后,则此程序被结束,LED不再闪烁。
15.进入/sbin,查看文件列表会发现我们添加的驱动测试程序ledtest:
进入/dev会看到我们加入内核的驱动leds(驱动程序super2410-leds.c中定义的驱动名称为leds),如下图:
这时候我们进行驱动程序的测试,输入ledtest11则点亮LED2,输入ledtest10则熄灭LED2。
实现一个简单的linux字符设备驱动
步骤1:
编写驱动程序
1.#include
<
linux/module.h>
2.#include
linux/init.h>
3.#include
linux/kernel.h>
4.#include
linux/cdev.h>
5.#include
linux/fs.h>
6.#include
linux/kdev_t.h>
7.#include
asm/uaccess.h>
8.#include
linux/device.h>
9.#define
DEVICE_NAME
"
cdev_zhangwei"
10.int
number_of_devices
=
1;
11.struct
cdev
mydev;
12.dev_t
dev
0;
13.char
data[128]
/0"
;
//
the
data
of
my
device
14.struct
class
*myclass;
15.static
int
mydev_open(struct
inode
*inode,
struct
file
*file)
16.{
17.
pr_info("
mydev
driver
open!
/n"
);
18.
return
19.}
20.static
mydev_release(struct
21.{
22.
released!
23.
24.}
25.ssize_t
mydev_write(struct
*file,
const
char
__user
*buf,
size_t
count,
loff_t
*f_pos)
26.{
27.
ssize_t
ret
28.
mydev_write!
29.
writing
%d
bytes/n"
count);
30.
if
(count
>
127)
31.
-ENOMEM;
32.
0)
33.
-EINVAL;
34.
(copy_from_user(data,
buf,
count))
{
35.
-EFAULT;
36.
}
37.
else
38.
data[127]
'
/0'
39.
kernel
received:
%s/n"
data);
40.
count;
41.
42.
ret;
43.}
44.static
mydev_read(struct
file*
filp,
char*
len,loff_t*
off)
45.{
46.
if(
copy_to_user(buf,data,len)
)
47.
48.
49.
50.
51.
len;
52.}
53.struct
file_operations
mydev_fops
54.
.owner
THIS_MODULE,
55.
.open
mydev_open,
56.
.read
mydev_read,
57.
.write
mydev_write,
58.
.release
mydev_release
59.
60.};
61.static
__init
mydev_init(void)
62.{
63.
result,
error;
64.
result
register_chrdev(0,
DEVICE_NAME,
&
mydev_fops);
65.
udev_cdev:
get
major
number:
%d/n"
result);
66.
MKDEV(result,
0);
67.
myclass
class_create(THIS_MODULE,
mydev_class"
68.
device_create(myclass,
NULL,
dev,
DEVICE_NAME);
69.
70.}
71.static
void
__exit
mydev_exit(void)
72.{
73.
cdev_del(&
mydev);
74.
unregister_chrdev_region(dev,
number_of_devices);
75.
device_destroy(myclass,
dev);
76.
class_destroy(myclass);
77.
Goodbye
cdev!
78.}
79.module_init(mydev_init);
80.module_exit(mydev_exit);
81.MODULE_LICENSE("
GPL"
82.MODULE_DESCRIPTION("
Simple
udev
test"
步骤2:
编译,形成ko文件,然后利用insmod命令插入内核。
(最好利用makefile进行编译,网上有文章专门有介绍)
步骤3:
创建设备节点:
mknod/dev/your_name
c
主设备号
次设备号
次设备号这里填0,主设备号可以利用cat/proc/devices查看
步骤4:
编写用户程序(测试咱们的驱动是否可行),如以下代码简单的用gcc命令编译就好了
stdio.h>
sys/types.h>
unistd.h>
stdlib.h>
fcntl.h>
6.int
main
(void)
7.{
8.
fd,len;
9.
pid_t
pid;
10.
buff[]
This
is
from
userspace
zhangwei
fight
it!
11.
buff_read[100]
12.
fd
open
("
/dev/cdev_zhangwei"
O_RDWR);
13.
(fd
14.
perror("
failed"
15.
exit(0);
16.
pid
fork();
if(pid>
19.
20.
len
write
(fd,
buff,
sizeof(buff));
21.
printf
son
Write
returns
len
parent
24.
25.
//waitpid(pid);
26.
read
read(fd,buff_read,len)
printf("
buff_read
buff_read);
close
(fd);
31.}
到了这里,对字符设备驱动就有一个直观的印象了。
【实验报告要求】
1.将实验中用到的驱动程序及测试程序打印出来附在实验报告中。
2.将实验中用到的Linux基本命令及其作用写在实验报告中。
3.回答实验思考题。
【思考题】
1.分析Linux内核与文件系统之间的关系。
2.简述硬件驱动开发的基本流程。
3.查看本实验中驱动程序的内容,分析其file_operations结构。