您的位置:首页 > 其它

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

2006-12-07 22:51 519 查看
uCOS-II在 S3C44B0x 系统上的移置代码及注意点

网上教程很多,个人感觉还有几个地方需要注意的:
第一, 推荐看的书是第二版的<嵌入式实时操作系统UCOS-II> 邵贝贝,北航的

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

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

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

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

注意:1AREA |***|, 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: