详细的S3C2440的ucOSII和ucGUI移植过程.docx

上传人:b****4 文档编号:12023462 上传时间:2023-04-16 格式:DOCX 页数:16 大小:516.41KB
下载 相关 举报
详细的S3C2440的ucOSII和ucGUI移植过程.docx_第1页
第1页 / 共16页
详细的S3C2440的ucOSII和ucGUI移植过程.docx_第2页
第2页 / 共16页
详细的S3C2440的ucOSII和ucGUI移植过程.docx_第3页
第3页 / 共16页
详细的S3C2440的ucOSII和ucGUI移植过程.docx_第4页
第4页 / 共16页
详细的S3C2440的ucOSII和ucGUI移植过程.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

详细的S3C2440的ucOSII和ucGUI移植过程.docx

《详细的S3C2440的ucOSII和ucGUI移植过程.docx》由会员分享,可在线阅读,更多相关《详细的S3C2440的ucOSII和ucGUI移植过程.docx(16页珍藏版)》请在冰豆网上搜索。

详细的S3C2440的ucOSII和ucGUI移植过程.docx

详细的S3C2440的ucOSII和ucGUI移植过程

基于S3C2440的uc/OS-II和uc-GUI移植和应用

实验目的:

1.熟悉ARM体系构造

2.深化学习操作系统原理

3.增强动手理论才能

实验平台:

ARM9体系构造处理器—S3C2440

飞凌嵌入式开发板—FL2440〔由于本实验大局部在宿舍完成,故采用了自己的嵌入式开发板作为平台,硬件与实验箱根本相似〕

功能实现

主要功能是利用uc/OS-II的多任务调度功能和uc-GUI提供的图形函数接口,编写一

个Uart传输测试程序。

通过Uart协议,传输PC机键盘输入的数据,在开发板的LCD上显示出来。

同时实现

了字符串挪动和现实系统信息的附加功能。

注:

本实验中,移植代码局部参考了网络上的一些相关文章,应用程序局部全部由自己编写完成。

实验原理:

1.背景介绍

(1)ARM9〔S3C2440〕

 ARM9系列处理器是英国ARM公司设计的主流嵌入式处理器。

S3C2440是三星公司消费的基于ARM9体系构造的处理器,可以运行linux、wince等大型操作系统,构成非常典型的cpu+os嵌入式系统。

[1]

(2)uc/OS-II

uc/OS是一种免费公开源代码、构造小巧、具有可剥夺实时内核的实时操作系统。

uc/OS-II是一个实时操作系统内核,它包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等根本功能。

是一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最根本的系统效劳,如信号量,邮箱,消息队列,内存管理,中断管理等。

(3)uc-GUI

uC/GUI是Micrium公司开发的通用的嵌入式用户图形界面软件。

它给任何使用图形LCD的应用程序提供独立于处理器和LCD控制器之外的有效的图形用户接口。

可以应用于单一任务环境,也可以应用于多任务环境中。

uC/GUI可以应用于任何LCD控制器和CPU的任何尺寸的物理显示或者模拟显示中。

2.移植原理

(1)uc/OS-II移植

为了方便移植,大局部的uC/OSII代码是用c语言写的,但仍需要用c和汇编语言写一些与处理器相关的代码,这是因为uC/OSII在读写处理器存放器时只能通过汇编语言来实现。

由于uC/OSII在设计时就已经充分考虑了可移植性,所以uC/OSII的移植相对来说是比拟容易的。

移植主要涉及的文件。

〔详细移植代码见后文附录〕

(a)设置与处理器及编译器相关的代码[OS_CPU.H]

这局部代码主要实现一些数据类型的定义。

不同的编译器会使用不同的字节长度来表示同一数据类型,所以要定义一系列数据

类型以确保移植的正确性。

下面是uC/OSII定义的一局部数据类型。

typedefunsignedcharBOOLEAN;/*布尔型数据类型*/

  typedefunsignedcharINT8U;/*无符号8位*/

  typedefsignedcharINT16S;/*带符号8位*/

  typedefunsignedintINT16U;/*无符号16位*/

……

uC/OSII需要先关中断再访问临界区的代码,并且在访问完后重新允许中断。

uC/OSII定义了两个宏来制止和允许中断:

OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(),本移植实现这两个宏的汇编代码。

  #defineOS_ENTER_CRITICAL()__asm{blARMDisableInt}//ARMDisableInt()

#defineOS_EXIT_CRITICAL()__asm{blARMEnableInt}//ARMEnableInt()

 

(b)用C语言实现与处理器任务相关的函数[OS_CPU_C.C]

这局部代码最主要的功能是实现一个系统的堆栈初始化函数

