UCOSII252成功移植到44B0的板子上的经验+自己总结的小细节

本文分享了uCOS-II在S3C44B0x平台上的移植经验,包括关键代码修改点及注意事项。特别强调了避免常见错误的方法,并提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

uCOS-II S3C44B0x 系统上的移置代码及注意点

 

 

 

网上教程很多,个人感觉还有几个地方需要注意的:

第一,  推荐看的书是第二版的<嵌入式实时操作系统UCOS-II> 邵贝贝,北航的

第二,  根据我自己的感觉,可以参考但不能全搬,网上很多文章也都是错的

第三,  UCOS-II252本身也有问题.

需要修改的文件:(OS_CPU_A.S,OS_CPU.H,OS_CPU_C.C,INCLUDES.H,U)

另外,UCOS-II.C文件有问题,编译通不过的可以参照我这个改

注意:1 AREA  |***|, CODE, READONLY (in OS_CPU_A.S)  /* 这行不能顶格写,第一列不能是伪代码,不然报错 */

2 INT8U  OSTaskDel (INT8U prio)      (in OS_TASK.C)

{

......

//    BOOLEAN       self;                                        /* 这句话注释掉,高版本里已经去掉这句话 */

(应该是BUG,不然只能这么理解:作者想用这个变量做扩展用)

......

}

3 #define debug    (in INCLUDES.H)                      /* 这么做的好处是,需要debug的地方,加上"#ifdef debug   (your debug vars or codes)  #endif" ,不需要的时候注释掉这一句就可以了 */

4 OS_EXT  INT32U  OSCtxSwCtr;   (in UCOS_II.H)       /* 这个变量是统计任务切换次数的,方便用户设置断点.如果不用,有关所有这个变量可以全注释掉. 编译器会报警告,但不报错*/

5 e-MAIL:vincent_zhangbin@hotmail.com可以有关移植UCOS-II的问题讨论

1)附上我自己的OS_CPU_A.S

 AREA |TEST|, CODE, READONLY
 EXPORT OSStartHighRdy
 IMPORT  OSRunning
 IMPORT  OSTaskSwHook
 IMPORT  OSTCBHighRdy
 
OSStartHighRdy
 BL OSTaskSwHook    ;Call user defined Hook function
 
 LDR R4, =OSRunning   ;Set OSRunning to 1
 MOV R5, #1
 STRB R5, [R4]

 LDR R4, =OSTCBHighRdy   ;get the spointer to the task which will resume
 LDR R4, [R4]
 LDR sp, [R4]
 
 LDMFD sp!, {R4}    ;resume all the registers from the new task stack
 MSR cpsr_cxsf, R4
 LDMFD sp!, {R0-R12,LR,PC}

 EXPORT OSCtxSw
 IMPORT  OSTCBCur
 IMPORT  OSTaskSwHook
 IMPORT  OSTCBHighRdy
 IMPORT  OSPrioCur
 IMPORT  OSPrioHighRdy
 
OSCtxSw
 STMFD sp!, {LR}   ;Save mcu registers
 STMFD  sp!, {R0-R12,LR}  
 MRS  R4, cpsr
 STMFD   sp!, {R4}

 LDR R4, =OSTCBCur   ;OSTCBCur->OSTCBStkPtr = Stack pointer;
 LDR  R4, [R4]
 STR  sp, [R4]
 
 BL OSTaskSwHook   ;OSTaskSwHook();

 LDR  R4, =OSTCBHighRdy  ;OSTCBCur = OSTCBHighRdy;
 LDR  R4, [R4]
 LDR R5, =OSTCBCur
 STR  R4, [R5]
 
 LDR  R4, =OSPrioHighRdy  ;OSPrioCur = OSPrioHighRdy;
 LDR  R4, [R4]
 LDR  R5, =OSPrioCur
 STRB R4, [R5]
 
 LDR  R4, =OSTCBHighRdy  ;Stack pointer = OSTCBHighRdy->OSTCBStkPtr;
 LDR  R4, [R4]
 LDR  sp, [R4]

 LDMFD sp!, {R4}   ;Resume all the registers from the new task stack
 MSR  cpsr_cxsf, R4
 LDMFD sp!, {R0-R12,LR,PC}
 
 EXPORT  OSIntCtxSw
 IMPORT  OSTaskSwHook
 IMPORT  OSTCBCur
 IMPORT  OSTCBHighRdy
 IMPORT  OSPrioCur
 IMPORT  OSPrioHighRdy
 
