8051 is getting closer. Still have to setup timer and uart.

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@32 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2007-03-02 22:44:29 +00:00
parent fcef572648
commit 273e5d0d0e
17 changed files with 282 additions and 53 deletions

View File

@ -33,10 +33,10 @@
<li><b>8051 Microcontroller</b>. <li><b>8051 Microcontroller</b>.
This port uses the <a href="http://www.pjrc.com/">PJRC</a> 87C52 development system This port uses the <a href="http://www.pjrc.com/">PJRC</a> 87C52 development system
and the <a href="http://sdcc.sourceforge.net/">SDCC</a> toolchain. and the <a href="http://sdcc.sourceforge.net/">SDCC</a> toolchain.
This port will require a few more weeks before it is ready for time prime.</li> This port will require a few more weeks before it is ready for prime time.</li>
<li><b>Motorola (Freescale) MC68HC908GP32 Microcontroller</b>. <li><b>Motorola (Freescale) MC68HC908GP32 Microcontroller</b>.
Using the Axiom CMS8GP32 development board. Using the Axiom CMS8GP32 development board.
This is next in the queue.</li? This is next in the queue.</li>
<li><b>Other ports</b>. <li><b>Other ports</b>.
I also have partial ports for the TI TMS320DM270 and for MIPS. I also have partial ports for the TI TMS320DM270 and for MIPS.
</ul> </ul>

View File

