UCOS-II ucGUI的完美移植
ucos_II移植总结

Ucos_II移植总结:之前已经基本算是成功的移植过ucos-II(内存管理部分没有处理),但是由于可恶的硬盘故障,让我的劳动成果付诸东流。
其间的一些移植经验没有及时总结,现在想来颇有点从头再来的悲壮!鉴于之前的教训,这次,边移植边总结,以防重蹈覆辙。
还好之前的移植过程已经解决了部分棘手的难题,现在复现一下权当是复习一下arm和ucos_II了。
这次的移植还是基于SEP4020芯片,其中的一些引导代码和中断处理代码还是照搬已经写好的代码吧,现在已经没有自己动手写的激情了!下面按照自己的移植步骤一步步总结吧:第一步:创建工程,将基本的启动代码照搬过来,建立一个最小系统,能够在开发板上运行成功。
第二步:将ucos-II源代码copy过来。
第三步:对基本的语法错误进行改正。
对工程进行编译,根据提示进行基本语法的改正。
主要包括:INCLUDES.h中头文件的调用第四步:对需要自己手动编写的函数首先要清空,防止编译报错,然后一步步手动编写代码。
1、临界段代码:os_cpu.h中OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()两个宏重新定义为我们自己写的开关中断函数。
Os_cpu_a.s文件添加如下代码:AREA MCUINIT , CODE, READONLYENTRY;/* 开启IRQ中断*/;voidEnableInterrupt(void);{EXPORT EnableInterruptEnableInterruptmrs r0,CPSRbic r0, r0, #0x80 ;set bit7 to 0msr CPSR_cxsf,r0movpc,lr ;Return to caller;};/* 关闭IRQ中断*/;voidDisableInterrupt(void);{EXPORT DisableInterruptDisableInterruptmrs r0,CPSRorr r0, r0, #0x80 ;set bit7 to 1msr CPSR_cxsf,r0movpc,lr ;Return to caller;}END2、OS_CPU_A.S文件代码编写AREA MCUINIT , CODE, READONLYENTRY;/* 开启IRQ中断*/;voidEnableInterrupt(void);{EXPORT EnableInterruptEnableInterruptmrs r0,CPSRbic r0, r0, #0x80 ;set bit7 to 0msr CPSR_cxsf,r0movpc,lr ;Return to caller;};/* 关闭IRQ中断*/;voidDisableInterrupt(void);{EXPORT DisableInterruptDisableInterruptmrs r0,CPSRorr r0, r0, #0x80 ;set bit7 to 1msr CPSR_cxsf,r0movpc,lr ;Return to caller;};任务切换代码OSCTXSWEXPORT OS_TASK_SW_ARMOS_TASK_SW_ARMSTMFD sp!, {lr} ; save pcSTMFD sp!, {lr} ; save lrMRS r14, SPSRSTMFD sp!, {r14} ; save current PSRSTMFD sp!, {r0-r12} ; save register file and ret address ;; OSPrioCur = OSPrioHighRdyIMPORT OSPrioCurIMPORT OSPrioHighRdyLDR r4, =OSPrioCurLDR r5, =OSPrioHighRdyLDRB r6, [r5]STRB r6, [r4]; Get current task TCB addressIMPORT OSTCBCurLDR r4, =OSTCBCurLDR r5, [r4]STR sp, [r5] ; store sp in preempted taskss TCB; Get highest priority task TCB addressIMPORT OSTCBHighRdyLDR r6, =OSTCBHighRdyLDR r6, [r6]LDR sp, [r6] ; get new tasks stack pointer; OSTCBCur = OSTCBHighRdySTR r6, [r4] ; set new current task TCB address;LDMFD sp!, {r0-r12} ; YYY+LDMFD sp!, {r14} ; YYY+; LDR r14, =0x000000D3MSR CPSR_cxsf, r14 ; YYY+;调试时屏掉此句才会跑的通,待解决LDMFD sp!, {lr,pc} ; YYY+;OS启动时开始运行创建的最高优先级任务; void OSStartHighRdy(void); ; Start the task with the highest priority;;EXPORT OSStartHighRdyOSStartHighRdyIMPORT OSTCBCurIMPORT OSTCBHighRdyIMPORT OSRunningLDR r4, =OSTCBCur ; Get current task TCB addressLDR r5, =OSTCBHighRdy ; Get highest priority task TCB addressLDR r5, [r5] ; get stack pointerLDR sp, [r5] ; switch to the new stackSTR r5, [r4] ; set new current task TCB address;OSRunning = 1 'TURE'LDR r4, =0x01 ; Get current task TCB addressLDR r5, =OSRunning ; Get highest priority task TCB addressSTRB r4, [r5];LDMFD sp!, {r0-r12} ; start the new taskLDMFD sp!, {r14} ; get new state from top of the stackMSR CPSR_cxsf, r14 ; CPSR should be SVC32ModeLDMFD sp!, {lr,pc};中断级任务切换EXPORT OSIntCtxSwOSIntCtxSwIMPORT OSTCBCurIMPORT OSPrioCurIMPORT OSTCBHighRdyIMPORT OSPrioHighRdyIMPORT OSTaskSwHookBL OSTaskSwHook;OSTCBCur = OSTCBHighRdyLDR r4, =OSTCBCurLDR r5, =OSTCBHighRdyLDR r6, [r5]STR r6, [r4];OSPrioCur = OSPrioHighRdyLDR r4, =OSPrioCurLDR r5, =OSPrioHighRdyLDRB r6, [r5]STRB r6, [r4];sp = OSTCBHighRdy->OSTCBStkPtrLDR r6, =OSTCBHighRdyLDR r6, [r6]LDR sp, [r6] ; get new tasks stack pointerLDMFD sp!,{r0, r1};在timedly中断服务程序中,函数开始压栈两个寄存器,为保证堆栈中数据一致,需出栈对齐;resume registersLDMFD sp!, {r0-r12} ; start the new taskLDMFD sp!, {r14} ; get new state from top of the stack; LDR r14, =0x000000D3MSR CPSR_cxsf, r14 ; CPSR SVC32Mode调试时屏掉此句才会跑的通,待解决LDMFD sp!, {lr,pc}END中断服务程序代码IRQ_DOstmfd sp!, {r0,r1}ldr r0, =IRQ_R1str r1, [r0]ldmfd sp!, {r0}ldr r1, =IRQ_R0str r0, [r1] ;保存R0和R1寄存器(因为这两个寄存器再后面要用到)add r13, r13, #4 ;restore the sp_irq top to original irq topsub r14, r14, #4mov r0, r14 ;LR_irq(R14)减4并保存在R0mrs r1, spsrorr r1, r1, #0x80 ;将SPSR_irq的中断屏蔽位置‘1’(屏蔽中断),并保存再R1 中msr cpsr_cxsf, r1 ;将模式切换到中断前的模式;---------------------------------------------------------------------------------------------bic r1, r1, #0x80 ;将原先保存的SPSR_irq的R1的中断屏蔽位清零(允许中断)stmfd sp!, {r0}stmfd sp!, {r14}stmfd sp!, {r1} ;依次将R0,R14,R1的值压入中断前模式下的堆栈(当前R0,R14,R1中存放的分别是LR_irq-4,中断前模式下的LR,SPSR_irq)ldr r0, =IRQ_R1ldr r1, [r0]stmfd sp!, {r1}ldr r1, =IRQ_R0ldr r0, [r1]stmfd sp!, {r0}ldmfd sp!, {r0,r1} ;恢复原先保存的R0和R1stmfd sp!, {r0-r12} ;将r0--r12全部压入中断以前模式下的堆栈;; Get current task TCB addressIMPORT OSTCBCurLDR r4, =OSTCBCur;及时保存当前任务中断,因为可能会进行任务切换LDR r5, [r4]STR sp, [r5] ; store sp in preempted taskss TCB;-----------------------------IMPORT int_vector_handlerbl int_vector_handler ;跳转到中断源判断和中断处理程序;----------------------------- ;restore the registerldmfd sp!, {r0-r12} ;恢复原先保存的R0-R12ldmfd sp!, {r14}msr cpsr_cxsf, r14ldmfd sp!, {r14} ;将原先保存的SPSR_irq恢复到CPSR中ldmfd sp!, {pc}3、堆栈初始化函数OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) {unsignedint *stk;opt = opt; /* 'opt' is not used, prevent warning */stk = (unsigned int *)ptos; /* Load stack pointer *//* build a context for the new task */*--stk = (unsigned int) task; /* pc */*--stk = (unsigned int) task; /* lr */*--stk = (0x60000053); /* cpsr IRQ, FIQ disable*/*--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 = (unsigned int) pdata; /* r0 */// *--stk = (0x0); /* spsr IRQ, FIQ disable */return ((void *)stk);}4、timertick函数void Timer_IRQ_Service1(void){U32 dummyread;U8 y;dummyread = *(RP)TIMER_T1ISCR;/* timerflag = 1;*///OSIntNesting = OSIntNesting + 1;clear_reg( TIMER_T1CR, 0);//关闭通道1中断OSTimeTick ();set_reg( TIMER_T1CR, 0);//使能通道1中断OS_ENTER_CRITICAL();if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Sched. only if all ISRs done & not locked */y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to HPT ready to run */OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);if (OSPrioHighRdy != OSPrioCur) { /* No CtxSw if current task is highest rdy */OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];OSCtxSwCtr++; /* Increment context switch counter *///OS_TASK_SW(); /* Perform a context switch */OSIntCtxSw();}}OS_EXIT_CRITICAL();}第五步:对移植好的代码进行调试。
UCGUI移植

移植UCGUI只需要修改3个文件:GUIConf.h,LCDConf.h,LCDDummy.c,并从源代码的Sample/GUI_X文件夹下复制GUI_X.c文件到工程的GUILib/Config目录下1、GUIConf.h刚开始移植的时候是没有RTOS的,LCD也不是触摸屏,所以GUI_OS和GUI_SUPPORT_TOUCH都定义为0,其他宏不需要修改2、LCDConf.hLCD_XSIZE、LCD_YSIZE和LCD_BITSPERPIXEL根据开发板LCD的配置定义,我用的屏的分辨率是480*272的,16位RGB;LCD_CONTROLLER必须定义成-1,表示使用自己定义的LCD驱动,这个LCD驱动是通过修改LCDDummy.c模板来实现的,因为LCDDummy.c中开始部分要判断宏LCD_CONTROLLER是否等于-1,如果不等于-1,LCDDummy.c中的内容不会被编译,当然LCD_CONTROLLER也可以定义成其他植,但和LCDDummy.c中一定要对应起来,而且不能等于UCGUI自带的LCD驱动号LCD_ON和LCD_OFF一定要定义,因为LCDDummy.c中的LCD_On()和LCD_Off()函数先判断相应的宏是否被定义,如果没定义则不会执行函数体中的内容UCGUI的初始化过程中的LCD部分是通过GUI_Init()(GUICore.c)->LCD_Init()(LCD.c)->LCD_L0_Init()(LCD_Dummy.c)实现的,因为LCDDummy.c中的LCD初始化函数LCD_L0_Init()调用LCD_INIT_CONTROLLER()宏来调用自定义的LCD初始化函数,所以要将宏LCD_INIT_CONTROLLER()定义成自定义的LCD 初始化函数GLCD_Init()。
也可以在不用修改LCD_INIT_CONTROLLER()宏,而是在LCD_L0_Init()直接调用GLCD_Init()3、LCDDummy.cLCDDummy.c文件中需要修改的函数有:1)、void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex)2)、void LCD_L0_GetPixelIndex(int x, int y)3)、void LCD_On(void)4)、void LCD_Off(void)5)、int LCD_L0_Init(void)修改如下:其中395行的SetPixelIndex函数,422行的GetPixelIndex函数,536行的GLCD_On函数,542行GLCD_Off函数都是自己在LCD驱动文件中定义的函数,LCD_INIT_CONTROLLER()也被定义成LCD驱动文件中的LCD初始化函数4、LCD驱动文件1)、头文件drv_glcd.h:#include "lpc_types.h"#include "sdram_mt48lc2m32lfb5.h"#ifndef __GLCD_DRV_H#define __GLCD_DRV_H#define C_GLCD_PIX_CLK 9000000#define C_GLCD_REFRESH_FREQ (50HZ)#define C_GLCD_H_SIZE 480#define C_GLCD_H_PULSE 41#define C_GLCD_H_FRONT_PORCH 2#define C_GLCD_H_BACK_PORCH 2#define C_GLCD_V_SIZE 272#define C_GLCD_V_PULSE 10#define C_GLCD_V_FRONT_PORCH 2#define C_GLCD_V_BACK_PORCH 2#define LCD_RED 0xf800 /* red color */#define LCD_GREEN 0x07e0 /* green color */#define LCD_BLUE 0x001f /* blue color */#define LCD_BLACK 0x0000 /* black color */#define LCD_WHITE 0xffff /* white color */#define C_GLCD_PWR_ENA_DIS_DL Y 10000#define C_GLCD_ENA_DIS_DL Y 10000extern uint16_t LCD_Frame_Buffer[C_GLCD_H_SIZE * C_GLCD_V_SIZE];void GLCD_Init(void);void GLCD_Ctrl(BOOLEAN bEna);void SetPixelIndex(int x, int y, int PixelIndex);uint16_t GetPixelIndex(int x, int y);void GLCD_On(void);void GLCD_Off(void);#endif // __GLCD_DRV_H2)、drv_glcd.c文件#include <stdio.h>#include <stdlib.h>#include <assert.h>#include "board.h"#include "sdram_mt48lc2m32lfb5.h"#include "drv_glcd.h"#include "lpc177x_8x_clkpwr.h"#include "lpc177x_8x_pinsel.h"uint16_t LCD_Frame_Buffer[C_GLCD_H_SIZE * C_GLCD_V_SIZE];/************************************************************************** Function Name: GLCD_Init* Parameters: const uint32_t *pPain, const uint32_t * pPallete** Return: none** Description: GLCD controller init**************************************************************************/ void GLCD_Init(void){uint32_t i;//uint32_t *pDst = (uint32_t *)LCD_Frame_Buffer;//uint32_t p0,p1,p2,p3;/*Back light enable*///Turn on LCD clockCLKPWR_ConfigPPWR(CLKPWR_PCONP_PCLCD, ENABLE);// Disable cursorLPC_LCD->CRSR_CTRL &=~(1<<0);// disable GLCD controllerLPC_LCD->CTRL = 0;// 16 bppLPC_LCD->CTRL &= ~(0x07 <<1);LPC_LCD->CTRL |=(6<<1);// TFT panelLPC_LCD->CTRL |= (1<<5);// single panelLPC_LCD->CTRL &= ~(1<<7);// notmal output// LPC_LCD->CTRL &= ~(1<<8);LPC_LCD->CTRL |= (1<<8);// little endian byte orderLPC_LCD->CTRL &= ~(1<<9);// little endian pix orderLPC_LCD->CTRL &= ~(1<<10);// disable powerLPC_LCD->CTRL &= ~(1<<11);// init pixel clockLPC_SC->LCD_CFG = 1;//CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER) / ((uint32_t)C_GLCD_PIX_CLK);// bypass inrenal clk dividerLPC_LCD->POL |=(1<<26);// clock source for the LCD block is HCLKLPC_LCD->POL &= ~(1<<5);// LCDFP pin is active LOW and inactive HIGHLPC_LCD->POL |= (1<<11);// LCDLP pin is active LOW and inactive HIGH// LPC_LCD->POL |= (1<<12);LPC_LCD->POL &= ~(1<<12);// data is driven out into the LCD on the falling edge// LPC_LCD->POL |= (1<<13);LPC_LCD->POL &= ~(1<<13);// active highLPC_LCD->POL &= ~(1<<14);LPC_LCD->POL &= ~(0x3FF <<16);LPC_LCD->POL |= (C_GLCD_H_SIZE-1)<<16;// init Horizontal TimingLPC_LCD->TIMH = 0; //reset TIMH before set valueLPC_LCD->TIMH |= (C_GLCD_H_BACK_PORCH - 1)<<24;LPC_LCD->TIMH |= (C_GLCD_H_FRONT_PORCH - 1)<<16;LPC_LCD->TIMH |= (C_GLCD_H_PULSE - 1)<<8;LPC_LCD->TIMH |= ((C_GLCD_H_SIZE/16) - 1)<<2;// init Vertical TimingLPC_LCD->TIMV = 0; //reset TIMV value before settingLPC_LCD->TIMV |= (C_GLCD_V_BACK_PORCH)<<24;LPC_LCD->TIMV |= (C_GLCD_V_FRONT_PORCH)<<16;LPC_LCD->TIMV |= (C_GLCD_V_PULSE - 1)<<10;LPC_LCD->TIMV |= C_GLCD_V_SIZE - 1;// Frame Base Address doubleword alignedLPC_LCD->UPBASE = (uint32_t)LCD_Frame_Buffer & ~7UL ;LPC_LCD->LPBASE = (uint32_t)LCD_Frame_Buffer & ~7UL ;for(i = C_GLCD_ENA_DIS_DL Y; i; i--);return ;}/************************************************************************* * Function Name: GLCD_Ctrl* Parameters: Bool bEna** Return: none** Description: GLCD enable disabe sequence**************************************************************************/void GLCD_Ctrl (BOOLEAN bEna){volatile uint32_t i;if (bEna){// LCD_CTRL_bit.LcdEn = 1;LPC_LCD->CTRL |= (1<<0);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--);// LCD_CTRL_bit.LcdPwr= 1; // enable powerLPC_LCD->CTRL |= (1<<11);}else{// LCD_CTRL_bit.LcdPwr= 0; // disable powerLPC_LCD->CTRL &= ~(1<<11);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--);// LCD_CTRL_bit.LcdEn = 0;LPC_LCD->CTRL &= ~(1<<0);}}void SetPixelIndex(int x, int y, int PixelIndex){if ((x < C_GLCD_H_SIZE) && (y < C_GLCD_V_SIZE)) {LCD_Frame_Buffer[x + y * C_GLCD_H_SIZE] = (uint16_t)PixelIndex;}}uint16_t GetPixelIndex(int x, int y){if ((x < C_GLCD_H_SIZE) && (y < C_GLCD_V_SIZE)) {return LCD_Frame_Buffer[x + y * C_GLCD_H_SIZE];}return 0;}void GLCD_On(void){uint32_t i;// LCD_CTRL_bit.LcdEn = 1;LPC_LCD->CTRL |= (1<<0);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--);// LCD_CTRL_bit.LcdPwr= 1; // enable powerLPC_LCD->CTRL |= (1<<11);}void GLCD_Off(void){uint32_t i;// LCD_CTRL_bit.LcdPwr= 0; // disable power LPC_LCD->CTRL &= ~(1<<11);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--); // LCD_CTRL_bit.LcdEn = 0;LPC_LCD->CTRL &= ~(1<<0);}。
实验一 uCOS-II的移植