OSIntCtxSw
 BL OSTaskSwHook   ;Recall usr defined OSTaskSwHook()

 LDR R4, =OSTCBHighRdy  ;OSTCBCur = OSTCBHighRdy;
 LDR  R4, [R4]
 LDR   R5, =OSTCBCur
 STR  R4, [R5]

 LDR R4, =OSPrioHighRdy  ;OSPrioCur = OSPrioHighRdy;
 LDR  R4, [R4]
 LDR   R5, =OSPrioCur
 STRB R4, [R5]
 
 LDR  R4, =OSTCBHighRdy  ;Stack pointer = OSTCBHighRdy->OSTCBStkPtr;
 LDR  R4, [R4]
 LDR sp, [R4]
 
 LDMFD  sp!, {R4}   ;resume all processors registers from the new task
 MSR cpsr_cxsf, R4
 LDMFD sp!, {R0-R12,LR,PC}
 
 EXPORT  OSTickISR
 IMPORT  OSTCBCur
 IMPORT  OSIntNesting
 IMPORT  OSTimeTick
 IMPORT  OSIntExit

OSTickISR

 STMFD sp!, {LR}   ;Save mcu registers
 STMFD  sp!, {R0-R12,LR}  
 MRS  R4, cpsr
 STMFD    sp!, {R4}

 LDR  R4, =OSIntNesting   ;OSIntNesting +1
 LDR  R4, [R4]
 ADD  R4, R4, #1
 
 CMP  R4, #1    ;if (OSIntNesting == 1){
 BNE  JMP
 
 LDR  R4, =OSTCBCur  ;OSTCBCur->OSTCBStkPtr = Stack Pointer;}
 LDR  R4, [R4]
 STR  sp, [R4]

JMP
 BL  OSTimeTick    ;OSTimeTick();
 BL OSIntExit     ;OSIntExit();
 
 LDMFD  sp!, {R4}                 ;resume processors registers
 MSR  cpsr_cxsf, R4
 LDMFD  sp!, {R0-R12,LR,PC}

 EXPORT  ARMDisableInt
 
ARMDisableInt

 MRS  R0, cpsr
 STMFD sp!, {R0}            ; push current PSR
 ORR  R0, R0, #0xC0
 MSR  cpsr_c, R0     ; disable IRQ Int s

 MOV  PC, LR

       EXPORT  ARMEnableInt

ARMEnableInt

 LDMFD sp!, {R0}                  ; pop current PSR
 MSR  cpsr_c, R0                 ; restore original cpsr 

 MOV  PC, LR


            END

2)附上我自己的OS_CPU.H

#ifdef  OS_CPU_GLOBALS
#define OS_CPU_EXT
#else
#define OS_CPU_EXT  extern
#endif

/*
*********************************************************************************************************
*                                              DATA TYPES
*                                         (Compiler Specific)
*********************************************************************************************************
*/

typedef unsigned char  BOOLEAN;
typedef unsigned char  INT8U;                    /* Unsigned  8 bit quantity                           */
typedef signed   char  INT8S;                    /* Signed    8 bit quantity                           */
typedef unsigned int   INT16U;                   /* Unsigned 16 bit quantity                           */
typedef signed   int   INT16S;                   /* Signed   16 bit quantity                           */
typedef unsigned long  INT32U;                   /* Unsigned 32 bit quantity                           */
typedef signed   long  INT32S;                   /* Signed   32 bit quantity                           */
typedef float          FP32;                     /* Single precision floating point                    */
typedef double         FP64;                     /* Double precision floating point                    */

