需要工程文件的加我的QQ:1653687969需要嵌入式arm和linux入门资料和驱动资料加我QQ:1653687969uc/os-ii移植笔记(此部分参考了tomato的介绍) os_cpu.h 与编译器相关的数据类型 typedef unsigned char BOOLEAN; typedef unsigned char INT8U; /* Unsigned 8 bit quantity */ typedef signed char INT8S; /* Signed 8 bit quantity */ typedef unsigned short INT16U; /* Unsigned 16 bit quantity */ typedef signed short INT16S; /* Signed 16 bit quantity */ typedef unsigned int INT32U; /* Unsigned 32 bit quantity */ typedef signed int INT32S; /* Signed 32 bit quantity */ typedef float FP32; /* Single precision floating point*/ typedef double FP64; /* Double precision floating point */ typedef unsigned int OS_STK; /* 堆栈类型为32位 Each stack entry is 32-bit wide */ typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */ 与ARM 处理器相关的代码 #define OS_CRITICAL_METHOD 3 //进入临界段的方法 #if OS_CRITICAL_METHOD == 3 #define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();} //关中断 #define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);} //开中断 #endif #if OS_CRITICAL_METHOD == 3 OS_CPU_SR OS_CPU_SR_Save(void); void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr); #endif void OSCtxSw(void); void OSIntCtxSw(void); void OSStartHighRdy(void); 设置堆栈的增长方向 #define OS_STK_GROWTH 1 /*堆栈由高地址向低地址增长*/ OS_CPU_C.C 用C 语言编写六个操作系统相关的函数 OS_STK *OSTaskStkInit ( void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt) { OS_STK *stk; (void)opt; /* 'opt' is not used, prevent warning */ stk = ptos; /* Load stack pointer */ /* Registers stacked as if auto-saved on exception */ *(stk) = (INT32U)0x01000000L; /* xPSR */ *(--stk) = (INT32U)task; /* Entry Point */ *(--stk) = (INT32U)0xFFFFFFFEL; /* R14 (LR) (init value will cause fault if ever used)*/ *(--stk) = (INT32U)0x12121212L; /* R12 */ *(--stk) = (INT32U)0x03030303L; /* R3 */ *(--stk) = (INT32U)0x02020202L; /* R2 */ *(--stk) = (INT32U)0x01010101L; /* R1 */ *(--stk) = (INT32U)p_arg; /* R0 : argument */ /* Remaining registers saved on process stack */ *(--stk) = (INT32U)0x11111111L; /* R11 */ *(--stk) = (INT32U)0x10101010L; /* R10 */ *(--stk) = (INT32U)0x09090909L; /* R9 */ *(--stk) = (INT32U)0x08080808L; /* R8 */ *(--stk) = (INT32U)0x07070707L; /* R7 */ *(--stk) = (INT32U)0x06060606L; /* R6 */ *(--stk) = (INT32U)0x05050505L; /* R5 */ *(--stk) = (INT32U)0x04040404L; /* R4 */ return (stk); } void OSTaskCreateHook (OS_TCB *ptcb) {ptcb=ptcb;//防止编译时出现警告 } OS_CPU_A.ASM 用汇编语言编写四个与处理器相关的函数 ;// 引用外部变量的声明 EXTERN OSRunning EXTERN OSPrioCur EXTERN OSPrioHighRdy EXTERN OSTCBCur EXTERN OSTCBHighRdy EXTERN OSIntNesting EXTERN OSTaskSwHook EXTERN OSRdyGrp EXTERN OSRdyTbl EXTERN OSPrioHighRdy ;// 外部可以调用的函数 PUBLIC OS_CPU_SR_Save PUBLIC OS_CPU_SR_Restore PUBLIC OSStartHighRdy PUBLIC OSCtxSw PUBLIC OSIntCtxSw ;//以上5个函数在os_cpu_c.c文件下有声明 PUBLIC PendSVC ;//此函数在stm3210x_it.c stm32f10x_it.h stm32f10x_vector.c文件下有声明 ;//*********************************************************************************************** ;// PendSV 所使用的几个寄存器 ;//*********************************************************************************************** NVIC_INT_CTRL EQU 0xE000ED04 ;// 中断控制及状态寄存器 NVIC_SYSPRI14 EQU 0xE000ED22 ;// 控制PendSV优先级的寄存器 NVIC_PENDSV_PRI EQU 0xFF ;// PendSV 异常优先级(最低) NVIC_PENDSVSET EQU 0x10000000 ;// PendSV 异常触发位掩码 (1) OSStartHighRdy( );运行优先级最高的就绪任务 OSStartHighRdy LDR R0, =NVIC_SYSPRI14 ;// 设置PendSV优先级 LDR R1, =NVIC_PENDSV_PRI STRB R1, [R0] MOVS R0, #0 ;// 初始化线程PSP MSR PSP, R0 LDR R0, =OSRunning ;// OSRunning = TRUE MOVS R1, #1 STRB R1, [R0] LDR R0, =NVIC_INT_CTRL ;// 触发PendSV异常, 让PendSv任务切换开始 LDR R1, =NVIC_PENDSVSET STR R1, [R0] CPSIE I ;// 打开总中断 OSStartHang B OSStartHang ;// while(1); (2)OSCtxSw();任务级的任务切换函数 OSCtxSw LDR R0, =NVIC_INT_CTRL ;// 触发PendSV异常 LDR R1, =NVIC_PENDSVSET STR R1, [R0] BX LR (3)OSIntCtxSw();中断级的任务切换函数 OSIntCtxSw LDR R0, =NVIC_INT_CTRL ;// 触发PendSV异常 LDR R1, =NVIC_PENDSVSET STR R1, [R0] BX LR (4)OSTickISR();中断服务函数 未添加 (5)临界段代码 OS_CPU_SR_Save MRS R0, PRIMASK CPSID I BX LR OS_CPU_SR_Restore MSR PRIMASK, R0 BX LR (6)PendSVC代码 在cm3内核下,真正的任务文本切换是靠本函数实现 PendSVC CPSID I ;// 任务context切换是关闭中断 MRS R0, PSP ;// 获取PSP CBZ R0, OS_CPU_PendSVHandler_nosave ;// 在多任务初始化时,PSP被初始化为0 ;// PSP如果是0,标示任务没有运行过,那么不需要压栈 ;// 直接加载任务context SUBS R0, R0, #0x20 ;// 调整PSP指针, R4-R11 共32字节 STM R0, {R4-R11} ;// 压栈R4-R11, 其他8个寄存器是在异常时自动压栈的 LDR R1, =OSTCBCur ;// 获取OSTCBCur->OSTCBStkPtr LDR R1, [R1] STR R0, [R1] ;// 将当前任务的堆栈保存到自己的任务控制块 ;// OSTCBCur->OSTCBStkPtr = PSP ;// 程序运行此位置,已经保存了当前任务的context了 OS_CPU_PendSVHandler_nosave ;// 使能OSTaskSwHook的时候去掉注释 ;//PUSH {R14} ;//LDR R0, =OSTaskSwHook ;//BLX R0 ;//POP {R14}
;// 在调度之前,系统内核已经计算好 ;// OSPrioHighRdy 和 OSTCBHighRdy LDR R0, =OSPrioCur ;// 当前任务优先级 = 就绪任务优先级 LDR R1, =OSPrioHighRdy ;// OSPrioCur = OSPrioHighRdy; LDRB R2, [R1] STRB R2, [R0] LDR R0, =OSTCBCur ;// 当前任务控制块 = 就绪任务控制块; LDR R1, =OSTCBHighRdy ;// OSTCBCur = OSTCBHighRdy; LDR R2, [R1] ;// STR R2, [R0] ;// 此时 [R2] = 新任务的PSP LDR R0, [R2] ;// R0 = 新任务的PSP LDM R0, {R4-R11} ;// 出栈 R4 - R11 ADDS R0, R0, #0x20 ;// 调整PSP MSR PSP, R0 ;//
;// 当前异常使用的堆栈是MPS ORR LR, LR, #0x04 ;// 修改LR的BIT2=1, 确保异常退出时堆栈使用PSP ;// 类似修改CONTROL[1] = 1 CPSIE I BX LR ;// 异常返回 END 在引用头文件中需要包含宏定义 #define OS_GLOBALS ucgui移植笔记在源文件夹的Start\GUI\LCDDriver下有个LCDDummy.c文件,主要修改此文件与自己的lcd驱动文件进行链接。 主要修改以下这两个函数就可以了: unsigned int LCD_L0_GetPixelIndex(int x, int y) void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) 移植步骤: 配置LCDConf.h文件如下:#ifndef LCDCONF_H #define LCDCONF_H #define LCD_XSIZE (240) /*X轴分辨率 */ #define LCD_YSIZE (320) /* Y轴分辨率 */ #define LCD_BITSPERPIXEL (16) //像素位数 #define LCD_FIXEDPALETTE (565) //颜色模板 //#define LCD_SWAP_RB (1) //以下两部分在LCDDummy.c文件中要用到 #define LCD_CONTROLLER 9320 //控制器型号的配置 #define LCD_INIT_CONTROLLER() Touch_Initializtion();ili9320_Initializtion() //LCD初始化 #endif 在LCDDummy.c文件中,需要修改以下3个函数和一个宏判断,并添加自己的lcd驱动头文件 (1)宏修改#if (LCD_CONTROLLER == -1) \ && (!defined(WIN32) | defined(LCD_SIMCONTROLLER)) 此处 将 -1 改为 9320 ,以对应上面的配置。 (2)LCD_L0_Init 初始化lcd函数int LCD_L0_Init(void) { LCD_INIT_CONTROLLER() ; //对应LCDConf.h文件中的宏定义 return 0; } (3)LCD_L0_GetPixelIndexunsigned int LCD_L0_GetPixelIndex(int x , int y) { LCD_PIXELINDEX PixelIndex; /* Convert logical into physical coordinates (Dep. on LCDConf.h) */ #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y int xPhys = LOG2PHYS_X(x, y); int yPhys = LOG2PHYS_Y(x, y); #else #define xPhys x #define yPhys y #endif /* Read from hardware ... Adapt to your system 需要自己添加的部分*/ { PixelIndex = 0; /* ... */ ili9320_SetCursor(x,y); LCD_WriteRAM_Prepare(); PixelIndex = LCD_ReadRAM(); return PixelIndex; } return PixelIndex; } (4)LCD_L0_SetPixelIndexvoid LCD_L0_SetPixelIndex (int x , int y , int PixelIndex) { /* Convert logical into physical coordinates (Dep. on LCDConf.h) */ #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y int xPhys = LOG2PHYS_X(x, y); int yPhys = LOG2PHYS_Y(x, y); #else #define xPhys x #define yPhys y #endif /* Write into hardware ... Adapt to your system 以下部分需要自己去写的,对应自己的lcd驱动文件*/ { /* ... */ ili9320_SetCursor(x,y); LCD_WriteRAM_Prepare(); LCD_WriteRAM(PixelIndex); } } 配置GUIConf.h文件如下:#define GUI_OS (1) /* Compile with multitasking support */ #define GUI_SUPPORT_TOUCH (1) /* Support a touch screen (req. win-manager) */ #define GUI_SUPPORT_UNICODE (1) /* Support mixed ASCII/UNICODE strings */ #define GUI_DEFAULT_FONT &GUI_Font6x8 #define GUI_ALLOC_SIZE 1024*2 /* Size of dynamic memory ... For WM and memory devices*/ #define GUI_WINSUPPORT 1 /* Window manager package available */ #define GUI_SUPPORT_MEMDEV 1 /* Memory devices available */ #define GUI_SUPPORT_AA 1 /* Anti aliasing available */ 配置GUITouchConf.h文件如下:#define GUI_TOUCH_AD_LEFT 400 //模拟电压值,左、右、上、下 #define GUI_TOUCH_AD_RIGHT 3800 //根据自己的触摸屏参数填写 #define GUI_TOUCH_AD_TOP 3730 #define GUI_TOUCH_AD_BOTTOM 400 #define GUI_TOUCH_XSIZE 240 #define GUI_TOUCH_YSIZE 320
#define GUI_TOUCH_SWAP_XY 0 #define GUI_TOUCH_MIRROR_X 1 #define GUI_TOUCH_MIRROR_Y 0 在源文件夹的Sample\GUI_X下GUI_X_Touch.c文件中,包含触摸相关函数,需要对其进行修改,将自己的触摸驱动添加进去即可。#include "GUI.h" #include "GUI_X.h" void GUI_TOUCH_X_ActivateX(void) { } void GUI_TOUCH_X_ActivateY(void) { } int GUI_TOUCH_X_MeasureX(void) { return Touch_MeasurementX(); //对应触摸驱动中的读取x值函数 } int GUI_TOUCH_X_MeasureY(void) { return Touch_MeasurementY(); //对应触摸驱动中的读取y值函数 } 在源文件夹的Sample\GUI_X下GUI_X.c文件中,只保留以下内容#include "GUI.h" #include "GUI_X.h" void GUI_X_Log (const char *s) { GUI_USE_PARA(s); } void GUI_X_Warn (const char *s) { GUI_USE_PARA(s); } void GUI_X_ErrorOut(const char *s) { GUI_USE_PARA(s); } 在源文件夹的Sample\GUI_X下GUI_X_uCOS.c文件中,只修改以下内容:static void CheckInit (void) { if (KeyIsInited == FALSE) { KeyIsInited = TRUE; GUI_X_Init(); } } 由于 FALSE和TRUE 未定义,会提示出错,因此将他们分别改为 0和1 /*WM空闲时调用*/ void GUI_X_ExecIdle (void) { //OS_X_Delay(1); 原内容 OSTimeDly(50); //新内容 } 最后将上面提到的三个文件加入工程就可以了。至此移植结束。 |
|