实验一uC/OS-II的移植1.实验目的(1)理解uCOS-II实时内核的工作原理;(2)熟悉uCOS-II在XS128上的移植过程;(3)掌握uCOS-II移植的细节。
2.实验任务(1)观察示例程序中的代码,体会实时操作系统与前后台程序的不同之处。
(2)完成由前后台程序编程到基于实时操作系统编程的思想转变。
3.预习要求(1)参考《嵌入式实时操作系统uCOS-II》(第2版),熟悉uCOS-II各模块的基本工作原理。
(2)参考《单片机与嵌入式系统开发方法》第9章内容以及《uCOS-II移植说明文档》。
熟悉uCOS-II在XS128上的移植过程。
4.实验步骤(1)打开示例程序,观察程序结构。
(2)识别出哪些是与硬件无关的文件,哪些是移植需要修改和添加的文件。
(3)打开OS_CPU.H文件,该文件定义CPU的数据类型,定义相关的宏。
打开OS_CPU_C文件,分析文件里各个函数的作用。
这两个文件是与CPU特性有关的文件。
(4)分别打开OS_CFG.H, INCLUDES.H. OS_CFG.H这三个文件,了解这三个文件的作用。
用户根据自己的应用系统来定制合适的内核服务功能.包括两个文件:OS_CFG.H, INCLUDES.H. OS_CFG.H是来配置内核, 用户根据需要对内核进行定制, 留下需要的部分, 去掉不需要的部分, 设置系统的基本情况. 比如系统可提供的最大任务数量, 是否定制邮箱服务, 是否需要系统提供任务挂起功能, 是否提供任务优先级动态改变功能等等;头文件INCLUDES.H为整个实时系统程序所需要的文件,包括了内核和用户的头文件。
(5)修改.prm文件中的中断向量,将其中的ROM_C000 = READ_ONLY DATA_NEAR IBCC_NEAR 0xC000 TO 0xFEFF;改为ROM_C000 = READ_ONLYDATA_NEAR IBCC_NEAR 0xC000 TO 0xEEFF;将结尾处原有的VECTOR 0 _Startup;改为VECTOR ADDRESS 0xEFFE _Startup;再添加上VECTOR ADDRESS 0xEFF6 OSCtxSw;VECTOR ADDRESS 0xEFF0 OSTickISR两个中断向量。
关于UCOS-Ⅱ的移植