typedef unsigned int   OS_STK;                   /* Each stack entry is 16-bit wide                    */
typedef unsigned short OS_CPU_SR;                /* Define size of CPU status register (PSW = 16 bits) */

#define BYTE           INT8S                     /* Define data types for backward compatibility ...   */
#define UBYTE          INT8U                     /* ... to uC/OS V1.xx.  Not actually needed for ...   */
#define WORD           INT16S                    /* ... uC/OS-II.                                      */
#define UWORD          INT16U
#define LONG           INT32S
#define ULONG          INT32U

/*
*********************************************************************************************************
*
*********************************************************************************************************
*/

#define OS_CRITICAL_METHOD 0

#define OS_ENTER_CRITICAL() ARMDisableInt()    /* Close Interrupt                */
#define OS_EXIT_CRITICAL() ARMEnableInt()     /* Open Interrupt   */


#define  OS_STK_GROWTH        1                       /* Stack grows from HIGH to LOW memory   */

#define  OS_TASK_SW()         OSCtxSw()
/*
*********************************************************************************************************
*                                            GLOBAL VARIABLES & PROTOTYPE
*********************************************************************************************************
*/

#define SVC32MODE 0x13  /* Definitions specific to ARM/uHAL */
extern void OSCtxSw(void);   /* Task switch    */
extern void OSIntCtxSw(void);  /* Interrupt switch */
extern void ARMDisableInt(void);
extern void ARMEnableInt(void);

3)附上我自己的OS_CPU_C.C

#define  OS_CPU_GLOBALS
#include "includes.h"

/*
*********************************************************************************************************
*                                       OS INITIALIZATION HOOK
*                                            (BEGINNING)
*
* Description: This function is called by OSInit() at the beginning of OSInit().
*
* Arguments  : none
*
* Note(s)    : 1) Interrupts should be disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void  OSInitHookBegin (void)
{
}
#endif

/*
*********************************************************************************************************
*                                       OS INITIALIZATION HOOK
*                                               (END)
*
* Description: This function is called by OSInit() at the end of OSInit().
*
* Arguments  : none
*
* Note(s)    : 1) Interrupts should be disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void  OSInitHookEnd (void)
{
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*                                          TASK CREATION HOOK
*
* Description: This function is called when a task is created.
*
* Arguments  : ptcb   is a pointer to the task control block of the task being created.
*
* Note(s)    : 1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void  OSTaskCreateHook (OS_TCB *ptcb)
{
    ptcb = ptcb;                       /* Prevent compiler warning                                     */
}
#endif


/*
*********************************************************************************************************
*                                           TASK DELETION HOOK
*
* Description: This function is called when a task is deleted.
*
* Arguments  : ptcb   is a pointer to the task control block of the task being deleted.
*
* Note(s)    : 1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void  OSTaskDelHook (OS_TCB *ptcb)
{
    ptcb = ptcb;                       /* Prevent compiler warning                                     */
}
#endif

/*
*********************************************************************************************************
*                                             IDLE TASK HOOK
*
* Description: This function is called by the idle task.  This hook has been added to allow you to do 
*              such things as STOP the CPU to conserve power.
*
* Arguments  : none
*
* Note(s)    : 1) Interrupts are enabled during this call.
*********************************************************************************************************
*/
#ifdef debug
 extern BOOLEAN fg;
#endif

#if OS_CPU_HOOKS_EN > 0 && OS_VERSION >= 251
void  OSTaskIdleHook (void)
{

#ifdef debug
 if (fg == 1) {
  fg = 0;
  Led_Display(0x1fd);
 }
 else {
  fg = 1;
  Led_Display(0x1fe);
 }
#endif

}
#endif

