嵌入式操作系统课程设计报告

cdrs

嵌入式系统设计报告

院):         计算机科学学院          

专业班级:           计科11201            

    名:            微   尘              

   号:           201203300           

指导教师:              王剑                 

设计时间:        2015.6.22 - 2015.7.3        

设计地点:           4教硬件实验室        


目录

一、         课程设计的目的... 2

1.1        设计目的... 2

1.2        任务介绍... 2

二、         实验及开发环境... 3

2.1 实验室环境... 3

2.2 个人计算机课后开发环境... 3

三、         总体设计... 3

四、         详细设计... 4

4.1 Windows CE系统编译与安装... 4

4.2 编程驱动LED和数码管显示正确的信息... 7

4.3 编程驱动电机运转... 8

4.4 个人设计小程序... 10

五、课程设计小结... 17

5.1 设计小结... 17


一、课程设计的目的

1.1   设计目的

本次课程设计的目的是了解嵌入式系统、嵌入式操作系统,掌握基于嵌入式系统的应用开发基本知识。了解嵌入式操作系统Windows CE的特点,Windows CE的主要模块及各自的功能。掌握嵌入式操作系统Windows CE的配置、编译、移植方法。了解Visual Studio .NET开发环境,掌握基于Windows CE平台的应用程序设计方法。

1.2   任务介绍

以下任务需基于实验室的XSBase270开发平台完成

1.      嵌入式操作系统Windows CE平台的搭建

使用Platform Builder编译出自己的Windows CE 5.0操作系统,然后根据实验提供的EBOOT引导程序将编译出的Windows CE 5.0系统安装(刷入)到实验平台。

2.      IO接口控制-七段数码管的LED显示控制程序

了解Windows CE下I/O访问机制的原理。了解LED和七段数码管的显示和控制原理。掌握Windows CE下访问硬件I/O寄存器的方法。

3.      IO接口控制-点击控制设计

了解Window CE下I/O访问机制和原理。掌握Windows CE下访问硬件I/O寄存器的方法,以及使用Visual Studio .NET对硬件设备编程的一般方法。

4.      编写实用小程序并在指定的Windows CE平台上运行调试(选做)

这一部分我选择的是在Windows CE平台上使用Visual Studio 2005基于.NET利用C#语言编写一个简易计算器小程序。从而体验对嵌入式设备编程与普通PC编程的区别。


二、实验及开发环境

2.1 实验室环境

       硬件环境:

              PC机:X86构架Pentium D处理器、1G内存

              开发板: XSBase270开发平台、ARM处理器、PXA270

       软件环境:

              PC机:Windows XP SP3、Visual Studio 20## SP1、

Platform Builder 6.0 for Windows CE 5.0、jflashmm

2.2 个人计算机课后开发环境

软件环境:Windows 8.1、Visual Studio 20## + SP1 Package、Windows CE SDK、

             Windows CE SDK .NET 、DevEmulator for Windows CE 5.0

由于个人开发环境缺乏外部硬件支持,所以采用模拟器仿真环境。

三、总体设计

本次课程设计的第一个任务也是后续设计的前提条件,第一个任务要求在实验平台上安装Windows CE 5.0嵌入式操作系统,大致步骤如下,首先像平时做实验一样将EBOOT引导程序EBOOT.nb0烧录到实验平台,此时PC机端使用“终端”工具与装有EBOOT的实验平台进行通讯,然后在终端上控制实验平台设置其网络环境,使得实验平台与PC机能够联网;然后,使用Platform Builder编译出指定的Windows CE 5.0系统镜像nk.bin文件,并且通过连通的网络将nk.bin下载到实验平台;重启实验平台,正常加载Windows CE操作系统,则第一步正常完成。第二步,编写I/O接口控制的程序用来控制LED和七段数码管正常显示,编译成功并且下载到目标机(实验平台)成功正确运行则完成第二步。第三步,编写I/O接口控制的程序用来控制实验平台上的两个电机正常运转,编译成功并且下载到目标机(实验平台)成功正确运行则完成第三步。

最后一步,自己编写一个小程序在目标机上成功运行或者是使用自己以前编写的程序移植到目标机上成功运行,则完成任务。


四、详细设计