关于UC/OS-II的移植网上介绍的已经很多了,比较流行的几款处理器(例如ARM)在网上都可以直接下载移植好的代码。
由于最近选修了一门嵌入式系统的课,用的处理器是EPSON公司的S1C33系列,做实验的时候要进行操作系统的移植,这个周末花了一天半的时间学习了一下,因为毕业设计的时候做过ARM 上的移植,于是将两者比较了一下,给出一般的移植要点。
由于将来实验还要设计到GUI的移植以及文件系统的移植和网络协议的移植,我会将自己的学习笔记都记录下来。
大家下载到源码后,针对Intel 80x86的代码在uCOS-II\Ix86L目录下。
代码是80x86实模式,且在编译器大模式下编译的。
移植部分的代码可在下述文件中找到:OS_CPU.H, OS_CPU_C.C, 和OS_CPU_A.ASM。
大家可以参考这个例子,对它进行修改。
INCLUDES.H 是主头文件,在所有后缀名为.C的文件的开始都包含INCLUDES.H文件。
使用INCLUDES.H 的好处是所有的.C文件都只包含一个头文件,程序简洁,可读性强。
缺点是.C文件可能会包含一些它并不需要的头文件,额外的增加编译时间。
与优点相比,多一些编译时间还是可以接受的。
用户可以改写INCLUDES.H文件,增加自己的头文件,但必须加在文件末尾。
//////////////////////////////////////////////////////////一、(1)OS_CPU.H文件的移植(针对S1C33209)//////////////////////////////////////////////////////////OS_CPU.H 文件中包含与处理器相关的常量,宏和结构体的定义。
#ifdef OS_CPU_GLOBALS#define OS_CPU_EXT //全局变量#else#define OS_CPU_EXT extern#endif//////////////////////////////////////////////////////////由于不同的处理器有不同的字长,µC/OS-II的移植需要重新定义一系列的数据结构。
uCGUI简单移植

