Improved certain Cortex-M3 context switch times

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2177 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2009-10-25 02:24:40 +00:00
parent cc347e43c3
commit b8824028b1
17 changed files with 997 additions and 160 deletions

View File

@ -1,5 +1,5 @@
/****************************************************************************
* arch/arm/src/common/up_blocktask.c
* arch/arm/src/arm/up_blocktask.c
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>

View File

@ -1,5 +1,5 @@
/****************************************************************************
* arch/arm/src/common/up_releasepending.c
* arch/arm/src/arm/up_releasepending.c
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>

View File

@ -1,5 +1,5 @@
/****************************************************************************
* arch/arm/src/common/up_reprioritizertr.c
* arch/arm/src/arm/up_reprioritizertr.c
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>

View File

@ -114,7 +114,7 @@ void up_sigdeliver(void)
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
/* Then restore the task interrupt statat. */
/* Then restore the task interrupt state */
irqrestore(regs[REG_CPSR]);

View File

@ -1,5 +1,5 @@
/****************************************************************************
* arch/arm/src/common/up_unblocktask.c
* arch/arm/src/arm/up_unblocktask.c
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>

View File

@ -155,9 +155,10 @@ extern uint32 _ebss; /* End+1 of .bss */
extern void up_boot(void);
extern void up_copystate(uint32 *dest, uint32 *src);
extern void up_decodeirq(uint32 *regs);
extern void up_fullcontextrestore(uint32 *regs) __attribute__ ((noreturn));
extern void up_irqinitialize(void);
extern int up_saveusercontext(uint32 *regs);
extern int up_saveusercontext(uint32 *saveregs);
extern void up_fullcontextrestore(uint32 *restoreregs) __attribute__ ((noreturn));
extern void up_switchcontext(uint32 *saveregs, uint32 *restoreregs);
extern void up_sigdeliver(void);
extern int up_timerisr(int irq, uint32 *regs);
extern void up_lowputc(char ch);

View File

@ -0,0 +1,167 @@
/****************************************************************************
* arch/arm/src/cortexm3/up_blocktask.c
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include "os_internal.h"
#include "up_internal.h"
/****************************************************************************
* Private Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_block_task
*
* Description:
* The currently executing task at the head of
* the ready to run list must be stopped. Save its context
* and move it to the inactive list specified by task_state.
*
* Inputs:
* tcb: Refers to a task in the ready-to-run list (normally
* the task at the head of the list). It most be
* stopped, its context saved and moved into one of the
* waiting task lists. It it was the task at the head
* of the ready-to-run list, then a context to the new
* ready to run task must be performed.
* task_state: Specifies which waiting task list should be
* hold the blocked task TCB.
*
****************************************************************************/
void up_block_task(_TCB *tcb, tstate_t task_state)
{
/* Verify that the context switch can be performed */
if ((tcb->task_state < FIRST_READY_TO_RUN_STATE) ||
(tcb->task_state > LAST_READY_TO_RUN_STATE))
{
PANIC(OSERR_BADBLOCKSTATE);
}
else
{
_TCB *rtcb = (_TCB*)g_readytorun.head;
boolean switch_needed;
/* Remove the tcb task from the ready-to-run list. If we
* are blocking the task at the head of the task list (the
* most likely case), then a context switch to the next
* ready-to-run task is needed. In this case, it should
* also be true that rtcb == tcb.
*/
switch_needed = sched_removereadytorun(tcb);
/* Add the task to the specified blocked task list */
sched_addblocked(tcb, (tstate_t)task_state);
/* If there are any pending tasks, then add them to the g_readytorun
* task list now
*/
if (g_pendingtasks.head)
{
switch_needed |= sched_mergepending();
}
/* Now, perform the context switch if one is needed */
if (switch_needed)
{
/* Are we in an interrupt handler? */
if (current_regs)
{
/* Yes, then we have to do things differently.
* Just copy the current_regs into the OLD rtcb.
*/
up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
*/
rtcb = (_TCB*)g_readytorun.head;
/* Then switch contexts */
up_restorestate(rtcb->xcp.regs);
}
/* No, then we will need to perform the user context switch */
else
{
/* Switch context to the context of the task at the head of the
* ready to run list.
*/
_TCB *nexttcb = (_TCB*)g_readytorun.head;
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
/* up_switchcontext forces a context switch to the task at the
* head of the ready-to-run list. It does not 'return' in the
* normal sense. When it does return, it is because the blocked
* task is again ready to run and has execution priority.
*/
}
}
}
}