@ -1,5 +1,15 @@
Architecture-Specific Code Architecture-Specific Code
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
Table of Contents
^^^^^^^^^^^^^^^^^
o Architecture-Specific Code
o Summary of Files
o Supported Architectures
o Configuring NuttX
Architecture-Specific Code
^^^^^^^^^^^^^^^^^^^^^^^^^^
The file include/nuttx/arch.h identifies all of the APIs that must The file include/nuttx/arch.h identifies all of the APIs that must
be provided by the architecture specific logic. (It also includes be provided by the architecture specific logic. (It also includes
@ -192,6 +202,30 @@ src/Makefile
the final link with libup.a and other system archives to generate the the final link with libup.a and other system archives to generate the
final executable. final executable.
Supported Architectures
^^^^^^^^^^^^^^^^^^^^^^^
arch/c5471
TI TMS320C5471 (also called TMS320DM180).
NuttX operates on the ARM7 of this dual core processor. This port
uses the Spectrum Digital evaluation board with a GNU arm-elf toolchain*.
This port is in progress and partially functional (However, my board
is dead at the moment so it will be awhile before I fix it).
arch/pjrc-8051
8051 Microcontroller. This port uses the PJRC 87C52 development system
and the SDCC toolchain. This port is not quite ready for prime time.
arch/axiom-mc68
For the Motorola (Freescale) MC68HC908GP32 Microcontroller using the
Axiom CMS8GP32 development board. This has not yet been checked-in.
arch/sim
x86 Linux Simulation</b>. Fully functional.
Other ports for the for the TI TMS320DM270 and for MIPS are in various states
of progress
Configuring NuttX Configuring NuttX
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^

View File

@ -147,7 +147,7 @@ static inline void up_vectorinitialize(void)
************************************************************/ ************************************************************/
/************************************************************ /************************************************************
* Name: irq_initialize * Name: up_irqinitialize
************************************************************/ ************************************************************/
void up_irqinitialize(void) void up_irqinitialize(void)

View File

@ -47,7 +47,8 @@ CSRCS = up_initialize.c up_idle.c up_interruptcontext.c \
up_initialstate.c up_unblocktask.c up_blocktask.c \ up_initialstate.c up_unblocktask.c up_blocktask.c \
up_releasepending.c up_reprioritizertr.c \ up_releasepending.c up_reprioritizertr.c \
up_exit.c up_assert.c up_allocateheap.c \ up_exit.c up_assert.c up_allocateheap.c \
up_irq.c up_savecontext.c up_restorecontext.c up_putc.c up_irq.c up_savecontext.c up_restorecontext.c \
up_timerisr.c up_putc.c
COBJS = $(CSRCS:.c=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(SSRCS) $(CSRCS) SRCS = $(SSRCS) $(CSRCS)
OBJS = $(AOBJS) $(COBJS) OBJS = $(AOBJS) $(COBJS)

View File

@ -125,27 +125,24 @@ void up_block_task(FAR _TCB *tcb, tstate_t task_state)
{ {
/* Are we in an interrupt handler? */ /* Are we in an interrupt handler? */
if (g_ininterrupt) if (g_irqtos)
{ {
#if 0
# warning REVISIT
/* Yes, then we have to do things differently. /* Yes, then we have to do things differently.
* Just copy the current registers into the OLD rtcb. * Just copy the current registers into the OLD rtcb.
*/ */
up_copystate(&tcb->xcp, current_regs); up_savestack(&tcb->xcp);
/* Restore the exception context of the rtcb at the (new) head /* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list. * of the g_readytorun task list.
*/ */
rtcb = (_TCB*)g_readytorun.head; rtcb = (FAR _TCB*)g_readytorun.head;
dbg("New Active Task TCB=%p\n", rtcb); dbg("New Active Task TCB=%p\n", rtcb);
/* Then switch contexts */ /* Then switch contexts */
up_copystate(current_regs, &tcb->xcp); up_restorestack(&tcb->xcp);
#endif
} }
/* Copy the user C context into the TCB at the (old) head of the /* Copy the user C context into the TCB at the (old) head of the

View File

@ -54,7 +54,7 @@
* Public Data * Public Data
************************************************************/ ************************************************************/
.globl _g_ininterrupt .globl _g_irqtos
/************************************************************ /************************************************************
* Public Functions * Public Functions
@ -174,6 +174,11 @@ _up_interrupt:
clr psw clr psw
push _bp push _bp
/* Mark that we are in an interrupt */
mov dptr, #_g_irqtos
movx @dptr, a
/* Now call void irq_dispatch(int irq, FAR void *context) /* Now call void irq_dispatch(int irq, FAR void *context)
* *
* First, create the first argument as (int)irqno * First, create the first argument as (int)irqno
@ -184,18 +189,31 @@ _up_interrupt:
/* Create the second argument (void *context) on the stack */ /* Create the second argument (void *context) on the stack */
push sp push sp
clr a clr a
push acc push acc
/* Then dispatch the IRQ */ /* Then dispatch the IRQ. On return, the stack is off by
* by two because the above two pushes, but we fix that by
* reloading sp from g_irqtos below.
*/
lcall _irq_dispatch lcall _irq_dispatch
/* Clean up the stack */ /* Get the stackpointer. This might be the stack pointer that
* we increment above or it might be the stack pointer of a
* new task if the a context switch happened during the
* interrupt handling.
*/
dec sp mov dptr, #_g_irqtos
dec sp movx a, @dptr
mov sp, a
/* Indicate that we are no longer in an interrupt */
clr a
movx @dptr, a
/* Then return from the interrupt */ /* Then return from the interrupt */

View File

@ -51,9 +51,13 @@
* Private Data * Private Data
************************************************************/ ************************************************************/
/* TRUE if processing an interrupt */ /* This is the top of the stack containing the interrupt stack frame. It
* is set when processing an interrupt. It is also cleared when the
* interrupt returns so this can also be used like a boolean indication that
* we are in an interrupt.
*/
boolean g_ininterrupt; ubyte g_irqtos;
/************************************************************ /************************************************************
* Private Functions * Private Functions
@ -87,12 +91,16 @@ void up_initialize(void)
{ {
/* Initialize global variables */ /* Initialize global variables */
g_ininterrupt = FALSE; g_irqtos = 0;
/* Initialize the interrupt subsystem */ /* Initialize the interrupt subsystem */
up_irqinitialize();
/* Initialize the system timer interrupt */ /* Initialize the system timer interrupt */
up_timerinit();
/* Initialize the serial console support */ /* Initialize the serial console support */
} }

View File

@ -106,9 +106,13 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
/* TRUE if processing an interrupt */ /* This is the top of the stack containing the interrupt stack frame. It
* is set when processing an interrupt. It is also cleared when the
* interrupt returns so this can also be used like a boolean indication that
* we are in an interrupt.
*/
extern boolean g_ininterrupt; extern ubyte g_irqtos;
#endif /* __ASSEMBLY */ #endif /* __ASSEMBLY */
@ -118,8 +122,12 @@ extern boolean g_ininterrupt;
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern ubyte up_savecontext(FAR struct xcptcontext *context); extern void up_irqinitialize(void);
extern void up_restorecontext(FAR struct xcptcontext *context); extern void up_restorecontext(FAR struct xcptcontext *context);
extern void up_restorestack(FAR struct xcptcontext *context);
extern ubyte up_savecontext(FAR struct xcptcontext *context);
extern void up_savestack(FAR struct xcptcontext *context);
extern void up_timerinit(void);
#endif /* __ASSEMBLY */ #endif /* __ASSEMBLY */
#endif /* __ARCH_UP_INTERNAL_H */ #endif /* __ARCH_UP_INTERNAL_H */

View File

@ -64,5 +64,5 @@
boolean up_interrupt_context(void) boolean up_interrupt_context(void)
{ {
return g_ininterrupt; return g_irqtos != 0;
} }

View File

@ -154,4 +154,4 @@ void up_enable_irq(int irq)
{ {
_up_enable_irq(~(1 << irq)); _up_enable_irq(~(1 << irq));
} }
} }

View File

@ -88,27 +88,24 @@ void up_release_pending(void)
* interrupt context: * interrupt context:
*/ */
if (g_ininterrupt) if (g_irqtos)
{ {
#if 0
# warning REVISIT
/* Yes, then we have to do things differently. /* Yes, then we have to do things differently.
* Just copy the current registers into the OLD rtcb. * Just copy the current registers into the OLD rtcb.
*/ */
up_copystate(&tcb->xcp, current_regs); up_savestack(&rtcb->xcp);
/* Restore the exception context of the rtcb at the (new) head /* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list. * of the g_readytorun task list.
*/ */
rtcb = (_TCB*)g_readytorun.head; rtcb = (FAR _TCB*)g_readytorun.head;
dbg("New Active Task TCB=%p\n", rtcb); dbg("New Active Task TCB=%p\n", rtcb);
/* Then switch contexts */ /* Then switch contexts */
up_copystate(current_regs, &tcb->xcp); up_restorestack(&rtcb->xcp);
#endif
} }
/* Copy the exception context into the TCB of the task that /* Copy the exception context into the TCB of the task that

View File

@ -136,28 +136,26 @@ void up_reprioritize_rtr(FAR _TCB *tcb, ubyte priority)
/* Are we in an interrupt handler? */ /* Are we in an interrupt handler? */
if (g_ininterrupt) if (g_irqtos)
{ {
#if 0
# warning REVISIT
/* Yes, then we have to do things differently. /* Yes, then we have to do things differently.
* Just copy the current registers into the OLD rtcb. * Just copy the current registers into the OLD rtcb.
*/ */
up_copystate(&tcb->xcp, current_regs); up_savestack(&tcb->xcp);
/* Restore the exception context of the rtcb at the (new) head /* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list. * of the g_readytorun task list.
*/ */
rtcb = (_TCB*)g_readytorun.head; rtcb = (FAR _TCB*)g_readytorun.head;
dbg("New Active Task TCB=%p\n", rtcb); dbg("New Active Task TCB=%p\n", rtcb);
/* Then switch contexts */ /* Then switch contexts */
up_copystate(current_regs, &tcb->xcp); up_restorestack(&tcb->xcp);
#endif
} }
/* Copy the exception context into the TCB at the (old) head of the /* Copy the exception context into the TCB at the (old) head of the
* g_readytorun Task list. if up_savecontext returns a non-zero * g_readytorun Task list. if up_savecontext returns a non-zero
* value, then this is really the previously running task restarting! * value, then this is really the previously running task restarting!

View File

@ -134,8 +134,8 @@ static void up_popcontext(ubyte newsp) __naked
void up_restorecontext(FAR struct xcptcontext *context) void up_restorecontext(FAR struct xcptcontext *context)
{ {
int nbytes = context->nbytes; int nbytes = context->nbytes;
FAR ubyte *src = context->stack; FAR ubyte *src = context->stack;
FAR ubyte *dest = (FAR ubyte*)STACK_BASE; FAR ubyte *dest = (FAR ubyte*)STACK_BASE;
/* Interrupts should be disabled for the following. up_popcontext() will /* Interrupts should be disabled for the following. up_popcontext() will
@ -149,8 +149,50 @@ void up_restorecontext(FAR struct xcptcontext *context)
*src++ = *dest++; *src++ = *dest++;
} }
/* Then return to the restored context */ /* Then return to the restored context (probably restoring interrupts) */
up_popcontext(context->nbytes + (STACK_BASE-1)); up_popcontext(context->nbytes + (STACK_BASE-1));
} }
/**************************************************************************
* Name: up_restorestack
*
* Description:
* Restore the entire interrupt stack contents in the provided context
* structure.
*
* Inputs:
* context - the context structure from which to restore the stack info
*
* Return:
* None
*
* Assumptions:
* - We are in an interrupt handler with g_irqtos set
* - Interrupts are disabled
*
**************************************************************************/
void up_restorestack(FAR struct xcptcontext *context)
{
/* Now copy the current stack frame (including the saved execution
* context) from internal RAM to XRAM.
*/
ubyte nbytes = context->nbytes;
FAR ubyte *src = context->stack;
FAR ubyte *dest = (FAR ubyte*)STACK_BASE;
while (nbytes--)
{
*dest++ = *src++;
}
/* We are still in the interrupt context, but the size of the interrupt
* stack has changed.
*/
g_irqtos = context->nbytes + (STACK_BASE-1);
}