OS_STK*OSTaskStkInit(void(*task)(void*pd),

void*pdata,

OS_STK*ptos,

INT16Uopt)

其他的一些操作系统的钩子函数也在这里定义,如:

voidOSTaskCreateHook(OS_TCB*ptcb);

等等,用来实现操作系统的扩展功能。

由于本实验没有使用到这些钩子函数,故在这里只定义成空函数即可。

(c)处理器相关局部汇编实现

这局部代码是移植的核心内容,主要实现操作系统的任务调度等核心功能。

a)OSStartHighRdy()

  该函数在OSStart()多任务启动之后,负责从最高优先级任务的TCB控制块中获得该任务的堆栈指针sp,通过sp依次将CPU现场恢复,此时系统就将控制权交给用户创立的该任务的进程,直到该任务被阻塞或者被其他更高优先级的任务抢占了CPU。

该函数仅仅在多任务启动时被执行一次,用来启动第一个,也就是最高优先级的任务执行。

  b)OSCtxSw()

  该函数是任务级的上下文切换函数,在任务因为被阻塞而主动恳求与CPU调度时执行,主要工作是先将当前任务的CPU现场保存到该任务堆栈中,然后获得最高优先级任务的堆栈指针,从该堆栈中恢复此任务的CPU现场,使之继续执行,从而完成一次任务切换。

  c)OSIntExit()

  该函数是中断级的任务切换函数,在时钟中断ISR中发现有高优先级任务在等待时,需要在中断退出后不返回被中断的任务,而是直接调度就绪的高优先级任务执行。

其目的在于可以尽快让高优先级的任务得到响应,保证系统的实时性能。

  d)OSTickISR()

该函数是时钟中断处理函数,主要任务是负责处理时钟中断,调用系统实现的OSTimeTick函数,假如有等待时钟信号的高优先级任务,那么需要在中断级别上调度其执行。

另外两个相关函数是OSIntEnter()和OSIntExit(),都需要在ISR中执行。

[2]

〔2〕uc-GUI移植

移植uC/GUI主要集中在修改三个头文件和两个C文件。

三个头文件都在\Config下,分别是GUICon.h,GUITouchConf.h,LCDConf.h;两个C文件一个是GUI_X.C(Sample\GUI_X.C),.另外一个在GUI\LCDDriver目录下〔LCDWin.c〕

(a)

主要修改的地方:

#defineLCD_XSIZE     (320)  

#defineLCD_YSIZE     (240)  

 #defineLCD_BITSPERPIXEL(16)  //16Bpp

 #defineLCD_CONTROLLER1375

 LCD_XSIZE ,LCD_YSIZE是对应LCD的尺寸大小

LCD_BISPERPIXEL 指定每象素的位的数量

LCD_CONTROLLER是LCD控制器

(b)

 #ifndefGUICONF_H

#defineGUICONF_H

 #defineGUI_OS                   

(1)/* 是否支持OS*/

#defineGUI_SUPPORT_TOUCH        (0) /*是否支持触摸屏*/

#defineGUI_SUPPORT_UNICODE      

(1) /*是否支持ASCII/UNICODE*/

 #defineGUI_DEFAULT_FONT         &GUI_Font6x8/*选择一个默认的字体*/

#defineGUI_ALLOC_SIZE         1024*1024 /*动态内存的大小*/

 #defineGUI_WINSUPPORT           

(1) /*是否支持WM〔视窗管理器〕*/

#defineGUI_SUPPORT_MEMDEV       

(1) /*是否支持存储设备*/

#defineGUI_SUPPORT_AA           (0) /*是否支持反锯齿*/

 #endif 

在LCD的最根本操作就是在某一个坐标上画点,其他的操作都是画点操作延伸出来的。

uC/GUI的所有对LCD的操作也是基于这个动作。

在FL2440_LCD_for_GUI.c文件中实现开发板LCD的根本操作函数,与uc-GUI中定义的函数对接。

如:

 

voidFL2440_LCD_SetPixel(U32x,U32y,U16c)

{

PutPixel(x,y,c);/*根本的LCD画点函数*/

}

U16FL2440_LCD_GetPixel(U32x,U32y)

{

return(GUI_Point(x,y));/*根本的LCD读点函数*/

}

voidFL2440_LCD_Off(void)

{

Lcd_EnvidOnOff(0);/*LCD开关*/

}

 

voidFL2440_LCD_On(void)

{

Lcd_EnvidOnOff

(1);/*LCD开关*/

}

[3]

实验过程:

前面介绍了根本的移植原理,要想让开发板可以正常工作,还需要一些额外的工作。

1.启动代码