View File

@ -0,0 +1,93 @@
/************************************************************************************
* arch/arm/src/cortexm3/up_fullcontextrestore.S
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include <arch/irq.h>
#include "nvic.h"
/************************************************************************************
* Preprocessor Definitions
************************************************************************************/
/************************************************************************************
* Global Symbols
************************************************************************************/
.syntax unified
.thumb
.file "up_fullcontextrestore.S"
/************************************************************************************
* Macros
************************************************************************************/
/************************************************************************************
* Public Functions
************************************************************************************/
/**************************************************************************
* Name: up_fullcontextrestore
*
* Description:
* Restore the current thread context. Full prototype is:
*
* void up_fullcontextrestore(uint32 *restoreregs) __attribute__ ((noreturn));
*
* Return:
* None
*
**************************************************************************/
.thumb_func
.globl up_fullcontextrestore
.type up_fullcontextrestore, function
up_fullcontextrestore:
/* Perform the System call with R0=1 and R1=regs */
mov r1, r0 /* R1: regs */
mov r0, #1 /* R0: 1 means restore context */
svc 0 /* Force synchronous SVCall (or Hard Fault) */
/* This call should not return */
bx lr /* Unnecessary ... will not return */
.size up_fullcontextrestore, .-up_fullcontextrestore
.end

View File

@ -0,0 +1,129 @@
/****************************************************************************
* arch/arm/src/cortexm3/up_releasepending.c
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include "os_internal.h"
#include "up_internal.h"
/****************************************************************************
* Private Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_release_pending
*
* Description:
* Release and ready-to-run tasks that have
* collected in the pending task list. This can call a
* context switch if a new task is placed at the head of
* the ready to run list.
*
****************************************************************************/
void up_release_pending(void)
{
_TCB *rtcb = (_TCB*)g_readytorun.head;
slldbg("From TCB=%p\n", rtcb);
/* Merge the g_pendingtasks list into the g_readytorun task list */
/* sched_lock(); */
if (sched_mergepending())
{
/* The currently active task has changed! We will need to
* switch contexts. First check if we are operating in
* interrupt context:
*/
if (current_regs)
{
/* Yes, then we have to do things differently.
* Just copy the current_regs into the OLD rtcb.
*/
up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
*/
rtcb = (_TCB*)g_readytorun.head;
slldbg("New Active Task TCB=%p\n", rtcb);
/* Then switch contexts */
up_restorestate(rtcb->xcp.regs);
}
/* No, then we will need to perform the user context switch */
else
{
/* Switch context to the context of the task at the head of the
* ready to run list.
*/
_TCB *nexttcb = (_TCB*)g_readytorun.head;
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
/* up_switchcontext forces a context switch to the task at the
* head of the ready-to-run list. It does not 'return' in the
* normal sense. When it does return, it is because the blocked
* task is again ready to run and has execution priority.
*/
}
}
}

View File

@ -0,0 +1,178 @@
/****************************************************************************
* arch/arm/src/cortexm3/up_reprioritizertr.c
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include "os_internal.h"
#include "up_internal.h"
/****************************************************************************
* Private Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_reprioritize_rtr
*
* Description:
* Called when the priority of a running or
* ready-to-run task changes and the reprioritization will
* cause a context switch. Two cases:
*
* 1) The priority of the currently running task drops and the next
* task in the ready to run list has priority.
* 2) An idle, ready to run task's priority has been raised above the
* the priority of the current, running task and it now has the
* priority.
*
* Inputs:
* tcb: The TCB of the task that has been reprioritized
* priority: The new task priority
*
****************************************************************************/
void up_reprioritize_rtr(_TCB *tcb, ubyte priority)
{
/* Verify that the caller is sane */
if (tcb->task_state < FIRST_READY_TO_RUN_STATE ||
tcb->task_state > LAST_READY_TO_RUN_STATE ||
priority < SCHED_PRIORITY_MIN ||
priority > SCHED_PRIORITY_MAX)
{
PANIC(OSERR_BADREPRIORITIZESTATE);
}
else
{
_TCB *rtcb = (_TCB*)g_readytorun.head;
boolean switch_needed;
slldbg("TCB=%p PRI=%d\n", tcb, priority);
/* Remove the tcb task from the ready-to-run list.
* sched_removereadytorun will return TRUE if we just
* remove the head of the ready to run list.
*/
switch_needed = sched_removereadytorun(tcb);
/* Setup up the new task priority */
tcb->sched_priority = (ubyte)priority;
/* Return the task to the specified blocked task list.
* sched_addreadytorun will return TRUE if the task was
* added to the new list. We will need to perform a context
* switch only if the EXCLUSIVE or of the two calls is non-zero
* (i.e., one and only one the calls changes the head of the
* ready-to-run list).
*/
switch_needed ^= sched_addreadytorun(tcb);
/* Now, perform the context switch if one is needed */
if (switch_needed)
{
/* If we are going to do a context switch, then now is the right
* time to add any pending tasks back into the ready-to-run list.
* task list now
*/
if (g_pendingtasks.head)
{
sched_mergepending();
}
/* Are we in an interrupt handler? */
if (current_regs)
{
/* Yes, then we have to do things differently.
* Just copy the current_regs into the OLD rtcb.
*/
up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
*/
rtcb = (_TCB*)g_readytorun.head;
slldbg("New Active Task TCB=%p\n", rtcb);
/* Then switch contexts */
up_restorestate(rtcb->xcp.regs);
}
/* No, then we will need to perform the user context switch */
else
{
/* Switch context to the context of the task at the head of the
* ready to run list.
*/
_TCB *nexttcb = (_TCB*)g_readytorun.head;
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
/* up_switchcontext forces a context switch to the task at the
* head of the ready-to-run list. It does not 'return' in the
* normal sense. When it does return, it is because the blocked
* task is again ready to run and has execution priority.
*/
}
}
}
}

