原创 ucos-ii和ucgui在stm32上的移植及工程

2010-10-5 11:04 12232 11 60 分类: MCU/ 嵌入式

需要工程文件的留下邮箱哈!奋斗!


uc/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;//防止编译时出现警告 } 
void  OSTaskDelHook (OS_TCB *ptcb)   { ptcb=ptcb;//防止编译时出现警告 } 
void  OSTaskSwHook (void) 
void  OSTaskStatHook (void) 
void  OSTimeTickHook (void) 
后5 个函数为钩子函数,可以不加代码。







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)



移植步骤: 
第一步:首先,得把你的TFT底层驱动和触摸驱动写好,既在裸机下,可以正常显示并实现触摸。 
第二步:加入UCGUI程序包。 
第三步:配置LCDConf.h  GUIConf.h  GUITouchConf.h


配置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_GetPixelIndex  


unsigned 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_SetPixelIndex


void  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); //新内容


}





最后将上面提到的三个文件加入工程就可以了。至此移植结束。

文章评论49条评论)

登录后参与讨论

用户377235 2015-11-19 20:39

我也需要一个,824229769@qq.com

用户377235 2015-11-18 12:17

我也需要一个,984978444@qq.com

用户377235 2014-9-27 22:35

我也需要一个,谢谢了!771709530@qq.com 谢谢

用户377235 2014-5-25 16:36

感谢分享,学习了。

用户377235 2014-5-13 21:05

我的邮箱是1023122918@qq.com 麻烦博主发一份给我,万分感谢

用户377235 2013-8-25 00:09

很希望得到工程文件哦!麻烦给发一个!谢谢哈!heyanggao2006@163.com

用户377235 2013-7-10 11:35

感谢楼主的分享,我的邮箱850584852@qq.com

用户1451707 2013-7-1 15:50

感谢楼主的分享,我的邮箱:lui515520@163.com

用户377235 2013-4-21 21:43

915686122@qq.com 急求一份,不胜感激。

用户377235 2013-4-18 14:11

wuxin204@126.com 求一个
相关推荐阅读
用户228782 2014-05-28 12:00
efm32 小板 蜂鸣器测试ok,上个视频先
使用PWM驱动无源蜂鸣器,效果还是不错的 http://v.youku.com/v_show/id_XNzA0NDU2MDU2.html?f=22188836 ...
用户228782 2014-05-28 12:00
efm32 小板 触摸按键测试ok
触摸检测中使用了2个定时器,因此,使用io方式来驱动蜂鸣器发声,   按键发声,感觉还不错...
用户228782 2014-05-28 11:59
板子焊接了一部分,测试了部分功能,一切顺利
目前进展,加速度计、锂电池的充电切换、oled一切正常,晶振和蓝牙部分下次再焊接吧 上个靓照吧   再来个落照 ...
用户228782 2014-05-28 11:59
efm32板子终于收到了
争取焊完一块吧,试试情况,嘿嘿   ...
用户228782 2014-05-28 11:59
我的efm32小板在路上
...
用户228782 2014-05-28 11:58
【Espruino】NO.05 按键是你的仆人
  【Espruino】NO.05 按键是你的仆人 本文属于个人理解,能力有限,纰漏在所难免,还望指正! 按键,生活中随处可见,手机、电脑、家用电器,用来执行各种功能,不要小看它额。 ...
我要评论
49
11
关闭 站长推荐上一条 /2 下一条