嵌入式系统实验报告华中科技大学.docx
《嵌入式系统实验报告华中科技大学.docx》由会员分享,可在线阅读,更多相关《嵌入式系统实验报告华中科技大学.docx(18页珍藏版)》请在冰点文库上搜索。
嵌入式系统实验报告华中科技大学
嵌入式系统
xxxxx
指导老师:
张杰
2012/6/25
试验一:
bootloader(ads、引导)
一、实验任务
1、熟悉ADS1.2开发工具
创建、编译、下载、调试工程
2、串口通讯
串口控制器初始化、收/发数据
3、配置主机端的nfs服务器
配置主机端的nfs服务器,以连接linux核心
4、下载并运行linux核心
使用自己的串口程序下载并运行linux核心
二、实验内容
●编写串口接收数据函数
●编写串口发送数据函数
●学习ads、jtag调试、flash烧写
●打印菜单,等待用户输入
●下载并运行linux核心
●配置主机的nfs服务器,与linux核心连接
三、实验步骤
1.编写串口接收数据函数
编写串口发送数据函数
修改bootloader:
菜单、串口收发、命令行;
接收串口数据并做相应处理:
while
(1)
{
打印菜单并等待用户输入;
switch(ch)//根据用户输入做相应处理
{
case'1':
imgsize=xmodem_receive((char*)KERNEL_BASE,MAX_KERNEL_SIZE);
if(imgsize==0)//下载出错;
else//下载成功;
break;
case'3':
nand_read((unsignedchar*)KERNEL_BASE,0x00030000,4*1024*1024);
case'2':
BootKernel();//这里是不会返回的,否则出错;
break;
default:
break;
}
}
Bootloader的main()函数打印菜单:
intmain(void)
{
ARMTargetInit();//目标板初始化;
//接收用户命令,传递linux核心;
Uart_puts("Menu:
\n\r");
Uart_puts("1.LoadkernelviaXmodem;\n\r");
Uart_puts("2.Bootlinux;\n\r");
Uart_puts("3.Loadkernelfromflashandboot;\n\r");
Uart_puts("Makeyourchoice.\n\r");
do{
ch=Uart_getc();
}while(ch!
='1'&&ch!
='2'&&ch!
='3');
return0;
}
串口读写:
voidUart_putc(charc)
{
while(!
SERIAL_WRITE_READY());
((UTXH0)=(c));
}
unsignedcharUart_getc()
{
while(!
SERIAL_CHAR_READY());
returnURXH0;
}
2.使用ads1.2编译bootloader;
3.使用uarmjtag下载、调试bootloader;
4.使用axd查看变量、内存,单步跟踪;
5.配置超级终端,与bootloader通讯;
6.配置nfs;
编辑/etc/export文件:
/home/arm_os/filesystem/rootfs目标板ip(rw,sync)
/home/arm_os/filesystem/rootfs主机ip(rw,sync)
启动nfs服务器:
/etc/init.d/nfsrestart
测试nfs服务器是否正常运行:
mount主机ip:
/home/arm_os/filesystem/rootfs/mnt
7.以root用户启动cutecom,将cutecom配置改为115200bps,8位,1位停止位,无校验,xmodem,nolineend;
8.使用bootloader重新下载Linux核心映像,启动核心运行后,察看是否成功加载nfs上的root文件系统;
9.启动Linux核心运行,察看结果;
10.linux核心能够运行到加载root步骤,说明bootloader正常运行;
11.将bootloader烧写到flash中,重启目标板电源,察看bootloader是否烧写正常,下载核心测试;
目标板linux系统正常运行到命令行模式下,能够正常输入linux命令,说明实验成功。
四、实验过程中遇到的问题及解决方案
问题一:
打开dubug,下载zImage失败,调试时发现下载失败原因是发生错误程序写为无限循环。
解决方法:
重新做了很多遍,仍然失败,最终发现同样的bootloader初始化及同样的下载操作在别的机器中能够正常运行,最终换了试验台终于成功地下载了核心映像。
问题二:
实验中虽然下载完成,但是在cutecom中并没有显示成功下载映像,没有出现#号不能进入命令行模式,不能够进行后续的操作。
解决方法:
因为不明白错误出现的原因,向老师提出疑问,经老师指点,发现linux系统中网络连接处没有网络连接,通过重新配置了ip地址,最终成功下载了核心映像。
试验二:
linuxkernel(gcc、make)
一、实验任务
1、熟悉基本的linux命令
文件操作、文件编辑
串口工具、程序开发
2、配置linux核心
makemenuconfig
3、交叉编译linux核心
makezImage
二、实验内容
●熟悉基本的linux命令
●配置linux核心
●交叉编译linux核心
●调试自己编译的核心
●挂载nfs上的root(根目录)
●编写一个小程序在目标板上运行
三、实验步骤
1.登陆linux系统,在终端进入管理员模式;
2.解压缩源码包到/home/下;
3.察看解压缩后的/home/arm_os目录:
Linux核心、编译器、rootfs等;
4.配置并测试nfs;
5.配置cutecom:
115200,XModem,Nolineend;
6.配置核心:
makemenuconfig;
7.编译核心:
make;
8.下载并运行核心,加载root文件系统;
9.重新设置cutecom为LFlineend;
熟悉基本的Linux命令;
10.编写一个小程序hello.c在目标板上运行,察看结果。
#include
Intmain(){
Printf(“hello”);
Return0;
}
四、实验中遇到的主要问题及解决方法
问题1:
写成的hello.c程序用gcc编译之后不能在目标板上运行。
解决方法:
通过请教老师才知道编译的命令不对,此实验板需要通过用arm-gcc-linux进行交叉编译,而不是用gcc,得到的可执行文件可以用命令./hello成功运行。
试验三:
linuxdriver(uart)
一、实验任务
1、Linux驱动编程
基本接口
常用函数
2、串口驱动
申请中断处理
串口数据读、写
二、实验内容
编写串口驱动初始化、释放函数;
编写串口驱动接收数据函数;
编写串口驱动发送数据函数;
编写串口驱动中断处理函数;
编写串口访问应用程序;
使用模块方式编译驱动;
使用模块方式调试驱动;实现基本的串口数据收发。
三、实验步骤
1.编写初始化、释放函数:
uart_init、uart_exit、uart_open、uart_release分别实现串口设备初始化、释放、打开、关闭
串口设备初始化函数:
intret;
dev_tdevno=MKDEV(uart_major,0);
if(uart_major){
ret=register_chrdev_region(devno,1,"uart");
}else{
ret=alloc_chrdev_region(&devno,0,1,"uart");
uart_major=MAJOR(devno);
}
if(ret<0){printk("Registerchrdevregionfailed!
\n");returnret;}
cdev_init(&uart_cdev,&uart_fops);
ret=cdev_add(&uart_cdev,devno,1);
if(ret){printk("Addcdevicefailed!
\n");returnret;}
uart=ioremap(S3C2410_PA_UART1,0x4000);
device_init();
ret=request_irq(IRQ_S3CUART_RX1,irq_rev_uart,IRQF_DISABLED,"uart",NULL);
if(ret){printk("Requestirqfailed!
\n");returnret;}
loop_buffer_init(&readb,UART_SIZE);printk("Uartmoduleinit.\n");
return0;
串口设备释放函数:
loop_buffer_free(&readb);
free_irq(IRQ_S3CUART_RX1,NULL);
cdev_del(&uart_cdev);
unregister_chrdev_region(MKDEV(uart_major,0),1);
printk("Uartmoduleexit.\n");
2.编写串口驱动接收数据函数、发送数据函数、中断处理函数:
irq_rev_uart、uart_write、uart_read,实现串口设备中断处理、读、写;
串口设备中断处理函数:
charc;
while(!
(__raw_readb(uart+S3C2410_UTRSTAT)&0x1));
c=(char)__raw_readl(uart+S3C2410_URXH);
loop_buffer_add(&readb,c);
return0;
串口设备读函数:
inti=0;
if(*ppos>=UART_SIZE)return-EIO;
if(*ppos+size>UART_SIZE)size=UART_SIZE-*ppos;
do
{
charc;
if(!
loop_buffer_del(&readb,&c))
{
copy_to_user(buf+i,&c,1);
i++;
}
else
schedule_timeout(10);
}while(ireturnsize;
串口设备写函数:
inti;charwmem[UART_SIZE];
if(*ppos>=UART_SIZE)return-EIO;
if(*ppos+size>UART_SIZE)
size=UART_SIZE-*ppos;
copy_from_user(wmem,buf,size);
for(i=0;iwhile(!
(__raw_readl(uart+S3C2410_UTRSTAT)&0x4));
__raw_writel(*(wmem+i),uart+S3C2410_UTXH);
}
returnsize;
串口访问应用程序:
#include
#include
intmain()
{
intuart_fd,i;charc;
uart_fd=open("/dev/uart",O_RDWR);
if(uart_fd<0)
{printf("Opendeviceerror!
\n");return-1;}
for(i=0;i<50;i++){
read(uart_fd,&c,1);printf("%c",c);
write(uart_fd,&c,1);
if(c=='q')break;
}
close(uart_fd);
return0;
}
3.用模块方式编译Linux核心,生成uart.ko,启动目标板Linux核心,用insmod、rmmod等命令操作模块;用printk打印调试串口驱动,包括中断相应,读写等;
4.编写应用程序:
uart.c,实现打开串口设备、读写等,把主机端由cutecom发过来的串口数据回传给主机;
5.将目标板上串口线连到串口1;
6.编译应用程序uart.c,实现和主机间的串口通讯。
四、实验中遇到的问题及解决方法
问题1:
由于模块化编译方法不太了解,对其过程不清楚。
解决方法:
向老师提出疑问后才知道首先修改uart.c中的波特率,然后拷贝驱动:
/home/arm_os/test/st/test3/driver/下的makefile和uart.c拷贝到:
/home/arm_os
/kernel/linux-2.6.29.8/driver/char下,再拷贝应用程序:
把:
/home/arm_os/test/st/tes
T3/下的makefile和uart.c拷贝到自己的文件夹,用于测试。
问题2:
前面步骤都照常执行但是发送接收始终不能够成功。
解决方法:
通过问老师仍然查不出错误,于是换了试验台再次尝试后能够成功,同样是实验台的问题。
试验四:
linuxdriver(touchscreen)
一、实验任务
1、触摸屏驱动
初始化
坐标值
2、触摸屏、图形系统协调工作
触摸屏校准
拨号键盘
二、实验内容
●编写触摸屏驱动初始化、释放函数;
●编写触摸屏驱动读取数据函数;
●编写触摸屏驱动中断处理函数;
●使用模块方式调试驱动;
●编写触摸屏读取应用程序;
●编写简单图形系统绘制应用程序,绘制一个数字键盘;
●实现基本的触摸键盘程序。
三、实验步骤
1.填写函数:
ts_init、ts_exit、ts_open、ts_release,实现触摸屏设备初始化、释放、打开、关闭;
触摸屏设备初始化函数:
intret;
dev_tdevno=MKDEV(ts_major,0);
if(ts_major){
ret=register_chrdev_region(devno,1,“ts_ads7843");
}else{
ret=alloc_chrdev_region(&devno,0,1,"ts_ads7843");
ts_major=MAJOR(devno);
}
if(ret<0){printk("Registerchrdevregionfailed!
\n");returnret;}
cdev_init(&ts_cdev,&ts_fops);
ret=cdev_add(&ts_cdev,devno,1);
if(ret){printk("Addcdevicefailed!
\n");returnret;}
spi0_base=ioremap(S3C2410_PA_SPI,0x20);
device_init();
init_waitqueue_head(&wq);
ret=request_irq(IRQ_EINT5,ts_isr,IRQF_DISABLED,"ts_ads7843",NULL);
if(ret){printk("Requestirqfailed!
\n");returnret;}
TS_OPEN_INT();ts_time=jiffies;
printk("Ts_ads7843moduleinit.\n");
return0;
触摸屏设备释放函数:
free_irq(IRQ_EINT5,NULL);
cdev_del(&ts_cdev);
unregister_chrdev_region(MKDEV(ts_major,0),1);
printk("Ts_ads7843moduleexit.\n");
2.填写函数:
ts_isr、ts_read,实现触摸屏读、中断处理
触摸屏设备中断处理函数:
if(jiffiesreturn0;
if((s3c2410_gpio_getpin(S3C2410_GPF5)
&ADS7843_PIN_PEN)==0)
{
udelay(10);
get_XY();
ts_time=jiffies;
wake_up_interruptible(&wq);
udelay
(2);
}
return0;
触摸屏设备读函数:
structts_retts_ret;
intsize=0;
while(count>=sizeof(structts_ret))
{
interruptible_sleep_on(&wq);
ts_ret.x=x;
ts_ret.y=y;
ts_ret.pressure=PEN_DOWN;
copy_to_user(buffer,(char*)&ts_ret,sizeof(structts_ret));count-=sizeof(structts_ret);
size+=sizeof(structts_ret);
}
returnsize;
3.用模块方式编译Linux核心,生成ts_ads7843.ko,启动目标板Linux核心,用insmod、rmmod等操作模块;
4.用printk打印调试触摸屏驱动,包括中断相应,读等;
5.编写应用程序:
ts_ads7843.c,实现打开触摸屏设备、读等;
触摸屏访问应用程序:
#include
#include
intmain()
{
intts_fd,i;charc;structts_retts_ret;
ts_fd=open("/dev/ts_ads7843",O_RDWR);
if(ts_fd<0){
printf("Opentsdeviceerror!
\n");return-1;}
for(i=0;i<50;i++){
if(read(ts_fd,&ts_ret,sizeof(structts_ret))){
if(ts_ret.xif(ts_ret.x>Xmax)ts_ret.x=Xmax;
if(ts_ret.yif(ts_ret.y>Ymax)ts_ret.y=Ymax;
x=(ts_ret.x-Xmin)*SCREEN_WIDTH/(Xmax-Xmin);
y=(ts_ret.y-Ymin)*SCREEN_HEIGHT/(Ymax-Ymin);}}
close(ts_fd);
return0;
}
6.触摸屏校准
通过多次点击触摸屏四个边界点得到几组坐标,取平均值来得到屏幕Xmin,Xmax,Ymin,Ymax,在ts_ads7843.c修改程序,将这四个值代入函数中,并将SCREEN_WIDTH,SCREEN_HEIGHT设置为640*480,修改后的ts_ads7843.c程序如下:
#include
#include
#defineXmin500
#defineXmax2200
#defineYmin1400
#defineYmax3000
staticstructts_ret{
unsignedintpressure;
unsignedintx;
unsignedinty;
}ts_ret;
intmain()
{
intx,y;
intts_fd,i;charc;structts_retts_ret;
ts_fd=open("/dev/ts_ads7843",O_RDWR);
if(ts_fd<0){
printf("Opentsdeviceerror!
\n");return-1;}
for(i=0;i<50;i++){
if(read(ts_fd,&ts_ret,sizeof(structts_ret))){
if(ts_ret.xif(ts_ret.x>Xmax)ts_ret.x=Xmax;
if(ts_ret.yif(ts_ret.y>Ymax)ts_ret.y=Ymax;
x=(ts_ret.x-Xmin)*640/(Xmax-Xmin);
y=(ts_ret.y-Ymin)*480/(Ymax-Ymin);}
printf("%d,%d,%d\n",x,y,ts_ret.pressure);
}
close(ts_fd);
return0;
}
实验五、六:
GPRS综合试验(framebuffer)GPRS综合试验
一、实验任务
1、GPRS模块控制试验
串口控制GPRS模块
AT命令集
2、综合实验
电话拨号
短消息发送
二、实验内容
●编写简单图形系统绘制应用程序,绘制一个数字键盘;
●实现基本的触摸键盘程序。
●编写应用程序实现拨号,发短信功能。
三、实验步骤
1.编写实现绘制数字键盘及触摸键盘程序及实现拨号发短信功能的程序main.c,程序修改于test5.c,显示数字键盘及触摸键盘程序已给出,只需做少部分修改:
修改删除功能函数:
if(key=='')
{
if(phonenum.tail>0)
{phonenum.tail--;
printf("deleteok.Nowphonenumis");
for(i=0;iprintf("%c",phonenum.buffer[i]);
printf("\n");
}
}
2.将手机sim卡插入目标板上即可实现通话和发短信功能。