/*
*********************************************************************************************************
*                                           STATISTIC TASK HOOK
*
* Description: This function is called every second by uC/OS-II's statistics task.  This allows your
*              application to add functionality to the statistics task.
*
* Arguments  : none
*********************************************************************************************************
*/

#if OS_CPU_HOOKS_EN > 0
void  OSTaskStatHook (void)
{
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*                                        INITIALIZE A TASK'S STACK
*
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
*              stack frame of the task being created.  This function is highly processor specific.
*
* Arguments  : task          is a pointer to the task code
*
*              pdata         is a pointer to a user supplied data area that will be passed to the task
*                            when the task first executes.
*
*              ptos          is a pointer to the top of stack.  It is assumed that 'ptos' points to
*                            a 'free' entry on the task stack.  If OS_STK_GROWTH is set to 1 then
*                            'ptos' will contain the HIGHEST valid address of the stack.  Similarly, if
*                            OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
*                            of the stack.
*
*              opt           specifies options that can be used to alter the behavior of OSTaskStkInit().
*                            (see uCOS_II.H for OS_TASK_OPT_???).
*
* Returns    : Always returns the location of the new top-of-stack' once the processor registers have
*              been placed on the stack in the proper order.
*
* Note(s)    : Interrupts are enabled when your task starts executing. You can change this by setting the
*              PSW to 0x0002 instead.  In this case, interrupts would be disabled upon task startup.  The
*              application code would be responsible for enabling interrupts at the beginning of the task
*              code.  You will need to modify OSTaskIdle() and OSTaskStat() so that they enable
*              interrupts.  Failure to do this will make your system crash!
*********************************************************************************************************
*/

OS_STK  *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{
    INT16U *stk;


    opt    = opt;                           /* 'opt' is not used, prevent warning                      */
    stk    = (INT16U *)ptos;           /* Load stack pointer                                      */
 
    *--stk = (INT16U)task;       /* pc                                   */
    *--stk = (INT16U)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 = (INT16U)pdata;  /* r0                                           */
    *--stk = (SVC32MODE|0x40);   /* cpsr  FIQ disable*/ 
    return ((OS_STK *)stk);
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                           TASK SWITCH HOOK
*
* Description: This function is called when a task switch is performed.  This allows you to perform other
*              operations during a context switch.
*
* Arguments  : none
*
* Note(s)    : 1) Interrupts are disabled during this call.
*              2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
*                 will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the
*                 task being switched out (i.e. the preempted task).
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void  OSTaskSwHook (void)
{
}
#endif

/*
*********************************************************************************************************
*                                           OSTCBInit() HOOK
*
* Description: This function is called by OS_TCBInit() after setting up most of the TCB.
*
* Arguments  : ptcb    is a pointer to the TCB of the task being created.
*
* Note(s)    : 1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void  OSTCBInitHook (OS_TCB *ptcb)
{
    ptcb = ptcb;                                           /* Prevent Compiler warning                 */
}
#endif


/*
*********************************************************************************************************
*                                               TICK HOOK
*
* Description: This function is called every tick.
*
* Arguments  : none
*
* Note(s)    : 1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void  OSTimeTickHook (void)
{
}
#endif

4)INCLUDES.H

#include    <stdio.h>
#include    <string.h>
#include    <ctype.h>
#include    <stdlib.h>

#include    "os_cpu.h"
#include    "os_cfg.h"
#include    "ucos_ii.h"

#define debug  /*移植UCOSII  TO  44B0 测试用*/

5)UCOS-II.C

#define  OS_GLOBALS                           /* Declare GLOBAL variables                              */
//#include "includes.h"


#define  OS_MASTER_FILE                       /* Prevent the following files from including includes.h */

#if 0

#include "os_core.c"
#include "os_flag.c"
#include "os_mbox.c"
#include "os_mem.c"
#include "os_mutex.c"
#include "os_q.c"
#include "os_sem.c"
#include "os_task.c"
#include "os_time.c"

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值