采用三星公司针对2440的启动代码,根本无需修改。

2.应用程序

前面介绍的uc/OS-II只是一个操作系统的最根本内核,要实现详细功能,要求开发人员自己编写相关的应用程序。

本实验中,应用程序在主函数文件finalmain.c中实现。

主要功能是利用uc/OS-II的多任务调度功能和uc-GUI提供的图形函数接口,编写一个Uart传输测试程序。

通过Uart协议,传输PC机键盘输入的数据,在开发板的LCD上显示出来。

同时实现了字符串挪动和现实系统信息的附加功能。

主函数如下:

 

voidMain()

{

//系统时钟,LCD,Uart,GUI以及uc/OS-II的初始化

cpu_init();

FL_Lcd_Init();

Uart_Init(0,115200);

Uart_Printf("begin!

\n");

GUI_Init();

GUITASK_Init();

OSInit();

OSTimeSet(0);

//创立起始任务

OSTaskCreate(TaskStart,0,&TaskStartSTK[TaskStkLeath-1],NormalTaskPrio+13);

//创立信号量,用于在文本框输入满后去除文本框内容使用

Cls=OSSemCreate

(1);

OSStart();

}

voidTaskStart(void*pdata)//起始任务

{

//设置系统时钟节拍

Init_Timer4();

//初始化统计任务

OSStatInit();

//创立任务

/*Task_Text为创立文本框任务,在LCD上画出一个文本框,同时实如今文本框输入满的时候清楚文本框内容*/

OSTaskCreate(Task_Text,0,&Task_Text_Stk[TaskStkLeath-1],NormalTaskPrio);

/*Task_SideText任务,在LCD侧边处现实操作系统名称及版本,并向上挪动*/

OSTaskCreate(Task_SideText,0,&Task_SideText_Stk[TaskStkLeath-1],NormalTaskPrio+3);

/*Task_Info任务,在文本框下方显示系统信息,包括CPU使用率,系统任务切换频率,系统开机时间*/

OSTaskCreate(Task_Info,0,&Task_Info_Stk[TaskStkLeath-1],NormalTaskPrio+5);

/*Task_Title任务在文本框上方滚动现实提示信息*/

OSTaskCreate(Task_Title,0,&Task_Title_Stk[TaskStkLeath-1],NormalTaskPrio+6);

/*Task_Uart任务,从Uart串口读取数据显示在文本框中*/

OSTaskCreate(Task_Uart,0,&Task_Uart_Stk[TaskStkLeath-1],NormalTaskPrio+8);

/*在文本框中现实位图,〔可选〕*/

//OSTaskCreate(Task_Bmp,0,&Task_Bmp_Stk[TaskStkLeath-1],NormalTaskPrio+7);

OSTaskDel(OS_PRIO_SELF);

Uart_Printf("ExitTaskStart.\n");

}

实验结果:

经过屡次实验和调试,最终实现了上述功能,以下是实验结果截图:

ADS工程源文件组织构造

附录:

1.uc/OS-II移植代码〔汇编函数局部〕:

OSStartHighRdy

BLOSTaskSwHook;Calluser-definedhookfunction

LDRr4,=OSRunning;Indicatethatmultitaskinghasstarted

MOVr5,#1

STRBr5,[r4];OSRunning=true

LDRr4,=OSTCBHighRdy;GethighestprioritytaskTCBaddress

LDRr4,[r4];getstackpointer

LDRsp,[r4];switchtothenewstack

LDMFDsp!

{r4};popnewtasksspsr

MSRspsr_c,r4

LDMFDsp!

{r4};popnewtaskspsr

MSRcpsr_c,r4

LDMFDsp!

{r0-r12,lr,pc};popnewtasksr0-r12,lr&pc

OSCtxSw

STMFDsp!

{lr}

STMFDsp!

{r0-r12,lr};pushlr®isterfile

MRSr4,cpsr;copyCPSRtoR4

STMFDsp!

{r4};pushcurrentpsr

MRSr4,spsr;copySPSRtoR4

STMFDsp!

{r4};pushcurrentspsr

_OSCtxSw

LDRr4,=OSPrioCur;OSPrioCur=OSPrioHighRdy

LDRr5,=OSPrioHighRdy

LDRBr6,[r5]

STRBr6,[r4]

LDRr4,=OSTCBCur;GetcurrenttaskTCBaddress

LDRr5,[r4]

STRsp,[r5];storespinpreemptedtasks'sTCB

BLOSTaskSwHook;callTaskSwitchHook

LDRr6,=OSTCBHighRdy;GethighestprioritytaskTCBaddress

LDRr6,[r6]

LDRsp,[r6];getnewtasksstackpointer

STRr6,[r4];setnewcurrenttaskTCBaddress

LDMFDsp!

{r4};popnewtaskspsr

MSRspsr_c,r4

LDMFDsp!

{r4};popnewtaskcpsr

MSRcpsr_c,r4

LDMFDsp!

{r0-r12,lr,pc};popnewtaskr0-r12,lr&pc

OSIntCtxSw

LDRr0,=OSIntCtxSwFlag;OSIntCtxSwFlag=true

MOVr1,#1

STRr1,[r0]

MOVpc,lr;Thisisonlychangeflag,returntoOSIntExit

/

OSTickISR

SUBlr,lr,#4

STMFDsp!

{r0-r12,lr};pushr0-r12registerfileandlr(pcreturnaddress)

MRSr4,spsr

STMFDsp!

{r4};pushcurrentspsr_irq(=cpsr_svc)

movr0,#0x4000

movr1,#0x4a000000

strr0,[r1,#0]

movr0,#0x4000

movr1,#0x4a000000

strr0,[r1,#0x10]

BLOSIntEnter

BLOSTimeTick

BLTmrSignalTmr

BLOSIntExit

LDRr0,=OSIntCtxSwFlag;checkifOSIntCtxFlagismarkedastrue

LDRr1,[r0]

CMPr1,#1

BEQ_IntCtxSw;ifOSIntCtxFlag=true,thenjumpto_IntCtxSw

LDMFDsp!

{r4};getcpsr_svcfromstack

MSRspsr_c,r4;preparespsrtoreturnsvcmode

LDMFDsp!

{r0-r12,pc}^;recoverr0-r12andpcfromstack,cpsralso

_IntCtxSw

MOVr1,#0;clearOSIntCtxSwFlag=flase

STRr1,[r0]

LDMFDsp!

{r4};restorespsr_irq

MSRspsr_c,r4

LDMFDsp!

{r0-r12,lr};recovertheirqstackpointer

LDRr5,=SAVED_LR_IRQ

LDRr6,=SAVED_LR_SVC

STRlr,[r5];savelr_irqtoSAVED_LR_IRQ

MOVlr,#0x00000093;changeforcelycpsrtosvcmode

MSRcpsr_c,lr

STRlr,[r6];savelr_svctoSAVED_LR_SVC

LDRlr,[r5];getlr_irqvaluesavedinSAVED_LR_IRQ

STMFDsp!

{lr}

LDRlr,[r6]

STMFDsp!

{r0-r12,lr};pushlr&r0-r12registerfile

MRSr4,spsr

STMFDsp!

{r4};pushcurrentpsr

MRSr4,spsr

STMFDsp!

{r4};pushspsr

B_OSCtxSw;jumpto_OSCtxSw

ARMDisableInt

MRSr0,cpsr

STMFDsp!

{r0};pushcurrentPSR

ORRr0,r0,#0x80

MSRcpsr_c,r0;disableIRQInts

MOVpc,lr

ARMEnableInt

LDMFDsp!

{r0};popcurrentPSR

MSRcpsr_c,r0;restoreoriginalcpsr

MOVpc,lr

 

2.uc/OS-II移植代码〔C语言函数局部〕:

OS_STK*OSTaskStkInit(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT16Uopt)

{

unsignedint*stk;

opt=opt;/*'opt'isnotused,preventwarning*/

stk=(unsignedint*)ptos;/*Loadstackpointer*/

/*buildacontextforthenewtask*/

*--stk=(unsignedint)task;/*pc*/

*--stk=(unsignedint)task;/*lr*/

*--stk=0;/*r12*/

*--stk=0;/*r11*/

*--stk=0;/*r10*/

*--stk=0;/*r9*/

*--stk=0;/*r8*/

*--stk=0;/*r7*/

*--stk=0;/*r6*/

*--stk=0;/*r5*/

*--stk=0;/*r4*/

*--stk=0;/*r3*/

*--stk=0;/*r2*/

*--stk=0;/*r1*/

*--stk=(unsignedint)pdata;/*r0*/

*--stk=(SVC32MODE|0x0);/*cpsrIRQ,FIQdisable*/

*--stk=(SVC32MODE|0x0);/*spsrIRQ,FIQdisable*/

return((void*)stk);

}

3.LCD驱动函数相关〔局部〕

staticvoidPutPixel(U32x,U32y,U16c)

{

if((x

LCD_BUFFER[(y)][(x)]=c;

}

staticU16GUI_Point(U32x,U32y)

{

U16c;

if((x

c=LCD_BUFFER[(y)][(x)];

returnc;

}

参考文献:

[1]

[2]

[3]

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 文学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1