View File

@ -1,132 +1,102 @@
/************************************************************************************
* arch/arm/src/cortexm3/up_context.S
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include <arch/irq.h>
#include "nvic.h"
/************************************************************************************
* Preprocessor Definitions
************************************************************************************/
/************************************************************************************
* Global Symbols
************************************************************************************/
.syntax unified
.thumb
.file "up_context.S"
/************************************************************************************
* Macros
************************************************************************************/
/************************************************************************************
* Public Functions
************************************************************************************/
/**************************************************************************
* Name: up_saveusercontext
*
* Description:
* Save the current thread context. Full prototype is:
*
* int up_saveusercontext(uint32 *regs);
*
* Return:
* 0: Normal return
* 1: Context switch return
*
**************************************************************************/
.text
.thumb_func
.globl up_saveusercontext
.type up_saveusercontext, function
up_saveusercontext:
/* Perform the System call with R0=0 and R1=regs */
mov r1, r0 /* R1: regs */
mov r0, #0 /* R0: 0 means save context (also return value) */
svc 0 /* Force synchronous SVCall (or Hard Fault) */
/* There are two return conditions. On the first return, R0 (the
* return value will be zero. On the second return we need to
* force R0 to be 1.
*/
add r2, r1, #(4*REG_R0)
mov r3, #1
str r3, [r2, #0]
bx lr /* "normal" return with r0=0 or
* context switch with r0=1 */
.size up_saveusercontext, .-up_saveusercontext
/**************************************************************************
* Name: up_fullcontextrestore
*
* Description:
* Restore the current thread context. Full prototype is:
*
* void up_fullcontextrestore(uint32 *regs) __attribute__ ((noreturn));
*
* Return:
* None
*
**************************************************************************/
.thumb_func
.globl up_fullcontextrestore
.type up_fullcontextrestore, function
up_fullcontextrestore:
/* Perform the System call with R0=1 and R1=regs */
mov r1, r0 /* R1: regs */
mov r0, #1 /* R0: 1 means restore context */
svc 0 /* Force synchronous SVCall (or Hard Fault) */
/* This call should not return */
bx lr /* Unnecessary ... will not return */
.size up_fullcontextrestore, .-up_fullcontextrestore
.end
/************************************************************************************
* arch/arm/src/cortexm3/up_saveusercontext.S
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include <arch/irq.h>
#include "nvic.h"
/************************************************************************************
* Preprocessor Definitions
************************************************************************************/
/************************************************************************************
* Global Symbols
************************************************************************************/
.syntax unified
.thumb
.file "up_saveusercontext.S"
/************************************************************************************
* Macros
************************************************************************************/
/************************************************************************************
* Public Functions
************************************************************************************/
/**************************************************************************
* Name: up_saveusercontext
*
* Description:
* Save the current thread context. Full prototype is:
*
* int up_saveusercontext(uint32 *saveregs);
*
* Return:
* 0: Normal return
* 1: Context switch return
*
**************************************************************************/
.text
.thumb_func
.globl up_saveusercontext
.type up_saveusercontext, function
up_saveusercontext:
/* Perform the System call with R0=0 and R1=regs */
mov r1, r0 /* R1: regs */
mov r0, #0 /* R0: 0 means save context (also return value) */
svc 0 /* Force synchronous SVCall (or Hard Fault) */
/* There are two return conditions. On the first return, R0 (the
* return value will be zero. On the second return we need to
* force R0 to be 1.
*/
add r2, r1, #(4*REG_R0)
mov r3, #1
str r3, [r2, #0]
bx lr /* "normal" return with r0=0 or
* context switch with r0=1 */
.size up_saveusercontext, .-up_saveusercontext
.end

View File

@ -115,7 +115,7 @@ void up_sigdeliver(void)
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
/* Then restore the task interrupt statat. */
/* Then restore the task interrupt state */
irqrestore((uint16)regs[REG_PRIMASK]);

View File

@ -81,50 +81,98 @@
int up_svcall(int irq, FAR void *context)
{
uint32 *svregs = (uint32*)context;
uint32 *tcbregs = (uint32*)svregs[REG_R1];
uint32 *regs = (uint32*)context;
DEBUGASSERT(svregs && svregs == current_regs && tcbregs);
DEBUGASSERT(regs && regs == current_regs);
DEBUGASSERT(regs[REG_R1] != 0);
/* The SVCall software interrupt is called with R0 = SVC command and R1 =
* the TCB register save area.
*/
sllvdbg("Command: %d svregs: %p tcbregs: %08x\n", svregs[REG_R0], svregs, tcbregs);
sllvdbg("Command: %d regs: %p R1: %08x R2: %08x\n",
regs[REG_R0], regs, regs[REG_R1], regs[REG_R2]);
#ifdef DEBUG_SVCALL
lldbg("SVCall Entry:\n");
lldbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
svregs[REG_R0], svregs[REG_R1], svregs[REG_R2], svregs[REG_R3],
svregs[REG_R4], svregs[REG_R5], svregs[REG_R6], svregs[REG_R7]);
regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
lldbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
svregs[REG_R8], svregs[REG_R9], svregs[REG_R10], svregs[REG_R11],
svregs[REG_R12], svregs[REG_R13], svregs[REG_R14], svregs[REG_R15]);
lldbg(" PSR=%08x\n", svregs[REG_XPSR]);
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
lldbg(" PSR=%08x\n", regs[REG_XPSR]);
#endif
/* Handle the SVCall according to the command in R0 */
switch (svregs[REG_R0])
switch (regs[REG_R0])
{
/* R0=0: This is a save context command. In this case, we simply need
* to copy the svregs to the tdbregs and return.
/* R0=0: This is a save context command:
*
* int up_saveusercontext(uint32 *saveregs);
*
* At this point, the following values are saved in context:
*
* R0 = 0
* R1 = saveregs
*
* In this case, we simply need to copy the current regsters to the
* save regiser space references in the saved R1 and return.
*/
case 0:
memcpy(tcbregs, svregs, XCPTCONTEXT_SIZE);
{
memcpy((uint32*)regs[REG_R1], regs, XCPTCONTEXT_SIZE);
}
break;
/* R1=1: This a restore context command. In this case, we simply need to
* set current_regs to tcbrgs. svregs == current_regs is the normal exception
* turn. By setting current_regs = tcbregs, we force the return through
* the saved context.
/* R0=1: This a restore context command:
*
* void up_fullcontextrestore(uint32 *restoreregs) __attribute__ ((noreturn));
*
* At this point, the following values are saved in context:
*
* R0 = 1
* R1 = restoreregs
*
* In this case, we simply need to set current_regs to restore register
* area referenced in the saved R1. context == current_regs is the normal
* exception return. By setting current_regs = context[R1], we force
* the return to the saved context referenced in R1.
*/
case 1:
current_regs = tcbregs;
{
current_regs = (uint32*)regs[REG_R1];
}
break;
/* R0=2: This a switch context command:
*
* void up_switchcontext(uint32 *saveregs, uint32 *restoreregs);
*
* At this point, the following values are saved in context:
*
* R0 = 1
* R1 = saveregs
* R2 = restoreregs
*
* In this case, we do both: We save the context registers to the save
* register area reference by the saved contents of R1 nad then set
* current_regs to to the save register area referenced by the saved
* contents of R2.
*/
case 2:
{
DEBUGASSERT(regs[REG_R2] != 0);
memcpy((uint32*)regs[REG_R1], regs, XCPTCONTEXT_SIZE);
current_regs = (uint32*)regs[REG_R2];
}
break;
default:
PANIC(OSERR_INTERNAL);
break;

View File

@ -0,0 +1,95 @@
/************************************************************************************
* arch/arm/src/cortexm3/up_switchcontext.S
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include <arch/irq.h>
#include "nvic.h"
/************************************************************************************
* Preprocessor Definitions
************************************************************************************/
/************************************************************************************
* Global Symbols
************************************************************************************/
.syntax unified
.thumb
.file "up_context.S"
/************************************************************************************
* Macros
************************************************************************************/
/************************************************************************************
* Public Functions
************************************************************************************/
/**************************************************************************
* Name: up_switchcontext
*
* Description:
* Save the current thread context and restore the specified context.
* Full prototype is:
*
* void up_switchcontext(uint32 *saveregs, uint32 *restoreregs);
*
* Return:
* None
*
**************************************************************************/
.thumb_func
.globl up_switchcontext
.type up_switchcontext, function
up_switchcontext:
/* Perform the System call with R0=1, R1=saveregs, R2=restoreregs */
mov r2, r1 /* R2: restoreregs */
mov r1, r0 /* R1: saveregs */
mov r0, #2 /* R0: 2 means context switch */
svc 0 /* Force synchronous SVCall (or Hard Fault) */
/* This call should not return */
bx lr /* Unnecessary ... will not return */
.size up_switchcontext, .-up_switchcontext
.end

View File

@ -0,0 +1,156 @@
/****************************************************************************
* arch/arm/src/cortexm3/up_unblocktask.c
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include "os_internal.h"
#include "clock_internal.h"
#include "up_internal.h"
/****************************************************************************
* Private Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_unblock_task
*
* Description:
* A task is currently in an inactive task list
* but has been prepped to execute. Move the TCB to the
* ready-to-run list, restore its context, and start execution.
*
* Inputs:
* tcb: Refers to the tcb to be unblocked. This tcb is
* in one of the waiting tasks lists. It must be moved to
* the ready-to-run list and, if it is the highest priority
* ready to run taks, executed.
*
****************************************************************************/
void up_unblock_task(_TCB *tcb)
{
/* Verify that the context switch can be performed */
if ((tcb->task_state < FIRST_BLOCKED_STATE) ||
(tcb->task_state > LAST_BLOCKED_STATE))
{
PANIC(OSERR_BADUNBLOCKSTATE);
}
else
{
_TCB *rtcb = (_TCB*)g_readytorun.head;
/* Remove the task from the blocked task list */
sched_removeblocked(tcb);
/* Reset its timeslice. This is only meaningful for round
* robin tasks but it doesn't here to do it for everything
*/
#if CONFIG_RR_INTERVAL > 0
tcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK;
#endif
/* Add the task in the correct location in the prioritized
* g_readytorun task list
*/
if (sched_addreadytorun(tcb))
{
/* The currently active task has changed! We need to do
* a context switch to the new task.
*
* Are we in an interrupt handler?
*/
if (current_regs)
{
/* Yes, then we have to do things differently.
* Just copy the current_regs into the OLD rtcb.
*/
up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
*/
rtcb = (_TCB*)g_readytorun.head;
/* Then switch contexts */
up_restorestate(rtcb->xcp.regs);
}
/* No, then we will need to perform the user context switch */
else
{
/* Switch context to the context of the task at the head of the
* ready to run list.
*/
_TCB *nexttcb = (_TCB*)g_readytorun.head;
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
/* up_switchcontext forces a context switch to the task at the
* head of the ready-to-run list. It does not 'return' in the
* normal sense. When it does return, it is because the blocked
* task is again ready to run and has execution priority.
*/
}
}
}
}

View File

@ -35,7 +35,7 @@
HEAD_ASRC = lm3s_vectors.S
CMN_ASRCS = up_context.S
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
up_createstack.c up_mdelay.c up_udelay.c up_exit.c \
up_idle.c up_initialize.c up_initialstate.c up_interruptcontext.c \

View File

@ -35,7 +35,7 @@
HEAD_ASRC = stm32_vectors.S
CMN_ASRCS = up_context.S
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
up_createstack.c up_mdelay.c up_udelay.c up_exit.c \
up_idle.c up_initialize.c up_initialstate.c up_interruptcontext.c \