View File

@ -126,7 +126,7 @@ static ubyte up_pushcontext(void) __naked
* Inputs: * Inputs:
* context - the context structure in which to save the stack info * context - the context structure in which to save the stack info
* *
* Return * Return:
* 0 = Normal state save return * 0 = Normal state save return
* 1 = This is the matching return from up_restorecontext() * 1 = This is the matching return from up_restorecontext()
* *
@ -165,3 +165,39 @@ ubyte up_savecontext(FAR struct xcptcontext *context)
irqrestore(flags); irqrestore(flags);
return 1; return 1;
} }
/**************************************************************************
* 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:
* - We are in an interrupt handler with g_irqtos set
* - Interrupts are disabled
*
**************************************************************************/
void up_savestack(FAR struct xcptcontext *context)
{
/* Now copy the current stack frame (including the saved execution
* context) from internal RAM to XRAM.
*/
ubyte nbytes = g_irqtos - (STACK_BASE-1);
FAR ubyte *src = (FAR ubyte*)STACK_BASE;
FAR ubyte *dest = context->stack;
context->nbytes = nbytes;
while (nbytes--)
{
*dest++ = *src++;
}
}

View File

@ -0,0 +1,91 @@
/************************************************************
* up_timerisr.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 <debug.h>
#include <nuttx/arch.h>
#include "clock_internal.h"
#include "up_internal.h"
/************************************************************
* Definitions
************************************************************/
/************************************************************
* Private Types
************************************************************/
/************************************************************
* Private Function Prototypes
************************************************************/
/************************************************************
* Global Functions
************************************************************/
/************************************************************
* Function: timer_isr
*
* Description:
* The timer ISR will perform a variety of services for
* various portions of the systems.
*
************************************************************/
int up_timerisr(int irq, FAR ubyte *frame)
{
/* Process timer interrupt */
sched_process_timer();
return 0;
}
void up_timerinit(void)
{
up_disable_irq(TIMER2_IRQ);
#warning "Missing TIMER2 setup logic here"
/* Attach and enable the timer interrupt */
irq_attach(TIMER2_IRQ, (xcpt_t)up_timerisr);
up_enable_irq(TIMER2_IRQ);
}

