mirror of
https://github.com/apache/nuttx.git
synced 2026-08-27 12:20:46 +00:00
reason:
1 On different architectures, we can utilize more optimized strategies
to implement up_current_regs/up_set_current_regs.
eg. use interrupt registersor percpu registers.
code size
before
text data bss dec hex filename
262848 49985 63893 376726 5bf96 nuttx
after
text data bss dec hex filename
262844 49985 63893 376722 5bf92 nuttx
size change -4
Configuring NuttX and compile:
$ ./tools/configure.sh -l qemu-armv8a:nsh_smp
$ make
Running with qemu
$ qemu-system-aarch64 -cpu cortex-a53 -smp 4 -nographic \
-machine virt,virtualization=on,gic-version=3 \
-net none -chardev stdio,id=con,mux=on -serial chardev:con \
-mon chardev=con,mode=readline -kernel ./nuttx
Signed-off-by: hujun5 <hujun5@xiaomi.com>
103 lines
3.3 KiB
C
103 lines
3.3 KiB
C
/****************************************************************************
|
|
* arch/arm/src/common/arm_switchcontext.c
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
#include <sched.h>
|
|
#include <assert.h>
|
|
#include <debug.h>
|
|
#include <nuttx/arch.h>
|
|
#include <nuttx/sched.h>
|
|
|
|
#include "sched/sched.h"
|
|
#include "group/group.h"
|
|
#include "clock/clock.h"
|
|
#include "arm_internal.h"
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: up_switch_context
|
|
*
|
|
* Description:
|
|
* A task is currently in the ready-to-run list but has been prepped
|
|
* to execute. Restore its context, and start execution.
|
|
*
|
|
* Input Parameters:
|
|
* tcb: Refers to the head task of the ready-to-run list
|
|
* which will be executed.
|
|
* rtcb: Refers to the running task which will be blocked.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
|
{
|
|
/* Update scheduler parameters */
|
|
|
|
nxsched_suspend_scheduler(rtcb);
|
|
|
|
/* Are we in an interrupt handler? */
|
|
|
|
if (up_current_regs())
|
|
{
|
|
/* Yes, then we have to do things differently.
|
|
* Just copy the current_regs into the OLD rtcb.
|
|
*/
|
|
|
|
arm_savestate(rtcb->xcp.regs);
|
|
|
|
/* Update scheduler parameters */
|
|
|
|
nxsched_resume_scheduler(tcb);
|
|
|
|
/* Then switch contexts. Any necessary address environment
|
|
* changes will be made when the interrupt returns.
|
|
*/
|
|
|
|
arm_restorestate(tcb->xcp.regs);
|
|
}
|
|
|
|
/* No, then we will need to perform the user context switch */
|
|
|
|
else
|
|
{
|
|
/* Update scheduler parameters */
|
|
|
|
nxsched_resume_scheduler(tcb);
|
|
|
|
/* Switch context to the context of the task at the head of the
|
|
* ready to run list.
|
|
*/
|
|
|
|
arm_switchcontext(&rtcb->xcp.regs, tcb->xcp.regs);
|
|
|
|
/* arm_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.
|
|
*/
|
|
}
|
|
}
|