嵌入式系统实验报告(华中科技大学)
xxxxx
指导老师: 张杰
2012/6/25
试验一:bootloader (ads、引导) 一、实验任务
1、熟悉ADS 1.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((unsigned char *)KERNEL_BASE, 0x00030000, 4*1024*1024);
case '2':
BootKernel(); //这里是不会返回的,否则出错;
break;
default:
break;
}
}
Bootloader的main()函数打印菜单:
int main(void)
{
ARMTargetInit(); //目标板初始化;
//接收用户命令,传递linux核心;
Uart_puts("Menu:\n\r");
Uart_puts("1.Load kernel via Xmodem;\n\r");
Uart_puts("2.Boot linux; \n\r");
Uart_puts("3.Load kernel from flash and boot; \n\r");
Uart_puts("Make your choice.\n\r");
do{
ch=Uart_getc();
}while(ch!='1' && ch!='2' && ch!='3');
return 0;
}
串口读写:
void Uart_putc(char c)
{
while(!SERIAL_WRITE_READY());
((UTXH0) = (c));
}
unsigned char Uart_getc( )
{
while(!SERIAL_CHAR_READY());
return URXH0;
}
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/nfs restart
测试nfs服务器是否正常运行:
mount 主机ip:/home/arm_os/filesystem/rootfs /mnt
7.以root用户启动cutecom,将cutecom配置改为115200 bps,8位,1位停止位,无校验,xmodem,no line end;
8.使用bootloader重新下载Linux核心映像,启动核心运行后,察看是否成功加载nfs上
的root文件系统;
9.启动Linux核心运行,察看结果;
10.linux核心能够运行到加载root步骤,说明bootloader正常运行; 11.将bootloader烧写到flash中,重启目标板电源,察看bootloader是否烧写正常,下载核心测试;
目标板linux系统正常运行到命令行模式下,能够正常输入linux命令,说明实验成功。
四、实验过程中遇到的问题及解决方案
问题一 :打开dubug,下载zImage失败,调试时发现下载失败原因是发生错误程序写为无限循环。
解决方法:重新做了很多遍,仍然失败,最终发现同样的bootloader初始化及同样的下载操作在别的机器中能够正常运行,最终换了试验台终于成功地下载了核心映像。 问题二 :实验中虽然下载完成,但是在cutecom中并没有显示成功下载映像,没有出现#号不能进入命令行模式,不能够进行后续的操作。
解决方法: 因为不明白错误出现的原因,向老师提出疑问,经老师指点,发现linux系统中网络连接处没有网络连接,通过重新配置了ip地址,最终成功下载了核心映像。
试验二:linux kernel (gcc、make) 一、实验任务
1、熟悉基本的linux命令
文件操作、文件编辑
串口工具、程序开发
2、配置linux核心
make menuconfig
3、 交叉编译linux核心
make zImage
二、实验内容
, 熟悉基本的linux命令
, 配置linux核心
, 交叉编译linux核心
, 调试自己编译的核心
, 挂载nfs上的root(根目录)
, 编写一个小程序在目标板上运行
三、实验步骤
1.登陆linux系统,在终端进入管理员模式;
2.解压缩源码包到/home/下;
3.察看解压缩后的/home/arm_os目录:Linux核心、编译器、rootfs等;
4.配置并测试nfs;
5.配置cutecom:115200,XModem,No line end; 6.配置核心:make menuconfig;
7.编译核心:make;
8.下载并运行核心,加载root文件系统;
9.重新设置cutecom为LF line end;
熟悉基本的Linux命令;
10.编写一个小程序hello.c在目标板上运行,察看结果。 #include
Int main(){
Printf(“hello”);
Return 0;
}
四、实验中遇到的主要问题及解决方法 问题1:写成的hello.c程序用gcc编译之后不能在目标板上运行。 解决方法:通过请教老师才知道编译的命令不对,此实验板需要通过用arm-gcc-linux进行
交叉编译,而不是用gcc,得到的可执行文件可以用命令./hello成功运行。
试验三:linux driver (uart)
一、实验任务
1、 Linux驱动编程
基本接口
常用函数
2、 串口驱动
申请中断处理
串口数据读、写
二、实验内容
编写串口驱动初始化、释放函数;
编写串口驱动接收数据函数;
编写串口驱动发送数据函数;
编写串口驱动中断处理函数;
编写串口访问应用程序;
使用模块方式编译驱动;
使用模块方式调试驱动;实现基本的串口数据收发。
三、实验步骤
1(编写初始化、释放函数:uart_init、uart_exit、uart_open、uart_ release分别实现
串口设备初始化、释放、打开、关闭
串口设备初始化函数:
int ret;
dev_t devno = 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("Register chrdev region failed!\n"); return ret; }
cdev_init(&uart_cdev, &uart_fops);
ret = cdev_add(&uart_cdev, devno, 1);
if(ret){ printk("Add c device failed!\n"); return ret; }
uart = ioremap(S3C2410_PA_UART1, 0x4000);
device_init();
ret = request_irq(IRQ_S3CUART_RX1, irq_rev_uart, IRQF_DISABLED, "uart", NULL);
if(ret){ printk("Request irq failed!\n"); return ret; }
loop_buffer_init(&readb, UART_SIZE); printk("Uart module init.\n");
return 0;
串口设备释放函数:
loop_buffer_free(&readb);
free_irq(IRQ_S3CUART_RX1, NULL);
cdev_del(&uart_cdev);
unregister_chrdev_region(MKDEV(uart_major,0),1);
printk("Uart module exit.\n");
2.编写串口驱动接收数据函数、发送数据函数、中断处理函数: irq_rev_uart、uart_write、
uart_read,实现串口设备中断处理、读、写;
串口设备中断处理函数:
char c;
while(!(__raw_readb(uart + S3C2410_UTRSTAT) & 0x1));
c = (char)__raw_readl(uart + S3C2410_URXH);
loop_buffer_add(&readb, c);
return 0;
串口设备读函数:
int i = 0;
if(*ppos >= UART_SIZE) return -EIO; if(*ppos + size > UART_SIZE) size = UART_SIZE - *ppos;
do
{
char c;
if(!loop_buffer_del(&readb, &c))
{
copy_to_user(buf+i, &c, 1);
i++;
}
else
schedule_timeout(10);
} while(i < size);
return size;
串口设备写函数:
int i; char wmem[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; i
#include
int main()
{
int uart_fd, i; char c;
uart_fd = open("/dev/uart", O_RDWR);
if(uart_fd < 0)
{printf("Open device error!\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);
return 0;
}
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:前面步骤都照常执行但是发送接收始终不能够成功。
解决方法:通过问老师仍然查不出错误,于是换了试验台再次尝试后能够成功,同样是实验台的问题。
试验四:linux driver (touchscreen)
一、实验任务
1、 触摸屏驱动
初始化
坐标值
2、 触摸屏、图形系统协调工作
触摸屏校准
拨号键盘
二、实验内容
, 编写触摸屏驱动初始化、释放函数;
, 编写触摸屏驱动读取数据函数;
, 编写触摸屏驱动中断处理函数;
, 使用模块方式调试驱动;
, 编写触摸屏读取应用程序;
, 编写简单图形系统绘制应用程序,绘制一个数字键盘;
, 实现基本的触摸键盘程序。
三、实验步骤
1.填写函数:ts_init、ts_exit、ts_open、ts_ release,实现触摸屏设备初始化、释放、
打开、关闭;
触摸屏设备初始化函数:
int ret;
dev_t devno = 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("Register chrdev region failed!\n"); return ret; }
cdev_init(&ts_cdev, &ts_fops);
ret = cdev_add(&ts_cdev, devno, 1); if(ret){ printk("Add c device failed!\n"); return ret; }
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("Request irq failed!\n"); return ret; }
TS_OPEN_INT(); ts_time = jiffies; printk("Ts_ads7843 module init.\n"); return 0;
触摸屏设备释放函数:
free_irq(IRQ_EINT5, NULL);
cdev_del(&ts_cdev);
unregister_chrdev_region(MKDEV(ts_major,0),1); printk("Ts_ads7843 module exit.\n");
2.填写函数:ts_isr、ts_read,实现触摸屏读、中断处理
触摸屏设备中断处理函数:
if(jiffies < ts_time + HZ/20)
return 0;
if((s3c2410_gpio_getpin(S3C2410_GPF5)
& ADS7843_PIN_PEN) == 0)
{
udelay(10);
get_XY();
ts_time = jiffies;
wake_up_interruptible(&wq);
udelay(2);
}
return 0;
触摸屏设备读函数:
struct ts_ret ts_ret;
int size = 0;
while(count >= sizeof(struct ts_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(struct ts_ret));
count -= sizeof(struct ts_ret);
size += sizeof(struct ts_ret); }
return size;
3.用模块方式编译Linux核心,生成ts_ads7843.ko,启动目标板Linux核心,用insmod、
rmmod等操作模块;
4.用printk打印调试触摸屏驱动,包括中断相应,读等;
5.编写应用程序:ts_ads7843.c,实现打开触摸屏设备、读等;
触摸屏访问应用程序:
#include
#include
int main()
{
int ts_fd, i; char c; struct ts_ret ts_ret;
ts_fd = open("/dev/ts_ads7843", O_RDWR);
if(ts_fd < 0) {
printf("Open ts device error!\n"); return -1; }
for(i=0; i<50; i++){
if(read(ts_fd, &ts_ret, sizeof(struct ts_ret))) {
if(ts_ret.x < Xmin) ts_ret.x = Xmin;
if(ts_ret.x > Xmax) ts_ret.x = Xmax;
if(ts_ret.y < Ymin) ts_ret.y = Ymin;
if(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);
return 0;
}
6.触摸屏校准
通过多次点击触摸屏四个边界点得到几组坐标,取平均值来得到屏幕Xmin,Xmax,Ymin,
Ymax,在ts_ads7843.c 修改程序,将这四个值代入函数中,并将SCREEN_WIDTH,
SCREEN_HEIGHT设置为640*480,修改后的ts_ads7843.c程序如下:
#include
#include
#define Xmin 500
#define Xmax 2200
#define Ymin 1400
#define Ymax 3000
static struct ts_ret {
unsigned int pressure;
unsigned int x;
unsigned int y;
} ts_ret;
int main()
{
int x,y;
int ts_fd, i; char c; struct ts_ret ts_ret;
ts_fd = open("/dev/ts_ads7843", O_RDWR);
if(ts_fd < 0) {
printf("Open ts device error!\n"); return -1; }
for(i=0; i<50; i++){
if(read(ts_fd, &ts_ret, sizeof(struct ts_ret))) {
if(ts_ret.x < Xmin) ts_ret.x = Xmin;
if(ts_ret.x > Xmax) ts_ret.x = Xmax;
if(ts_ret.y < Ymin) ts_ret.y = Ymin;
if(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);
return 0;
}
实验五、六:GPRS综合试验 (framebuffer)GPRS综合试验
一、实验任务
1、 GPRS模块控制试验
串口控制GPRS模块
AT命令集
2、 综合实验
电话拨号
短消息发送
二、实验内容
, 编写简单图形系统绘制应用程序,绘制一个数字键盘;
, 实现基本的触摸键盘程序。
, 编写应用程序实现拨号,发短信功能。
三、实验步骤
1.编写实现绘制数字键盘及触摸键盘程序及实现拨号发短信功能的程序main.c,程序修改于test5.c,显示数字键盘及触摸键盘程序已给出,只需做少部分修改: 修改删除功能函数:
if(key == ' ')
{
if(phonenum.tail > 0)
{phonenum.tail--;
printf("delete ok.Now phonenum is");
for(i=0;i
本文档为【嵌入式系统实验报告(华中科技大学)】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。