⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 up_savecontext.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
字号:
/************************************************************************** * up_savecontext.c * *   Copyright (C) 2007 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 Gregory Nutt 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 <nuttx/irq.h>#include "up_internal.h"/************************************************************************** * Private Definitions **************************************************************************//************************************************************************** * Private Types **************************************************************************//************************************************************************** * Private Function Prototypes **************************************************************************//************************************************************************** * Global Variables **************************************************************************//************************************************************************** * Private Variables **************************************************************************//************************************************************************** * Private Functions **************************************************************************//************************************************************************** * Name: up_savestack * * Description: *   Save the entire interrupt stack contents in the provided context *   structure. * * Inputs: *   context - the context structure in which to save the stack info * * Return: *   None * * Assumptions: *   - Interrupts are disabled * **************************************************************************/static void up_savestack(FAR struct xcptcontext *context, ubyte tos){  /* Copy the current stack frame from internal RAM to XRAM. */  ubyte nbytes     = tos - (STACK_BASE-1);  NEAR ubyte *src  = (NEAR ubyte*)STACK_BASE;  FAR  ubyte *dest = context->stack;  context->nbytes = nbytes;  while (nbytes--)    {      *dest++ = *src++;    }}/************************************************************************** * Name: up_saveregs * * Description: *   Save the interrupt registers into the TCB. * * Inputs: *   context - the context structure in which to save the register info * * Return: *   None * * Assumptions: *   - Interrupts are disabled * **************************************************************************/static void up_saveregs(FAR struct xcptcontext *context, ubyte tos){  /* Copy the irq register save area into the TCB */  FAR ubyte *src  = g_irqregs;  FAR ubyte *dest = context->regs;  ubyte nbytes    = REGS_SIZE;  while (nbytes--)    {      *dest++ = *src++;    }}/************************************************************************** * Public Functions **************************************************************************//************************************************************************** * Name: up_saveregisters * * Description: *   Save the current registers in the context save area.  This function *   is called from up_savecontext (below) and also from interrupt *   handling logic. * *   Note that this function does not save: *   a, dptr, ie - these are saved in the stack area *   sp - this can be inferred from g_irqtos or struct xcptontext.nbytes. * * Inputs: *   regs - the context register array in which to save the register info * * Return: *   None * **************************************************************************/void up_saveregisters(FAR ubyte *regs) _naked{ _asm	mov	a, b	movx	@dptr, a	inc	dptr	mov	a, r2	movx	@dptr, a	inc	dptr	mov	a, r3	movx	@dptr, a	inc	dptr	mov	a, r4	movx	@dptr, a	inc	dptr	mov	a, r5	movx	@dptr, a	inc	dptr	mov	a, r6	movx	@dptr, a	inc	dptr	mov	a, r7	movx	@dptr, a	inc	dptr	mov	a, r0	movx	@dptr, a	inc	dptr	mov	a, r1	movx	@dptr, a	inc	dptr	mov	a, psw	movx	@dptr, a	clr	psw	inc	dptr	mov	a, _bp	movx	@dptr, a	ret  _endasm;}/************************************************************************** * Name: up_savecontext * * Description: *   Push the current execution context onto the stack, then save the *   entire stack contents in the provided context structure. * * Inputs: *   context - the context structure in which to save the stack info * * Return: *   0 = Normal state save return *   1 = This is the matching return from up_restorecontext() * **************************************************************************/ubyte up_savecontext(FAR struct xcptcontext *context) _naked{ _asm	/* Create the stack frame that we want when it is time to restore	 * this context.  The return address will be the return address	 * of this function, the return value will be zero.         *         * ...         * return address (2 bytes, already on the stack)         * register a=0   (1 byte)         * register ie    (1 byte)         * register dptr  (2 bytes)	 */	clr	a	push	acc	/* ACC = 0 */	push	ie	mov	a, #1	push	acc	/* DPL = 1 */	clr	a	push	acc	/* DPH = 0 */	/* Dump the stack contents before they are occupied into XRAM */#ifdef CONFIG_SWITCH_FRAME_DUMP	push	dpl	push	dph	lcall	_up_dumpstack	pop	dph	pop	dpl#endif	/* Disable interrupts while we create a snapshot of the stack         * and registers.  At this point, we have 5 bytes on the stack	 * to account for.         */	push	ie	mov	ea, 0	/* Save the registers in the context save area */	push	dpl	push	dph	mov	a, #XCPT_REGS	add	a, dpl	mov	dpl, a	clr	a	addc	a, dph	mov	dph, a	lcall	_up_saveregisters	pop	dph	pop	dpl#ifdef CONFIG_SWITCH_FRAME_DUMP	/* Save the address of the context structure.  We will	 * need this later to dump the saved frame.  Now we have	 * 7 bytes on the stack to account for.	 */	push	dpl	push	dph	/* Push the top of frame stack pointer.  We need to	 * decrement the current SP value by three to account	 * for dptr+IE on the stack above the end of the frame.	 */	mov	a, sp	subb	a, #3#else	/* Push the top of frame stack pointer.  We need to	 * decrement the current stack pointer by one to account	 * for IE that we saved on the stack.	 */	mov	a, sp	dec	a#endif	push	acc	/* Copy the current stack frame from internal RAM to XRAM. */	lcall	_up_savestack	pop	acc	/* Dump the contents of the saved frame after it has been	 * copied from  memory/registers.	 */#ifdef CONFIG_SWITCH_FRAME_DUMP	pop	dph	pop	dpl	push	dpl	push	dph	lcall	_up_dumpframe	pop	dph	pop	dpl	lcall	_up_dumpstack#endif	/* Restore the interrupt state */	pop	ie	/* Now that we have a snapshot of the desired stack frame saved,	 * we can release the stack frame (all but the return address)	 */	mov	a, sp	subb	a, #4	mov	sp, a	mov	dpl,#0	ret  _endasm;}/************************************************************************** * Name: up_saveirqcontext * * Description: *   The interrupt context was saved in g_irqtos and g_irqregs when the *   interrupt was taken.  If a context switch from the interrupted task *   will be made at the interrupt level, then these saved values must be *   copied into the TCB. * * Inputs: *   context - the structure in which to save the context info * * Return: *   None * * Assumptions: *   - Interrupts are disabled * **************************************************************************/void up_saveirqcontext(FAR struct xcptcontext *context){  /* Save the number of bytes in the stack */   context->nbytes = g_irqtos - (STACK_BASE-1);  /* Copy the current stack frame from internal RAM to XRAM. */  up_savestack(context, g_irqtos);  /* Copy the saved registers into the TCB */  up_saveregisters(context->regs);}

⌨️ 快捷键说明

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