一、新建工程
1.新建一个ARM Executable Image
2.创建uCOS_II文件夹,创建两个子文件夹,分别为ARM、SOURCE
ARM存放和平台相关的文件("OS_CPU.H" "Os_cpu_a.s" "Os_cpu_c.c" )
SOURCE下存入和平台无关的文件("ucos_ii.h" "os_cfg.h" "os_core.c" "os_flag.c" "os_mbox.c" "os_mem.c" "os_mutex.c" "os_q.c" "os_sem.c" "os_task.c" "os_time.c" "os_tmr.c" )
3.创建一个S3C2440文件夹,创建两个子文件夹,分别为INC、SRC
INC存放S3C2440相关头文件("2440addr.h" "2440lib.h" "2440slib.h" "config.h" "Def1.h" "lcd.h" "mmu.h" "Option.h" "Target.h" "Timer.h" )
SRC存放S3C2440相关源文件("Timer.c" "2440init.s" "2440lib.c" "2440slib.s" "Font_Libs.c" "iphone.c" "lcd.c" "mmu.c" "nand.c" "Target.c" )
4.创建一个app文件夹(app_cfg.h、main.c、Printf.c、Printf.h)
二、工程设置Edit->DebugRel Settings下
1.Target->Target Settings,Post-linker:ARM fromELF
2.Target->Access Paths选中Always Search User Paths(ucos_ii部分文件采用#include <>包涵,不修改这里找不到文件)
3.Language Settings下ARM Assembler、ARM C Compliler、ARM C++ Complier处理器设置成ARM920T
4.Language Settings下ARM C Compliler下Errors下去掉Implicit pointer c,ARM C Compliler下Warnings下去掉Unused declaration(-O1 -g+ -cpu ARM920T -Wx -Ec)
5.ARM Linker下,Output下RO Base设置成0x30000000,Options下Image entry point设置成0x30000000,Layout下Place at beginning of image下的Object/Symbol设置成2440init.o,Section设置成Init,Listings下选勾Image map、List file设置list.txt,勾上Sizes、Totals、Unused、Veneers
对Os_cpu_c.c的修改:
对Os_cpu_a.s的修改:
1.新建一个ARM Executable Image
2.创建uCOS_II文件夹,创建两个子文件夹,分别为ARM、SOURCE
ARM存放和平台相关的文件("OS_CPU.H" "Os_cpu_a.s" "Os_cpu_c.c" )
SOURCE下存入和平台无关的文件("ucos_ii.h" "os_cfg.h" "os_core.c" "os_flag.c" "os_mbox.c" "os_mem.c" "os_mutex.c" "os_q.c" "os_sem.c" "os_task.c" "os_time.c" "os_tmr.c" )
3.创建一个S3C2440文件夹,创建两个子文件夹,分别为INC、SRC
INC存放S3C2440相关头文件("2440addr.h" "2440lib.h" "2440slib.h" "config.h" "Def1.h" "lcd.h" "mmu.h" "Option.h" "Target.h" "Timer.h" )
SRC存放S3C2440相关源文件("Timer.c" "2440init.s" "2440lib.c" "2440slib.s" "Font_Libs.c" "iphone.c" "lcd.c" "mmu.c" "nand.c" "Target.c" )
4.创建一个app文件夹(app_cfg.h、main.c、Printf.c、Printf.h)
二、工程设置Edit->DebugRel Settings下
1.Target->Target Settings,Post-linker:ARM fromELF
2.Target->Access Paths选中Always Search User Paths(ucos_ii部分文件采用#include <>包涵,不修改这里找不到文件)
3.Language Settings下ARM Assembler、ARM C Compliler、ARM C++ Complier处理器设置成ARM920T
4.Language Settings下ARM C Compliler下Errors下去掉Implicit pointer c,ARM C Compliler下Warnings下去掉Unused declaration(-O1 -g+ -cpu ARM920T -Wx -Ec)
5.ARM Linker下,Output下RO Base设置成0x30000000,Options下Image entry point设置成0x30000000,Layout下Place at beginning of image下的Object/Symbol设置成2440init.o,Section设置成Init,Listings下选勾Image map、List file设置list.txt,勾上Sizes、Totals、Unused、Veneers
6.ARM fromELF下Output file name下填写输出的二进制
三、移植文件的修改
对OS_CPU.H的修改:
- /*
- *********************************************************************************************************
- * ARM
- *
- * Method #1: NOT IMPLEMENTED
- * Disable/Enable interrupts using simple instructions. After critical section, interrupts
- * will be enabled even if they were disabled before entering the critical section.
- *
- * Method #2: NOT IMPLEMENTED
- * Disable/Enable interrupts by preserving the state of interrupts. In other words, if
- * interrupts were disabled before entering the critical section, they will be disabled when
- * leaving the critical section.
- * NOT IMPLEMENTED
- *
- * Method #3: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
- * would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
- * disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to
- * disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
- * into the CPU's status register. This is the prefered method to disable interrupts.
- *********************************************************************************************************
- */
- #define OS_CRITICAL_METHOD 3
- #if OS_CRITICAL_METHOD == 3
- #define OS_ENTER_CRITICAL() (cpu_sr = OSCPUSaveSR()) /* Disable interrupts */
- #define OS_EXIT_CRITICAL() (OSCPURestoreSR(cpu_sr)) /* Restore interrupts */
- #endif
- /*
- *********************************************************************************************************
- * ARM Miscellaneous
- *********************************************************************************************************
- */
- #define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */
- #define OS_TASK_SW() OSCtxSw()
对Os_cpu_c.c的修改:
- /*
- *********************************************************************************************************
- * uC/OS-II
- * The Real-Time Kernel
- *
- * (c) Copyright 1992-2003, Micrium, Inc., Weston, FL
- * All Rights Reserved
- *
- * ARM9 Port
- *
- * File : OS_CPU_C.C
- *********************************************************************************************************
- */
- //#define OS_CPU_GLOBALS
- #include "ucos_ii.h"
- /*
- *********************************************************************************************************
- * 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
- *
- * p_arg 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) : 1) Interrupts are enabled when your task starts executing.
- * 2) All tasks run in SVC mode.
- *********************************************************************************************************
- */
- OS_STK *OSTaskStkInit (void (*task)(void *pd), void *p_arg, OS_STK *ptos, INT16U opt)
- {
- OS_STK *stk;
- optopt = opt; /* 'opt' is not used, prevent warning */
- stk = ptos; /* Load stack pointer */
- *(stk) = (OS_STK)task; /* Entry Point */
- *(--stk) = (INT32U)0; /* LR */
- *(--stk) = (INT32U)0; /* R12 */
- *(--stk) = (INT32U)0; /* R11 */
- *(--stk) = (INT32U)0; /* R10 */
- *(--stk) = (INT32U)0; /* R9 */
- *(--stk) = (INT32U)0; /* R8 */
- *(--stk) = (INT32U)0; /* R7 */
- *(--stk) = (INT32U)0; /* R6 */
- *(--stk) = (INT32U)0; /* R5 */
- *(--stk) = (INT32U)0; /* R4 */
- *(--stk) = (INT32U)0; /* R3 */
- *(--stk) = (INT32U)0; /* R2 */
- *(--stk) = (INT32U)0; /* R1 */
- *(--stk) = (INT32U)p_arg; /* R0 : argument */
- *(--stk) = (INT32U)0x00000013L; /* CPSR (SVC mode, Enable both IRQ and FIQ interrupts) */
- return (stk);
- }
- #if OS_CPU_HOOKS_EN
- /*
- *********************************************************************************************************
- * 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_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_VERSION > 203
- void OSInitHookEnd (void)
- {
- }
- #endif
- /*
- *********************************************************************************************************
- * 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.
- *********************************************************************************************************
- */
- void OSTaskCreateHook (OS_TCB *ptcb)
- {
- ptcbptcb = ptcb; /* Prevent compiler warning */
- }
- /*
- *********************************************************************************************************
- * 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.
- *********************************************************************************************************
- */
- void OSTaskDelHook (OS_TCB *ptcb)
- {
- ptcbptcb = ptcb; /* Prevent compiler warning */
- }
- /*
- *********************************************************************************************************
- * 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).
- *********************************************************************************************************
- */
- void OSTaskSwHook (void)
- {
- }
- /*
- *********************************************************************************************************
- * 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
- *********************************************************************************************************
- */
- void OSTaskStatHook (void)
- {
- }
- /*
- *********************************************************************************************************
- * OSTCBInit() HOOK
- *
- * Description: This function is called by OSTCBInit() 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_VERSION > 203
- void OSTCBInitHook (OS_TCB *ptcb)
- {
- ptcbptcb = 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.
- *********************************************************************************************************
- */
- void OSTimeTickHook (void)
- {
- }
- /*
- *********************************************************************************************************
- * 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.
- *********************************************************************************************************
- */
- #if OS_VERSION >= 251
- void OSTaskIdleHook (void)
- {
- }
- #endif
- #endif
对Os_cpu_a.s的修改:
- ;*********************************************************************************************************
- ; uC/OS-II
- ; The Real-Time Kernel
- ;
- ; (c) Copyright 1992-2003, Jean J. Labrosse, Weston, FL
- ; All Rights Reserved
- ;
- ; ARM920T Port
- ; ADS v1.2 Compiler
- ; Samsung S3C2440A
- ;
- ; File : os_cpu_a.s refrence to ucos application note for arm AN-1014
- ; Des : S3C2440 uC/OS-II Port
- ; by : tangxiaofeng xidian 503
- ; History :
- ; OSCtxSw(), OSIntCtxSw() OSStartHighRdy() OS_CPU_IRQ_ISR() OSTickISR()
- ;******************************************************************************************************** */
- SRCPND EQU 0x4a000000 ; Source pending
- INTPND EQU 0x4a000010 ; Interrupt request status
- rEINTPEND EQU 0x560000a8
- INTOFFSET EQU 0x4a000014
- USERMODE EQU 0x10
- FIQMODE EQU 0x11
- IRQMODE EQU 0x12
- SVCMODE EQU 0x13
- ABORTMODE EQU 0x17
- UNDEFMODE EQU 0x1b
- MODEMASK EQU 0x1f
- NOINT EQU 0xc0
- ;*********************************************************************************************************
- ; EXPORT and EXTERNAL REFERENCES
- ;*********************************************************************************************************/
- IMPORT OSRunning
- IMPORT OSTCBCur
- IMPORT OSTCBHighRdy
- IMPORT OSPrioCur
- IMPORT OSPrioHighRdy
- IMPORT OSIntNesting
- IMPORT OSIntEnter
- IMPORT OSIntExit
- IMPORT OSTaskSwHook
- IMPORT OSTimeTick
- IMPORT HandleEINT0
- EXPORT OSStartHighRdy
- EXPORT OSCtxSw
- EXPORT OSTickISR
- EXPORT OSIntCtxSw
- EXPORT OSCPUSaveSR
- EXPORT OSCPURestoreSR
- EXPORT OS_CPU_IRQ_ISR
- AREA UCOS_ARM, CODE, READONLY
- ;*********************************************************************************************************
- ; START MULTITASKING
- ; void OSStartHighRdy(void)
- ;
- ; The stack frame is assumed to look as follows:
- ;
- ; Entry Point(Task Name) (High memory)
- ; LR(R14)
- ; R12
- ; R11
- ; R10
- ; R9
- ; R8
- ; R7
- ; R6
- ; R5
- ; R4
- ; R3
- ; R2
- ; R1
- ; R0 : argument
- ; OSTCBHighRdy->OSTCBStkPtr --> CPSR (Low memory)
- ;
- ; Note : OSStartHighRdy() MUST:
- ; a) Call OSTaskSwHook() then,
- ; b) Set OSRunning to TRUE,
- ; c) Switch to the highest priority task.
- ;********************************************************************************************************** */
- OSStartHighRdy
- ;----------------------------------------------------------------------------------
- ; OSRunning = TRUE;
- ;----------------------------------------------------------------------------------
- MSR CPSR_cxsf,#SVCMODE|NOINT ;Switch to SVC mode with IRQ&FIQ disable
- BL OSTaskSwHook ;Call user define Task switch hook
- LDR R0, =OSRunning ; OSRunning =TRUE
- MOV R1, #1
- STRB R1, [R0]
- ;----------------------------------------------------------------------------------
- ; SP = OSTCBHighRdy->OSTCBStkPtr;
- ;----------------------------------------------------------------------------------
- LDR R0, =OSTCBHighRdy
- LDR R0, [R0]
- LDR SP, [R0]
- ;----------------------------------------------------------------------------------
- ; Prepare to return to proper mode
- ;----------------------------------------------------------------------------------
- LDMFD SP!, {R0}
- MSR SPSR_cxsf, R0
- LDMFD SP!, {R0-R12, LR, PC}^
- ;**********************************************************************************************************
- ; PERFORM A CONTEXT SWITCH (From task level)
- ; void OSCtxSw(void)
- ;
- ; Note(s): 1) Upon entry:
- ; OSTCBCur points to the OS_TCB of the task to suspend
- ; OSTCBHighRdy points to the OS_TCB of the task to resume
- ;
- ; 2) The stack frame of the task to suspend looks as follows:
- ;
- ; PC (High memory)
- ; LR(R14)
- ; R12
- ; R11
- ; R10
- ; R9
- ; R8
- ; R7
- ; R6
- ; R5
- ; R4
- ; R3
- ; R2
- ; R1
- ; R0
- ; OSTCBCur->OSTCBStkPtr ----> CPSR (Low memory)
- ;
- ;
- ; 3) The stack frame of the task to resume looks as follows:
- ;
- ; PC (High memory)
- ; LR(R14)
- ; R12
- ; R11
- ; R10
- ; R9
- ; R8
- ; R7
- ; R6
- ; R5
- ; R4
- ; R3
- ; R2
- ; R1
- ; R0
- ; OSTCBHighRdy->OSTCBStkPtr ----> CPSR (Low memory)
- ;*********************************************************************************************************/
- OSCtxSw
- STMFD SP!, {LR} ;PC
- STMFD SP!, {R0-R12, LR} ;R0-R12 LR
- MRS R0, CPSR ;Push CPSR
- STMFD SP!, {R0}
- ;----------------------------------------------------------------------------------
- ; OSTCBCur->OSTCBStkPtr = SP
- ;----------------------------------------------------------------------------------
- LDR R0, =OSTCBCur
- LDR R0, [R0]
- STR SP, [R0]
- ;----------------------------------------------------------------------------------
- ; OSTaskSwHook();
- ;---------------------------------------------------------------------------------
- BL OSTaskSwHook
- ;----------------------------------------------------------------------------------
- ; OSTCBCur = OSTCBHighRdy;
- ;----------------------------------------------------------------------------------
- LDR R0, =OSTCBHighRdy
- LDR R1, =OSTCBCur
- LDR R0, [R0]
- STR R0, [R1]
- ;----------------------------------------------------------------------------------
- ; OSPrioCur = OSPrioHighRdy;
- ;----------------------------------------------------------------------------------
- LDR R0, =OSPrioHighRdy
- LDR R1, =OSPrioCur
- LDRB R0, [R0]
- STRB R0, [R1]
- ;----------------------------------------------------------------------------------
- ; OSTCBHighRdy->OSTCBStkPtr;
- ;----------------------------------------------------------------------------------
- LDR R0, =OSTCBHighRdy
- LDR R0, [R0]
- LDR SP, [R0]
- ;----------------------------------------------------------------------------------
- ;Restore New task context
- ;----------------------------------------------------------------------------------
- LDMFD SP!, {R0} ;POP CPSR
- MSR SPSR_cxsf, R0
- LDMFD SP!, {R0-R12, LR, PC}^
- ;*********************************************************************************************************
- ; TICK HANDLER
- ;
- ; Description:
- ; This handles all the Timer0(INT_TIMER0) interrupt which is used to generate the uC/OS-II tick.
- ;*********************************************************************************************************/
- OSTickISR
- MOV R5,LR
- MOV R1, #1
- MOV R1, R1, LSL #10 ; Timer0 Source Pending Reg.
- LDR R0, =SRCPND
- LDR R2, [R0]
- ORR R1, R1,R2
- STR R1, [R0]
- LDR R0, =INTPND
- LDR R1, [R0]
- STR R1, [R0]
- ;----------------------------------------------------------------------------------
- ; OSTimeTick();
- ;----------------------------------------------------------------------------------
- BL OSTimeTick
- MOV PC, R5 ; Return
- ;*********************************************************************************************************
- ; PERFORM A CONTEXT SWITCH (From an ISR)
- ; void OSIntCtxSw(void)
- ;
- ; Description: 1) This code performs a context switch if a higher priority task has been made ready-to-run
- ; during an ISR.
- ;
- ; 2) The stack frame of the task to suspend looks as follows:
- ;
- ; PC (High memory)
- ; LR(R14)
- ; R12
- ; R11
- ; R10
- ; R9
- ; R8
- ; R7
- ; R6
- ; R5
- ; R4
- ; R3
- ; R2
- ; R1
- ; R0
- ;
- ; OSTCBCur->OSTCBStkPtr ----> CPSR (Low memory)
- ;
- ;
- ; 3) The stack frame of the task to resume looks as follows:
- ;
- ; PC (High memory)
- ; LR(R14)
- ; R12
- ; R11
- ; R10
- ; R9
- ; R8
- ; R7
- ; R6
- ; R5
- ; R4
- ; R3
- ; R2
- ; R1
- ; R0
- ; OSTCBHighRdy->OSTCBStkPtr ----> CPSR (Low memory)
- ;*********************************************************************************************************/
- OSIntCtxSw
- ;----------------------------------------------------------------------------------
- ; Call OSTaskSwHook();
- ;----------------------------------------------------------------------------------
- BL OSTaskSwHook
- ;----------------------------------------------------------------------------------
- ; OSTCBCur = OSTCBHighRdy;
- ;----------------------------------------------------------------------------------
- LDR R0, =OSTCBHighRdy
- LDR R1, =OSTCBCur
- LDR R0, [R0]
- STR R0, [R1]
- ;----------------------------------------------------------------------------------
- ; OSPrioCur = OSPrioHighRdy;
- ;----------------------------------------------------------------------------------
- LDR R0, =OSPrioHighRdy
- LDR R1, =OSPrioCur
- LDRB R0, [R0]
- STRB R0, [R1]
- ;----------------------------------------------------------------------------------
- ; SP = OSTCBHighRdy->OSTCBStkPtr;
- ;----------------------------------------------------------------------------------
- LDR R0, =OSTCBHighRdy
- LDR R0, [R0]
- LDR SP, [R0]
- ;----------------------------------------------------------------------------------
- ; Restore New Task context
- ;----------------------------------------------------------------------------------
- LDMFD SP!, {R0} ;POP CPSR
- MSR SPSR_cxsf, R0
- LDMFD SP!, {R0-R12, LR, PC}^
- OS_CPU_IRQ_ISR
- STMFD SP!, {R1-R3} ; We will use R1-R3 as temporary registers
- ;----------------------------------------------------------------------------
- ; R1--SP
- ; R2--PC
- ; R3--SPSR
- ;------------------------------------------------------------------------
- MOV R1, SP
- ADD SP, SP, #12 ;Adjust IRQ stack pointer
- SUB R2, LR, #4 ;Adjust PC for return address to task
- MRS R3, SPSR ; Copy SPSR (Task CPSR)
- MSR CPSR_cxsf, #SVCMODE|NOINT ;Change to SVC mode
- ; SAVE TASK''S CONTEXT ONTO OLD TASK''S STACK
- STMFD SP!, {R2} ; Push task''s PC
- STMFD SP!, {R4-R12, LR} ; Push task''s LR,R12-R4
- LDMFD R1!, {R4-R6} ; Load Task''s R1-R3 from IRQ stack
- STMFD SP!, {R4-R6} ; Push Task''s R1-R3 to SVC stack
- STMFD SP!, {R0} ; Push Task''s R0 to SVC stack
- STMFD SP!, {R3} ; Push task''s CPSR
- LDR R0,=OSIntNesting ;OSIntNesting++
- LDRB R1,[R0]
- ADD R1,R1,#1
- STRB R1,[R0]
- CMP R1,#1 ;if(OSIntNesting==1){
- BNE %F1
- LDR R4,=OSTCBCur ;OSTCBHighRdy->OSTCBStkPtr=SP;
- LDR R5,[R4]
- STR SP,[R5] ;}
- 1
- MSR CPSR_c,#IRQMODE|NOINT ;Change to IRQ mode to use IRQ stack to handle interrupt
- LDR R0, =INTOFFSET
- LDR R0, [R0]
- LDR R1, IRQIsrVect
- MOV LR, PC ; Save LR befor jump to the C function we need return back
- LDR PC, [R1, R0, LSL #2] ; Call OS_CPU_IRQ_ISR_handler();
- MSR CPSR_c,#SVCMODE|NOINT ;Change to SVC mode
- BL OSIntExit ;Call OSIntExit
- LDMFD SP!,{R4} ;POP the task''s CPSR
- MSR SPSR_cxsf,R4
- LDMFD SP!,{R0-R12,LR,PC}^ ;POP new Task''s context
- IRQIsrVect DCD HandleEINT0
- ;*********************************************************************************************************
- ; CRITICAL SECTION METHOD 3 FUNCTIONS
- ;
- ; Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
- ; would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
- ; disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II''s functions that need to
- ; disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
- ; into the CPU''s status register.
- ;
- ; Prototypes : OS_CPU_SR OSCPUSaveSR(void);
- ; void OSCPURestoreSR(OS_CPU_SR cpu_sr);
- ;
- ;
- ; Note(s) : 1) These functions are used in general like this:
- ;
- ; void Task (void *p_arg)
- ; {
- ; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
- ; OS_CPU_SR cpu_sr;
- ; #endif
- ;
- ; :
- ; :
- ; OS_ENTER_CRITICAL(); /* cpu_sr = OSCPUSaveSR(); */
- ; :
- ; :
- ; OS_EXIT_CRITICAL(); /* OSCPURestoreSR(cpu_sr); */
- ; :
- ; :
- ; }
- ;
- ; 2) OSCPUSaveSR() is implemented as recommended by Atmel''s application note:
- ;
- ; "Disabling Interrupts at Processor Level"
- ;*********************************************************************************************************
- OSCPUSaveSR
- MRS R0, CPSR ; Set IRQ and FIQ bits in CPSR to disable all interrupts
- ORR R1, R0, #0xC0
- MSR CPSR_c, R1
- MRS R1, CPSR ; Confirm that CPSR contains the proper interrupt disable flags
- AND R1, R1, #0xC0
- CMP R1, #0xC0
- BNE OSCPUSaveSR ; Not properly disabled (try again)
- MOV PC, LR ; Disabled, return the original CPSR contents in R0
- OSCPURestoreSR
- MSR CPSR_c, R0
- MOV PC, LR
- END