4.1 Windows CE系统编译与安装

       本次课设所用到的Windows CE 5.0操作系统是一中嵌入式操作系统,该系统是由微软提供的闭源商业软件,但是它将各功能模块编译为静态库文件(lib),用户可以通过配置编译选项对系统做裁剪,从而得到用户所需要的Windows CE系统。在Platform Builder中新建系统,有配置选项如下:

               

上面是询问系统平台,由于我们用的是XBase PXA270,选择最后一项,下一步;后续步骤中将会出现系统的类型,此时选择Internet Application,这是由于我们的后续任务中需要使用到网络连接进行同步。待所有选项配置完毕后,执行Compiler & Sysgen操作进行系统编译,并且生成系统镜像bk.bin。

       接下来,找到实验室提供的系统引导程序EBOOT.nb0,这个程序能够提供系统的引导以及未安装系统时通过网络下载并安装系统的功能。使用下载工具jflashmm.exe将EBOOT.nb0下载到目标机,注意,下载过程中将会有询问“是否为了节省时间而不编程指定区域”,初次下载建议选择否(N),将目标机中的原有内容全部覆盖。

整个下载有两个过程,编程(Programming)过程和验证(Verify)过程,两个过程进度正确完成并且最后没有任何的报错表示下载成功,若有报错建议完全重新下载,不要为了偷懒而就此略过,因为即使后面终端能够正常通讯也无法保证后续步骤能够正确进行。

       下一步是启动Windows XP系统附件中的“终端”程序,将波特率设置为38400,重启目标机,终端与目标机通讯成功,如下图:

待其询问是“继续载入存在的镜像还是取消”,此时按空格键选择取消,接下来EBOOT会自动进入主菜单,选择0,设置IP为192.168.0.5(只需要设置前3段位192.168.0保证在同一网段即可),然后选择1,设置子网掩码(Subnet mask)为255.255.255.0。然后,设置PC机的IP为192.168.0.2,与目标机同一网段,以及子网掩码255.255.255.0,与目标机一致。最后输入D,进入等待镜像下载状态。接下来设置PC机上的Platform Builder的Connectivity Option设置如下:

点击“应用”(Apply),是设置生效,关闭,在菜单栏Target选择Attach,开始下载镜像,镜像通过网络传输,如下:

此时,终端显示如下:

下载完毕后不要立即重启目标机,等待终端显示的三个步骤结束后才能重启,中断点线进度条显示擦除(FlashErase)过程,写入过程(Writting),验证过程(Verify),三个过程结束,目标机会自动重启,重启后会听到Windows CE的开机声音,以及屏幕上显示Windows CE 的界面,至此,Windows CE 5.0系统安装成功。第一个任务完成。

4.2 编程驱动LED和数码管显示正确的信息

实验室提供了参考代码,此处程序设计的关键部分是对硬件设备的控制,即I/O控制。

各端口设置代码如下:

#define LED_BASEADDR1   0x10200000

#define LED_BASEADDR2   0x10300000

#define LED_BASEADDR3   0x10400000

#define pLightIoBaseAddress 0x10500000

