Backup before error handling refactoring
This commit is contained in:
139
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/GNU/os_cpu.h
Normal file
139
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/GNU/os_cpu.h
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
|
||||
* All rights reserved. Protected by international copyright laws.
|
||||
*
|
||||
* ARM Cortex-M3 Port
|
||||
*
|
||||
* File : OS_CPU.H
|
||||
* Version : V3.01.2
|
||||
* By : JJL
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-III is provided in source form to registered licensees ONLY. It is
|
||||
* illegal to distribute this source code to any third party unless you receive
|
||||
* written permission by an authorized Micrium representative. Knowledge of
|
||||
* the source code may NOT be used to develop a similar product.
|
||||
*
|
||||
* Please help us continue to provide the Embedded community with the finest
|
||||
* software available. Your honesty is greatly appreciated.
|
||||
*
|
||||
* You can contact us at www.micrium.com.
|
||||
*
|
||||
* For : ARMv7M Cortex-M3
|
||||
* Mode : Thumb2
|
||||
* Toolchain : GNU C Compiler
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_CPU_H
|
||||
#define OS_CPU_H
|
||||
|
||||
#ifdef OS_CPU_GLOBALS
|
||||
#define OS_CPU_EXT
|
||||
#else
|
||||
#define OS_CPU_EXT extern
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MACROS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NVIC_INT_CTRL
|
||||
#define NVIC_INT_CTRL *((CPU_REG32 *)0xE000ED04)
|
||||
#endif
|
||||
|
||||
#ifndef NVIC_PENDSVSET
|
||||
#define NVIC_PENDSVSET 0x10000000
|
||||
#endif
|
||||
|
||||
#define OS_TASK_SW() NVIC_INT_CTRL = NVIC_PENDSVSET
|
||||
#define OSIntCtxSw() NVIC_INT_CTRL = NVIC_PENDSVSET
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TIMESTAMP CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) OS_TS_GET() is generally defined as CPU_TS_Get32() to allow CPU timestamp timer to be of
|
||||
* any data type size.
|
||||
*
|
||||
* (2) For architectures that provide 32-bit or higher precision free running counters
|
||||
* (i.e. cycle count registers):
|
||||
*
|
||||
* (a) OS_TS_GET() may be defined as CPU_TS_TmrRd() to improve performance when retrieving
|
||||
* the timestamp.
|
||||
*
|
||||
* (b) CPU_TS_TmrRd() MUST be configured to be greater or equal to 32-bits to avoid
|
||||
* truncation of TS.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_CFG_TS_EN == 1u
|
||||
#define OS_TS_GET() (CPU_TS)CPU_TS_TmrRd() /* See Note #2a. */
|
||||
#else
|
||||
#define OS_TS_GET() (CPU_TS)0u
|
||||
#endif
|
||||
|
||||
#if (CPU_CFG_TS_32_EN == DEF_ENABLED) && \
|
||||
(CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)
|
||||
/* CPU_CFG_TS_TMR_SIZE MUST be >= 32-bit (see Note #2b). */
|
||||
#error "cpu_cfg.h, CPU_CFG_TS_TMR_SIZE MUST be >= CPU_WORD_SIZE_32"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS TICK INTERRUPT PRIORITY CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) For systems that don't need any high, real-time priority interrupts; the tick interrupt
|
||||
* should be configured as the highest priority interrupt but won't adversely affect system
|
||||
* operations.
|
||||
*
|
||||
* (2) For systems that need one or more high, real-time interrupts; these should be configured
|
||||
* higher than the tick interrupt which MAY delay execution of the tick interrupt.
|
||||
*
|
||||
* (a) If the higher priority interrupts do NOT continually consume CPU cycles but only
|
||||
* occasionally delay tick interrupts, then the real-time interrupts can successfully
|
||||
* handle their intermittent/periodic events with the system not losing tick interrupts
|
||||
* but only increasing the jitter.
|
||||
*
|
||||
* (b) If the higher priority interrupts consume enough CPU cycles to continually delay the
|
||||
* tick interrupt, then the CPU/system is most likely over-burdened & can't be expected
|
||||
* to handle all its interrupts/tasks. The system time reference gets compromised as a
|
||||
* result of losing tick interrupts.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_CFG_SYSTICK_PRIO 0u
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_CPU_EXT CPU_STK *OS_CPU_ExceptStkBase;
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSStartHighRdy (void);
|
||||
|
||||
void OS_CPU_PendSVHandler (void);
|
||||
|
||||
|
||||
void OS_CPU_SysTickHandler(void);
|
||||
void OS_CPU_SysTickInit (CPU_INT32U cnts);
|
||||
|
||||
#endif
|
||||
170
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/GNU/os_cpu_a.s
Normal file
170
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/GNU/os_cpu_a.s
Normal file
@@ -0,0 +1,170 @@
|
||||
@
|
||||
@********************************************************************************************************
|
||||
@ uC/OS-III
|
||||
@ The Real-Time Kernel
|
||||
@
|
||||
@
|
||||
@ (c) Copyright 2009-2011; Micrium Inc.; Weston, FL
|
||||
@ All rights reserved. Protected by international copyright laws.
|
||||
@
|
||||
@ ARM Cortex-M3 Port
|
||||
@
|
||||
@ File : OS_CPU_A.ASM
|
||||
@ Version : V3.01.2
|
||||
@ By : JJL
|
||||
@ FT
|
||||
@
|
||||
@ For : ARMv7M Cortex-M3
|
||||
@ Mode : Thumb2
|
||||
@ Toolchain : GNU C Compiler
|
||||
@********************************************************************************************************
|
||||
@
|
||||
|
||||
@********************************************************************************************************
|
||||
@ PUBLIC FUNCTIONS
|
||||
@********************************************************************************************************
|
||||
|
||||
.extern OSRunning @ External references.
|
||||
.extern OSPrioCur
|
||||
.extern OSPrioHighRdy
|
||||
.extern OSTCBCurPtr
|
||||
.extern OSTCBHighRdyPtr
|
||||
.extern OSIntExit
|
||||
.extern OSTaskSwHook
|
||||
.extern OS_CPU_ExceptStkBase
|
||||
|
||||
|
||||
.global OSStartHighRdy @ Functions declared in this file.
|
||||
.global OS_CPU_PendSVHandler
|
||||
|
||||
@********************************************************************************************************
|
||||
@ EQUATES
|
||||
@********************************************************************************************************
|
||||
|
||||
.equ NVIC_INT_CTRL, 0xE000ED04 @ Interrupt control state register.
|
||||
.equ NVIC_SYSPRI14, 0xE000ED22 @ System priority register (priority 14).
|
||||
.equ NVIC_PENDSV_PRI, 0xFF @ PendSV priority value (lowest).
|
||||
.equ NVIC_PENDSVSET, 0x10000000 @ Value to trigger PendSV exception.
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@********************************************************************************************************
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.syntax unified
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ START MULTITASKING
|
||||
@ void OSStartHighRdy(void)
|
||||
@
|
||||
@ Note(s) : 1) This function triggers a PendSV exception (essentially, causes a context switch) to cause
|
||||
@ the first task to start.
|
||||
@
|
||||
@ 2) OSStartHighRdy() MUST:
|
||||
@ a) Setup PendSV exception priority to lowest;
|
||||
@ b) Set initial PSP to 0, to tell context switcher this is first run;
|
||||
@ c) Set the main stack to OS_CPU_ExceptStkBase
|
||||
@ d) Trigger PendSV exception;
|
||||
@ e) Enable interrupts (tasks will run with interrupts enabled).
|
||||
@********************************************************************************************************
|
||||
.thumb_func
|
||||
OSStartHighRdy:
|
||||
LDR R0, =NVIC_SYSPRI14 @ Set the PendSV exception priority
|
||||
LDR R1, =NVIC_PENDSV_PRI
|
||||
STRB R1, [R0]
|
||||
|
||||
MOVS R0, #0 @ Set the PSP to 0 for initial context switch call
|
||||
MSR PSP, R0
|
||||
|
||||
LDR R0, =OS_CPU_ExceptStkBase @ Initialize the MSP to the OS_CPU_ExceptStkBase
|
||||
LDR R1, [R0]
|
||||
MSR MSP, R1
|
||||
|
||||
LDR R0, =NVIC_INT_CTRL @ Trigger the PendSV exception (causes context switch)
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
CPSIE I @ Enable interrupts at processor level
|
||||
|
||||
OSStartHang:
|
||||
B OSStartHang @ Should never get here
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ HANDLE PendSV EXCEPTION
|
||||
@ void OS_CPU_PendSVHandler(void)
|
||||
@
|
||||
@ Note(s) : 1) PendSV is used to cause a context switch. This is a recommended method for performing
|
||||
@ context switches with Cortex-M3. This is because the Cortex-M3 auto-saves half of the
|
||||
@ processor context on any exception, and restores same on return from exception. So only
|
||||
@ saving of R4-R11 is required and fixing up the stack pointers. Using the PendSV exception
|
||||
@ this way means that context saving and restoring is identical whether it is initiated from
|
||||
@ a thread or occurs due to an interrupt or exception.
|
||||
@
|
||||
@ 2) Pseudo-code is:
|
||||
@ a) Get the process SP, if 0 then skip (goto d) the saving part (first context switch);
|
||||
@ b) Save remaining regs r4-r11 on process stack;
|
||||
@ c) Save the process SP in its TCB, OSTCBCurPtr->OSTCBStkPtr = SP;
|
||||
@ d) Call OSTaskSwHook();
|
||||
@ e) Get current high priority, OSPrioCur = OSPrioHighRdy;
|
||||
@ f) Get current ready thread TCB, OSTCBCurPtr = OSTCBHighRdyPtr;
|
||||
@ g) Get new process SP from TCB, SP = OSTCBHighRdyPtr->OSTCBStkPtr;
|
||||
@ h) Restore R4-R11 from new process stack;
|
||||
@ i) Perform exception return which will restore remaining context.
|
||||
@
|
||||
@ 3) On entry into PendSV handler:
|
||||
@ a) The following have been saved on the process stack (by processor):
|
||||
@ xPSR, PC, LR, R12, R0-R3
|
||||
@ b) Processor mode is switched to Handler mode (from Thread mode)
|
||||
@ c) Stack is Main stack (switched from Process stack)
|
||||
@ d) OSTCBCurPtr points to the OS_TCB of the task to suspend
|
||||
@ OSTCBHighRdyPtr points to the OS_TCB of the task to resume
|
||||
@
|
||||
@ 4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we
|
||||
@ know that it will only be run when no other exception or interrupt is active, and
|
||||
@ therefore safe to assume that context being switched out was using the process stack (PSP).
|
||||
@********************************************************************************************************
|
||||
|
||||
.thumb_func
|
||||
OS_CPU_PendSVHandler:
|
||||
CPSID I @ Prevent interruption during context switch
|
||||
MRS R0, PSP @ PSP is process stack pointer
|
||||
CBZ R0, OS_CPU_PendSVHandler_nosave @ Skip register save the first time
|
||||
|
||||
SUBS R0, R0, #0x20 @ Save remaining regs r4-11 on process stack
|
||||
STM R0, {R4-R11}
|
||||
|
||||
LDR R1, =OSTCBCurPtr @ OSTCBCurPtr->OSTCBStkPtr = SP;
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1] @ R0 is SP of process being switched out
|
||||
|
||||
@ At this point, entire context of process has been saved
|
||||
OS_CPU_PendSVHandler_nosave:
|
||||
PUSH {R14} @ Save LR exc_return value
|
||||
LDR R0, =OSTaskSwHook @ OSTaskSwHook();
|
||||
BLX R0
|
||||
POP {R14}
|
||||
|
||||
LDR R0, =OSPrioCur @ OSPrioCur = OSPrioHighRdy;
|
||||
LDR R1, =OSPrioHighRdy
|
||||
LDRB R2, [R1]
|
||||
STRB R2, [R0]
|
||||
|
||||
LDR R0, =OSTCBCurPtr @ OSTCBCurPtr = OSTCBHighRdyPtr;
|
||||
LDR R1, =OSTCBHighRdyPtr
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
LDR R0, [R2] @ R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
|
||||
LDM R0, {R4-R11} @ Restore r4-11 from new process stack
|
||||
ADDS R0, R0, #0x20
|
||||
MSR PSP, R0 @ Load PSP with new process SP
|
||||
ORR LR, LR, #0x04 @ Ensure exception return uses process stack
|
||||
CPSIE I
|
||||
BX LR @ Exception return will restore remaining context
|
||||
|
||||
.end
|
||||
411
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/GNU/os_cpu_c.c
Normal file
411
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/GNU/os_cpu_c.c
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
|
||||
* All rights reserved. Protected by international copyright laws.
|
||||
*
|
||||
* ARM Cortex-M3 Port
|
||||
*
|
||||
* File : OS_CPU_C.C
|
||||
* Version : V3.01.2
|
||||
* By : JJL
|
||||
* FT
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-III is provided in source form to registered licensees ONLY. It is
|
||||
* illegal to distribute this source code to any third party unless you receive
|
||||
* written permission by an authorized Micrium representative. Knowledge of
|
||||
* the source code may NOT be used to develop a similar product.
|
||||
*
|
||||
* Please help us continue to provide the Embedded community with the finest
|
||||
* software available. Your honesty is greatly appreciated.
|
||||
*
|
||||
* You can contact us at www.micrium.com.
|
||||
*
|
||||
* For : ARMv7M Cortex-M3
|
||||
* Mode : Thumb2
|
||||
* Toolchain : GNU C Compiler
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_GLOBALS
|
||||
|
||||
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
|
||||
const CPU_CHAR *os_cpu_c__c = "$Id: $";
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE FILES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include <os.h>
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSIdleTaskHook (void)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppIdleTaskHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppIdleTaskHookPtr)();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS INITIALIZATION HOOK
|
||||
*
|
||||
* Description: This function is called by OSInit() at the beginning of OSInit().
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSInitHook (void)
|
||||
{
|
||||
CPU_STK_SIZE i;
|
||||
CPU_STK *p_stk;
|
||||
|
||||
|
||||
p_stk = OSCfg_ISRStkBasePtr; /* Clear the ISR stack */
|
||||
for (i = 0u; i < OSCfg_ISRStkSize; i++) {
|
||||
*p_stk++ = (CPU_STK)0u;
|
||||
}
|
||||
OS_CPU_ExceptStkBase = (CPU_STK *)(OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize - 1u);
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* STATISTIC TASK HOOK
|
||||
*
|
||||
* Description: This function is called every second by uC/OS-III's statistics task. This allows your
|
||||
* application to add functionality to the statistics task.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSStatTaskHook (void)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppStatTaskHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppStatTaskHookPtr)();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK CREATION HOOK
|
||||
*
|
||||
* Description: This function is called when a task is created.
|
||||
*
|
||||
* Arguments : p_tcb Pointer to the task control block of the task being created.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskCreateHook (OS_TCB *p_tcb)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskCreateHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppTaskCreateHookPtr)(p_tcb);
|
||||
}
|
||||
#else
|
||||
(void)p_tcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK DELETION HOOK
|
||||
*
|
||||
* Description: This function is called when a task is deleted.
|
||||
*
|
||||
* Arguments : p_tcb Pointer to the task control block of the task being deleted.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskDelHook (OS_TCB *p_tcb)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskDelHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppTaskDelHookPtr)(p_tcb);
|
||||
}
|
||||
#else
|
||||
(void)p_tcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK RETURN HOOK
|
||||
*
|
||||
* Description: This function is called if a task accidentally returns. In other words, a task should
|
||||
* either be an infinite loop or delete itself when done.
|
||||
*
|
||||
* Arguments : p_tcb Pointer to the task control block of the task that is returning.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskReturnHook (OS_TCB *p_tcb)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskReturnHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppTaskReturnHookPtr)(p_tcb);
|
||||
}
|
||||
#else
|
||||
(void)p_tcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* INITIALIZE A TASK'S STACK
|
||||
*
|
||||
* Description: This function is called by OS_Task_Create() or OSTaskCreateExt() to initialize the stack
|
||||
* frame of the task being created. This function is highly processor specific.
|
||||
*
|
||||
* Arguments : p_task Pointer to the task entry point address.
|
||||
*
|
||||
* p_arg Pointer to a user supplied data area that will be passed to the task
|
||||
* when the task first executes.
|
||||
*
|
||||
* p_stk_base Pointer to the base address of the stack.
|
||||
*
|
||||
* stk_size Size of the stack, in number of CPU_STK elements.
|
||||
*
|
||||
* opt Options used to alter the behavior of OS_Task_StkInit().
|
||||
* (see OS.H for OS_TASK_OPT_xxx).
|
||||
*
|
||||
* 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 task starts executing.
|
||||
*
|
||||
* 2) All tasks run in Thread mode, using process stack.
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
|
||||
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
|
||||
void *p_arg,
|
||||
CPU_STK *p_stk_base,
|
||||
CPU_STK *p_stk_limit,
|
||||
CPU_STK_SIZE stk_size,
|
||||
OS_OPT opt)
|
||||
{
|
||||
CPU_STK *p_stk;
|
||||
|
||||
|
||||
(void)opt; /* Prevent compiler warning */
|
||||
|
||||
p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
|
||||
/* Registers stacked as if auto-saved on exception */
|
||||
*--p_stk = (CPU_STK)0x01000000u; /* xPSR */
|
||||
*--p_stk = (CPU_STK)p_task; /* Entry Point */
|
||||
*--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
|
||||
*--p_stk = (CPU_STK)0x12121212u; /* R12 */
|
||||
*--p_stk = (CPU_STK)0x03030303u; /* R3 */
|
||||
*--p_stk = (CPU_STK)0x02020202u; /* R2 */
|
||||
*--p_stk = (CPU_STK)p_stk_limit; /* R1 */
|
||||
*--p_stk = (CPU_STK)p_arg; /* R0 : argument */
|
||||
/* Remaining registers saved on process stack */
|
||||
*--p_stk = (CPU_STK)0x11111111u; /* R11 */
|
||||
*--p_stk = (CPU_STK)0x10101010u; /* R10 */
|
||||
*--p_stk = (CPU_STK)0x09090909u; /* R9 */
|
||||
*--p_stk = (CPU_STK)0x08080808u; /* R8 */
|
||||
*--p_stk = (CPU_STK)0x07070707u; /* R7 */
|
||||
*--p_stk = (CPU_STK)0x06060606u; /* R6 */
|
||||
*--p_stk = (CPU_STK)0x05050505u; /* R5 */
|
||||
*--p_stk = (CPU_STK)0x04040404u; /* R4 */
|
||||
|
||||
return (p_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 'OSTCBHighRdyPtr' points to the TCB of the task
|
||||
* that will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCurPtr' points
|
||||
* to the task being switched out (i.e. the preempted task).
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskSwHook (void)
|
||||
{
|
||||
#if OS_CFG_TASK_PROFILE_EN > 0u
|
||||
CPU_TS ts;
|
||||
#endif
|
||||
#ifdef CPU_CFG_INT_DIS_MEAS_EN
|
||||
CPU_TS int_dis_time;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppTaskSwHookPtr)();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_CFG_TASK_PROFILE_EN > 0u
|
||||
ts = OS_TS_GET();
|
||||
if (OSTCBCurPtr != OSTCBHighRdyPtr) {
|
||||
OSTCBCurPtr->CyclesDelta = ts - OSTCBCurPtr->CyclesStart;
|
||||
OSTCBCurPtr->CyclesTotal += (OS_CYCLES)OSTCBCurPtr->CyclesDelta;
|
||||
}
|
||||
|
||||
OSTCBHighRdyPtr->CyclesStart = ts;
|
||||
#endif
|
||||
|
||||
#ifdef CPU_CFG_INT_DIS_MEAS_EN
|
||||
int_dis_time = CPU_IntDisMeasMaxCurReset(); /* Keep track of per-task interrupt disable time */
|
||||
if (OSTCBCurPtr->IntDisTimeMax < int_dis_time) {
|
||||
OSTCBCurPtr->IntDisTimeMax = int_dis_time;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
|
||||
/* Keep track of per-task scheduler lock time */
|
||||
if (OSTCBCurPtr->SchedLockTimeMax < OSSchedLockTimeMaxCur) {
|
||||
OSTCBCurPtr->SchedLockTimeMax = OSSchedLockTimeMaxCur;
|
||||
}
|
||||
OSSchedLockTimeMaxCur = (CPU_TS)0; /* Reset the per-task value */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TICK HOOK
|
||||
*
|
||||
* Description: This function is called every tick.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) This function is assumed to be called from the Tick ISR.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTimeTickHook (void)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTimeTickHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppTimeTickHookPtr)();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* SYS TICK HANDLER
|
||||
*
|
||||
* Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick
|
||||
* interrupt.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickHandler (void)
|
||||
{
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
OSIntNestingCtr++; /* Tell uC/OS-III that we are starting an ISR */
|
||||
CPU_CRITICAL_EXIT();
|
||||
|
||||
OSTimeTick(); /* Call uC/OS-III's OSTimeTick() */
|
||||
|
||||
OSIntExit(); /* Tell uC/OS-III that we are leaving the ISR */
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE SYS TICK
|
||||
*
|
||||
* Description: Initialize the SysTick.
|
||||
*
|
||||
* Arguments : cnts Number of SysTick counts between two OS tick interrupts.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickInit (CPU_INT32U cnts)
|
||||
{
|
||||
CPU_INT32U prio;
|
||||
|
||||
|
||||
CPU_REG_NVIC_ST_RELOAD = cnts - 1u;
|
||||
|
||||
/* Set SysTick handler prio. */
|
||||
prio = CPU_REG_NVIC_SHPRI3;
|
||||
prio &= DEF_BIT_FIELD(24, 0);
|
||||
prio |= DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24);
|
||||
|
||||
CPU_REG_NVIC_SHPRI3 = prio;
|
||||
|
||||
/* Enable timer. */
|
||||
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_CLKSOURCE |
|
||||
CPU_REG_NVIC_ST_CTRL_ENABLE;
|
||||
/* Enable timer interrupt. */
|
||||
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_TICKINT;
|
||||
}
|
||||
|
||||
139
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/IAR/os_cpu.h
Normal file
139
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/IAR/os_cpu.h
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
|
||||
* All rights reserved. Protected by international copyright laws.
|
||||
*
|
||||
* ARM Cortex-M3 Port
|
||||
*
|
||||
* File : OS_CPU.H
|
||||
* Version : V3.01.2
|
||||
* By : JJL
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-III is provided in source form to registered licensees ONLY. It is
|
||||
* illegal to distribute this source code to any third party unless you receive
|
||||
* written permission by an authorized Micrium representative. Knowledge of
|
||||
* the source code may NOT be used to develop a similar product.
|
||||
*
|
||||
* Please help us continue to provide the Embedded community with the finest
|
||||
* software available. Your honesty is greatly appreciated.
|
||||
*
|
||||
* You can contact us at www.micrium.com.
|
||||
*
|
||||
* For : ARMv7M Cortex-M3
|
||||
* Mode : Thumb2
|
||||
* Toolchain : IAR EWARM
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_CPU_H
|
||||
#define OS_CPU_H
|
||||
|
||||
#ifdef OS_CPU_GLOBALS
|
||||
#define OS_CPU_EXT
|
||||
#else
|
||||
#define OS_CPU_EXT extern
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MACROS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NVIC_INT_CTRL
|
||||
#define NVIC_INT_CTRL *((CPU_REG32 *)0xE000ED04)
|
||||
#endif
|
||||
|
||||
#ifndef NVIC_PENDSVSET
|
||||
#define NVIC_PENDSVSET 0x10000000
|
||||
#endif
|
||||
|
||||
#define OS_TASK_SW() NVIC_INT_CTRL = NVIC_PENDSVSET
|
||||
#define OSIntCtxSw() NVIC_INT_CTRL = NVIC_PENDSVSET
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TIMESTAMP CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) OS_TS_GET() is generally defined as CPU_TS_Get32() to allow CPU timestamp timer to be of
|
||||
* any data type size.
|
||||
*
|
||||
* (2) For architectures that provide 32-bit or higher precision free running counters
|
||||
* (i.e. cycle count registers):
|
||||
*
|
||||
* (a) OS_TS_GET() may be defined as CPU_TS_TmrRd() to improve performance when retrieving
|
||||
* the timestamp.
|
||||
*
|
||||
* (b) CPU_TS_TmrRd() MUST be configured to be greater or equal to 32-bits to avoid
|
||||
* truncation of TS.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_CFG_TS_EN == 1u
|
||||
#define OS_TS_GET() (CPU_TS)CPU_TS_TmrRd() /* See Note #2a. */
|
||||
#else
|
||||
#define OS_TS_GET() (CPU_TS)0u
|
||||
#endif
|
||||
|
||||
#if (CPU_CFG_TS_32_EN == DEF_ENABLED) && \
|
||||
(CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)
|
||||
/* CPU_CFG_TS_TMR_SIZE MUST be >= 32-bit (see Note #2b). */
|
||||
#error "cpu_cfg.h, CPU_CFG_TS_TMR_SIZE MUST be >= CPU_WORD_SIZE_32"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS TICK INTERRUPT PRIORITY CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) For systems that don't need any high, real-time priority interrupts; the tick interrupt
|
||||
* should be configured as the highest priority interrupt but won't adversely affect system
|
||||
* operations.
|
||||
*
|
||||
* (2) For systems that need one or more high, real-time interrupts; these should be configured
|
||||
* higher than the tick interrupt which MAY delay execution of the tick interrupt.
|
||||
*
|
||||
* (a) If the higher priority interrupts do NOT continually consume CPU cycles but only
|
||||
* occasionally delay tick interrupts, then the real-time interrupts can successfully
|
||||
* handle their intermittent/periodic events with the system not losing tick interrupts
|
||||
* but only increasing the jitter.
|
||||
*
|
||||
* (b) If the higher priority interrupts consume enough CPU cycles to continually delay the
|
||||
* tick interrupt, then the CPU/system is most likely over-burdened & can't be expected
|
||||
* to handle all its interrupts/tasks. The system time reference gets compromised as a
|
||||
* result of losing tick interrupts.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_CFG_SYSTICK_PRIO 0u
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_CPU_EXT CPU_STK *OS_CPU_ExceptStkBase;
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSStartHighRdy (void);
|
||||
|
||||
void OS_CPU_PendSVHandler (void);
|
||||
|
||||
|
||||
void OS_CPU_SysTickHandler(void);
|
||||
void OS_CPU_SysTickInit (CPU_INT32U cnts);
|
||||
|
||||
#endif
|
||||
170
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/IAR/os_cpu_a.asm
Normal file
170
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/IAR/os_cpu_a.asm
Normal file
@@ -0,0 +1,170 @@
|
||||
;
|
||||
;********************************************************************************************************
|
||||
; uC/OS-III
|
||||
; The Real-Time Kernel
|
||||
;
|
||||
;
|
||||
; (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
|
||||
; All rights reserved. Protected by international copyright laws.
|
||||
;
|
||||
; ARM Cortex-M3 Port
|
||||
;
|
||||
; File : OS_CPU_A.ASM
|
||||
; Version : V3.01.2
|
||||
; By : JJL
|
||||
; BAN
|
||||
;
|
||||
; For : ARMv7M Cortex-M3
|
||||
; Mode : Thumb2
|
||||
; Toolchain : IAR EWARM
|
||||
;********************************************************************************************************
|
||||
;
|
||||
|
||||
;********************************************************************************************************
|
||||
; PUBLIC FUNCTIONS
|
||||
;********************************************************************************************************
|
||||
|
||||
EXTERN OSRunning ; External references
|
||||
EXTERN OSPrioCur
|
||||
EXTERN OSPrioHighRdy
|
||||
EXTERN OSTCBCurPtr
|
||||
EXTERN OSTCBHighRdyPtr
|
||||
EXTERN OSIntExit
|
||||
EXTERN OSTaskSwHook
|
||||
EXTERN OS_CPU_ExceptStkBase
|
||||
|
||||
|
||||
PUBLIC OSStartHighRdy ; Functions declared in this file
|
||||
PUBLIC OS_CPU_PendSVHandler
|
||||
|
||||
;PAGE
|
||||
;********************************************************************************************************
|
||||
; EQUATES
|
||||
;********************************************************************************************************
|
||||
|
||||
NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register.
|
||||
NVIC_SYSPRI14 EQU 0xE000ED22 ; System priority register (priority 14).
|
||||
NVIC_PENDSV_PRI EQU 0xFF ; PendSV priority value (lowest).
|
||||
NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
|
||||
;********************************************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;********************************************************************************************************
|
||||
|
||||
RSEG CODE:CODE:NOROOT(2)
|
||||
THUMB
|
||||
|
||||
|
||||
;PAGE
|
||||
;********************************************************************************************************
|
||||
; START MULTITASKING
|
||||
; void OSStartHighRdy(void)
|
||||
;
|
||||
; Note(s) : 1) This function triggers a PendSV exception (essentially, causes a context switch) to cause
|
||||
; the first task to start.
|
||||
;
|
||||
; 2) OSStartHighRdy() MUST:
|
||||
; a) Setup PendSV exception priority to lowest;
|
||||
; b) Set initial PSP to 0, to tell context switcher this is first run;
|
||||
; c) Set the main stack to OS_CPU_ExceptStkBase
|
||||
; d) Trigger PendSV exception;
|
||||
; e) Enable interrupts (tasks will run with interrupts enabled).
|
||||
;********************************************************************************************************
|
||||
|
||||
OSStartHighRdy
|
||||
LDR R0, =NVIC_SYSPRI14 ; Set the PendSV exception priority
|
||||
LDR R1, =NVIC_PENDSV_PRI
|
||||
STRB R1, [R0]
|
||||
|
||||
MOVS R0, #0 ; Set the PSP to 0 for initial context switch call
|
||||
MSR PSP, R0
|
||||
|
||||
LDR R0, =OS_CPU_ExceptStkBase ; Initialize the MSP to the OS_CPU_ExceptStkBase
|
||||
LDR R1, [R0]
|
||||
MSR MSP, R1
|
||||
|
||||
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
CPSIE I ; Enable interrupts at processor level
|
||||
|
||||
OSStartHang
|
||||
B OSStartHang ; Should never get here
|
||||
|
||||
|
||||
;PAGE
|
||||
;********************************************************************************************************
|
||||
; HANDLE PendSV EXCEPTION
|
||||
; void OS_CPU_PendSVHandler(void)
|
||||
;
|
||||
; Note(s) : 1) PendSV is used to cause a context switch. This is a recommended method for performing
|
||||
; context switches with Cortex-M3. This is because the Cortex-M3 auto-saves half of the
|
||||
; processor context on any exception, and restores same on return from exception. So only
|
||||
; saving of R4-R11 is required and fixing up the stack pointers. Using the PendSV exception
|
||||
; this way means that context saving and restoring is identical whether it is initiated from
|
||||
; a thread or occurs due to an interrupt or exception.
|
||||
;
|
||||
; 2) Pseudo-code is:
|
||||
; a) Get the process SP, if 0 then skip (goto d) the saving part (first context switch);
|
||||
; b) Save remaining regs r4-r11 on process stack;
|
||||
; c) Save the process SP in its TCB, OSTCBCurPtr->OSTCBStkPtr = SP;
|
||||
; d) Call OSTaskSwHook();
|
||||
; e) Get current high priority, OSPrioCur = OSPrioHighRdy;
|
||||
; f) Get current ready thread TCB, OSTCBCurPtr = OSTCBHighRdyPtr;
|
||||
; g) Get new process SP from TCB, SP = OSTCBHighRdyPtr->OSTCBStkPtr;
|
||||
; h) Restore R4-R11 from new process stack;
|
||||
; i) Perform exception return which will restore remaining context.
|
||||
;
|
||||
; 3) On entry into PendSV handler:
|
||||
; a) The following have been saved on the process stack (by processor):
|
||||
; xPSR, PC, LR, R12, R0-R3
|
||||
; b) Processor mode is switched to Handler mode (from Thread mode)
|
||||
; c) Stack is Main stack (switched from Process stack)
|
||||
; d) OSTCBCurPtr points to the OS_TCB of the task to suspend
|
||||
; OSTCBHighRdyPtr points to the OS_TCB of the task to resume
|
||||
;
|
||||
; 4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we
|
||||
; know that it will only be run when no other exception or interrupt is active, and
|
||||
; therefore safe to assume that context being switched out was using the process stack (PSP).
|
||||
;********************************************************************************************************
|
||||
|
||||
OS_CPU_PendSVHandler
|
||||
CPSID I ; Prevent interruption during context switch
|
||||
MRS R0, PSP ; PSP is process stack pointer
|
||||
CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time
|
||||
|
||||
SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack
|
||||
STM R0, {R4-R11}
|
||||
|
||||
LDR R1, =OSTCBCurPtr ; OSTCBCurPtr->OSTCBStkPtr = SP;
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1] ; R0 is SP of process being switched out
|
||||
|
||||
; At this point, entire context of process has been saved
|
||||
OS_CPU_PendSVHandler_nosave
|
||||
PUSH {R14} ; Save LR exc_return value
|
||||
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
|
||||
BLX R0
|
||||
POP {R14}
|
||||
|
||||
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
|
||||
LDR R1, =OSPrioHighRdy
|
||||
LDRB R2, [R1]
|
||||
STRB R2, [R0]
|
||||
|
||||
LDR R0, =OSTCBCurPtr ; OSTCBCurPtr = OSTCBHighRdyPtr;
|
||||
LDR R1, =OSTCBHighRdyPtr
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
|
||||
LDM R0, {R4-R11} ; Restore r4-11 from new process stack
|
||||
ADDS R0, R0, #0x20
|
||||
MSR PSP, R0 ; Load PSP with new process SP
|
||||
ORR LR, LR, #0x04 ; Ensure exception return uses process stack
|
||||
CPSIE I
|
||||
BX LR ; Exception return will restore remaining context
|
||||
|
||||
END
|
||||
407
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/IAR/os_cpu_c.c
Normal file
407
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/IAR/os_cpu_c.c
Normal file
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
|
||||
* All rights reserved. Protected by international copyright laws.
|
||||
*
|
||||
* ARM Cortex-M3 Port
|
||||
*
|
||||
* File : OS_CPU_C.C
|
||||
* Version : V3.02.01
|
||||
* By : JJL
|
||||
* BAN
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
|
||||
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
|
||||
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
|
||||
* application/product. We provide ALL the source code for your convenience and to help you
|
||||
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
|
||||
* it commercially without paying a licensing fee.
|
||||
*
|
||||
* Knowledge of the source code may NOT be used to develop a similar product.
|
||||
*
|
||||
* Please help us continue to provide the embedded community with the finest software available.
|
||||
* Your honesty is greatly appreciated.
|
||||
*
|
||||
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
|
||||
*
|
||||
* For : ARMv7M Cortex-M3
|
||||
* Mode : Thumb2
|
||||
* Toolchain : IAR EWARM
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_GLOBALS
|
||||
|
||||
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
|
||||
const CPU_CHAR *os_cpu_c__c = "$Id: $";
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE FILES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include <os.h>
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSIdleTaskHook (void)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppIdleTaskHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppIdleTaskHookPtr)();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS INITIALIZATION HOOK
|
||||
*
|
||||
* Description: This function is called by OSInit() at the beginning of OSInit().
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSInitHook (void)
|
||||
{
|
||||
OS_CPU_ExceptStkBase = (CPU_STK *)(OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize - 1u);
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* STATISTIC TASK HOOK
|
||||
*
|
||||
* Description: This function is called every second by uC/OS-III's statistics task. This allows your
|
||||
* application to add functionality to the statistics task.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSStatTaskHook (void)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppStatTaskHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppStatTaskHookPtr)();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK CREATION HOOK
|
||||
*
|
||||
* Description: This function is called when a task is created.
|
||||
*
|
||||
* Arguments : p_tcb Pointer to the task control block of the task being created.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskCreateHook (OS_TCB *p_tcb)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskCreateHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppTaskCreateHookPtr)(p_tcb);
|
||||
}
|
||||
#else
|
||||
(void)p_tcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK DELETION HOOK
|
||||
*
|
||||
* Description: This function is called when a task is deleted.
|
||||
*
|
||||
* Arguments : p_tcb Pointer to the task control block of the task being deleted.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskDelHook (OS_TCB *p_tcb)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskDelHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppTaskDelHookPtr)(p_tcb);
|
||||
}
|
||||
#else
|
||||
(void)p_tcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK RETURN HOOK
|
||||
*
|
||||
* Description: This function is called if a task accidentally returns. In other words, a task should
|
||||
* either be an infinite loop or delete itself when done.
|
||||
*
|
||||
* Arguments : p_tcb Pointer to the task control block of the task that is returning.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskReturnHook (OS_TCB *p_tcb)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskReturnHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppTaskReturnHookPtr)(p_tcb);
|
||||
}
|
||||
#else
|
||||
(void)p_tcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* INITIALIZE A TASK'S STACK
|
||||
*
|
||||
* Description: This function is called by OS_Task_Create() or OSTaskCreateExt() to initialize the stack
|
||||
* frame of the task being created. This function is highly processor specific.
|
||||
*
|
||||
* Arguments : p_task Pointer to the task entry point address.
|
||||
*
|
||||
* p_arg Pointer to a user supplied data area that will be passed to the task
|
||||
* when the task first executes.
|
||||
*
|
||||
* p_stk_base Pointer to the base address of the stack.
|
||||
*
|
||||
* stk_size Size of the stack, in number of CPU_STK elements.
|
||||
*
|
||||
* opt Options used to alter the behavior of OS_Task_StkInit().
|
||||
* (see OS.H for OS_TASK_OPT_xxx).
|
||||
*
|
||||
* 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 task starts executing.
|
||||
*
|
||||
* 2) All tasks run in Thread mode, using process stack.
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
|
||||
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
|
||||
void *p_arg,
|
||||
CPU_STK *p_stk_base,
|
||||
CPU_STK *p_stk_limit,
|
||||
CPU_STK_SIZE stk_size,
|
||||
OS_OPT opt)
|
||||
{
|
||||
CPU_STK *p_stk;
|
||||
|
||||
|
||||
(void)opt; /* Prevent compiler warning */
|
||||
|
||||
p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
|
||||
/* Registers stacked as if auto-saved on exception */
|
||||
*--p_stk = (CPU_STK)0x01000000u; /* xPSR */
|
||||
*--p_stk = (CPU_STK)p_task; /* Entry Point */
|
||||
*--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
|
||||
*--p_stk = (CPU_STK)0x12121212u; /* R12 */
|
||||
*--p_stk = (CPU_STK)0x03030303u; /* R3 */
|
||||
*--p_stk = (CPU_STK)0x02020202u; /* R2 */
|
||||
*--p_stk = (CPU_STK)p_stk_limit; /* R1 */
|
||||
*--p_stk = (CPU_STK)p_arg; /* R0 : argument */
|
||||
/* Remaining registers saved on process stack */
|
||||
*--p_stk = (CPU_STK)0x11111111u; /* R11 */
|
||||
*--p_stk = (CPU_STK)0x10101010u; /* R10 */
|
||||
*--p_stk = (CPU_STK)0x09090909u; /* R9 */
|
||||
*--p_stk = (CPU_STK)0x08080808u; /* R8 */
|
||||
*--p_stk = (CPU_STK)0x07070707u; /* R7 */
|
||||
*--p_stk = (CPU_STK)0x06060606u; /* R6 */
|
||||
*--p_stk = (CPU_STK)0x05050505u; /* R5 */
|
||||
*--p_stk = (CPU_STK)0x04040404u; /* R4 */
|
||||
|
||||
return (p_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 'OSTCBHighRdyPtr' points to the TCB of the task
|
||||
* that will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCurPtr' points
|
||||
* to the task being switched out (i.e. the preempted task).
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskSwHook (void)
|
||||
{
|
||||
#if OS_CFG_TASK_PROFILE_EN > 0u
|
||||
CPU_TS ts;
|
||||
#endif
|
||||
#ifdef CPU_CFG_INT_DIS_MEAS_EN
|
||||
CPU_TS int_dis_time;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppTaskSwHookPtr)();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_CFG_TASK_PROFILE_EN > 0u
|
||||
ts = OS_TS_GET();
|
||||
if (OSTCBCurPtr != OSTCBHighRdyPtr) {
|
||||
OSTCBCurPtr->CyclesDelta = ts - OSTCBCurPtr->CyclesStart;
|
||||
OSTCBCurPtr->CyclesTotal += (OS_CYCLES)OSTCBCurPtr->CyclesDelta;
|
||||
}
|
||||
|
||||
OSTCBHighRdyPtr->CyclesStart = ts;
|
||||
#endif
|
||||
|
||||
#ifdef CPU_CFG_INT_DIS_MEAS_EN
|
||||
int_dis_time = CPU_IntDisMeasMaxCurReset(); /* Keep track of per-task interrupt disable time */
|
||||
if (OSTCBCurPtr->IntDisTimeMax < int_dis_time) {
|
||||
OSTCBCurPtr->IntDisTimeMax = int_dis_time;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
|
||||
/* Keep track of per-task scheduler lock time */
|
||||
if (OSTCBCurPtr->SchedLockTimeMax < OSSchedLockTimeMaxCur) {
|
||||
OSTCBCurPtr->SchedLockTimeMax = OSSchedLockTimeMaxCur;
|
||||
}
|
||||
OSSchedLockTimeMaxCur = (CPU_TS)0; /* Reset the per-task value */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TICK HOOK
|
||||
*
|
||||
* Description: This function is called every tick.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) This function is assumed to be called from the Tick ISR.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTimeTickHook (void)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTimeTickHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppTimeTickHookPtr)();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* SYS TICK HANDLER
|
||||
*
|
||||
* Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick
|
||||
* interrupt.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickHandler (void)
|
||||
{
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
OSIntNestingCtr++; /* Tell uC/OS-III that we are starting an ISR */
|
||||
CPU_CRITICAL_EXIT();
|
||||
|
||||
OSTimeTick(); /* Call uC/OS-III's OSTimeTick() */
|
||||
|
||||
OSIntExit(); /* Tell uC/OS-III that we are leaving the ISR */
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE SYS TICK
|
||||
*
|
||||
* Description: Initialize the SysTick.
|
||||
*
|
||||
* Arguments : cnts Number of SysTick counts between two OS tick interrupts.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickInit (CPU_INT32U cnts)
|
||||
{
|
||||
CPU_INT32U prio;
|
||||
|
||||
|
||||
CPU_REG_NVIC_ST_RELOAD = cnts - 1u;
|
||||
|
||||
/* Set SysTick handler prio. */
|
||||
prio = CPU_REG_NVIC_SHPRI3;
|
||||
prio &= DEF_BIT_FIELD(24, 0);
|
||||
prio |= DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24);
|
||||
|
||||
CPU_REG_NVIC_SHPRI3 = prio;
|
||||
|
||||
/* Enable timer. */
|
||||
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_CLKSOURCE |
|
||||
CPU_REG_NVIC_ST_CTRL_ENABLE;
|
||||
/* Enable timer interrupt. */
|
||||
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_TICKINT;
|
||||
}
|
||||
|
||||
139
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/RealView/os_cpu.h
Normal file
139
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/RealView/os_cpu.h
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
|
||||
* All rights reserved. Protected by international copyright laws.
|
||||
*
|
||||
* ARM Cortex-M3 Port
|
||||
*
|
||||
* File : OS_CPU.H
|
||||
* Version : V3.01.2
|
||||
* By : JJL
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-III is provided in source form to registered licensees ONLY. It is
|
||||
* illegal to distribute this source code to any third party unless you receive
|
||||
* written permission by an authorized Micrium representative. Knowledge of
|
||||
* the source code may NOT be used to develop a similar product.
|
||||
*
|
||||
* Please help us continue to provide the Embedded community with the finest
|
||||
* software available. Your honesty is greatly appreciated.
|
||||
*
|
||||
* You can contact us at www.micrium.com.
|
||||
*
|
||||
* For : ARMv7M Cortex-M3
|
||||
* Mode : Thumb2
|
||||
* Toolchain : RealView
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_CPU_H
|
||||
#define OS_CPU_H
|
||||
|
||||
#ifdef OS_CPU_GLOBALS
|
||||
#define OS_CPU_EXT
|
||||
#else
|
||||
#define OS_CPU_EXT extern
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MACROS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NVIC_INT_CTRL
|
||||
#define NVIC_INT_CTRL *((CPU_REG32 *)0xE000ED04)
|
||||
#endif
|
||||
|
||||
#ifndef NVIC_PENDSVSET
|
||||
#define NVIC_PENDSVSET 0x10000000
|
||||
#endif
|
||||
|
||||
#define OS_TASK_SW() NVIC_INT_CTRL = NVIC_PENDSVSET
|
||||
#define OSIntCtxSw() NVIC_INT_CTRL = NVIC_PENDSVSET
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TIMESTAMP CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) OS_TS_GET() is generally defined as CPU_TS_Get32() to allow CPU timestamp timer to be of
|
||||
* any data type size.
|
||||
*
|
||||
* (2) For architectures that provide 32-bit or higher precision free running counters
|
||||
* (i.e. cycle count registers):
|
||||
*
|
||||
* (a) OS_TS_GET() may be defined as CPU_TS_TmrRd() to improve performance when retrieving
|
||||
* the timestamp.
|
||||
*
|
||||
* (b) CPU_TS_TmrRd() MUST be configured to be greater or equal to 32-bits to avoid
|
||||
* truncation of TS.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_CFG_TS_EN == 1u
|
||||
#define OS_TS_GET() (CPU_TS)CPU_TS_TmrRd() /* See Note #2a. */
|
||||
#else
|
||||
#define OS_TS_GET() (CPU_TS)0u
|
||||
#endif
|
||||
|
||||
#if (CPU_CFG_TS_32_EN == DEF_ENABLED) && \
|
||||
(CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)
|
||||
/* CPU_CFG_TS_TMR_SIZE MUST be >= 32-bit (see Note #2b). */
|
||||
#error "cpu_cfg.h, CPU_CFG_TS_TMR_SIZE MUST be >= CPU_WORD_SIZE_32"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS TICK INTERRUPT PRIORITY CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) For systems that don't need any high, real-time priority interrupts; the tick interrupt
|
||||
* should be configured as the highest priority interrupt but won't adversely affect system
|
||||
* operations.
|
||||
*
|
||||
* (2) For systems that need one or more high, real-time interrupts; these should be configured
|
||||
* higher than the tick interrupt which MAY delay execution of the tick interrupt.
|
||||
*
|
||||
* (a) If the higher priority interrupts do NOT continually consume CPU cycles but only
|
||||
* occasionally delay tick interrupts, then the real-time interrupts can successfully
|
||||
* handle their intermittent/periodic events with the system not losing tick interrupts
|
||||
* but only increasing the jitter.
|
||||
*
|
||||
* (b) If the higher priority interrupts consume enough CPU cycles to continually delay the
|
||||
* tick interrupt, then the CPU/system is most likely over-burdened & can't be expected
|
||||
* to handle all its interrupts/tasks. The system time reference gets compromised as a
|
||||
* result of losing tick interrupts.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_CFG_SYSTICK_PRIO 0u
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_CPU_EXT CPU_STK *OS_CPU_ExceptStkBase;
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSStartHighRdy (void);
|
||||
|
||||
void OS_CPU_PendSVHandler (void);
|
||||
|
||||
|
||||
void OS_CPU_SysTickHandler(void);
|
||||
void OS_CPU_SysTickInit (CPU_INT32U cnts);
|
||||
|
||||
#endif
|
||||
175
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/RealView/os_cpu_a.s
Normal file
175
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/RealView/os_cpu_a.s
Normal file
@@ -0,0 +1,175 @@
|
||||
;
|
||||
;********************************************************************************************************
|
||||
; uC/OS-III
|
||||
; The Real-Time Kernel
|
||||
;
|
||||
;
|
||||
; (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
|
||||
; All rights reserved. Protected by international copyright laws.
|
||||
;
|
||||
; ARM Cortex-M3 Port
|
||||
;
|
||||
; File : OS_CPU_A.ASM
|
||||
; Version : V3.01.2
|
||||
; By : JJL
|
||||
; BAN
|
||||
;
|
||||
; For : ARMv7M Cortex-M3
|
||||
; Mode : Thumb2
|
||||
; Toolchain : RealView Development Suite
|
||||
; RealView Microcontroller Development Kit (MDK)
|
||||
; ARM Developer Suite (ADS)
|
||||
; Keil uVision
|
||||
;********************************************************************************************************
|
||||
;
|
||||
|
||||
;********************************************************************************************************
|
||||
; PUBLIC FUNCTIONS
|
||||
;********************************************************************************************************
|
||||
|
||||
IMPORT OSRunning ; External references
|
||||
IMPORT OSPrioCur
|
||||
IMPORT OSPrioHighRdy
|
||||
IMPORT OSTCBCurPtr
|
||||
IMPORT OSTCBHighRdyPtr
|
||||
IMPORT OSIntExit
|
||||
IMPORT OSTaskSwHook
|
||||
IMPORT OS_CPU_ExceptStkBase
|
||||
|
||||
|
||||
EXPORT OSStartHighRdy ; Functions declared in this file
|
||||
EXPORT OS_CPU_PendSVHandler
|
||||
|
||||
;PAGE
|
||||
;********************************************************************************************************
|
||||
; EQUATES
|
||||
;********************************************************************************************************
|
||||
|
||||
NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register.
|
||||
NVIC_SYSPRI14 EQU 0xE000ED22 ; System priority register (priority 14).
|
||||
NVIC_PENDSV_PRI EQU 0xFF ; PendSV priority value (lowest).
|
||||
NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
|
||||
;********************************************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;********************************************************************************************************
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
AREA CODE, CODE, READONLY
|
||||
|
||||
|
||||
;PAGE
|
||||
;********************************************************************************************************
|
||||
; START MULTITASKING
|
||||
; void OSStartHighRdy(void)
|
||||
;
|
||||
; Note(s) : 1) This function triggers a PendSV exception (essentially, causes a context switch) to cause
|
||||
; the first task to start.
|
||||
;
|
||||
; 2) OSStartHighRdy() MUST:
|
||||
; a) Setup PendSV exception priority to lowest;
|
||||
; b) Set initial PSP to 0, to tell context switcher this is first run;
|
||||
; c) Set the main stack to OS_CPU_ExceptStkBase
|
||||
; d) Trigger PendSV exception;
|
||||
; e) Enable interrupts (tasks will run with interrupts enabled).
|
||||
;********************************************************************************************************
|
||||
|
||||
OSStartHighRdy
|
||||
LDR R0, =NVIC_SYSPRI14 ; Set the PendSV exception priority
|
||||
LDR R1, =NVIC_PENDSV_PRI
|
||||
STRB R1, [R0]
|
||||
|
||||
MOVS R0, #0 ; Set the PSP to 0 for initial context switch call
|
||||
MSR PSP, R0
|
||||
|
||||
LDR R0, =OS_CPU_ExceptStkBase ; Initialize the MSP to the OS_CPU_ExceptStkBase
|
||||
LDR R1, [R0]
|
||||
MSR MSP, R1
|
||||
|
||||
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
CPSIE I ; Enable interrupts at processor level
|
||||
|
||||
OSStartHang
|
||||
B OSStartHang ; Should never get here
|
||||
|
||||
|
||||
;PAGE
|
||||
;********************************************************************************************************
|
||||
; HANDLE PendSV EXCEPTION
|
||||
; void OS_CPU_PendSVHandler(void)
|
||||
;
|
||||
; Note(s) : 1) PendSV is used to cause a context switch. This is a recommended method for performing
|
||||
; context switches with Cortex-M3. This is because the Cortex-M3 auto-saves half of the
|
||||
; processor context on any exception, and restores same on return from exception. So only
|
||||
; saving of R4-R11 is required and fixing up the stack pointers. Using the PendSV exception
|
||||
; this way means that context saving and restoring is identical whether it is initiated from
|
||||
; a thread or occurs due to an interrupt or exception.
|
||||
;
|
||||
; 2) Pseudo-code is:
|
||||
; a) Get the process SP, if 0 then skip (goto d) the saving part (first context switch);
|
||||
; b) Save remaining regs r4-r11 on process stack;
|
||||
; c) Save the process SP in its TCB, OSTCBCurPtr->OSTCBStkPtr = SP;
|
||||
; d) Call OSTaskSwHook();
|
||||
; e) Get current high priority, OSPrioCur = OSPrioHighRdy;
|
||||
; f) Get current ready thread TCB, OSTCBCurPtr = OSTCBHighRdyPtr;
|
||||
; g) Get new process SP from TCB, SP = OSTCBHighRdyPtr->OSTCBStkPtr;
|
||||
; h) Restore R4-R11 from new process stack;
|
||||
; i) Perform exception return which will restore remaining context.
|
||||
;
|
||||
; 3) On entry into PendSV handler:
|
||||
; a) The following have been saved on the process stack (by processor):
|
||||
; xPSR, PC, LR, R12, R0-R3
|
||||
; b) Processor mode is switched to Handler mode (from Thread mode)
|
||||
; c) Stack is Main stack (switched from Process stack)
|
||||
; d) OSTCBCurPtr points to the OS_TCB of the task to suspend
|
||||
; OSTCBHighRdyPtr points to the OS_TCB of the task to resume
|
||||
;
|
||||
; 4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we
|
||||
; know that it will only be run when no other exception or interrupt is active, and
|
||||
; therefore safe to assume that context being switched out was using the process stack (PSP).
|
||||
;********************************************************************************************************
|
||||
|
||||
OS_CPU_PendSVHandler
|
||||
CPSID I ; Prevent interruption during context switch
|
||||
MRS R0, PSP ; PSP is process stack pointer
|
||||
CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time
|
||||
|
||||
SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack
|
||||
STM R0, {R4-R11}
|
||||
|
||||
LDR R1, =OSTCBCurPtr ; OSTCBCurPtr->OSTCBStkPtr = SP;
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1] ; R0 is SP of process being switched out
|
||||
|
||||
; At this point, entire context of process has been saved
|
||||
OS_CPU_PendSVHandler_nosave
|
||||
PUSH {R14} ; Save LR exc_return value
|
||||
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
|
||||
BLX R0
|
||||
POP {R14}
|
||||
|
||||
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
|
||||
LDR R1, =OSPrioHighRdy
|
||||
LDRB R2, [R1]
|
||||
STRB R2, [R0]
|
||||
|
||||
LDR R0, =OSTCBCurPtr ; OSTCBCurPtr = OSTCBHighRdyPtr;
|
||||
LDR R1, =OSTCBHighRdyPtr
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
|
||||
LDM R0, {R4-R11} ; Restore r4-11 from new process stack
|
||||
ADDS R0, R0, #0x20
|
||||
MSR PSP, R0 ; Load PSP with new process SP
|
||||
ORR LR, LR, #0x04 ; Ensure exception return uses process stack
|
||||
CPSIE I
|
||||
BX LR ; Exception return will restore remaining context
|
||||
|
||||
END
|
||||
411
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/RealView/os_cpu_c.c
Normal file
411
UCOSIII/uCOS-III/Ports/ARM-Cortex-M3/Generic/RealView/os_cpu_c.c
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
|
||||
* All rights reserved. Protected by international copyright laws.
|
||||
*
|
||||
* ARM Cortex-M3 Port
|
||||
*
|
||||
* File : OS_CPU_C.C
|
||||
* Version : V3.01.2
|
||||
* By : JJL
|
||||
* BAN
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-III is provided in source form to registered licensees ONLY. It is
|
||||
* illegal to distribute this source code to any third party unless you receive
|
||||
* written permission by an authorized Micrium representative. Knowledge of
|
||||
* the source code may NOT be used to develop a similar product.
|
||||
*
|
||||
* Please help us continue to provide the Embedded community with the finest
|
||||
* software available. Your honesty is greatly appreciated.
|
||||
*
|
||||
* You can contact us at www.micrium.com.
|
||||
*
|
||||
* For : ARMv7M Cortex-M3
|
||||
* Mode : Thumb2
|
||||
* Toolchain : RealView
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_GLOBALS
|
||||
|
||||
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
|
||||
const CPU_CHAR *os_cpu_c__c = "$Id: $";
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE FILES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include <os.h>
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSIdleTaskHook (void)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppIdleTaskHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppIdleTaskHookPtr)();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS INITIALIZATION HOOK
|
||||
*
|
||||
* Description: This function is called by OSInit() at the beginning of OSInit().
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSInitHook (void)
|
||||
{
|
||||
CPU_STK_SIZE i;
|
||||
CPU_STK *p_stk;
|
||||
|
||||
|
||||
p_stk = OSCfg_ISRStkBasePtr; /* Clear the ISR stack */
|
||||
for (i = 0u; i < OSCfg_ISRStkSize; i++) {
|
||||
*p_stk++ = (CPU_STK)0u;
|
||||
}
|
||||
OS_CPU_ExceptStkBase = (CPU_STK *)(OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize - 1u);
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* STATISTIC TASK HOOK
|
||||
*
|
||||
* Description: This function is called every second by uC/OS-III's statistics task. This allows your
|
||||
* application to add functionality to the statistics task.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSStatTaskHook (void)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppStatTaskHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppStatTaskHookPtr)();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK CREATION HOOK
|
||||
*
|
||||
* Description: This function is called when a task is created.
|
||||
*
|
||||
* Arguments : p_tcb Pointer to the task control block of the task being created.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskCreateHook (OS_TCB *p_tcb)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskCreateHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppTaskCreateHookPtr)(p_tcb);
|
||||
}
|
||||
#else
|
||||
(void)p_tcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK DELETION HOOK
|
||||
*
|
||||
* Description: This function is called when a task is deleted.
|
||||
*
|
||||
* Arguments : p_tcb Pointer to the task control block of the task being deleted.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskDelHook (OS_TCB *p_tcb)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskDelHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppTaskDelHookPtr)(p_tcb);
|
||||
}
|
||||
#else
|
||||
(void)p_tcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK RETURN HOOK
|
||||
*
|
||||
* Description: This function is called if a task accidentally returns. In other words, a task should
|
||||
* either be an infinite loop or delete itself when done.
|
||||
*
|
||||
* Arguments : p_tcb Pointer to the task control block of the task that is returning.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskReturnHook (OS_TCB *p_tcb)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskReturnHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppTaskReturnHookPtr)(p_tcb);
|
||||
}
|
||||
#else
|
||||
(void)p_tcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* INITIALIZE A TASK'S STACK
|
||||
*
|
||||
* Description: This function is called by OS_Task_Create() or OSTaskCreateExt() to initialize the stack
|
||||
* frame of the task being created. This function is highly processor specific.
|
||||
*
|
||||
* Arguments : p_task Pointer to the task entry point address.
|
||||
*
|
||||
* p_arg Pointer to a user supplied data area that will be passed to the task
|
||||
* when the task first executes.
|
||||
*
|
||||
* p_stk_base Pointer to the base address of the stack.
|
||||
*
|
||||
* stk_size Size of the stack, in number of CPU_STK elements.
|
||||
*
|
||||
* opt Options used to alter the behavior of OS_Task_StkInit().
|
||||
* (see OS.H for OS_TASK_OPT_xxx).
|
||||
*
|
||||
* 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 task starts executing.
|
||||
*
|
||||
* 2) All tasks run in Thread mode, using process stack.
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
|
||||
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
|
||||
void *p_arg,
|
||||
CPU_STK *p_stk_base,
|
||||
CPU_STK *p_stk_limit,
|
||||
CPU_STK_SIZE stk_size,
|
||||
OS_OPT opt)
|
||||
{
|
||||
CPU_STK *p_stk;
|
||||
|
||||
|
||||
(void)opt; /* Prevent compiler warning */
|
||||
|
||||
p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
|
||||
/* Registers stacked as if auto-saved on exception */
|
||||
*--p_stk = (CPU_STK)0x01000000u; /* xPSR */
|
||||
*--p_stk = (CPU_STK)p_task; /* Entry Point */
|
||||
*--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
|
||||
*--p_stk = (CPU_STK)0x12121212u; /* R12 */
|
||||
*--p_stk = (CPU_STK)0x03030303u; /* R3 */
|
||||
*--p_stk = (CPU_STK)0x02020202u; /* R2 */
|
||||
*--p_stk = (CPU_STK)p_stk_limit; /* R1 */
|
||||
*--p_stk = (CPU_STK)p_arg; /* R0 : argument */
|
||||
/* Remaining registers saved on process stack */
|
||||
*--p_stk = (CPU_STK)0x11111111u; /* R11 */
|
||||
*--p_stk = (CPU_STK)0x10101010u; /* R10 */
|
||||
*--p_stk = (CPU_STK)0x09090909u; /* R9 */
|
||||
*--p_stk = (CPU_STK)0x08080808u; /* R8 */
|
||||
*--p_stk = (CPU_STK)0x07070707u; /* R7 */
|
||||
*--p_stk = (CPU_STK)0x06060606u; /* R6 */
|
||||
*--p_stk = (CPU_STK)0x05050505u; /* R5 */
|
||||
*--p_stk = (CPU_STK)0x04040404u; /* R4 */
|
||||
|
||||
return (p_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 'OSTCBHighRdyPtr' points to the TCB of the task
|
||||
* that will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCurPtr' points
|
||||
* to the task being switched out (i.e. the preempted task).
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskSwHook (void)
|
||||
{
|
||||
#if OS_CFG_TASK_PROFILE_EN > 0u
|
||||
CPU_TS ts;
|
||||
#endif
|
||||
#ifdef CPU_CFG_INT_DIS_MEAS_EN
|
||||
CPU_TS int_dis_time;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppTaskSwHookPtr)();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_CFG_TASK_PROFILE_EN > 0u
|
||||
ts = OS_TS_GET();
|
||||
if (OSTCBCurPtr != OSTCBHighRdyPtr) {
|
||||
OSTCBCurPtr->CyclesDelta = ts - OSTCBCurPtr->CyclesStart;
|
||||
OSTCBCurPtr->CyclesTotal += (OS_CYCLES)OSTCBCurPtr->CyclesDelta;
|
||||
}
|
||||
|
||||
OSTCBHighRdyPtr->CyclesStart = ts;
|
||||
#endif
|
||||
|
||||
#ifdef CPU_CFG_INT_DIS_MEAS_EN
|
||||
int_dis_time = CPU_IntDisMeasMaxCurReset(); /* Keep track of per-task interrupt disable time */
|
||||
if (OSTCBCurPtr->IntDisTimeMax < int_dis_time) {
|
||||
OSTCBCurPtr->IntDisTimeMax = int_dis_time;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
|
||||
/* Keep track of per-task scheduler lock time */
|
||||
if (OSTCBCurPtr->SchedLockTimeMax < OSSchedLockTimeMaxCur) {
|
||||
OSTCBCurPtr->SchedLockTimeMax = OSSchedLockTimeMaxCur;
|
||||
}
|
||||
OSSchedLockTimeMaxCur = (CPU_TS)0; /* Reset the per-task value */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TICK HOOK
|
||||
*
|
||||
* Description: This function is called every tick.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) This function is assumed to be called from the Tick ISR.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTimeTickHook (void)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTimeTickHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppTimeTickHookPtr)();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* SYS TICK HANDLER
|
||||
*
|
||||
* Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick
|
||||
* interrupt.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickHandler (void)
|
||||
{
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
OSIntNestingCtr++; /* Tell uC/OS-III that we are starting an ISR */
|
||||
CPU_CRITICAL_EXIT();
|
||||
|
||||
OSTimeTick(); /* Call uC/OS-III's OSTimeTick() */
|
||||
|
||||
OSIntExit(); /* Tell uC/OS-III that we are leaving the ISR */
|
||||
}
|
||||
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE SYS TICK
|
||||
*
|
||||
* Description: Initialize the SysTick.
|
||||
*
|
||||
* Arguments : cnts Number of SysTick counts between two OS tick interrupts.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickInit (CPU_INT32U cnts)
|
||||
{
|
||||
CPU_INT32U prio;
|
||||
|
||||
|
||||
CPU_REG_NVIC_ST_RELOAD = cnts - 1u;
|
||||
|
||||
/* Set SysTick handler prio. */
|
||||
prio = CPU_REG_NVIC_SHPRI3;
|
||||
prio &= DEF_BIT_FIELD(24, 0);
|
||||
prio |= DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24);
|
||||
|
||||
CPU_REG_NVIC_SHPRI3 = prio;
|
||||
|
||||
/* Enable timer. */
|
||||
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_CLKSOURCE |
|
||||
CPU_REG_NVIC_ST_CTRL_ENABLE;
|
||||
/* Enable timer interrupt. */
|
||||
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_TICKINT;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user