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

📄 up_head.s

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 S
字号:
/************************************************************ * up_head.S * *   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 <nuttx/irq.h>#include "up_internal.h"	.module	up_head	.optsdcc -mmcs51 --model-large/************************************************************ * Private Data ************************************************************/	.area REG_BANK_0	(REL,OVR,DATA)	.ds 8#ifndef CONFIG_8052_TIMER2	.area	XSEG_g_timer0tick:	.ds 1#endif/************************************************************ * Public Data ************************************************************/	.globl	_g_irqtos	.globl	_g_irqcontext	.globl	_g_irqregs/************************************************************ * Public Functions ************************************************************/	.globl	_irq_dispatch	.globl	_up_restoreregisters/************************************************************ * Program entry points ************************************************************//* Program entry is through PROGRAM_BASE.  This is just a * branch to our start up logic. */	.area	CODE1 (ABS)	.org	PROGRAM_BASE	ljmp	start/* These are indirect interrupt vectors.  Logic in PAULMON2, * captures the interrupt vectors (near address 0x0000) and * re-routes them through the following entry points. * * Each of these saves acc and ie then passes the IRQ number * to higher level logic in a */	.org	PM2_VECTOR_EXTINT0	push	acc	mov	a, #EXT_INT0_IRQ	ljmp	_up_interrupt	.org	PM2_VECTOR_TIMER0	push	acc#ifdef CONFIG_8052_TIMER2	mov	a, #TIMER0_IRQ	ljmp	_up_interrupt#else	ljmp	_up_timer0#endif	.org	PM2_VECTOR_EXTINT1	push	acc	mov	a, #EXT_INT1_IRQ	ljmp	_up_interrupt	.org	PM2_VECTOR_TIMER1	push	acc	mov	a, #TIMER1_IRQ	ljmp	_up_interrupt	.org	PM2_VECTOR_UART	push	acc	mov	a, #UART_IRQ	ljmp	_up_interrupt	.org	PM2_VECTOR_TIMER2	push	acc	mov	a, #TIMER2_IRQ	ljmp	_up_interrupt/************************************************************ * Name: start * * Description: *   This is the initial entry point into NuttX * ************************************************************/start:	mov	sp, #(STACK_BASE-1)#ifdef CONFIG_ARCH_LEDS	lcall	_up_ledinit#endif	ljmp	_os_start/************************************************************ * Name: up_timer0 * * Description: *   Timer 0, mode 0 can be used as a system timer.  In that *   mode, the 1.8432 MHz clock is divided by 32.  A single *   8-bit value is incremented at 57600 Hz, which results *   in 225 Timer 0 overflow interrupts per second. * *   The Timer0 interrupt vectors to this point which then *   does a software divide by 2 to get a system timer of *   112.5Hz. * *   On Entry: * *   (1) acc on the stack and *   (2) the IRQ number(TIMER0_IRQ) in the accumulator * ************************************************************/#ifndef CONFIG_8052_TIMER2_up_timer0:	ar2 = 0x02	ar3 = 0x03	ar4 = 0x04	ar5 = 0x05	ar6 = 0x06	ar7 = 0x07	ar0 = 0x00	ar1 = 0x01	/* ACC already on the stack; push IE.  Then disable interrupts */	push	ie	clr	ea	/* Save the remaining registers with interrupts disabled 	 *	 * a, ie, and dptr go on the stack.	 */	push	dpl	push	dph	/* Increment the tick counter */	mov	dptr, #_g_timer0tick        movx    a, @dptr	inc	a	movx	@dptr, a	/* If bit 0 is '0', then just return from the interrupt */	anl	a, #0x01	jnz	00101$	ljmp	_up_timer0exit	/* If bit 0 is '1', then process the interrupt */00101$:	mov	a, #TIMER0_IRQ	sjmp	_up_timer0join#endif/************************************************************ * Name: up_interrupt * * Description: *   All interrupts vector to this point with: * *   (1) acc on the stack and *   (2) the IRQ number in the accumulator * ************************************************************/_up_interrupt:	ar2 = 0x02	ar3 = 0x03	ar4 = 0x04	ar5 = 0x05	ar6 = 0x06	ar7 = 0x07	ar0 = 0x00	ar1 = 0x01	/* ACC already on the stack; push IE.  Then disable interrupts */	push	ie	clr	ea	/* Save the remaining registers with interrupts disabled 	 *	 * a, ie, and dptr go on the stack.	 */	push	dpl	push	dph_up_timer0join:	/* Other registers go into the IRQ register save area */	push	acc	mov	dptr, #_g_irqregs	lcall	_up_saveregisters	/* Show interrupt status on the LEDs */#ifdef CONFIG_ARCH_LEDS	mov	dpl, #LED_INIRQ	lcall	_up_ledon#endif	/* Save the IRQ number in r2 */	pop	ar2	/* Mark that we are in an interrupt and provide the top	 * of stack pointer to the context switching logic.	 */	mov	dptr, #_g_irqtos	mov	a, sp        movx    @dptr, a	/* Nullify the context pointer.  If a context switch is	 * needed, this will be set to the address of the context	 * structure.	 */	mov	dptr, #_g_irqcontext	clr	a	movx	@dptr,a	inc	dptr	movx	@dptr,a	/* Now call void irq_dispatch(int irq, FAR void *context)         *	 * First, create the first argument as (int)irqno	 */        mov     dpl, r2	mov	dph, #0        /* Create the second argument (void *context) on the stack */	push	sp	clr	a	push	acc	/* Then dispatch the IRQ. */	lcall	_irq_dispatch	pop	acc	pop	acc	/* Indicate that we are no longer in an interrupt */	mov	dptr, #_g_irqtos	clr	a        movx    @dptr, a	/* Check if a context switch is pending */	mov	dptr,#_g_irqcontext	movx	a, @dptr	mov     r2, a	inc	dptr	movx	a, @dptr	mov	r3, a	orl	a, r2	jnz	00001$	/* No context switch is pending.  Restore registers	 * from the interrupt register save area.	 */	mov	dptr, #_g_irqregs	sjmp	00004$00001$: /****************************************************/	/* A context switch is pending, clear g_irqcontext */	mov	dpl, r2	mov	dph, r3	clr	a	movx	@dptr, a	inc	dptr	movx	@dptr, a#ifdef CONFIG_INTERRUPT_FRAME_DUMP	mov	dpl, r2	mov	dph, r3	push	ar2	push	ar3	lcall	_up_dumpframe	pop	ar3	pop	ar2#endif	/* Register usage in the following:	 *	 * R0   - Holds working the 8-bit IRAM pointer	 * R1   - Not used	 * R2-3 - Holds the working 16-bit XRAM pointer	 * R4   - Holds the working byte count	 * R5   - Holds the new stack pointer	 * R6-7 - Not used	 */	/* Fetch r4 = context->nbytes */	mov	dpl, r2	mov	dph, r3	movx	a, @dptr	mov	r4, a	/* Save the new stack pointer in r5 */	add	a, #(STACK_BASE-1)	mov	r5, a	/* Save r2-3 = &context->stack */	inc	dptr	push	dpl	push	dph	mov	r2, dpl	mov	r3, dph	/* Set r0 = stack base address */	mov	r0, #STACK_BASE	/* Top of the copy loop */00002$:	mov	a, r4	/* a = bytes left to transfer */	dec	r4	/* (for next time through the loop) */	jz	00003$	/* Jump if a = 0 (done) */	/* Fetch the next byte from context->stack */	mov	dpl, r2	mov	dph, r3	movx	a,@dptr	/* Increment the XRAM pointer */	inc	dptr	mov	r2, dpl	mov	r3, dph	/* Save the next byte into IRAM */	mov	@r0, a	/* Increment the IRAM pointer */	inc	r0	sjmp	00002$	/* The entire stack has been copied from XRAM into	 * IRAM.  Set the new stack pointer	 */00003$:	pop	dph	pop	dpl	mov	sp, r5#ifdef CONFIG_INTERRUPT_FRAME_DUMP	push	dpl	push	dph	lcall	_up_dumpstack	pop	dph	pop	dpl#endif	/* Get the pointer to the register save area */	mov	a, #STACK_SIZE	add	a, dpl	mov	dpl, a	clr	a	addc	a, dph	mov	dph, a	00004$: /****************************************************/	/* Restore the context from the register save area	 * and return from the interrupt.  At this point, dptr	 * holds the pointer to the memory region that holds	 * the register save area. This could be either	 * g_irqregs (no context switch) or &g_irqcontext->regs	 * (context switch).	 */#ifdef CONFIG_ARCH_LEDS	push	dpl	push	dph	mov	dpl, #LED_INIRQ	lcall	_up_ledoff	pop	dph	pop	dpl#endif	/* Restore registers from the register save area */	lcall	_up_restoreregisters_up_timer0exit:	/* Restore registers from the stack and return */	pop	dph	pop	dpl	/* Restore the interrupt state per the stored IE value */	pop	acc	jb	acc.7,00005$	clr	ie.7	sjmp	00006$00005$:	setb	ie.700006$:	pop	acc	reti

⌨️ 快捷键说明

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