BYTE NumData[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

设定LED:

void CLedDlg::SetLedValue(unsigned int indata){

    USHORT Data;

    UINT buf;

    buf=indata;

    buf=buf%1000000;   

    Data=NumData[buf/100000];

    buf=buf%100000;

    Data|=NumData[buf/10000]<<8;

    WRITE_PORT_USHORT(v_pLEDBaseAddr1,~(Data|BIT7|BIT15));

    buf=buf%10000;

    Data=NumData[buf/1000];

    buf=buf%1000;

    Data|=NumData[buf/100]<<8;

    WRITE_PORT_USHORT(v_pLEDBaseAddr2,~(Data|BIT7|BIT15));

    buf=buf%100;

    Data=NumData[buf/10];

    buf=buf%10;

    Data|=NumData[buf]<<8;

    WRITE_PORT_USHORT(v_pLEDBaseAddr3,~(Data|BIT7|BIT15));

}

定时器:

void CLedDlg::OnTimer(UINT_PTR nIDEvent){

    switch(nIDEvent){

    case 1:

        count++;

        if(count<8){

            if(m_LeftShift.GetCheck())

                outdata=outdata>>1;

            else

                outdata=outdata<<1;

        }else{

            count=0;

            if(m_LeftShift.GetCheck())

                outdata=0x80;

            else

                outdata=0x01;

        }

        *pLightReg=~outdata;

        break;

    case 2:

        m_LedValue++;

        SetLedValue(m_LedValue);

        UpdateData(FALSE);

        break;

    }   // TODO: Add your message handler code here and/or call default

    CDialog::OnTimer(nIDEvent);

}

4.3 编程驱动电机运转

实验室提供了参考代码,程序的关键部分是对硬件设备的控制。

步进参数及端口设置:

volatile GPIO_REGS  *v_pGPIOReg = NULL;

#define StepBaseTime 2500

#define GPIO_81_PullHigh()  v_pGPIOReg->GPSR_z|=GPIO_81 //用于直流电机

#define GPIO_81_PullLow()   v_pGPIOReg->GPCR_z|=GPIO_81

#define GPIO_82_PullHigh()  v_pGPIOReg->GPSR_z|=GPIO_82 //用于直流电机

#define GPIO_82_PullLow()   v_pGPIOReg->GPCR_z|=GPIO_82

#define GPIO_83_PullHigh()  v_pGPIOReg->GPSR_z|=GPIO_83 //用于产生步进电机脉冲

#define GPIO_83_PullLow()   v_pGPIOReg->GPCR_z|=GPIO_83

#define GPIO_84_PullHigh()  v_pGPIOReg->GPSR_z|=GPIO_84 //用于控制步进电机方向

#define GPIO_84_PullLow()   v_pGPIOReg->GPCR_z|=GPIO_84

#define GPIO_53_PullHigh()  v_pGPIOReg->GPSR_y|=GPIO_53//用于步进电机输出使能

#define GPIO_53_PullLow()   v_pGPIOReg->GPCR_y|=GPIO_53


步进电机运行线程:

UINT StepMotorThread(LPVOID lpParam)    //步进电机运行线程

{

    CMotorDlg *pDlg=(CMotorDlg*)lpParam;

    CWait waitTime;

    WaitForSingleObject(pDlg->StepThreadBegin.m_hObject,INFINITE);

    GPIO_53_PullLow();

    while(1)

    {          

        if(pDlg->m_StepMotorPositive.GetCheck())

            GPIO_84_PullLow();

        else   

            GPIO_84_PullHigh();

        if(!pDlg->m_StepContinue.GetCheck())

        {

            pDlg->m_StepRunTime--;

            if(pDlg->m_StepRunTime <=0)

                break;

        }

        int result=::WaitForSingleObject(pDlg->StepThreadEnd.m_hObject,0);

        if(result==WAIT_OBJECT_0)

            break;

        GPIO_83_PullHigh();

        waitTime.usWait(pDlg->g_HighTimeA);

        GPIO_83_PullLow();

        waitTime.usWait(pDlg->g_LowTimeA);

    }

    GPIO_53_PullHigh();

    return 0;

}

直流电机运行线程:

UINT DCMotorThread(LPVOID param)//直流电机运行线程

{

    CMotorDlg *pDlg=(CMotorDlg*)param;

    ::WaitForSingleObject(pDlg->DCThreadBegin.m_hObject ,INFINITE);

    while(1){

        int result=::WaitForSingleObject(pDlg->DCThreadEnd.m_hObject ,0);

        if(result==WAIT_OBJECT_0){

            GPIO_82_PullHigh();

            GPIO_81_PullHigh();

            break;

        }

        if(pDlg->m_DCMotorPositive.GetCheck()){

            GPIO_82_PullLow();

            GPIO_81_PullHigh();

        }else{

            GPIO_81_PullLow();

            GPIO_82_PullHigh();

        }

        if(!pDlg->m_DCContinue.GetCheck())

        {

            Sleep(pDlg->m_DCRunTime);

            GPIO_82_PullHigh();

            GPIO_81_PullHigh();

            break;

        }

    }

    return 0;

}

4.4 个人设计小程序

小程序介绍:

本次课程设计中的小程序,我们组设计的是一个Windows CE平台上的简易计算器,Windows CE 5.0中运行的界面如下:

上图是在Windows CE 5.0模拟器中运行的结果,在实体机上的Windows CE中运行的结果一样,都能够正常运行。


程序实现:

1.      新建项目 其它语言  Visual C#  智能设备  Windows CE 5.0 设备应用程序,建立项目,如图。

2.      界面设计如下


3.      各数字按键Click事件函数

4.      按键预处理函数

// 将输入的数据解析为数字

private void key_input_num(string input) {

    // 没输运算符

    if (append == true)

    {

        lb_screen.Text += input;

        if(input=="."){

            return;

        }

        try

        {

            lb_screen.Text = double.Parse(lb_screen.Text).ToString();

        }

        catch (Exception e)

        {

            status = 0;

            lb_screen.Text = "ERROR!";

        }

    }else if(append == false){

        lb_screen.Text = input.ToString();

        append = true;

        if(operation!=0){

            status = 3;

        }

       

    }

}


5.        加减乘除按键Click事件函数

/* ÷*/

private void btn_divide_Click(object sender, EventArgs e)

{

    if (status == 1)

    {

        status = 3;

        operation = 4; /* ÷*/

        num1 = double.Parse(lb_screen.Text);

        lb_status.Text = "数";

        append = false;

    }

}

// x

private void btn_multiply_Click(object sender, EventArgs e)

{

    if (status == 1)

    {

        status = 3;

        operation = 3; //x

        num1 = double.Parse(lb_screen.Text);

        lb_status.Text = "数";

        append = false;

    }

}

private void btn_minus_Click(object sender, EventArgs e)

{

    if (status == 1)

    {

        status = 3;

        operation = 2; //-

        num1 = double.Parse(lb_screen.Text);

        lb_status.Text = "数";

        append = false;

    }

}

private void btn_plus_Click(object sender, EventArgs e)

{

    if (status == 1)

    {

        status = 3;

        operation = 1; //+

        num1 = double.Parse(lb_screen.Text);

        lb_status.Text = "数";

        append = false;

    }

}


6.        等于按键Click事件

// 等于

private void btn_run_Click(object sender, EventArgs e)

{

    //lb_screen.Text = "ERROR!";

    if (status == 3)

    {

        //lb_status.Text = "run";

        num2 = double.Parse(lb_screen.Text);

        try

        {

            if (operation == 4)

            { // check 除

                if (num2 == 0)

                {

                    throw new Exception("除数为");

                }

                else {

                    lb_screen.Text = calculate(operation, num1, num2);

                    num1 = double.Parse(lb_screen.Text);

                    num2 = 0;

                    status = 1;

                    operation = 0;

                }

            }

            else

            {

                lb_screen.Text = calculate(operation, num1, num2);

                num1 = double.Parse(lb_screen.Text);

                num2 = 0;

                status = 1;

                operation = 0;

            }

        }

        catch (Exception ex)

        {

            status = 0;

            lb_screen.Text = "ERROR!";

        }

    }

    else {

        //lb_status.Text = "not";

    }

}


7.      处理运算

private string calculate(uint operation, double num1, double num2) {

    double result = 0;

    if(1==operation){ // 加

        result=num1+num2;

        return result.ToString();

    }

    else if (2 == operation) {//减

        result = num1 - num2; ;

        return result.ToString();

    } else if (3 == operation) { //乘

        result = num1 * num2;

        return result.ToString();

    }

    else if (4 == operation)

    { //除

        result = num1 / num2;

        lb_status.Text = result.ToString();

        return result.ToString();

    }

    else {

        throw new Exception("不存在的操作");

    }

}

8.      程序设计总结

简易计算器的设计比较简单,重点在于处理各种非法输入以及非法运算,比如0为除数,此程序用try-catch来捕捉这些异常,然后将当异常产生时计算器“显示器”部分会显示ERROR。另外一个重点在于两个运算数的各种状况下的实时更新。


五、课程设计小结

5.1 设计小结

本次课程设计任务比较简单,主要是通过“Windows CE平台的搭建”、“Windows CE平台上LED驱动”、“Windows CE平台电机驱动”以及“Windows CE平台上程序开发”这些实验任务使得我们更加深入的了解嵌入式操作系统的相关知识,同时也是让我们了解到了Windows CE这个平台的特性,以及Windows CE平台上应用程序的开发。同时,课程设计中遇到了一些问题,比如头文件缺失即找不到"pkfuncs.h"文件,这些问题是我和同组的卫盈同学共同解决,同时,在一些很奇怪的难题(后来证明是设备问题)上也获得了老师的帮助,成功的克服困难,顺利解决。

当然在课堂外的设计中也遇到了种种问题,比如开发平台的搭建,仿真器的搭建,SDK的安装等等。

 

相关推荐