z8_saveirqcontext.c

来自「這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU」· C语言 代码 · 共 135 行

C
135
字号
/**************************************************************************** * arch/z80/src/z8/z8_saveirqcontext.c * *   Copyright (C) 2008 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 <arch/irq.h>#include "chip/switch.h"#include "os_internal.h"#include "up_internal.h"/**************************************************************************** * Definitions ****************************************************************************//**************************************************************************** * Private Data ****************************************************************************//**************************************************************************** * Private Functions ****************************************************************************//**************************************************************************** * Public Functions ****************************************************************************//**************************************************************************** * Name: z8_saveirqcontext * * Description: *   In order to provide faster interrupt handling, the interrupt logic does *   "lazy" context saving as described below: * *   (1) At the time of the interrupt, minimum information is saved and the *       register pointer is changed so that the interrupt logic does not *       alter the state of the interrupted task's registers. *   (2) If no context switch occurs during the interrupt processing, then *       the return from interrupt is also simple. *   (3) If a context switch occurs during interrupt processing, then *       (a) The full context of the interrupt task is saved, and *       (b) A full context switch is performed when the interrupt exits *           (see z8_vector.S). * * This function implements the full-context switch of bullet 3a. * ****************************************************************************/void z8_saveirqcontext(FAR chipreg_t *regs){  /* If we have already saved the interrupted task's registers in the TCB,   * then we do not need to do anything.   */  if (g_z8irqstate.state == Z8_IRQSTATE_ENTRY)    {      /* Calculate the source address based on the saved RP value */      uint16         rp  = g_z8irqstate.regs[Z8_IRQSAVE_RPFLAGS] >> 8;      FAR chipreg_t *src = (FAR uint16*)(rp & 0xf0);      FAR chipreg_t *dest = &regs[XCPT_RR0];      /* Copy the interrupted tasks register into the TCB register save area. */      int i;      for (i = 0; i < XCPTCONTEXT_REGS; i++)        {          *dest++ = *src++;        }      /* Since the task was interrupted, we know that interrupts were enabled */      regs[XCPT_IRQCTL] = 0x0080; /* IRQE bit will enable interrupts */      /* The g_z8irqstate.regs pointer is the value of the stack pointer at       * the time that up_doirq() was called.  Therefore, we can calculate       * the correct value for the stack pointer on return from interrupt:       */      regs[XCPT_SP] = ((chipreg_t)g_z8irqstate.regs) + Z8_IRQSAVE_SIZE;      /* Copy the PC, RP, and FLAGS information from the lazy save to the TCB       * register save area.       */      regs[XCPT_RPFLAGS] = g_z8irqstate.regs[Z8_IRQSAVE_RPFLAGS];      regs[XCPT_PC]      = g_z8irqstate.regs[Z8_IRQSAVE_PC];      /* Now update the IRQ save area so that we will know that we have already       * done this.       */      g_z8irqstate.state = Z8_IRQSTATE_SAVED;      g_z8irqstate.regs  = regs;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?