大工嵌入式系统预习报告

大连理工大学

                                                                                   

本科实验报告

课程名称:嵌入式系统实验       

学院(系):电子信息与电气工程学部

专    业:自动化               

班    级:                 

学    号:           

学生姓名:                

    20##年   月


大连理工大学实验报告

学院(系):电信              专业:  自动化            班级:  0804         

姓     名:          学号:           组:            ___  

实验时间:          实验室:          实验台:            

指导教师签字:                                            成绩:              

实验一  ARM的串行口实验

一、     实验目的和要求

见预习报告

二、     实验原理和内容

见预习报告

三、     主要仪器设备

硬件:ARM嵌入式开发平台、用于ARM7TDMI 的JTAG 仿真器、PC机Pentium100 以上、串口线。

软件:PC 机操作系统win98、Win2000 或WinXP 、ARM SDT 2.51 或ADS1.2 集成开发环境、仿真器驱动程序、超级终端通讯程序。

四、实验步骤

见预习报告

五、核心代码

在主函数中实现将从串口0接收到的数据发送到串口0(Main.c)

int main(void)

{

    char c1[1];

    char err;

    ARMTargetInit();    //开发版初始化

   

    LCD_Init();

    LCD_ChangeMode(DspTxtMode);//转换LCD显示模式为文本显示模式

    LCD_Cls();//文本模式下清屏命令

    while(1)

    {

       Uart_SendByte(0,0xa);//换行

        Uart_SendByte(0,0xd);//回车

            err=Uart_Getch(c1,0,0); //从串口采集数据

            Uart_SendByte(0,c1[0]); //显示采集的数据

            LCD_printf(c1);//向液晶屏输出

    }

    return 0;

}

六、实验结果与分析

1.ARM串口实验超级终端上显示:

当输入一个字符,会在超级终端中显示出来,如下图所示。

2.ARM串口实验Debug运行显示:

七、实验心得

该实验展示了ARM的串行口通讯过程及控制方式,使我基本掌握了ARM 的串行口工作原理、编程实现ARM 的UART 通讯及CPU利用串口通讯的方法,对之前所学知识有了明确的理解和认识,能够在正确操作下准确做出实验现象,并在实验箱上显示出实验结果,使我收获很多。

实验二  uC/OS-IIARM平台的移植

一、     实验目的和要求

见预习报告

二、     实验原理和内容

见预习报告

三、     主要仪器设备

硬件:ARM嵌入式开发平台、用于ARM7TDMI 的JTAG 仿真器、PC机Pentium100 以上、串口线。

软件:PC 机操作系统win98、Win2000 或WinXP 、ARM SDT 2.51 或ADS1.2 集成开发环境、仿真器驱动程序、超级终端通讯程序。

四、实验步骤

见预习报告

五、核心代码

所涉及到的函数:

汇编函数

OSStartHighRdy()

OSCtxSw()

OSIntCtxSw()

OSTickISR()

C语言函数

void *OSTaskStkInit (void (*task)(void *pd),void *pdata, void *ptos, INT16U opt)

void OSTaskCreateHook (OS_TCB *ptcb)

void OSTaskDelHook (OS_TCB *ptcb)

void OSTaskSwHook (void)

后5个函数为接口函数,可以不加代码

cut/OS-II的启动:

void main (void)

{

OSInit(); // 初始化uC/OS-II

.

通过调用OSTaskCreate()或OSTaskCreateExt()创建至少一个任务;

.   

OSStart(); //开始多任务调度,永不返回

}

基于uC/OS的应用开发:

void YourTask (void *pdata)

{

    /* 用户代码 */

    OSTaskDel(OS_PRIO_SELF);

 }

main 函数,ucos-ii初始化等定义:

#include"../ucos-ii/includes.h"               /* uC/OS interface */

#include "../ucos-ii/add/osaddition.h"

#include "../inc/drivers.h"

#include "../inc/sys/lib.h"

#include "../src/gui/gui.h"

#include <string.h>

]= {0, }; //system task刷新任务堆栈

#define SYS_Task_Prio               1

 void SYS_Task(void *Id);*/

OS_STK task1_Stack[STACKSIZE]={0, };   //Main_Test_Task堆栈

void Task1(void *Id);             //Main_Test_Task

#define Task1_Prio     12

OS_STK task2_Stack[STACKSIZE]={0, };   //test_Test_Task堆栈

void Task2(void *Id);             //test_Test_Task

#define Task2_Prio     15

