华南理工大学
XXX课程实验报告
实验题目:嵌入式linux操作系统下触摸屏的实现与分析实验报告
姓名:___________ 学号:______
班级: ___________ 组别: ________
合作者: __________________
指导教师: ______________________
一.硬件平台
1、处理器:三星S3C2410,200MHZ
2、内存:SDRAM,64M
3、外存:NAND FLASH,64M
4、LCD&触摸屏:SHARP,640×480,TFT
5、串口:RS232,RS485
二.处理器结构
1、处理器核心
MMU,DCACHE,ICACHE,JTAG
2、系统总线
SDRAM,FLASH,LCD,中断,USB
3、外部总线
串口,USB,GPIO
试验一:bootloader (ads、引导)
1、熟悉ADS 1.2开发工具
创建、编译、下载、调试工程
2、串口通讯
串口控制器初始化、收/发数据
3、配置主机端的nfs服务器
配置主机端的nfs服务器,以连接linux核心
4、下载并运行linux核心
使用自己的串口程序下载并运行linux核心
主要内容:
•编写串口接收数据函数
•编写串口发送数据函数
•打印菜单,等待用户输入
•下载并运行linux核心
•配置主机的nfs服务器,与linux核心连接
其他部分代码从教师用机中拷贝
linux核心从教师机中拷贝
主要步骤:
•修改bootloader:菜单、串口收发、命令行;
•使用ads1.2编译bootloader;
•使用uarmjtag下载、调试bootloader;
•使用axd查看变量、内存,单步跟踪;
•配置超级终端,与bootloader通讯;
•使用超级终端下载Linux核心映像;
•启动Linux核心运行,察看结果;(bootloader调试成功后再继续以下步骤)
•主机重起到ubuntu,配置nfs,配置cutecom;
•重新下载Linux核心映像,启动核心运行后,察看是否成功加载nfs上的root文件系统。
需要补充的代码:
接收串口数据并做相应处理
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;
}
}
打印菜单:
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');
串口读写:
void Uart_putc(char c)
{
while(!SERIAL_WRITE_READY());
((UTXH0) = (c));
}
unsigned char Uart_getc( )
{
while(!SERIAL_CHAR_READY());
return URXH0;
}
设置Linux核心启动命令行
char *linux_cmd="noinitrd init=/init root=/dev/nfs nfsroot=172.16.68.25:/rootfs,tcp ip=172.16.68.24 console=ttySAC0";
nfs服务器设置
编辑/etc/export文件:
/home/arm_os/filesystem/rootfs 目标板ip(rw,sync)
/home/arm_os/filesystem/rootfs 主机ip(rw,sync)
启动nfs服务器:
/etc/init.d/nfs-kernel-server restart
测试nfs服务器:
mount 主机ip:/home/arm_os/filesystem/rootfs /mnt
•试验二:linux kernel (gcc、make)
1、熟悉基本的linux命令
文件操作、文件编辑
串口工具、程序开发
2、配置linux核心
make menuconfig
3、交叉编译linux核心
make zImage
主要工作
•熟悉基本的linux命令
•配置linux核心
•交叉编译linux核心
•调试自己编译的核心
•挂载nfs上的root(根目录)
•编写一个小程序在目标板上运行
主要步骤:
•用root用户登录ubuntu (合理使用权限);
•解压缩源码包到/home/下;
•察看解压缩后的/home/arm_os目录:Linux核心、编译器、root等;
•配置并测试nfs;
•配置cutecom:115200,XModem,No line end;
•配置核心:make menuconfig;
•编译核心:make;
•下载并运行核心,加载root文件系统;
•重新设置cutecom为LF line end;
•熟悉基本的Linux命令;
•编写一个小程序在目标板上运行,察看结果。
•试验三:linux driver (uart)
1、Linux驱动编程
•基本接口
•常用函数
2、串口驱动
•申请中断处理
•串口数据读、写
主要工作:
•编写串口驱动初始化、释放函数;
•编写串口驱动接收数据函数;
•编写串口驱动发送数据函数;
•编写串口驱动中断处理函数;
•编写串口访问应用程序;
•使用模块方式编译驱动;
•使用模块方式调试驱动;
•实现基本的串口数据收发。
主要步骤:
•填写函数:uart_init、uart_exit、uart_open、uart_ release,实现串口设备初始化、释放、打开、关闭;
•填写函数: irq_rev_uart、uart_write、uart_read,实现串口设备中断处理、读、写;
•用模块方式编译Linux核心,生成uart.ko,启动目标板Linux核心,用insmod、rmmod等命令操作模块;
•用printk打印调试串口驱动,包括中断相应,读写等;
•编写应用程序:uart.c,实现打开串口设备、读写等,把主机端由comcute发过来的串口数据回传给主机;
•将目标板上串口线连到串口1;
•编译应用程序uart.c,实现和主机间的串口通讯。
部分代码:
串口设备初始化函数
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");
串口设备中断处理函数
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<size; i++){
while(!(__raw_readl(uart + S3C2410_UTRSTAT) & 0x4));
__raw_writel(*(wmem + i), uart + S3C2410_UTXH);
}
return size;
串口访问应用程序
#include <stdio.h>
#include <fcntl.h>
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;
}
•试验四:linux driver (touchscreen)
1、触摸屏驱动
•初始化
•坐标值
2、触摸屏、图形系统协调工作
•触摸屏校准
•拨号键盘
LCD初始化
初始化GPIO(通用输入/输出):
rGPCUP=0xffffffff;
rGPCCON=0xaaaaaaaa;
rGPDUP=0xffffffff;
rGPDCON=0xaaaaaaaa;
该步骤主要配置CPU引脚的输入输出方向和工作模式
初始化LCD控制寄存器:
rLCDCON1=0x00000178; //配置成为16位颜色,TFT(真彩)模式;
rLCDCON2= 0x2077c241; //行数为480;
rLCDCON3=0x017A7F0F; //行宽为640;
设置 LCD在内存中的起始地址:
rLCDADDR1=0x1904b000; //FrameBuffer的首地址;
rLCDADDR2=0x00096000; // FrameBuffer的尾地址;
rLCDADDR3= 0x00000300; //虚屏行宽为640;
rLCDCON1 += 1; //使能LCD,开始显示;
Linux framebuffer设备操作
fb_fd = open("/dev/fb0", O_RDWR);
if(fb_fd < 0){
printf("Open fb device error!\n");
return -1;
}
LCD_MEM_BASE = mmap(NULL,
SCREEN_WIDTH*SCREEN_HEIGHT*2, PROT_READ|PROT_WRITE,
MAP_SHARED, fb_fd, 0);
memset(LCD_MEM_BASE, 0,
SCREEN_WIDTH*SCREEN_HEIGHT*2);
画像素函数
void drawpixel(int x, int y, unsigned short color_mask)
{
unsigned int bits =
(SCREEN_WIDTH*y+x)*BITS_PER_PIXEL;
unsigned short *tmp;
tmp = (unsigned short *)LCD_MEM_BASE+bits/16;
//计算像素在内存中的地址;
*tmp = color_mask; //给象素填充颜色;
return ;
}
画线函数
void drawline(int x, int y, int length,
int flag, unsigned short color_mask)
{
int i;
if (flag==0)//画横线;
for (i=0;i<length;i++)
drawpixel(x+i,y,color_mask);
if (flag==1)//画竖线;
???
}
画字符函数
void draw_char
(int x,int y, //字符在屏幕上的坐标
unsigned char c, //字符值
unsigned short color_mask) //字符的颜色
主要工作:
•编写触摸屏驱动初始化、释放函数;
•编写触摸屏驱动读取数据函数;
•编写触摸屏驱动中断处理函数;
•使用模块方式调试驱动;
•编写触摸屏读取应用程序;
•编写简单图形系统绘制应用程序,绘制一个数字键盘;
•实现基本的触摸键盘程序。
主要步骤:
•填写函数:ts_init、ts_exit、ts_open、ts_ release,实现触摸屏设备初始化、释放、打开、关闭;
•填写函数:ts_isr、ts_read,实现触摸屏读、中断处理
•用模块方式编译Linux核心,生成ts_ads7843.ko,启动目标板Linux核心,用insmod、rmmod等操作模块;
•用printk打印调试触摸屏驱动,包括中断相应,读等;
•编写应用程序:ts_ads7843.c,实现打开触摸屏设备、读等;
•在ts_ads7843.c 中增加简单图形系统绘制函数,绘制数字键盘,对触摸屏设备数据进行校正,实现触摸键盘的功能。
部分代码:
触摸屏设备初始化函数
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");
触摸屏设备中断处理函数
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;
触摸屏访问应用程序
#include <stdio.h>
#include <fcntl.h>
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;
}
•试验五:GPRS综合试验 (framebuffer)
•试验六:GPRS综合试验
1、GPRS模块控制试验
•串口控制GPRS模块
•AT命令集
2、综合试验
•电话拨号
•短消息发送
串口2初始化
寄存器定义:
#define OSULCON2 (*(volatile unsigned char *)0x50008000)
#define OSUCON2 (*(volatile unsigned char *)0x50008004)
#define OSUFCON2 (*(volatile unsigned char *)0x50008008)
#define OSUMCON2 (*(volatile unsigned char *)0x5000800C)
#define OSUBRDIV2 (*(volatile unsigned short *)0x50008028)
初始化:
OSULCON0=0x03; //设置串口数据长度、停止位、奇偶校验
OSUCON0=0x85; //设置串口时钟频率、中断类型等
OSUFCON0=0x01; //设置串口FIFO工作模式
OSUMCON0=0x00; //设置流量控制等
OSUBRDIV0=0x149; //设置串口波特率为9600bps
AT命令集
1 、查询无线模块状态:
发送:AT<CR>,应答:OK
2、主叫电话:
•发送ATD+Dial电话号码<CR>;应答:如连接不成功:NO CARRIER
•举例:发送“atd13476048972\r”即主叫该号码;
3、接电话:
•发送:ATA<CR>,连接成功:OK,否则:NO CARRIER
4、挂断电话:
发送:ATH <CR> ,应答:OK
5、发短消息:
•发送AT+CMGF=1 <CR>,设置短信为文本模式,应答:OK.
•或发送AT+CMGF=0 <CR>,设置短信为PDU模式, 应答:OK.
•发送AT+CMGS=电话号码<CR>短信内容<CTRL+Z>
•举例:(1)发送“at+cmgf=1\r”,设为文本模式;
(2) 发送“at+cmgs=13476048972\r”.
(3) 发送短信内容:“hello…”内容以ctrl+z结束(发送字符码26,表示结束).
上述例子表示向134….发送短消息,内容为:hello…
注意:发送AT命令给无线模块时,中间应有一定的时间延时。
主程序:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <linux/fb.h>
#include <linux/kd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <linux/vt.h>
#include <assert.h>
#include "lcd.h"
#define BITS_PER_PIXEL 16
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define CHAR_WIDTH 16
#define CHAR_HEIGHT 14
#define LINE_WIDTH
#define LINE_HEIGHT CHAR_HEIGHT*2+4
#define WHITE_COLOR 0xffff
#define BLUE_COLOR 0x7bf
#define GREEN_COLOR 0x7e0
#define RED_COLOR 0xf800
#define OFFSET_X 120
#define OFFSET_Y 80
int Xmin = 318, Xmax = 3381, Ymin = 420, Ymax = 3600;
int start_x[] = {80,81,126,248,366,480};
int start_y[] = {80,81,92,172,252,332,344};
unsigned short *LCD_MEM_BASE;
int fb_fd, ts_fd, uart_fd;
int x,y;
static int cur_x = 0;
static int cur_y = 0;
static struct ts_ret {
unsigned int pressure;
unsigned int x;
unsigned int y;
} ts_ret;
static struct phonenum {
char buffer[100];
unsigned int tail;
} phonenum;
static void drawpixel(int x, int y, unsigned short color_mask)
{
unsigned int bits;
unsigned short *tmp;
if((x>=SCREEN_WIDTH)||(y>=SCREEN_HEIGHT)) return;
bits = (SCREEN_WIDTH*y+x)*BITS_PER_PIXEL;
tmp = LCD_MEM_BASE + bits/16;
*tmp = color_mask;
return;
}
void drawline(int x, int y, int length, int flag, unsigned short color_mask)
{
int i;
if (flag)
for (i=0;i<length;i++)
drawpixel(x+i,y,color_mask);
else
for (i=0;i<length;i++)
drawpixel(x,y+i,color_mask);
}
void draw_char(int x, int y, unsigned char c, unsigned short color_mask)
{
int i, j, t;
unsigned short *p = helvB12_bits + (c - 0x20)*14;
for (i=0; i<CHAR_HEIGHT; i++)
{
unsigned short tmp = p[i];
for (j=0; j<CHAR_WIDTH; j++)
{
if (tmp & 0x8000)
{
for (t=0; t<4; t++)
{
drawpixel(x+j*4+t, y+i*4, color_mask);
drawpixel(x+j*4+t, y+i*4+1, color_mask);
drawpixel(x+j*4+t, y+i*4+2, color_mask);
drawpixel(x+j*4+t, y+i*4+3, color_mask);
}
}
tmp = tmp << 1;
}
}
}
void draw_keyboard(void)
{
int i;
for (i=0;i<5;i++)
{
drawline(start_x[0],start_y[0]+i*OFFSET_Y,SCREEN_HEIGHT,1,WHITE_COLOR);
drawline(start_x[0],start_y[1]+i*OFFSET_Y,SCREEN_HEIGHT,1,WHITE_COLOR);
}
for (i=0;i<5;i++)
{
drawline(start_x[0]+i*OFFSET_X,start_y[0],SCREEN_WIDTH/2,0,WHITE_COLOR);
drawline(start_x[1]+i*OFFSET_X,start_y[0],SCREEN_WIDTH/2,0,WHITE_COLOR);
}
for (i=0;i<3;i++)
{
draw_char(start_x[2]+i*OFFSET_X,start_y[2],'1'+i,BLUE_COLOR);
draw_char(start_x[2]+i*OFFSET_X,start_y[3],'4'+i,BLUE_COLOR);
draw_char(start_x[2]+i*OFFSET_X,start_y[4],'7'+i,BLUE_COLOR);
}
draw_char(start_x[2],start_y[5],'0',BLUE_COLOR);
draw_char(start_x[3],start_y[6],'*',BLUE_COLOR);
draw_char(start_x[4],start_y[5],'#',BLUE_COLOR);
draw_char(start_x[5],start_y[2],'%', GREEN_COLOR);
draw_char(start_x[5],start_y[3],'&',RED_COLOR);
draw_char(start_x[5],start_y[4],'$',WHITE_COLOR);
draw_char(start_x[5],start_y[5],'(',RED_COLOR);
}
void draw_stringline(char *s, unsigned short color_mask)
{
unsigned char *tmp = (unsigned char *)s;
while (*tmp)
{
draw_charline(*tmp,color_mask);
tmp ++;
}
}
void draw_charline(unsigned char c, unsigned short color_mask)
{
int i,k,n,x,y;
unsigned long offset,*tmpnew;
unsigned short *p = helvB12_bits+(c-0x20)*14;
offset = SCREEN_WIDTH*(LINE_HEIGHT)*BITS_PER_PIXEL/32;
n = SCREEN_WIDTH*(SCREEN_HEIGHT-LINE_HEIGHT-6)*BITS_PER_PIXEL/32;
tmpnew = (unsigned long *)LCD_MEM_BASE;
for (i=0;i<n;i++) tmpnew++;
if (c == '\n' || c == '\r')
{
cur_x = 0;
cur_y += LINE_HEIGHT;
return;
}
else
{
if (cur_y>=SCREEN_HEIGHT-6)
{
for (i=n;i<n+offset;i++)
*tmpnew++=0x1f001f;
cur_x = 0;
cur_y = SCREEN_HEIGHT-LINE_HEIGHT-6;
}
x=cur_x;y=cur_y;
for (i=0;i<CHAR_HEIGHT;i++)
{
unsigned short tmp = p[i];
for (k=0;k<CHAR_WIDTH;k++)
{
if (tmp & 0x8000)
{
drawpixel(x+k,y+i*2,color_mask);
drawpixel(x+k,y+i*2+1,color_mask);
}
tmp = tmp << 1;
}
}
cur_x += helvB12_width[c-0x20] + 1;
return;
}
}
char getkey(int x, int y)
{
char key;
char addr[4][4] = {{'0','7','4','1'},
{'*','8','5','2'},
{'#','9','6','3'},
{'S',' ','H','C'}};
x = (x - 80) / 120;
y = (y - 80) / 80;
if(x < 0) x = 0;
if(x > 3) x = 3;
if(y < 0) y = 0;
if(y > 3) y = 3;
key = addr[x][y];
draw_charline(key, RED_COLOR);
return key;
}
char dialing(void)
{
char key, ctl, cr;
ctl = 26;
cr = 13;
key = getkey(x, y);
printf("key = %c\n", key);
if(key!='S' & key!='H' & key!='C' & key!=' ')
phonenum.buffer[phonenum.tail++] = key;
if(key == 'C')
{
write(uart_fd, "atd", strlen("atd"));
usleep(1000);
write(uart_fd, phonenum.buffer, phonenum.tail);
usleep(1000);
write(uart_fd, ";\r", strlen(";\r"));
phonenum.tail = 0;
}
else if(key == 'S')
{
write(uart_fd, "at\r", strlen("at\r"));
usleep(1000);
write(uart_fd, "at\r", strlen("at\r"));
usleep(1000);
write(uart_fd, "at+cmgf=1\r", strlen("at+cmgf=1\r"));
usleep(1000);
write(uart_fd, "at+cmgs=", strlen("at+cmgs="));
usleep(1000);
write(uart_fd, phonenum.buffer, phonenum.tail);
usleep(1000);
write(uart_fd, &cr, 1);
usleep(1000);
write(uart_fd, "hello!", strlen("hello!"));
usleep(1000);
write(uart_fd, &ctl, 1);
phonenum.tail = 0;
}
else if(key == 'H')
{
write(uart_fd,"ath\r", strlen("ath\r"));
printf("Open fb device error!\n");
phonenum.tail = 0;
}
else if(key == ' ')
{
if(phonenum.tail > 0)
phonenum.tail--;
}
}
int main()
{
fb_fd = open("/dev/fb0", O_RDWR);
if(fb_fd < 0)
{
printf("Open fb device error!\n");
return -1;
}
ts_fd = open("/dev/ts_ads7843", O_RDWR);
if(ts_fd < 0)
{
printf("Open ts device error!\n");
return -1;
}
uart_fd = open("/dev/uart", O_RDWR);
if(uart_fd < 0)
{
printf("Open uart device error!\n");
return -1;
}
LCD_MEM_BASE = mmap(NULL, SCREEN_WIDTH*SCREEN_HEIGHT*2,
PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0);
memset(LCD_MEM_BASE, 0, SCREEN_WIDTH*SCREEN_HEIGHT*2);
phonenum.tail = 0;
draw_keyboard();
for(;;)
{
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);
dialing();
}
}
close(fb_fd);
close(ts_fd);
close(uart_fd);
return 0;
}
实验体会
通过这次实验,我对嵌入式有了实质性的认识,也有了一定的实践经验。实验的课时是很多的,通过这六次实验,我感受到使用linux嵌入式系统的乐趣,对此有了一定的理解。
美中不足的是,每次实验都是按老师说的一步一步做,没有对实验原理深刻的理解,没有时间思考实验原理,每次都是按部就班的做。如果说什么建议,我希望以后这课实验的时候之前多一点时间给我们准备思考,深刻想一想实验之中的道理和问题。
通过这实验,我相信大家都会多多少少有些收获,更深刻的了解了嵌入式,了解它的实验平台,最后出成果时,看到这么一台机子就能简单模拟手机来发送短信和打电话,还是触摸屏的心里还是异常欣喜的。