嵌入式图形用户界面uc/gui在nios II上的移植uc/gui是一个优秀的嵌入式图形用户界面,这几天的工作就是将它移植到nios II系统上。
前人也做了一些工作,不过大部分都是针对其他硬核处理器,针对nios II软核处理器的移植资料那简直是凤毛麟角。
在阅读了相关文档后,我决定自己亲自动手实践,这下面的很多过程都是自己摸索出来的,并通过了实验的验证。
这只是一个初步的移植,也许在以后的更复杂的应用中,还需要对其进行调整。
但对目前我的应用而言,应该足够了。
写这篇文章的目的一是由于自己记性不好,所以需要给自己留个备忘,免得以后忘的一干二净;二是给有需要的朋友提供一些参考,也好相互交流,共同进步。
请大家多提宝贵意见。
一、源码和文档下载/上有很多不同版本的源码下载,目前能下到的最新版本是3.98,不过还有一些组件不是很完整,但作基础开发已经够用了。
ucgui3.98源码下载地址:uC-GUI-V3-98.zip。
ucgui最新版用户手册下载地址:uC-GUI-user.rar。
开发软件:quartus II 6.0, Nios II IDE 6.0。
二、移植过程先来看看解压后都有些什么东西:如图,核心的东西包括Config和GUI两个文件夹,这里面是ucgui的所有源码和配置文件。
ConvertColor包含彩色转换函数,ConvertMono包含灰度到彩色转换的函数,Core包含核心程序,Font是字体文件,LCDDriver包含多种控制器驱动,Widget是窗口控件库,WM是窗口库,提供复杂的功能。
其他文件夹包含一些应用范例以及一些有用的工具,留待慢慢探索。
1、config文件的移植:Config文件夹是ucgui的配置文件夹,里面有3个文件:GUIConf.h:gui的基本属性配置文件,有很多开关可以配置,具体可以参考ucgui的用户手册,这里只需配置几个必要的参数如下:#ifndef GUICONF_H#define GUICONF_H#define GUI_OS (1) /* 支持操作系统,nios系统自带了ucosII,所以我们选择此项,使gui支持该操作系统*/#define GUI_SUPPORT_TOUCH (0) /* 支持触摸屏,由于暂时没有用触摸屏,所以关掉这个开关*/#define GUI_SUPPORT_MOUSE (0) /* 支持鼠标,暂时关闭*/#define GUI_SUPPORT_UNICODE (1) /* Unicode字符串支持*/#define GUI_DEFAULT_FONT &GUI_Font6x8/* 默认字体*/#define GUI_ALLOC_SIZE 12500/* WM和memery device分配的内存*/ #define GUI_WINSUPPORT 1 /* Window manager available */#define GUI_SUPPORT_MEMDEV 0 /* Memory devices available,由于下载到的源代码中缺少memery device组件的源码,所以关闭此项*/#define GUI_SUPPORT_AA 1 /* Anti aliasing available */#endif /* Avoid multiple inclusion */LCDConf.h:LCD控制器的硬件配置文件,这个文件与硬件直接相关,一般是根据你所使用的LCD的类型和所用的LCD控制器的类型来配置。
uCOS-II移植实验