/**************已经定义的OS任务*************

#define SYS_Task_Prio               1

#define Touch_Screen_Task_Prio      9

#define Main_Task_Prio     12

#define Key_Scan_Task_Prio      58

#define Lcd_Fresh_prio           59

#define Led_Flash_Prio           60

***************************************

int main(void)

{

    ARMTargetInit();        // do target (uHAL based ARM system) initialisation //

    OSInit();               // needed by uC/OS-II //

    //OSInitUart();

    //initOSFile();

//#if USE_MINIGUI==0

//  initOSMessage();

//  initOSDC();

//  LoadFont();

//#endif

    //loadsystemParam();

   

TACKSIZE-1],  Task1_Prio);

    OSTaskCreate(Task2,  (void *)0,  (OS_STK *)&task2_Stack[STACKSIZE-1],  Task2_Prio);

    OSAddTask_Init(0);

 

    //LCD_printf("Starting uCOS-II...\n");

    //LCD_printf("Entering graph mode...\n");

    //LCD_ChangeMode(DspGraMode);

    OSStart();              // start the OS //

    // never reached //

    return 0;

}//main

void Task1(void *Id)

{

   

    for(;;){

        printf("run task1\n");

        OSTimeDly(1000);

    }

}

void Task2(void *Id)

{

    for(;;){

        printf("run task2\n");

        OSTimeDly(3000);

    }

}

六、实验结果与分析

超级终端上交替显示run task1,run task2,run task1,run

task1,run task1,run task2,run task1,run task1,run task1。表明由于

task1 的优先级为12,而task2 的优先级为15,所以系统在task1 和task2 同

时就绪时总是先执行task1 后执行task2.由于task2 挂起时间为3 秒,所以在

task2 挂起期间task1 能执行两次,而当第三次时由于task1 与task2 同时处于

就绪态,由优先级次序,还是先执行task1 在执行task2.然后就这样周而复始

的循环下去。

为验证ucos 的强实时性,可以去掉task2()的“OSTimeDly(3000);”然后

令task1()中的“OSTimeDly(1000);”改为“OSTimeDly(10);”。观察到的实

验现象是在超级终端上显示被“run task1”打断的”“ run task2”,反之把task1

和task2 的优先级交换则在超级终端上只显示“run task2”。这说明ucos 的强

实时性得到了验证,因为在任何时候只要高优先级的任务都可以打断正在执行的

低优先级任务,反之低优先级任务却不可打断正在执行的高优先级的任务。

七、实验心得

该实验使我了解了uCOS-II 内核的主要结构,对所学知识有了加深刻的理解和认识,基本掌握了将uCOS-II 内核移植到ARM920T 处理器上的方法,能够正确完成基本操作得出正确结果。

实验九 uC/OS-IIARM平台的移植

一、     实验目的和要求

1.了解uCOS-II 内核的主要结构。

2.掌握将uCOS-II 内核移植到ARM920T 处理器上的基本方法。

二、实验原理和内容

实验原理:

所谓移植,指的是一个操作系统可以在某个微处理器或者微控制器上运行。虽然uCOS-II

的大部分源代码是用C 语言写成的,仍需要用C 语言和汇编语言完成一些与处理器相关的代

码。比如:uCOS-II 在读写处理器、寄存器时只能通过汇编语言来实现。因为uCOS-II 在设

计的时候就已经充分考虑了可移植性,所以,uCOS-II 的移植还是比较容易的。

要使uCOS-II 可以正常工作,处理器必须满足以下要求:

1.处理器的C 编译器能产生可重入代码。

可重入的代码指的是一段代码(如一个函数)可以被多个任务同时调用,而不必担心会

破坏数据。也就是说,可重入型函数在任何时候都可以被中断执行,过一段时间以后又可以

继续运行,而不会因为在函数中断的时候被其他的任务重新调用,影响函数中的数据。下面

的两个例子可以比较可重入型函数和非可重入型函数:

程序1:可重入型函数

void swap(int *x, int *y)

{int temp;

temp=*x;

*x=*y;

*y=temp;

}

程序2:非可重入型函数

int temp;

void swap(int *x, int *y)

{

temp=*x;

*x=*y;

*y=temp;

}

程序1 中使用的是局部变量temp 作为变量。通常的C 编译器,把局部变量分配在栈中。

所以,多次调用同一个函数,可以保证每次的temp 互不受影响。而程序2 中temp 定义的是

全局变量,多次调用函数的时候,必然受到影响。

代码的可重入性是保证完成多任务的基础,除了在C 程序中使用局部变量以外,还需要

C 编译器的支持。笔者使用的是ARM ADS 的集成开发环境,均可以生成可重入的代码。

2.在程序中可以打开或者关闭中断。

在uCOS-II 中,可以通过OS_ENTER_CRITICAL()或者OS_EXIT_CRITICAL()宏来控制系统

关闭或者打开中断。这需要处理器的支持,在ARM920T 的处理器上,可以设置相应的寄存器

来关闭或者打开系统的所有中断。

3.处理器支持中断,并且能产生定时中断(通常在10Hz?1000Hz 之间)。

uCOS-II 是通过处理器产生的定时器的中断来实现多任务之间的调度的。在ARM920T 的

处理器上可以产生定时器中断。

4.处理器支持能够容纳一定量数据的硬件堆栈。

5.处理器有将堆栈指针和其它CPU 寄存器存储和读出到堆栈(或者内存)的指令。

uCOS-II 进行任务调度的时候,会把当前任务的CPU 寄存器存放到此任务的堆栈中,然

后,再从另一个任务的堆栈中恢复原来的工作寄存器,继续运行另一个任务。所以,寄存器

的入栈和出栈是uCOS-II 多任务调度的基础。

图4-1 说明了uC/OS 的结构以及它与硬件的关系。

ARM920T 处理器完全满足上述要求。接下来将介绍如何把uCOS-II 移植到Samsung 公司

的一款ARM920T 的嵌入式处理器——S3C2410X 上。

实验内容:

1.将uC/OS-II 内核移植到ARM9 微处理器   上。

2.创建两个任务task1、task2,分别向串口 输出数据,在超级终端上显示当前正在运行那个任务。

三、实验步骤

1.将uCOS-II 内核移植到ARM7 微处理器上。

2.编写两个简单任务,在超级终端上观察两个任务的切换来测试一下移植

是否成功。

为了使uCOS-II 可以正常运行,除了上述必须的移植工作外,硬件初始化和

配置文件也是必须的。STARTUP 目录下的文件还包括中断处理,时钟,串口通信

等基本功能函数。

在文件main.c 中给出了应用程序的基本框架,包括初始化和多任务的创建,

启动等。任务创建方法如下:

1)在程序开头定义任务堆栈,任务函数声明和任务优先级:

OS_STK TaskName_Stack[STACKSIZE]={0, }; //任务堆栈

void TaskName(void *Id); //任务函数

#define TaskName_Prio N //任务优先级

2)在main()函数中调用OSStart()函数之前用下列语句创建任务:

OSTaskCreate(TaskName,(void*)0,(OS_STK*)&TaskName_Stack[STACK

SIZE-1], TaskName_Prio);

OSTaskCreate()函数的原型是:

INT8U OSTaskCreate (void (*task)(void *pd), void *p_arg,

OS_STK *ptos, INT8U prio);

需要将任务函数TaskName , 任务堆栈TaskName_Stack , 任务优先级

TaskName_Prio 三个参数传给OSTaskCreate()函数。根据任务函数的内容决定堆

栈大小,宏STACKSIZE 定义为4KB,可以在此基数上乘倍。任务优先级越高,

TaskName_Prio 值越小;uCOS-II 可以管理64 个任务,由OSInit()创建的空闲

任务的优先级最低为63;uCOS-II 保留4 个最高和4 个最低优先级,用户任务可

以使用其余56 个优先级值。

3)编写任务函数内容:

void TaskName(void *Id)

{

//添入任务初始化语句

for(;;)

{ //添入任务循环内容

OSTimeDly(SusPendTime);//挂起一定时间,以使其他任务可以占

用CPU

}

}

uCOS-II 至少要有一个任务,这里首先创建一个系统任务SYS_Task,其中由

语句

OSRunning=TRUE; //使能uCOS-II 运行

uHALr_InstallSystemTimer();

启动系统时钟和多任务切换。

为了验证uCOS-II 多任务切换的进行,再编写两个简单的任务,分别在超

级终端上输出run task1 和run task2。可以参考main.c 的结构创建多个不同

功能的任务,观察个任务的切换。

3.编译并下载移植后的uCOS-II

所有的源代码都准备好后就可以进行编译了。在ADS 环境下需要设置工程的

访问路径。从菜单Edit | Debug Settings 进入设置对话框,在Target | Access

Paths 中选择User Paths 并选上Always search user paths。然后点Add 按钮

添加路径ucos-ii 和arch。这主要是设置编译器处理文件包含时的搜索范围。

按照实验一的方法可以对编译后的代码进行调试或下载到平台的电子硬盘中。这

个实验从结构上看和其他的实验没有多大区别, 同样生成可执行文件

system.bin。可以在平台BIOS 中激活电子硬盘,然后把system.bin 拷贝进去,

重启平台,然后在超级终端上观察结果。

相关推荐