嵌入式报告 08210929.docx
- 文档编号:6632028
- 上传时间:2023-01-08
- 格式:DOCX
- 页数:35
- 大小:36.38KB
嵌入式报告 08210929.docx
《嵌入式报告 08210929.docx》由会员分享,可在线阅读,更多相关《嵌入式报告 08210929.docx(35页珍藏版)》请在冰豆网上搜索。
嵌入式报告08210929
嵌入式实验报告
姓名:
刘晓松
学号:
08210929
班级:
2008211202
专业:
电子信息科学与技术
一实验目的
通过宿主PC端与PXA270-EP目标板连接并且进行相关实验,了解相关嵌入式开发环境的搭建,以及相关相关底层驱动程序的编写与设置。
实验内容
一.嵌入式基本实验
1.基本实验linux开发环境的搭建,通讯配置
通过本实验的操作,我将宿主PC端与PXA270-EP目标板正确的连接起来。
并且
参照本教程给出的步骤,一步一步地完成RedHat9.0操作系统的安装。
此次试验属于所有试验的基础部分,通过实际操作,我了解各种接口的链接,linux的安装过程,为以后的各种试验打下了坚实的基础。
2.minicom与超级终端的建立
通过本实验的操作,我建立起了宿主PC机与PXA270目标板的通信环境。
在此次试验中,我并没有使用minicom,而是使用了windows的超级终端,在这一过程,我了解到了超级终端作为电脑与各种硬件平台的通信作用,通过配置相关参数,我渐渐了解到了串口通信,并且逐步建立起了宿主PC与PXA270目标板的通信环境。
3.实验五在此次试验中,我了解并设置了TFTP服务。
TFTP的全称是TrivialFileTransferProtocol,即简单文件传输协议。
使用此服务传送文件时没有数据校验、密码验证,非常适合小型文件的传输。
在通过TFTP传送文件时,需要服务端和客户端,对于我们嵌入式系统来讲,服务端就是我们的宿主机,客户端就是那个PXA270的系统板。
通过本实验的操作,我就利用已经启动好的tftp服务来完成宿主PC机与PXA270-EP目标机之间的文件传输了。
4.实验六,在此次试验中,我了解并掌握了NFS服务相关操作。
NFS(NetworkFileSystem)指网络文件系统,是Linux系统中经常使用的一种服务,NFS是一个RPCservice,很像windows中的文件共享服务。
它的设计是为了在不同的系统间使用,所以它的通讯协议设计与主机及作业系统无关。
当使用者想用远端档案时只要用"mount"就可把remote档案系统挂接在自己的档案系统之下,使得远端的档案在使用上和local的档案没两样。
按照书中实验步骤,我让宿主PC机通过网络挂接(mount)到PXA270-EP目标板的相应文件夹下。
我们可以看到,在Linux下的实验,我们使用超级终端通过串口给PXA270-EP目标板发送指令,而通过网络传送数据。
此次试验是最为重要的一次试验,是以后所有试验的基础,因为宿主PC与PXA270目标板的所有数据传输,相关IO操作,都是以NFS服务为基础的。
5.helloworld的试验,在这一次试验中,我通过NFS试验成功将宿主机挂载到PXA270上,并且第一次正面接触嵌入式Linux的开发,第一次编写嵌入式系统的应用程序,亲身实践一下
按照书上的步骤,一步一步地完成实验,编写、编译并运行HelloWorld程序。
我们在PC上编辑、编译一个应用程序,并且在嵌入式系统上运行和调试它。
这个程序虽然简单,但是它是典型嵌入式程序开发的一个反映。
通过这个实验,可以对嵌入式开发有一个更为直观的认识。
8掌握编译XSCALE系统Bootloader的过程。
BOOTLOADER是嵌入式系统的基本部分,负责了系统的启动与初始化,熟悉理解它的工作原理与使用是进入嵌入式世界的一个前提。
(了解BLOB的原理,可以参考第三章的“3.5.2启动引导BootLoader”部分)编译BOOTLOADER是非常基本的实验,如果要深入掌握嵌入式的开发,一定要能够熟练掌握此实验。
9掌握编译ARM系统内核的过程。
本实验我们编译了Linux内核。
Linux内核是相当复杂的,若您有兴趣的话,你可以有选择性的阅读我们提供给您的Linux源码。
二,嵌入式基本接口试验(驱动试验)
实验12:
在本次试验中,动手实践一个简单的字符型设备驱动程序。
在这一过程中,我了解并学习Linux驱动程序构架,掌握并学习在应用程序中调用驱动。
下面是相关的驱动程序,以及测试程序。
#include
#include
#include
#include
#include
#include
#include
//HELLODEVICEMAJOR
#defineSIMPLE_HELLO_MAJOR96
#defineOURS_HELLO_DEBUG
#defineVERSION"PXA2700EP-hello-V1.00-060530"voidshowversion(void)
{printk("*********************************************\n");
printk("\t%s\t\n",VERSION);
printk("*********************************************\n\n");
}
//-------------------READ-----------------------
//Read入口点.从设备上读数据.对于有缓冲区的I/O操作,一般是从缓冲区里读数据.对字符特别设备文件进行读操作将调用read子程序
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-----------------------
//Write入口点.往设备上写数据.对于有缓冲区的I/O设备操作,一般是把数据写入缓冲区里.对字符特别设备文件进行写操作将调用write子程序
ssize_tSIMPLE_HELLO_write(structfile*file,constchar*buf,size_tcount,loff_t*f_ops)
{#ifdefOURS_HELLO_DEBUG
printk("SIMPLE_HELLO_write[--kernel--]\n");
#endifreturncount;
}
//-------------------IOCTL-----------------------
//ioctl入口点.执行读,写之外的操作,实现对设备的控制
ssize_tSIMPLE_HELLO_ioctl(structinode*inode,structfile*file,unsignedintcmd,longdata)
{#ifdefOURS_HELLO_DEBUG
printk("SIMPLE_HELLO_ioctl[--kernel--]\n");
#endifreturn0;
}
//-------------------OPEN------------------------
//open入口点.打开设备准备I/O操作.对字符特别设备文件进行打开操作,都会调用设备的open入口点。
open子程序必须对将要进行的I/O操作做好必要的准备工作,如清除缓冲区等.如果设备是独占的,即同一时刻只能有一个程序访问此设备,则open子程序必须设置一些标志以表示设备处于忙状态.
ssize_tSIMPLE_HELLO_open(structinode*inode,structfile*file)
{#ifdefOURS_HELLO_DEBUG
printk("SIMPLE_HELLO_open[--kernel--]\n");
#endifMOD_INC_USE_COUNT;return0;
}
//-------------------RELEASE/CLOSE---------------
//Close入口点.关闭一个设备.当最后一次使用设备终结后,调用close子程序.独占设备必须标记设备可再次使用
ssize_tSIMPLE_HELLO_release(structinode*inode,structfile*file)
{#ifdefOURS_HELLO_DEBUG
printk("SIMPLE_HELLO_release[--kernel--]\n");
#endifMOD_DEC_USE_COUNT;return
structfile_operationsHELLO_ctl_ops={open:
SIMPLE_HELLO_open,read:
SIMPLE_HELLO_read,
write:
SIMPLE_HELLO_write,ioctl:
SIMPLE_HELLO_ioctl,release:
SIMPLE_HELLO_release,
};
//-------------------INIT------------------------
staticint
initHW_HELLO_CTL_init(void)
{intret=-ENODEV;
ret=devfs_register_chrdev(SIMPLE_HELLO_MAJOR,"hello_ctl",&HELLO_ctl_ops);
showversion();
if(ret<0)
{printk("pxa270init_modulefailedwith%d\n[--kernel--]",ret);
returnret;
}
else
{printk("pxa270hello_driverregistersuccess!
!
!
[--kernel--]\n");
}
returnret;
}
staticint
initpxa270_HELLO_CTL_init(void)
{intret=-ENODEV;
#ifdefOURS_HELLO_DEBUG
printk("pxa270_HELLO_CTL_init[--kernel--]\n");
#endif
ret=HW_HELLO_CTL_init();
if(ret)
returnret;
return0;
}
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_CTL_init);module_exit(cleanup_HELLO_ctl);
实验总结:
通过本实验的操作,编写的测试程序能够正常的对驱动程序进行操作,就表示驱动程序功能正常。
试验十三:
GPIO的使用
编写第一个针对实际硬件的驱动程序,进一步了解驱动程序构架。
凡是操作系统控制外部设备,即使是最简单的硬件电路,也是需要驱动的。
本实验涉及的外部硬件只有电阻,蓝色发光二极管。
我们使用自己编写得驱动程序与应用程序控制GPIO96的电平。
通过LED的亮灭来判断,是否CPU做出了正确的响应
以下是相关驱动程序,测试程序及其相关注释
编写GPIO驱动程序
使用GPIO控制led灯的亮与灭。
先编写对应的驱动程序和makefile文件,然后交叉编译,用串口登录目标机,挂载上之后,便可以进行读写操作。
通过控制CPU的GPIO寄存器,来实现GPIO的电平控制。
控制GPIO的寄存器主要有:
GPDR:
IO方向控制器.
GPCR:
清楚GPIO对应位。
CPSR:
设置GPIO对应位。
补充添加代码:
1。
write函数
//-------------------WRITE-----------------------
57ssize_tSIMPLE_GPIO_LED_write(structfile*file,constchar*buf,size_tcount,loff_t*f_ops)
{
#ifdefOURS_GPIO_LED_DEBUG
printk("SIMPLE_GPIO_LED_write[--kernel--]\n");
#endif
returncount;
2。
open函数
//-------------------OPEN------------------------
ssize_tSIMPLE_GPIO_LED_open(structinode*inode,structfile*file)
{
#ifdefOURS_GPIO_LED_DEBUG
printk("SIMPLE_GPIO_LED_open[--kernel--]\n");
#endif
MOD_INC_USE_COUNT;
return0;
3。
ops
//-------------------------------------------------
structfile_operationsGPIO_LED_ctl_ops={open:
SIMPLE_GPIO_LED_open,
read:
SIMPLE_GPIO_LED_read,
write:
SIMPLE_GPIO_LED_write,
ioctl:
SIMPLE_GPIO_LED_ioctl,
release:
SIMPLE_GPIO_LED_release,}
建立操作映射,注册借口函数。
为应用层提供统一的接口。
详细说明:
Write,open,ops的相关补充代码已经填写完毕。
Write,read,open,release只有基本操作和调试信息。
Ioctl函数为GPIO口的控制函数,其代码如下:
ssize_tSIMPLE_GPIO_LED_ioctl(structinode*inode,structfile*file,unsignedintcmd,longdata)
{
#ifdefOURS_GPIO_LED_DEBUG
printk("SIMPLE_GPIO_LED_ioctl[--kernel--]\n");//调试信息
#endif
switch(cmd)//io控制,cmd为输入的命令
{
caseLED_ON:
{GPCR3|=0x1;break;}//通过修改寄存器控制GPIO口电平
caseLED_OFF:
{GPSR3|=0x1;break;}
default:
{printk("lcdcontrol:
nocmdrun[--kernel--]\n");return(-EINVAL);//非法命令}
}
return0;
}
structfile_operationsGPIO_LED_ctl_ops
建立操作映射,注册借口函数。
为应用层提供统一的接口。
下面的部分包括初始化函数,卸载函数
初始化函数如下:
staticint__initpxa270_GPIO_LED_CTL_init(void)
{
intret=-ENODEV;//初始化失败将返回次错误信息
//调试信息
#ifdefOURS_GPIO_LED_DEBUG
printk("pxa270_GPIO_LED_CTL_init[--kernel--]\n");
#endif
//调用HW_GPIO_LED_CTL_init函数完成初始化
ret=HW_GPIO_LED_CTL_init();
if(ret)
returnret;
return0;
}
该函数通过调用HW_GPIO_LED_CTL_init函数实现初始化,HW_GPIO_LED_CTL_init函数相关注释如下:
staticint__initHW_GPIO_LED_CTL_init(void)
{
intret=-ENODEV;
printk("hhhhhhhhhhhhhhhhhhhhhhhhhhhhh\n\n");
showversion();//显示版本信息
//initGPIO
//初始化相关寄存器数值,继而控制初始化输出
GPDR3|=0x00000001;//设置输出端口模式
GPSR3|=0x00000001;//关闭led灯
//调试信息,显示寄存器信息
#ifdefOURS_GPIO_LED_DEBUG
printk("GPLR3=%x\n",GPLR3);
printk("GPDR3=%x\n",GPDR3);
#endif
//注册设备
ret=devfs_register_chrdev(SIMPLE_GPIO_LED_MAJOR//主设备号,"gpio_led_ctl",&GPIO_LED_ctl_ops//函数映射结构体);
if(ret<0)
{
printk("pxa270:
init_modulefailedwith%d\n[--kernel--]",ret);
returnret;
}
else
{
printk("pxa270gpio_led_driverregistersuccess!
!
!
[--kernel--]\n");
}
returnret;
}
清除卸载函数为cleanup_GPIO_LED_ctl,其代码实现如下:
staticvoid__exitcleanup_GPIO_LED_ctl(void)
{
#ifdefOURS_GPIO_LED_DEBUG
printk("cleanup_GPIO_LED_ctl[--kernel--]\n");
#endif
//注销主设备号,释放设备
devfs_unregister_chrdev(SIMPLE_GPIO_LED_MAJOR,"gpio_led_ctl");
}
测试函数:
通过调用ioctl函数实现对led灯的控制。
intmain(void)
{
intfd;
intret;
char*i;
printf("\nstartgpio_led_drivertest\n\n");
fd=open(DEVICE_NAME,O_RDWR);
//系统通过ops调用SIMPLE_GPIO_LED_open函数打开设备
printf("fd=%d\n",fd);
if(fd==-1)
{
printf("opendevice%serror\n",DEVICE_NAME);
}
else
{
//通过调用SIMPLE_GPIO_LED_ioctl函数控制led灯
//主循环
while
(1)
{ioctl(fd,LED_OFF);
sleep
(1);//修改sleep时间即可改变led灯点亮的时间,如sleep(7)即灭7秒
ioctl(fd,LED_ON);
sleep
(1);//sleep(5)亮5秒
}
//close
ret=close(fd);//
printf("ret=%d\n",ret);
printf("closegpio_led_drivertest\n");
}
return0;
}//endmain
实验十三是通过操作CPU的GPIO端口来控制LED的亮灭,通过该实验基本掌握了驱动模块的结构和一些函数的实现,如ioctl函数。
十四中断试验
与中断有关的函数说明:
(1)request_int函数:
函数原型:
request_int(unsignedintirq,void(handler*)(int,void*,structpt_regs*),
unsignedlongirg_flags,constchar*devname,void*dev_id);
该函数有5个参数:
(a)irq:
外设使用的中断号。
(b)handler中断服务程序的函数入口
(c)irg_flag:
设备驱动程序指定的中断请求类型标志,它可以是一下三个值的或:
SA_SHIRQ,SA_INTERRUPT和SA_SAMPLE_RANDOM
(d)devname指针,设备名字字符串
(e)dev_id:
指向全局唯一的设备标识ID,这是一个void类型的指针,可提供设备驱动程序的自行解释
(2)free_irq函数:
free_irq(unsignedintirq,void*dev_id)
中断驱动模块的基本框架和GPIO的驱动模块基本相同,同样是通过module_init和module_exit来分别映射初始化和卸载模块。
具体实现如下:
module_init(pxa270_HELLO_CTL_init);
module_exit(cleanup_HELLO_ctl);
和GPIO驱动相同,加载模块时,系统调用pxa270_HELLO_CTL_init函数初始化模块;卸载模块时,调用cleanup_HELLO_ctl函数来卸载模块,并释放资源。
中断驱动的初始化与GPIO模块略有不同,除了要注册主设备好之外,还要注册中断向量和中断处理函数。
pxa270_HELLO_CTL_init通过调用HW_HELLO_CTL_init函数完成模块初始化。
pxa27
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式报告 08210929 嵌入式 报告