福建工程学院
《嵌入式系统》课程设计
报告书
题目: 基于S3C2440设备驱动及其界面设计
班级:
姓名:
学号:
指导老师: 陈靖,张平均,李光炀
目 录
一、设计课题... 3
二、设计目的... 3
三、设计任务及要求... 3
四、设计内容... 4
五、操作界面的生成... 6
六、操作界面调试... 8
七、设计总结... 9
八、设计参考书... 10
九、附件(程序)... 11
基于S3C2440的设备驱动及其界面设计
1.进一步巩固嵌入式系统的基本知识;
2.掌握嵌入式应用系统的基本结构;
3.掌握嵌入式系统开发环境建立和使用;
4.掌握嵌入式系统基本驱动、应用程序的设计调试和编译移植方法;
5.学会查阅有关专业资料及设计手册;
6.MiniGUI界面编程。
1.掌握嵌入式系统开发环境建立和使用;
2.掌握嵌入式系统基本驱动、应用程序的设计调试和编译移植方法;
3、MiniGUI在PC上的安装、移植
4、Linux基本输入输出驱动程序设计编译与移植
5、基于MiniGUI的基本输入输出应用编程编译与移植
6、编写设计说明书(方案的确定、设计环节的考虑及必要说明等)及设备的使用说明;
7、绘制有关图纸.
1、 基础知识准备
1)讲解设计任务;
2)熟悉ubuntu的使用;
3)熟悉TQ2440试验系统的使用;
4)掌握嵌入式系统开发环境建立和使用;
5)掌握嵌入式系统基本驱动、应用程序的设计调试和编译移植方法.
2、界面设计环境构建:MiniGUI在PC上的安装、移植
2.1、MiniGUI在pc机上安装和运行
建立工作目录:mkdir /minigui-free
cd /minigui-free
mkdir /src
复制源文件包到工作目录:cp /mnt/hgfs/D/src/*
/minigui-free
解压文件到/minigui-free:
tar zxvf libminigui-1.6.10.tar.gz
tar zxvf minigui-res-1.6.10.tar.gz
tar zxvf mg-samples-1.6.10.tar.gz
2.2、MiniGUI库安装
(2)将libcross.sh考到minigui的lib库的解压文件夹中
(3)将rescross.sh 考到minigui的res资源解压文件夹中
(4)将samplecorss.sh 考到sample例子解压文件夹中
(5)依次运行libcross.sh,rescross.sh,samplecorss.sh
(6)到nfsroot的,目录下,将libreduce.sh考到这个目录下,运行libreduce.sh
2.3、安装qvfb
(1)解压qvfb1.1.tar.gz
(2)./configure
(3)make
(4)make install
2.4、配置MiniGUI.cfg
vi /etc/MiniGUI.cfg 修改如下部分为
[system]
# GAL engine and default options
gal_engine=fbcon
defaultmode=800x480-16bpp
# IAL engine
ial_engine=fbcon
mdev=/dev/mouse
mtype=IMPS2
[fbcon]
defaultmode=800x480-16bpp
[qvfb]
defaultmode=800x480-16bpp
display=0
1.5运行MiniGUI例子程序
(1)打开qvfb:qvfb &
(2)运行helloword:
1、操作界面面执行文件的生成
1).在/minigui-free/mg-samples-1.6.10/src/修改源文件treeview.c
2).再次运行samplecorss.sh,生成执行文件treeview
2、利用nfs进行挂载
1).将本地PC机的网络方式设置成为桥接
2).查看/etc/exports下可以挂载的目录
3).启动服务/etc/init.d/nfs-kernel-server restart
4).查看本机和ARM上的IP地址,设置在同一网段,然后ping,使其能够互通。
5).在超级终端上,进行操作
Mount -o nolock,rsize=1024,wsize=1024 本机IP:/ /mnt
将虚拟机和ARM进行挂载,可以查看到虚拟机根目录下的文件。
3、在超级终端上将需要的文件从虚拟机上复制到ARM机上
1).重新烧写文件系统镜像文件
2).挂载成功后,将/mnt/minigui-free/nfsroot/lib/*复制到/usr/lib/
3).将/mnt/minigui-free/nfsroot/usr/local/lib/*复制到/usr/local/lib/
4).将/mnt/etc/MiniGUI.cfg复制到/etc/
5).将/mnt/minigui-free/mg-samples-1.6.10/src/*复制到/usr/minigui/
4、在超级终端上运行执行文件
1).进入/usr/minigui/运行treeview文件
2).可以再操作界面上现实我们所设计的界面
1、点击LED1\LED2\LED3\LED4,分别控制四盏led灯的亮暗,调试界面如下:
2、输入频率值,点击START键控制四盏led灯闪烁,调试界面如下:
1、设计过程中遇到的问题
错误1:
InitGUI: Can not initialize colors of window element!
InitGUI failure when using /usr/local/etc/MiniGUI.cfg as cfg file.
解决方法:正确配置MiniGUI.cfg文件
错误2:
Permission denied
解决方法:权限不够,使用root用户登录。
错误3:
编译出错未找到jpeg,png等
解决方法:安装zlib,png,jpeg库。
错误4:
出现符号未找到等编译错误
解决方法:make clean 后在make
错误5:
在minigui创建和移植的过程中,出现lib库编译不成功的现象,这是由于minigui是基于qt3的,因此需要添加qt3所在路径至配置文件。
错误:6
在开发板上添加鼠标设备后,提示视频采集失败,这是因为/etc下的配置文件MiniGUI.cfg中对外设控制范围的控制过大,银将其修改为与界面统一大小800*480.
错误:7
在执行led灯控制程序之前应该首先停止开发板上原有的流水灯进程led-player。
错误:8
运行执行程序treeview后界面上出现两个光标,此时应该在/etc/init.d下的rcS文件中停用qt3的光标。
2、心得体会
本学期为期两周的嵌入式课程设计在不知不觉中结束了,虽说这次课程设计时间不是很长,但是感觉自己收获颇丰,不仅学习到了一些新知识,回顾了以前的一些快要遗忘的知识点,而且使自己的学习目标更加明确,学习方法更加完善,也体会到软件开发的趣味,更加清楚地认识到了自己在软件开发及学习上的一些不足之处。
两周的课程设计,在计算机这个博大深奥的领域我感觉自己还有好多东西要学,还有好多的东西不懂!嵌入式软件开发应用广泛而且前景很好,目前正处于人才紧缺的关口,嵌入式技术在未来能够得到更加广泛的应用。学好嵌入式,C语言很重要,所以感觉自己有必要在学习、积累一下这方面的知识。很多东西的学习不是一帆风顺也是比较耗时的,嵌入式也不例外,要想学好还必须下大力气,还必须坚持。这次的课程设计让我明确了一点:嵌入式开发对于提升我们的系统知识有很大的帮助,尤其是操作系统的知识。嵌入式系统开发对于我们的知识面要求非常的广,且要有一定的深度。这次的课程设计因为是一个有针对性的训练,所以记的会非常牢固。跟平时上课不太一样,平时上完理论课很少有时间上机进行时间或者隔几天才上机练习,等到上机时一些东西可能遗忘了,比较耗费时间。在课上,有老师在前面演示我们感觉看得懂或感觉没问题,可轮到我们独立完成的时候,因为实际操作的少,其中的问题就来了!我很感谢学校特别是学院老师有实训这样的安排,把我们这一学期学的东西系统的集中的进行训练,让我们深刻明确的体验了一下软件开发的流程!还要感谢给我们实训的楚老师,感觉楚老师能力很强,也很有耐心,即使老师讲了很多遍的问题,我们不会,老师还是会走进我们给我们耐心的指导,还给我们讲一些学习计算机的方法,一些软件开发需要注意的细节,让我们知道自己在哪方面不足,需要加强,也让我们了解到哪些需要认真的学习,那些是重点,不是没有方向的乱学一通,什么也学不好!经过这次的实训,我真真确确的感受到了计算机在我们生活中工作中的运用,这些软件、程序能让我们提高工作的效率,更直观更便捷的切入主题。当然,在学习的过程中并不是一帆风顺的,在这之中,因为要操作的东西很多,有时错一步,后面的结果就无法显示,而自己的计算机水平还有待提高,根本检查不出来是哪里出了错!这时候,老师都会耐心的过来帮助我!在平时我们就需要好好的查阅书籍或者上网搜集相关资料去解决问题。
短短两周的课程设计很快结束了,我发现我对计算机这个专业、对嵌入式技术、对Linux都有了新的认识。通过这次的实训,我了解到,要真真正正的掌握计算机程序还不是一件简单容易的事儿,但真正掌握后,它带给我们的将是无穷的便捷与科技,我喜欢高端便捷的生活。我希望我能做计算机这个万能机器人的主人而不是奴隶,我会努力加油的!感谢学校,感谢老师给我的帮助,让我的思想、技能又上了一个台阶!感谢!加油!
八、设计参考书
1、《嵌入式系统接口设计与Linux驱动程序开发》
2、《ARM9嵌入式LINUX系统构建与应用》
4、MiniGUI编程手册
5、Linux应用程序编程
九、附件(程序)
#include <stdio.h>
#include <minigui/common.h> /*包括 MiniGUI 常用的宏以及数据类型的定义*/
#include <minigui/minigui.h> /*包含了全局的和通用的接口函数以及某些杂项函数的定义*/
#include <minigui/gdi.h> /*包含了 MiniGUI 绘图函数的接口定义*/
#include <minigui/control.h> /*包含了 libminigui 中所有内建控件的接口定义*/
#include <string.h>
#include <stdlib.h>
#include <unistd.h> /*包含了许多UNIX系统服务的函数原型*/
#include <sys/ioctl.h> /*提供对I/O控制的函数*/
#define ID_LED1 101 /*定义各个控件与定时器的ID号*/
#define ID_LED2 102
#define ID_LED3 103
#define ID_LED4 104
#define ID_TEXT1 105
#define ID_TEXT2 106
#define ID_START 107
#define ID_STOP 108
#define ID_COMBOBOX 109
#define ID_TIMER 110
static int a,b,c,d=0; /*定义LED灯的初始值*/
static int fd_led; /*定义文件描述符*/
HWND hMainWnd; /*定义主窗口句柄*/
static void draw_circular(HWND hdig,int x,int y,int r,int which)
/*自定义一个画圆函数,x、y、r、which分别表示圆心坐标、半径、颜色*/
{
HDC hdc; /*定义设备上下文句柄*/
int color;
color=((which==0)?PIXEL_green:PIXEL_red);
hdc=BeginPaint(hdig); /*获得设备上下文句柄*/
SetBrushColor(hdc,color); /*设置画刷颜色*/
FillCircle(hdc,x,y,r); /*调用园填充函数*/
EndPaint(hdig,hdc); /*释放设备上下文句柄*/
}
static DLGTEMPLATE DlgInitProgress=
/*定义对话框模板. 用static类型数据,使该数据的定义只在所在文件中有效,以免因为名字空间污染造成潜在的编译或连接错误*/
{
WS_BORDER|WS_CAPTION,
/*对话框风格,WS_BORDER创建有边框的窗口 ,WS_CAPTION创建含标题栏的主窗口*/
WS_EX_NONE,
/*对话框扩展风格,WS_EX_NONE表示无扩展风格*/
0,0,800,480, /*对话框位置,左上角坐标(0,0),800、480分别为宽和高*/
"MY_LED_CONTROL", /*对话框标题*/
0, /*对话框图标*/
0, /*对话框菜单*/
9, /*对话框中控件个数。这个必须要匹配*/
NULL, /*pointer to control array*/
0 /*附加值*/
};
static CTRLDATA CtrlInitData[]= /*控件数组*/
{
{
"static", /*控件类型*/
WS_VISIBLE|SS_SIMPLE,
/*控件风格,WS_VISIBLE创建初始可见的窗口,SS_SIMPLE显示单行文本*/
100,270,150,40, /*控件位置*/
ID_TEXT1, /*控件ID*/
"Please input frequency", /*控件内容*/
0, /*附加值*/
WS_EX_NONE /*控件扩展风格*/
},
{
"static",
WS_VISIBLE|SS_SIMPLE,
605,270,150,40,
ID_TEXT2,
"HZ",
0,
WS_EX_NONE
},
{
"button",
WS_VISIBLE|WS_TABSTOP, /*WS_TABSTOP支持Tab键*/
135,160,80,60,
ID_LED1,
"LED1",
0,
WS_EX_NONE
},
{
"button",
WS_VISIBLE|WS_TABSTOP,
285,160,80,60,
ID_LED2,
"LED2",
0,
WS_EX_NONE
},
{
"button",
WS_VISIBLE|WS_TABSTOP,
435,160,80,60,
ID_LED3,
"LED3",
0,
WS_EX_NONE
},
{
"button",
WS_VISIBLE|WS_TABSTOP,
585,160,80,60,
ID_LED4,
"LED4",
0,
WS_EX_NONE
},
{
"button",
WS_VISIBLE|WS_TABSTOP,
285,360,80,60,
ID_START,
"START",
0,
WS_EX_NONE
},
{
"button",
WS_VISIBLE|WS_TABSTOP,
435,360,80,60,
ID_STOP,
"STOP",
0,
WS_EX_NONE
},
{
CTRL_COMBOBOX,
WS_VISIBLE|WS_TABSTOP|CBS_AUTOSPIN|CBS_AUTOLOOP, /*CBS_AUTOSPIN创建旋钮数字框,CBS_AUTOLOOP框中的数字将自动循 环显示*/
435,270,80,40,
ID_COMBOBOX,
"0", /*旋钮数字框初始值*/
0,
WS_EX_NONE
}
};
static int DialogBoxProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
/*对话框过程函数,用来接收和处理所有发送到该窗口的消息*/
{
int number; /*用来存从旋钮数字框获得的数值*/
static int t=0;
int num; /*存放定时时间*/
switch(message)
{
case MSG_INITDIALOG:
/*用户在定义自己的对话框回调函数时,需要处理 MSG_INITDIALOG消息,该消息是在 MiniGUI根据对话框模板建立对话框以及 控件之后 ,发送到对话框回调函数的 。*/
SendDlgItemMessage(hWnd, ID_COMBOBOX, CB_SETSPINRANGE, 0, 10000); /*设置旋钮数字框的最大小值*/
return 1;
case MSG_PAINT:/*重绘消息*/
draw_circular(hWnd,175,90,30,1);
draw_circular(hWnd,325,90,30,1);
draw_circular(hWnd,475,90,30,1);
draw_circular(hWnd,625,90,30,1);
printf("*************************init draw_circular******************************\n");
case MSG_TIMER:t++; /*定时器消息,这里完成LED灯的闪烁*/
if(t%2!=0)
{
ioctl(fd_led, 0,0);
ioctl(fd_led, 0, 1);
ioctl(fd_led, 0, 2);
ioctl(fd_led, 0, 3);
printf("*************************time red******************************\n");
draw_circular(hWnd,175,90,30,1);
draw_circular(hWnd,325,90,30,1);
draw_circular(hWnd,475,90,30,1);
draw_circular(hWnd,625,90,30,1);
break;
}
else
{
ioctl(fd_led, 1,0);
ioctl(fd_led, 1, 1);
ioctl(fd_led, 1, 2);
ioctl(fd_led, 1, 3);
printf("*************************time green******************************\n");
draw_circular(hWnd,175,90,30,0);
draw_circular(hWnd,325,90,30,0);
draw_circular(hWnd,475,90,30,0);
draw_circular(hWnd,625,90,30,0);
break;
}
case MSG_COMMAND: /*击键消息*/
switch (wParam)
{
case ID_LED1:a++; /*控制LED灯亮暗*/
if(a%2!=0)
{
ioctl(fd_led,0,0);
draw_circular(hWnd,175,90,30,1);
}
else
{
/ ioctl(fd_led,1,0);
draw_circular(hWnd,175,90,30,0);
}
printf("******************led1********************************\n");
break;
case ID_LED2:b++;
if(b%2!=0)
{
ioctl(fd_led,0,1);
draw_circular(hWnd,325,90,30,1);
}
else
{
ioctl(fd_led,1,1);
draw_circular(hWnd,325,90,30,0);
}
printf("*******************led2********************************\n");
break;
case ID_LED3:c++;
if(c%2!=0)
{
ioctl(fd_led,0,2);
draw_circular(hWnd,475,90,30,1);
}
else
{
ioctl(fd_led,1,2);
draw_circular(hWnd,475,90,30,0);
}
printf("*******************led3********************************\n");
break;
case ID_LED4:d++;
if(d%2!=0)
{
ioctl(fd_led,0,3);
draw_circular(hWnd,625,90,30,1);
printf("*******************led33********************************\n");
}
else
{
ioctl(fd_led,1,3);
draw_circular(hWnd,625,90,30,0 );
}
printf("*******************led4********************************\n");
break;
case ID_START:printf("*******************start1*********************\n");
number=SendMessage(GetDlgItem(hWnd,ID_COMBOBOX), CB_GETSPINVALUE, 0, 0);/*获取旋钮数字框的数值*/
printf("**********%d*******************\n",number);
printf("*******************start2*********************\n");
if(number!=0)
{
printf("*******************start3*********************\n");
num=(int)(1000*(1.0/number)); /*将频率转换为时间*/
printf("*******************start4*********************\n");
}
else
{
printf("*******************start5*********************\n");
num=1000;
}
printf("*******************start6*********************\n");
printf("*******************start7*********************\n");
printf("*******************start8*********************\n");
SetTimer(hWnd,ID_TIMER,num); /*创建定时器,时间为num*10ms*/
printf("*************************SetTimer OK******************************\n");
SendMessage(hWnd,BM_CLICK,0,0); /*发送点击信息*/
printf("*************************SendMessage OK******************************\n");
//for(i=0;i++;i<10000) /*当初用for循环时无法进入循环,也许是因为消息本身有循环机制,用for循环太多也许冲突,所以后来用了定时器*/
//{
// printf("********%d**********\n,i");
// ioctl(fd_led, 1,0);
// ioctl(fd_led, 1, 1);
// ioctl(fd_led, 1, 2);
// ioctl(fd_led, 1, 3);
// draw_circular(hWnd,175,90,30,0);
// draw_circular(hWnd,325,90,30,0);
// draw_circular(hWnd,475,90,30,0);
// draw_circular(hWnd,625,90,30,0);
printf("*******************start9*********************\n");
// usleep(number);
//usleep(num);
// ioctl(fd_led, 0,0);
// ioctl(fd_led, 0, 1);
// ioctl(fd_led,0, 2);
// ioctl(fd_led, 0, 3);
// draw_circular(hWnd,175,90,30,1);
// draw_circular(hWnd,325,90,30,1);
// draw_circular(hWnd,475,90,30,1);
// draw_circular(hWnd,625,90,30,1);
// printf("*******************start10*********************\n");
//usleep(number);
//usleep(num);
// }
printf("*******************start********************************\n");
break;
case ID_STOP:
KillTimer(hWnd,ID_TIMER);/*关闭定时器。下面的表示灯灭*/
ioctl(fd_led, 0,0);
ioctl(fd_led, 0, 1);
ioctl(fd_led, 0, 2);
ioctl(fd_led, 0, 3);
draw_circular(hWnd,175,90,30,1);
draw_circular(hWnd,325,90,30,1);
draw_circular(hWnd,475,90,30,1);
draw_circular(hWnd,625,90,30,1);
printf("**************stop******************\n");
break;
}
}
return(DefaultDialogProc(hWnd,message,wParam,lParam));
/*对话框的缺省消息处理由 DefaultDialogProc 函数完成*/
}
static void InitDialogBox(HWND hWnd)
{
DlgInitProgress.controls=CtrlInitData;
/*将对话框模板结构和控件结构数组关联起来*/
DialogBoxIndirectParam(&DlgInitProgress,hWnd,DialogBoxProc,0L);/*创建对话框*/
printf("*************create dialog**********************\n");
}
/*****************************************************************
主窗口的过程函数
static int LedWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
switch (message)
{
case MSG_PAINT:
hdc = BeginPaint (hWnd);
TextOut (hdc, 60, 60, "My leds control!");
EndPaint (hWnd, hdc);
return 0;
case MSG_CLOSE:
DestroyMainWindow (hWnd);
PostQuitMessage (hWnd);
return 0;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
*********************************************************************/
int MiniGUIMain (int argc, const char* argv[])
{
// MSG Msg;
// MAINWINCREATE CreateInfo; /*描述主窗口的属性*/
#ifdef _MGRM_PROCESSES
JoinLayer(NAME_DEF_LAYER , "led" , 0 , 0); /*选择PROCESSES模式*/
#endif
printf("****************into main*********************\n");
fd_led=open("/dev/GPIO-Control",0); /*打开驱动设备*/
if (fd_led < 0)
{
perror("open device led");
exit(1);
}
ioctl(fd_led, 0, 0); /*初始灯灭*/
ioctl(fd_led, 0, 1);
ioctl(fd_led, 0, 2);
ioctl(fd_led, 0, 3);
InitDialogBox( HWND_DESKTOP);
close(fd_led);
/***********************************************************
CreateInfo.dwStyle = WS_VISIBLE | WS_BORDER | WS_CAPTION; /窗口风格/
CreateInfo.dwExStyle=WS_EX_NONE; /窗口扩展风格/
CreateInfo.spCaption="MY_LED_CONTROL_WIN"; /窗口标题/
CreateInfo.hMenu=0; /菜单/
CreateInfo.hCursor= GetSystemCursor(0); /光标/
CreateInfo.hIcon=0; /图标/
CreateInfo.MainWindowProc=LedWinProc; /设置主窗口的窗口函数,所用发往该窗口的消息由该函数处理/
CreateInfo.lx=0; /窗口位置/
CreateInfo.ty = 0;
CreateInfo.rx = 240;
CreateInfo.by = 180;
CreateInfo.iBkColor=COLOR_lightwhite; /设置背景颜色/
CreateInfo.dwAddData=0; /附加数值/
CreateInfo.hHosting=HWND_DESKTOP; /设置窗口的托管窗口为桌面窗口/
hMainWnd = CreateMainWindow (&CreateInfo); /创建主窗口,返回创建窗口的句柄/
if (hMainWnd == HWND_INVALID)
return -1;
ShowWindow(hMainWnd,SW_SHOWNORMAL); /显示窗口的显示方式/
while(GetMessage(&Msg, hMainWnd)) /获取主窗口的句柄,指向MSG结构指针/
{
TranslateMessage(&Msg); /将击键消息转换为MSG_CHAR消息,然后直接发送到窗口的过程函数/
DispatchMessage(&Msg);
/获取消息的目标窗口的窗口过程,然后直接调用 该窗口过程函数对消息进行处理/
}
MainWindowThreadCleanup (hMainWnd); /清除主窗口所使用消息队列的系统资源/
*****************************************************************************/
return 0;
}
#ifndef _MGRM_PROCESSES
#include <minigui/dti.c>
#endif
福建工程学院嵌入式系统课程设计报告书题目基于S3C2440设备驱动及其界面设计班级姓名学号指导老师陈靖张平均李光炀2目录一设计课题…
福州大学课程设计任务书课程嵌入式课程设计题目姓名李仁煌学号011000610系别电机电器专业电气工程与自动化年级20xx起讫日期2…
嵌入式系统课程设计报告基于ARM的楼宇对讲系统设计摘要采用模块化设计方法设计出一款基于ARM微控制芯片和Linux操作系统的楼宇对…
嵌入式系统开发课程设计专周报告题目:具有日历功能的电子时钟系别及专业:计算机工程系计算机应用技术班级:10511学生姓名:XXX指…
课程设计综合实验报告20xx20xx年度第1学期名称题目院系班级学号学生姓名指导教师设计周数成绩日期年月日一课程设计的目的与要求1…
湖南科技大学计算机科学与工程学院嵌入式系统设计与开发实验报告书题目远程温光数据监测系统班级12级计算机一班姓名刘政材学号120xx…
课程设计报告基于ARM的嵌入式电子点菜系统班学姓级号名09061320xx061316叶尔多斯海拉提20xx年10月1题目基于AR…
中南大学嵌入式系统实验设计报告指导老师吴志虎李志民设计者连金涛专业班级测控0801班学号0909081012时间20xx年6月1实…
XXXX课程设计报告课程名称嵌入式系统设计题目专业班级学生姓名学生学号指导老师二一三年一月八日目录1概述111背景112设计目标2…
课程设计说明书20xx20xx学年第2学期目录1课程设计内容32课程设计目的33背景知识34工具准备工作45设计步骤与方法4515…
嵌入式系统课程设计报告基于ARM的楼宇对讲系统设计摘要采用模块化设计方法设计出一款基于ARM微控制芯片和Linux操作系统的楼宇对…