17
五
基础知识
OS_CPU.S的移植 -OSStartHighRd
OSStartHighRd()函数是在OSStart()多任务启动之后,从最高优先 级任务的TCB控制块中获得该任务的堆栈指针sp,通过sp依次将cpu现 场恢复,这时系统就将控制权交给用户创建的该任务进程,直到该任 务被阻塞或者被其他更高优先级的任务抢占cpu.该函数仅仅在多任务 启动时被执行一次,用来启动第一个,也就是最高优先级的任务执行.
void OSIntCtxSw(void) { need_to_swap_context = 1; }
12
五
基础知识
OS_CPU.S的移植 -时钟节拍中断服务函数
时钟节拍是特定的周期性中断.这个中断可以看作是系统 心脏的脉动. 时钟的节拍式中断使得内核可以将任务延时若干个整数时 钟节拍,及当任务等待事件发生时,提供等待超时的依据. 时钟节拍率越快,系统的额外开销就越大.中断之间的时 间间隔取决于不同的应用,本系统使用S3C44B0的timer 0 作为时钟节拍源,产生间隔10mS的时钟节拍. OSTickISR()就是时钟节拍中断服务函数,也就是S3C44B0 的timer 0的中断处理函数.
jx44b0实验系统教案ucosii移植实验jx44b0实验系统教案ucosii移植实验武汉创维特信息技术有限公司201969提纲11113333222244445555基础知识实验目的实验内容预备知识实验设备6666实验过程7777实验报告要求实验目的实验目的了解ucosii内核的基本原理和主要结构掌握将ucosii内核移植到arm处理器上的基本方法掌握ucosii下基本多任务应用程序的编写实验内容实验内容学习ucosii再arm处理器上的移植过程编写简单的多任务应用程序同时实现跑马灯和数码管显示的功能预备知识预备知识了解嵌入式操作系统的构架以及具体的ucosii的组成了解操作系统的移植方法实验设备实验设备jx44b0教学实验箱adt1000仿真器和adtide集成开发环境串口连接线基础知识ucosii概述ucosii在特定处理器上的移植工作绝大部分集中在多任务切换的实现上因为这部分代码主要是用来保存和恢复处理器现场许多操作如读写寄存器操作不能用c语言只能使用特定的处理器的汇编语言来完成
uCGUI NIOS II移植及应用笔记