View File

@ -116,27 +116,24 @@ void up_unblock_task(FAR _TCB *tcb)
* Are we in an interrupt handler? * Are we in an interrupt handler?
*/ */
if (g_ininterrupt) if (g_irqtos)
{ {
#if 0
# warning REVISIT
/* Yes, then we have to do things differently. /* Yes, then we have to do things differently.
* Just copy the current registers into the OLD rtcb. * Just copy the current stack into the OLD rtcb.
*/ */
up_copystate(&tcb->xcp, current_regs); up_savestack(&rtcb->xcp);
/* Restore the exception context of the rtcb at the (new) head /* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list. * of the g_readytorun task list.
*/ */
rtcb = (_TCB*)g_readytorun.head; rtcb = (FAR _TCB*)g_readytorun.head;
dbg("New Active Task TCB=%p\n", rtcb); dbg("New Active Task TCB=%p\n", rtcb);
/* Then switch contexts */ /* Then switch contexts */
up_copystate(current_regs, &tcb->xcp); up_restorestack(&rtcb->xcp);
#endif
} }
/* We are not in an interrupt andler. Copy the user C context /* We are not in an interrupt andler. Copy the user C context

View File

@ -162,12 +162,14 @@ void sched_process_timer(void)
{ {
/* Increment the system time (if in the link) */ /* Increment the system time (if in the link) */
#ifndef CONFIG_DISABLE_CLOCK
#ifdef CONFIG_HAVE_WEAKFUNCTIONS #ifdef CONFIG_HAVE_WEAKFUNCTIONS
if (clock_timer != NULL) if (clock_timer != NULL)
#endif #endif
{ {
clock_timer(); clock_timer();
} }
#endif
/* Process watchdogs (if in the link) */ /* Process watchdogs (if in the link) */