嵌入式系统实验报告.docx
- 文档编号:28508848
- 上传时间:2023-07-18
- 格式:DOCX
- 页数:14
- 大小:20.97KB
嵌入式系统实验报告.docx
《嵌入式系统实验报告.docx》由会员分享,可在线阅读,更多相关《嵌入式系统实验报告.docx(14页珍藏版)》请在冰豆网上搜索。
嵌入式系统实验报告
PXA270嵌入式实验开发系统
LINUX实验报告
本学期通过三节嵌入式实验课的学习,对LINUX系统和嵌入式系统有了一个大致的了解。
期间一共做了十四个实验,具体实验内容如下:
实验一建立硬件实验平台
本实验是以后所有实验的硬件基础,需要正确连接宿主PC机与PXA270-EP目标板,PXA270目标板与电源连接,用一根串口线将目标板串口0与PC机后方的串口相连,用一根交叉对接的网线将宿主PC机网口与目标板网口相连。
实验二Linux操作系统RedHat9的安装
按照实验书所讲的步骤在Linux虚拟机中正确安装RedHat9,这是以后所有实验的软件基础。
实验三建立主机软件开发环境
建立宿主PC机端的开发环境,此实验开始需要在RedHat9中的终端窗口(Terminal)中输入命令:
虚拟机载入ISO镜像270EP.iso,登陆RedHat,启动终端窗口,对cdrom镜像进行挂载(mount/dev/cdrom/mnt/cdrom),用“./install”命令进行iso安装,安装完成,修改/ect/profile的环境变量(pathmunge/usr/local/arm-linux-/bin)。
实验四配置超级终端
超级终端作为嵌入式实验性的终端,监视并控制其工作状态。
串口设置(每秒位数:
115200;位数据:
8;奇偶校验:
无;停止位:
1;数据流控制:
无;)。
实验五配置TFTP
配置宿主PC机端的TFTP(简单文件传输协议)服务,并开通此服务。
登陆RedHat,启动终端窗口,输入setup,选择Systemservices,取消ipchains和iptables两项服务,选中tftp服务,取消防火墙,重启TFTP服务(servicexinetdrestart),设置PC机ip地址为192.168.0.100(ifconfigeth0192.168.0.100up),使用tftp服务得到文件zImage。
实验六配置NFS服务
配置宿主PC机端的NFS(网络文件系统)服务,并开通此服务。
登陆RedHat,启动终端窗口,输入setup,选择Systemservices,选中nfs服务,保存退出,打开/ect/exports文件,在其中加入“/192.168.0.50(rw,insecure,no_root_squash,no_all_squash)”,然后重启服务(servicenfsrestart)。
注意:
每次启动宿主PC机上的Linux操作系统时,需要通过命令ifconfigeth0192.168.0.100up重置宿主PC机的IP地址,并在超级终端中用命令ifconfigeth0192.168.0.50给PXA270实验开发系统设置IP地址。
以上几个实验算是给以后的实验配置了软硬件条件,是以后各个实验的基础。
实验七HelloWorld
从此实验开始第一次正面接触嵌入式Linux的开发,第一次编写嵌入式系统的应用程序。
打开宿主PC机登陆RedHat,打开实验箱连接,root登陆实验箱,设置实验箱ip地址为192.168.0.50(ifconfigeth0192.168.0.50up),挂载宿主机根目录到实验板/mnt目录下,然后进入mnt目录;RedHat中打开终端窗口,进入home目录建立文件夹HW,并在其中建立HelloWorld.c文件,vi编辑器编辑它。
基本C语言代码为:
#include
Intmain()
{
printk(“HelloWorld!
\n”);
return0;
}
在终端窗口下进行交叉编译arm-linux-gcc–oHelloWorldHelloWorld.c,生成.o目标文件,进入超级终端的界面,回到/mnt/home/HW目录下,编译HelloWorld(./HelloWorld),看到打印输出“HelloWorld!
”。
实验十二简单设备驱动程序
该实验需要在宿主PC机端编辑三个文件:
驱动程序、编译驱动程序时用的Makefile、测试程序。
驱动程序pxa270_hello_drv.c如下:
#include
#include
#include
#include
#include
#include
#include
//HELLODEVICEMAJOR
#defineSIMPLE_HELLO_MAJOR96
#defineOURS_HELLO_DEBUG
#defineVERSION"PXA2700EP-SIMPLE_HELLO-V1.00-060530"
voidshowversion(void)
{
printk("***************************************");
printk("\t%s\t\n",VERSION);
printk("***************************************");
}//显示版本
//-------------------READ------------------------
/*读取模块,用于将指定文件描述符中读取数据,
file:
是文件指针
buf:
读取数据缓存区
count:
请求传输的字节数
f_ops:
文件当前偏移量*/
ssize_tSIMPLE_HELLO_read(structfile*file,char*buf,size_tcount,loff_t*f_ops)
{
#ifdefOURS_HELLO_DEBUG
printk("SIMPLE_HELLO_read[--kernel--]\n");
#endif
returncount;
}
//-------------------WRITE-----------------------
/*写模块,用于向打开的文件写数据,写操作从文件当前偏移量开始
file:
是文件指针
buf:
写入数据缓存区
count:
请求传输的字节数
f_ops:
文件当前偏移量*/
ssize_tSIMPLE_HELLO_write(structfile*file,constchar*buf,size_tcount,loff_t*f_ops)
{
#ifdefOURS_HELLO_DEBUG
printk("SIMPLE_HELLO_write[--kernel--]\n");
#endif
returncount;
}
//-------------------IOCTL-----------------------
/*控制IO设备,设备驱动程序中对设备的I/O通道进行管理的函数
inode:
设备节点
flip:
打开的一个文件
cmd:
驱动程序的特殊命令编号
data:
接收剩余参数*/
ssize_tSIMPLE_HELLO_ioctl(structinode*inode,structfile*file,unsignedintcmd,longdata)
{
#ifdefOURS_HELLO_DEBUG
printk("SIMPLE_HELLO_ioctl[--kernel--]\n");
#endif
return0;
}
//-------------------OPEN------------------------
/*打开函数
Inode:
打开文件所对应的i节点,主要获取从设备号
flip:
打开的一个文件
调用了宏MOD_INC_USE_COUNT,这个宏主要用来增加驱动程序使用计数器,避免不正确卸载程序*/
ssize_tSIMPLE_HELLO_open(structinode*inode,structfile*file)
{
#ifdefOURS_HELLO_DEBUG
printk("SIMPLE_HELLO_open[--kernel--]\n");
#endif
MOD_INC_USE_COUNT;
return0;
}
//-------------------RELEASE/CLOSE---------------
/*关闭函数
Inode:
打开文件所对应的i节点,主要获取从设备号
flip:
打开的一个文件
调用了宏MOD_DEC_INC_USE_COUNT,这个宏主要用来减少驱动程序使用计数器*/
ssize_tSIMPLE_HELLO_release(structinode*inode,structfile*file)
{
#ifdefOURS_HELLO_DEBUG
printk("SIMPLE_HELLO_release[--kernel--]\n");
#endif
MOD_DEC_INC_USE_COUNT;
return0;
}
//-------------------------------------------------
/*SIMPLE_HELLO设备向系统注册*/
structfile_operationsHELLO_ops={
open:
SIMPLE_HELLO_open,
read:
SIMPLE_HELLO_read,
write:
SIMPLE_HELLO_write,
ioctl:
SIMPLE_HELLO_ioctl,
release:
SIMPLE_HELLO_release,
};
//-------------------INIT------------------------
/*驱动程序初始化
devfs_register_chrdev(SIMPLE_HELLO_MAJOR,"hello_serial_ctl",&HELLO_ops)为最主要的语句,devfs_register_chrdev注册设备驱动程序,包括主设备号、驱动程序名、结构体指针*/
staticint__initHW_HELLO_init(void)
{
intret=-ENODEV;
ret=devfs_register_chrdev(SIMPLE_HELLO_MAJOR,"hello_serial_ctl",&HELLO_ops);
showversion();
if(ret<0)
{
printk("pxa270init_modulefailedwith%d\n[--kernel--]",ret);
}
else
{
printk("pxa270hello_driverregistersuccess!
!
!
[--kernel--]\n");
}
returnret;
}
/*模块初始化函数,调用HW_HELLO_init函数*/
staticint__initpxa270_HELLO_init(void)
{
intret=-ENODEV;
#ifdefOURS_HELLO_DEBUG
printk("pxa270_HELLO_init[--kernel--]\n");
#endif
ret=HW_HELLO_init();
if(ret)
returnret;
return0;
}
/*模块卸载函数
devfs_unregister_chrdev(SIMPLE_HELLO_MAJOR,"hello_ctl")为最主要的语句,devfs_unregister_chrdev卸载设备驱动程序,包括主设备号、驱动程序名*/
staticvoid__exitcleanup_HELLO_ctl(void)
{
#ifdefOURS_HELLO_DEBUG
printk("cleanup_HELLO_ctl[--kernel--]\n");
#endif
devfs_unregister_chrdev(SIMPLE_HELLO_MAJOR,"hello_ctl");
}
/**/
MODULE_DESCRIPTION("simplehellodrivermodule");//一些描述信息
MODULE_AUTHOR("liduo");//驱动作者
MODULE_LICENSE("GPL");
module_init(pxa270_HELLO_init);//指定驱动程序初始化函数
module_exit(cleanup_HELLO_ctl);//指定驱动程序卸载函数
编译程序Makefile如下:
#TOPDIR:
=$(shellcd..;pwd)
TOPDIR:
=.
KERNELDIR=/pxa270_linux/linux
INCLUDEDIR=$(KERNELDIR)/include
CROSS_COMPILE=arm-linux-
AS=$(CROSS_COMPILE)as
LD=$(CROSS_COMPILE)ld
CC=$(CROSS_COMPILE)gcc
CPP=$(CC)-E
AR=$(CROSS_COMPILE)ar
NM=$(CROSS_COMPILE)nm
STRIP=$(CROSS_COMPILE)strip
OBJCOPY=$(CROSS_COMPILE)objcopy
OBJDUMP=$(CROSS_COMPILE)objdump
CFLAGS+=-I..
CFLAGS+=-Wall-O-D__KERNEL__-DMODULE-I$(INCLUDEDIR)
TARGET=pxa270_hello_drv.o
modules:
$(TARGET)
all:
$(TARGET)
pxa270_hello_drv.o:
pxa270_hello_drv.c
$(CC)-c$(CFLAGS)$^-o$@
install:
install-d$(INSTALLDIR)
install-c$(TARGET).o$(INSTALLDIR)
clean:
rm-f*.o*~core.depend
Make工程管理器读入Makefile文件的内容执行编译工作,一个Makefile文件包括:
(1)由make工具创建的目标体(target),通常是目标文件或可执行文件;
(2)要创建目标体所依赖的文件(dependency_file);(3)创建每个目标需要运行的命令(command)
以上两个文件编辑后,然后makemodules编译驱动程序,编写测试文件simple_test_driver.c,然后GCC编辑器编译测试程序生成test测试文件,进入超级终端开始挂载,加载驱动程序,./test测试,实验完成。
通过本实验,初步认识了嵌入式系统程序的语法特点以及要运行所需的各种条件,学习了Linux驱动程序构架以及在应用程序中如何调用程序,为以后的实验打下了基础。
实验十三CPUGPIO驱动程序设计
该实验与实验十二实验步骤基本相同,程序略有不同:
//-------------------IOCTL-----------------------
switch(cmd)
{
caseLED_ON:
{GPCR3|=0x1;break;}//如果cmd=LED_ON,那么GPCR3置为1
caseLED_OFF:
{GPSR3|=0x1;break;}//如果cmd=LED_OFF,那么GPSR3置为1default:
{
printk("lcdcontrol:
nocmdrun[--kernel--]\n");
return(-EINVAL);
}
}
//-------------------INIT--------------------------
GPDR3|=0x00000001;//设置GPIO96输出模式:
开灯
GPSR3|=0x00000001;//关灯
实验现象是目标板的核心板上的LED闪烁。
通过本实验,编写了针对实际硬件的驱动程序,是自己对嵌入式程序有了一个更直观的理解,进一步了解了驱动构架。
实验十四中断实验
该实验与之前两个实验步骤基本相同,程序略有不同:
//-------------------INIT------------------------
ret=request_irq(SIMPLE_INT_IRQ,&SIMPLE_INT_interrupt,SA_INTERRUPT,"int_ctl",NULL);
解释:
request_irq申请硬件中断,参数包括申请的硬件中断号、设备id、中断处理的一些属性(SA_INTERRUPT是快速处理程序,调用时屏蔽所有中断)等
//-------------------卸载-------------------
free_irq(SIMPLE_INT_IRQ,NULL);
解释:
对应request_irq释放中断
实验现象是每当按下目标板上的SW2键时就会触发中断,并且打印相应的响应信息。
实验十五数码管显示驱动实验
不同之处:
//------------------WRITE---------------------
voidwrite_bit(intdata)
{
GPCR2|=(0x1<<27);
if((data&0x80)==0x80)
{
GPSR2|=(0x1<<26);
}
else
{
GPCR2|=(0x1<<26);
}
GPSR2|=(0x1<<27);
}
voidwrite_byte(intdata)
{
inti;
for(i=0;i<8;i++)
{
write_bit(data<
}
}
//-------------------gpioINIT-------------------------
printk("GPDR2=%x\n",GPDR2);
GPDR2=GPDR2|(0x3<<26);
printk("GPDR2=%x\n",GPDR2);
通过本实验,学习了串并转换的相关知识,并编写了驱动程序,对嵌入式系统可实现的功能有了更深入的了解。
实验十六LED点阵驱动程序设计
//----------------WRITE----------------------
inttmp_buf;
//-------------------------------------------
tmp_buf=buf[1];
tmp_buf=tmp_buf<<8;
tmp_buf=tmp_buf|buf[0];
#ifdefOURS_LED_DEBUG
printk("tmp=%x\n",tmp_buf);
#endif
outw(tmp_buf,ioremap_addr);
//----------------CLOSE---------------------
outw(0x0000,ioremap_addr);//closetheledary,allledoff
//----------------INIT------------------
ioremap_addr=ioremap(0x0800c000,0x0f);//
outw(0x00ff,ioremap_addr);//openledary,allledon
//----------------程序卸载---------------------
outw(0x0000,ioremap_addr);
本实验编写了一个针对总线操作的硬件驱动程序。
实验十七AD驱动实验
structucb1x00*ad_ucb;
//---------------IOCTL-----------------------
intval;
ucb1x00_adc_enable(ad_ucb);
val=ucb1x00_adc_read(ad_ucb,cmd,0);
ucb1x00_adc_disable(ad_ucb);
returnUCB_ADC_DAT(val);
//----------------INIT------------------
adctl_dev_handle=devfs_register(NULL,"ad_ctl",DEVFS_FL_DEFAULT,
ADCTL_MAJOR,0,S_IFCHR,&adctl_ops,NULL);
在本实验中编程对模拟量输入进行采集和转换,并将结果显示在超级终端上,通过改变模拟量输入,观察显示结果。
通过此实验,了解了模式转换的基本原理,掌握了模数转换的编程方法。
实验十八DA驱动实验
//----------------WRITE---------------------
outb(buf[0],ioremap_addr);
//----------------CLOSE---------------------
outb(0x00,ioremap_addr);//DAoutputminvalue
//----------------INIT------------------
ioremap_addr=ioremap(0x08014000,0x0f);//daaddress:
0x08808004
outb(0xff,ioremap_addr);//DAoutputmaxvalue
在本实验中利用D/A转换器编程实现波形,在液晶屏上观察经过DA转换后的波形。
通过本实验,了解了数模转换的基本原理,掌握了数模转换的编程方法。
至此,所有实验完成。
【实验总结】通过三节嵌入式实验课的学习,对嵌入式系统、XSCALE体系结构以及LINUX系统都有了一个初步的了解,对LINUX环境下的编程有了一定认识并且会进行实际操作。
学会了LINUX开发环境的搭建以及通讯配置,认识了嵌入式系统程序的语法特点以及要运行所需的各种条件,学习了Linux驱动程序构架以及在应用程序中如何调用程序。
这些知识在嵌入式开发领域中都可能会用到,对以后的学习和工作都很有帮助。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 系统 实验 报告