uC/GUI NIOS II移植及应用笔记这是前些日子在使用uc/GUI的时候即下来的一些东西原来发布在EDACN的bbs上面。
现在不知道沉到哪里去了。
现在把它重新整理发布在这里。
随后在明年过年的时候把后续的几个高级主题整理出来。
下面开始我的笔记!有兴趣的兄弟们可以来看看。
step1.下载uC/GUI的代码。
(废话没有源代码移植个鸟)我下载的时uC/GUI3.32这是能得到的源代码中最全的一个版本。
看看里面都有些什么东西。
由于这里的发间大小的限制的问题不能上传源代码。
很是郁闷。
有需要的同志可以联系我。
Email:william7447@首先看看所有名叫Simulation的东西这是uC/GUI在VC中仿真的VC工程,他的仿真功能非常的实用可以在没有具体硬件的情况下先行开发软件,而丝毫不影响软件的兼容性。
但是有一个问题比较郁闷,就是速度的问题。
大家知道嵌入式系统的CPU运算能力有限,而电脑的cpu.........我的整个项目的gui是在电脑上完成的。
拿到目标系统上面编译.......通过。
经过紧张的下载.....................运行..........显示出了第一个画面,无比的兴奋。
但测试发现极其郁闷而几乎无法解决的问题......目标系统的处理能力只有100mips而我的电脑的cpu是P4 3.0。
速度的差别太大了。
解决这个问题几乎成了我后半段工作的主题。
GUI文件夹存放全部uC/GUI源代码的地方看看它的属性有多达390个文件,全部是.c和.h。
可以看出GUI系统是一个庞大复杂的东西。
我在调试系统的时候跟踪过完整的消息循环再进入了60多个子函数调用后还没有看到希望,就彻底的放弃了跟踪的想法。
下来会具体说明这里面都有些什么东西。
config文件夹uC/GUI的配置文件夹。
里面存放的是uC/GUI的配置头文件。
改动里面的相应的就可以改动uC/GUI的配置。
这个GUI功能十分强大。
uCOS-II多核移植

uC/OS-II是源码开放、可固化、可移植、可裁剪、可剥夺的实时多任务OS 内核,适用于任务多、对实时性要求较高的场合。
uC/OS-II适合小型系统,具有执行效率高、占用空间小、实时性优良和可扩展性等特点,最小内核可编译至2K。
uC/OS-II内核提供任务调度与管理、时间管理、任务间同步与通信、内存管理和中断服务等功能。
所谓RTOS移植,就是使一个实时内核能在某个微处理器或微控制器上运行。
大部分的uC/OS-II代码试用C写的,但仍需要用C和ASM写一些与处理器相关的代码,这是因为uC/OS-II在读写处理器寄存器时只能通过ASM实现。
要是uC/OS-II正常运行,处理器必须满足一定的条件:处理器的C编译器能产生可重入代码;用C语言就可以打开和关闭中断;处理器支持中断,并能产生定时中断;处理器支持能够容纳一定量数据的硬件堆栈;处理器有将SP和其他CPU reg读出和存储到堆栈或内存中的指令;uC/OS-II移植工作主要包括以下三个方面的内容:(1)修改与处理器核编译器相关的代码:主要在includes.h中,修改数据类型定义说明,OS_ENTER_CRITICAL()、OS_EXIT_CRITICAL()和堆栈增长方向定义OS_STK_GROWTH。
(2)用C语言编写10个移植相关的函数:主要在OS_CPU_C.C中,包括堆栈初始化OSTaskStkInit()和各种回调函数。
(3)编写4个汇编语言函数:主要在OS_CPU_A.ASM中,包括:_OSTickISR //时钟中断处理函数_OSIntCtxSW //从ISR中调用的任务切换函数_OSCtxSW //从任务中调用的任务切换函数_OSStartHighRdy //启动最高优先级的任务uC/OS-II移植的关键问题:(1)临界区访问:uC/OS-II需要先禁止中断再访问代码临界段,并且在访问完毕后重新允许中断,这就使得uC/OS-II能够保护临界段代码免受多任务或ISR的破坏。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
stm32 UCGUI 完美移植作者:Changing发表时间:09-16 04:13分类:电子相关1 Comment前一篇:stm32 DA 数模转换后一篇:Stm32 SWD 下载 调试配置UCGUI是一种嵌入式应用中的图形支持系统。
它设计用于为任何使用LCD图形显示的应用提供高效的独立于处理器及LCD控制器的图形用户接口,它适用单任务或是多任务系统环境, 并适用于任意LCD控制器和CPU下任何尺寸的真实显示或虚拟显示。
它的设计架构是模块化的,由不同的模块中的不同层组成,由一个LCD驱动层来包含所有对LCD的具体图形操作。
UCGUI可以在任何的CPU上运行,因为它是100%的标准C代码编写的。
类似程序还有国产的一个MINIGUI (/zhcn/),MiniGUI 是一个自由软件项目。
其目标是提供一个快速、稳定、跨操作系统的图形用户界面(GUI)支持系统,尤其是基于 Li nux/uClinux、eCos 以及其他传统 RTOS(如 VxWorks、ThreadX、uC/OS-II、Nucleus 等)的实时嵌入式操作系统。
有机会尝试下,支持下国产,毕竟国内这样的公司不多。
这里移植的UCGUI3.90a版本,虽然已经有更新的版本,比如UCGUI3.98、甚至4.04版本。
但是目前来说只有这个版本的代码是最全的,包括了JPEG , MULTILAYER , MEMDEV ,AntiAlias等模块。
一直想尝试做一个数码相册,JEPG模块自然少不了,所以移植了这个版本。
UCGUI390a 下载整个移植过程,让LCD显示图案倒是没花多少时间,资料也比较多,但是在移植触摸屏的时候卡了好几天,然后又是 UCGUI 指针图标 移动有重影(LCD读取像素颜色函数有问题)。
总之移植是个累人的活首先需要保证你的LCD驱动和触摸屏驱动是有效的,如果你的LCD也是ili93xx 控制器 XPT2046控制器的触摸屏可以参考 stm32 驱动 T F T LCD stm32 驱动 触摸屏 两篇文章UCGUI的文件数量很大,主要用到UCGUI390a/Start/Con f ig 和 UCGUI390a/Start/GUI两个文件夹下文件,不过文件数量也已经很多了 。
相关文件介绍如下:将Con f ig和GUI下所有文件加入工程,MD K中新建工程需要划分好结构,这是UCGUI官方推荐的结构:JPEG, MemDe v, MultiLa y er , Widget , Wm 这5个文件夹的内容可以暂时不加入MD K 工程。
因为这些文件起到的是扩展功能,在移植阶段可以先不添加,等到以后用到其中的功能时再选择添加。
但是建议都添加进去,避免遇到各种无解问题。
当然前提是在配置时要把相应的功能开关关掉,在下面的步骤中会提到。
Con v erMono , Con v erColor ,Core ,F ont 这四个目录下的文件是不用修改的。
要修改的文件在LCDDri v er ,Con f ig 这两个目录下。
LCDDri v er 是LCD的驱动接口函数文件,需要将自己的LCD驱动函数提供给UCGUI调用。
需要提供3个LCD底层驱动函数:•v oid LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) LCD画点函数, 用指定颜色填充一个像素•unsigned int LCD_L0_GetPixelIndex(int x, int y) LCD读取定点颜色函数,读取一个像素点的16位RG B颜色值•v oid LCD_L0_F illRect(int x0, int y0, int x1, int y1)矩形填充函数,用指定颜色填充一个矩形 。
这个函数也可以不改使用UCGUI的函数,用一个一个的像素点填充成一个矩形。
也可以在底层驱动根据像素个数直接往GRAM 中写数据,封装成函数,供这个函数调用。
速度会快很多。
其他的画线画图形函数,也可以同样优化。
LCDDri v er 下有三个文件, LCDDumm y.c 、LCDNull.c 和LCDWin.c。
这三个都是UCGUI LCD接口模板文件。
功能一样,只是移植时修改的细节不一样。
我们可以选用其中一个,稍作修改作为接口文件。
以LCDDumm y.c为例:v iew sourceprint?0 1#include "LCD_Private.h" /* private modul definitions &config */02#include "GUI_Private.h"03#include "GUIDebug.h"0405/*#if (LCD_CONTROLLER == -1) \0 6&& (!defined(WIN32) | defined(LCD_SIMCONTROLLER))*///必须注释,否则不会编译070 8#include "ili93xx.h" //包含你的LCD驱动函数声明09#if (LCD_CONTROLLER == -1) //这句对应Config/LCDConf.h 1011........12........1314void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) { 151 6POINT_COLOR = PixelIndex; //我的画点函数使用了一个全局变量设定颜色1 7LCD_DrawPoint(x,y); //画点函数1819}2021........22........2324unsigned int LCD_L0_GetPixelIndex(int x, int y) {2526return LCD_ReadPoint(x,y); //我的读取像素颜色函数 27}28........29........3031void LCD_L0_FillRect(int x0, int y0, int x1, int y1) {3233LCD_Fill(x0,y0,x1,y1,LCD_COLORINDEX); //填充矩形函数 34/*for (; y0 <= y1; y0++) {35LCD_L0_DrawHLine(x0, y0, x1);36}*/37}UCGUI提供了一些LCD控制器的驱动函数,但是这种配置方法,可以适用于任何控制IC。
到这就算完成三分之一了,接下来修改Con f ig文件夹下文件,Con f ig下有三个文件:GUICon f.h LCDCon f.h GUITouchCon f.h还需要加入一个GUI_X.c文件,要不然编译的时候会有错误。
直接复制UCGUI390a\Sample\GUI_ X\GUI_X.c即可。
如果打开了触摸功能还需要加入一个UCGUI390a\Sample\GUI_X\GUI_X_Touch.c 。
这三个文件是UCGUI的上层配置文件,也就是GUI 一些功能的开关。
GUICon f.h:v iew sourceprint?01#ifndef GUICONF_H02#define GUICONF_H030 4#define GUI_OS (0) /* 操作系统的支持,当用到ucos 时需要打开 Compile with multitasking support */0 5#define GUI_SUPPORT_TOUCH (1) /* 触摸屏的支持 Support a touch screen (req. win-manager) */0 6#define GUI_SUPPORT_UNICODE (0) /* 用汉字库时再打开 S upport mixed ASCII/UNICODE strings */070 8#define GUI_DEFAULT_FONT &GUI_Font6x8 /* 定义字体大小 */0 9#define GUI_ALLOC_SIZE 12500 /*分配的动态内存空间 Size of dynamic memory ... For WM and memory devices*/101 1/*********************************************************************12*13* Configuration of available packages 14*/151 6#define GUI_WINSUPPORT 1 /* 窗口功能支持 要使用指针图标 必须打开 Window manager package available */1 7#define GUI_SUPPORT_MEMDEV 1 /* 内存管理 Memory devices available */1 8#define GUI_SUPPORT_AA 1 /* 抗锯齿功能,打开后可以提高显示效果 Anti aliasing available */1920#endif /* Avoid multiple inclusion */ LCDCon f.hv iew sourceprint?01#ifndef LCDCONF_H02#define LCDCONF_H030 4#define LCD_XSIZE (240) /* lcd 的水平分辨率 X-resolution of LCD, Logical coor. */0 5#define LCD_YSIZE (320) /* lcd 的垂直分辨率 Y-resolution of LCD, Logical coor. */060 7#define LCD_BITSPERPIXEL (16) /* 16位颜色RGB值 颜色深度*/08#define LCD_SWAP_RB (1) /*红蓝反色交换 */ 0910/* lcd 控制器的具体型号11*12* 设置为 -1时 会编译LCDDriver 下 LCDDummy.c13* 设置为 -2时 会编译LCDDriver 下 LCDNull.c14*15* 还需要修改LCDDriver 下文件的宏定义 才可以被编译 16* eg. LCDDummy.c:17*1 8* #if (LCD_CONTROLLER == -1) && (!defin ed(WIN32) |defined(LCD_SIMCONTROLLER))19* 改为20* #if (LCD_CONTROLLER == -1) 21*/2 2#define LCD_CONTROLLER -1 //设置为-1\-2,因为UCGUI没有相应LCD 控制IC驱动232 4#define LCD_INIT_CONTROLLER() LCD_Config(); //绑定相关LCD底层驱动的初始化函数配置完这两个文件,如果不启用触摸屏的话,UCGUI已经可以正常运行。