8052 context switch/interrupt integration; pthread arg setup changed

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@60 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2007-03-13 23:03:12 +00:00
parent d56d9ecde2
commit 613f809f5d
12 changed files with 242 additions and 89 deletions

View File

@ -33,16 +33,47 @@
#
############################################################
#
# architecture selection
# Architecture selection
#
# CONFIG_ARCH - identifies the arch subdirectory
# CONFIG_ARCH_name - for use in C code
# CONFIG_PJRC_LEDS - Use LEDs to show state. Unique to 8051.
# CONFIG_ARCH_8051 - Set if processor is 8051 family
# CONFIG_ARCH_8052 = Set if processor is 8052 family
#
CONFIG_ARCH=pjrc-8051
CONFIG_ARCH_8051=n
CONFIG_ARCH_8052=y
#
# Architecture-specific settings. These may mean nothing to
# other architectures.
#
# CONFIG-ARCH_PJRC - Set if using the PJRC 87C52 board
# CONFIG_ARCH_LEDS - Use LEDs to show state. Unique to 8051.
# CONFIG_8052_TIMER2 - Use timer2 for the 100Hz system timer.
# (default is timer0 at 112.5Hz).
#
# These features are only supported when CONFIG_ARCH_BRINGUP
# is set:
#
# CONFIG_ARCH_BRINGUP - Enables some bringup features
# CONFIG_FRAME_DUMP - Enable stack/frame dumping logic
# CONFIG_FRAME_DUMP_SHORT - Terse frame dump output
# CONFIG_SUPPRESS_INTERRUPTS - Do not enable interrupts
# CONFIG_SWITCH_FRAME_DUMP - Dump frames from normal switches
# CONFIG_INTERRUPT_FRAME_DUMP - Dump frames from interrupt switches
# CONFIG_LED_DEBUG - Enable debug output from LED logic
#
CONFIG_ARCH_PJRC=y
CONFIG_8051_LEDS=y
CONFIG_ARCH_LEDS=y
CONFIG_8052_TIMER2=y
CONFIG_ARCH_BRINGUP=y
CONFIG_FRAME_DUMP=y
CONFIG_FRAME_DUMP_SHORT=n
CONFIG_SUPPRESS_INTERRUPTS=y
CONFIG_SWITCH_FRAME_DUMP=y
CONFIG_INTERRUPT_FRAME_DUMP=n
CONFIG_LED_DEBUG=n
#
# General OS setup

View File

@ -183,8 +183,7 @@ sfr at 0xc9 T2MOD ;
* Timer 0 provides only a 8-bit auto-reload mode.
*/
#define CONFIG_80C52_TIMER2 1
#ifdef CONFIG_80C52_TIMER2
#ifdef CONFIG_8052_TIMER2
/* To use timer 2 as the 100Hz system timer, we need to calculate a 16-bit
* reload value that results in 100Hz overflow interrupts. That value
@ -207,8 +206,6 @@ sfr at 0xc9 T2MOD ;
* second.
*/
# warning "No support for timer 0 as the system timer"
#endif
/**************************************************************************

View File

@ -73,7 +73,7 @@ static void _up_assert(int errorcode) /* __attribute__ ((noreturn)) */
(void)irqsave();
for(;;)
{
#ifdef CONFIG_8051_LEDS
#ifdef CONFIG_ARCH_LEDS
up_ledon(LED_PANIC);
up_delay(250);
up_ledoff(LED_PANIC);

View File

@ -58,17 +58,8 @@
* Private Functions
************************************************************/
#ifdef CONFIG_FRAME_DUMP
static void _up_puthex(ubyte hex) __naked
{
hex; /* To avoid unreferenced argument warning */
_asm
mov a, dpl
ljmp PM2_ENTRY_PHEX
_endasm;
}
static void _up_putspace(void) __naked
#if defined(CONFIG_FRAME_DUMP) && defined(CONFIG_ARCH_BRINGUP)
static void up_putspace(void) __naked
{
_asm
mov a, #0x20
@ -84,34 +75,19 @@ static void _up_putcolon(void) __naked
_endasm;
}
static void _up_putnl(void) __naked
{
_asm
ljmp PM2_ENTRY_NEWLINE
_endasm;
}
static void _up_puts(__code char *ptr)
{
for (; *ptr; ptr++)
{
up_putc(*ptr);
}
}
static void _up_dump16(__code char *ptr, ubyte msb, ubyte lsb)
{
_up_puts(ptr);
_up_puthex(msb);
_up_puthex(lsb);
_up_putnl();
up_puts(ptr);
up_puthex(msb);
up_puthex(lsb);
up_putnl();
}
static void _up_dump8(__code char *ptr, ubyte b)
{
_up_puts(ptr);
_up_puthex(b);
_up_putnl();
up_puts(ptr);
up_puthex(b);
up_putnl();
}
#endif
@ -119,11 +95,49 @@ static void _up_dump8(__code char *ptr, ubyte b)
* Public Functions
************************************************************/
/************************************************************
* Name: up_puthex, up_puthex16, up_putnl, up_puts
************************************************************/
#if defined(CONFIG_ARCH_BRINGUP)
void up_puthex(ubyte hex) __naked
{
hex; /* To avoid unreferenced argument warning */
_asm
mov a, dpl
ljmp PM2_ENTRY_PHEX
_endasm;
}
void up_puthex16(int hex) __naked
{
hex; /* To avoid unreferenced argument warning */
_asm
ljmp PM2_ENTRY_PHEX16
_endasm;
}
void up_putnl(void) __naked
{
_asm
ljmp PM2_ENTRY_NEWLINE
_endasm;
}
void up_puts(__code char *ptr)
{
for (; *ptr; ptr++)
{
up_putc(*ptr);
}
}
#endif
/************************************************************
* Name: up_dumpstack
************************************************************/
#ifdef CONFIG_FRAME_DUMP
#if defined(CONFIG_FRAME_DUMP) && defined(CONFIG_ARCH_BRINGUP)
void up_dumpstack(void)
{
NEAR ubyte *start = (NEAR ubyte *)(STACK_BASE & 0xf0);
@ -132,25 +146,25 @@ void up_dumpstack(void)
while (start < end)
{
_up_puthex((ubyte)start);
up_puthex((ubyte)start);
_up_putcolon();
for (i = 0; i < 8; i++)
{
_up_putspace();
up_putspace();
if (start < (NEAR ubyte *)(STACK_BASE) ||
start > end)
{
_up_putspace();
_up_putspace();
up_putspace();
up_putspace();
}
else
{
_up_puthex(*start);
up_puthex(*start);
}
start++;
}
_up_putnl();
up_putnl();
}
}
#endif
@ -159,7 +173,7 @@ void up_dumpstack(void)
* Name: up_dumpframe
************************************************************/
#ifdef CONFIG_FRAME_DUMP
#if defined(CONFIG_FRAME_DUMP) && defined(CONFIG_ARCH_BRINGUP)
void up_dumpframe(FAR struct xcptcontext *context)
{
#ifdef CONFIG_FRAME_DUMP_SHORT
@ -180,33 +194,33 @@ void up_dumpframe(FAR struct xcptcontext *context)
for (i = 0; i < context->nbytes; i += 8)
{
_up_puthex(i);
up_puthex(i);
_up_putcolon();
for (j = 0; j < 8; j++)
{
k = i + j;
_up_putspace();
up_putspace();
if (k >= context->nbytes)
{
_up_putspace();
_up_putspace();
up_putspace();
up_putspace();
}
else
{
_up_puthex(context->stack[k]);
up_puthex(context->stack[k]);
}
}
_up_putnl();
up_putnl();
}
_up_puts(" REGS:");
up_puts(" REGS:");
for (i = 0; i < REGS_SIZE; i++)
{
_up_putspace();
_up_puthex(context->regs[i]);
up_putspace();
up_puthex(context->regs[i]);
}
_up_putnl();
up_putnl();
#endif
}
#endif

View File

@ -51,6 +51,12 @@
.area REG_BANK_0 (REL,OVR,DATA)
.ds 8
#ifndef CONFIG_8052_TIMER2
.area XSEG
_g_timer0tick:
.ds 1
#endif
/************************************************************
* Public Data
************************************************************/
@ -93,9 +99,12 @@
.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
@ -127,12 +136,76 @@
start:
mov sp, #(STACK_BASE-1)
#ifdef CONFIG_8051_LEDS
#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
*
@ -167,6 +240,7 @@ _up_interrupt:
push dpl
push dph
_up_timer0join:
/* Other registers go into the IRQ register save area */
push acc
@ -175,7 +249,7 @@ _up_interrupt:
/* Show interrupt status on the LEDs */
#ifdef CONFIG_8051_LEDS
#ifdef CONFIG_ARCH_LEDS
mov dpl, #LED_INIRQ
lcall _up_ledon
#endif
@ -343,12 +417,12 @@ _up_interrupt:
push dpl
push dph
lcall _up_dumpstack
pop dpl
pop dph
pop dpl
#endif
/* Get the pointer to the register save area */
mov a, #FRAME_SIZE
mov a, #STACK_SIZE
add a, dpl
mov dpl, a
clr a
@ -365,18 +439,19 @@ _up_interrupt:
* (context switch).
*/
#ifdef CONFIG_8051_LEDS
#ifdef CONFIG_ARCH_LEDS
push dpl
push dph
mov dpl, #LED_INIRQ
lcall _up_ledoff
pop dpl
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

View File

@ -50,7 +50,7 @@
* Private Data
************************************************************/
#if defined(CONFIG_8051_LEDS) && defined(CONFIG_8051_BRINGUP)
#if defined(CONFIG_ARCH_LEDS) && defined(CONFIG_ARCH_BRINGUP)
static ubyte g_ledtoggle = 0;
#endif
@ -79,7 +79,7 @@ static ubyte g_ledtoggle = 0;
void up_idle(void)
{
#if defined(CONFIG_8051_LEDS) && defined(CONFIG_8051_BRINGUP)
#if defined(CONFIG_ARCH_LEDS) && defined(CONFIG_ARCH_BRINGUP)
g_ledtoggle++;
if (g_ledtoggle == 0x80)
{

View File

@ -50,16 +50,6 @@
* Public Definitions
**************************************************************************/
/* Bring-up debug configurations */
#define CONFIG_8051_BRINGUP 1 /* Enables some bringup features */
#define CONFIG_FRAME_DUMP 1 /* Enable stack/frame dumping logic */
#undef CONFIG_FRAME_DUMP_SHORT /* Terse frame dump output */
#define CONFIG_SUPPRESS_INTERRUPTS 1 /* Do not enable interrupts */
#define CONFIG_SWITCH_FRAME_DUMP 1 /* Dump frames from normal switches */
#undef CONFIG_INTERRUPT_FRAME_DUMP /* Dump frames from interrupt switches */
#define CONFIG_LED_DEBUG 1 /* Enabled debug output from LED logic */
/**************************************************************************
* Public Types
**************************************************************************/
@ -124,9 +114,16 @@ extern void up_saveregisters(FAR ubyte *regs) _naked;
extern void up_saveirqcontext(FAR struct xcptcontext *context);
extern void up_timerinit(void);
/* Defined in up_assert.c */
/* Defined in up_debug.c */
#ifdef CONFIG_FRAME_DUMP
#if defined(CONFIG_ARCH_BRINGUP)
extern void up_puthex(ubyte hex) __naked;
extern void up_puthex16(int hex) __naked;
extern void up_putnl(void) __naked;
extern void up_puts(__code char *ptr);
#endif
#if defined(CONFIG_FRAME_DUMP) && defined(CONFIG_ARCH_BRINGUP)
extern void up_dumpstack(void);
extern void up_dumpframe(FAR struct xcptcontext *context);
#else
@ -136,7 +133,7 @@ extern void up_dumpframe(FAR struct xcptcontext *context);
/* Defined in up_leds.c */
#ifdef CONFIG_8051_LEDS
#ifdef CONFIG_ARCH_LEDS
extern void up_ledinit(void);
extern void up_ledon(ubyte led);
extern void up_ledoff(ubyte led);

View File

@ -71,6 +71,10 @@ extern int g_nints;
void up_irqinitialize(void)
{
/* Set interrupt priorities (all low) */
IP = 0;
#ifdef CONFIG_SUPPRESS_INTERRUPTS
/* Disable all interrupts */

View File

@ -57,7 +57,7 @@ static ubyte g_ledstate;
* Private Functions
************************************************************/
#if defined(CONFIG_LED_DEBUG) && defined(CONFIG_8051_LEDS)
#if defined(CONFIG_LED_DEBUG) && defined(CONFIG_ARCH_LEDS)
static void _up_puthex(ubyte hex) __naked
{
hex; /* To avoid unreferenced argument warning */
@ -122,7 +122,7 @@ static void _up_putnl(void) __naked
* Name: up_ledinit
************************************************************/
#ifdef CONFIG_8051_LEDS
#ifdef CONFIG_ARCH_LEDS
void up_ledinit(void)
{
/* Set all ports as outputs */
@ -143,6 +143,10 @@ void up_ledinit(void)
void up_ledon(ubyte led)
{
/* This may be called from an interrupt handler */
irqstate_t flags = irqsave();
#ifdef RESET_KLUDGE_NEEDED
/* I don't understand why this happens yet, but sometimes
* it is necessary to reconfigure port E.
@ -164,6 +168,7 @@ void up_ledon(ubyte led)
}
_up_showledon();
irqrestore(flags);
}
/************************************************************
@ -172,6 +177,10 @@ void up_ledon(ubyte led)
void up_ledoff(ubyte led)
{
/* This may be called from an interrupt handler */
irqstate_t flags = irqsave();
#ifdef RESET_KLUDGE_NEEDED
/* I don't understand why this happens yet, but sometimes
* it is necessary to reconfigure port E.
@ -193,5 +202,6 @@ void up_ledoff(ubyte led)
}
_up_showledoff();
irqrestore(flags);
}
#endif /* CONFIG_8051_LEDS */
#endif /* CONFIG_ARCH_LEDS */

View File

@ -37,6 +37,7 @@
* Included Files
**************************************************************************/
#include <nuttx/config.h>
#include <nuttx/irq.h>
#include "up_internal.h"
@ -260,7 +261,7 @@ void up_restorecontext(FAR struct xcptcontext *context) __naked
#endif
/* Get the pointer to the register save area */
mov a, #FRAME_SIZE
mov a, #STACK_SIZE
add a, dpl
mov dpl, a
clr a

View File

@ -37,6 +37,7 @@
* Included Files
**************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <nuttx/irq.h>
#include "up_internal.h"

View File

@ -89,10 +89,10 @@ int up_timerisr(int irq, FAR ubyte *frame)
void up_timerinit(void)
{
#ifdef CONFIG_80C52_TIMER2
#ifdef CONFIG_8052_TIMER2
up_disable_irq(TIMER2_IRQ);
/* Set up timer 2 -- See up_internal.h for details */
/* Set up timer 2 -- See pjrc.h for details */
T2MOD = 0;
@ -108,7 +108,7 @@ void up_timerinit(void)
/* Configure for interrupts */
T2CON = 0x40;
T2CON = 0x04;
/* Attach and enable the timer interrupt */
@ -116,6 +116,29 @@ void up_timerinit(void)
up_enable_irq(TIMER2_IRQ);
#else
/* 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.
*/
up_disable_irq(TIMER0_IRQ);
/* Initialize timer 0 */
TR0 = 0; /* Make sure timer 0 is stopped */
TF0 = 0; /* Clear the overflow flag */
TMOD &= 0xF0; /* Set to mode 0 (without changing timer1) */
TL0 = 0; /* Clear timer 0 value */
TH0 = 0;
/* Attach and enable the timer interrupt */
irq_attach(TIMER0_IRQ, (xcpt_t)up_timerisr);
TR0 = 1; /* Start the timer */
up_enable_irq(TIMER0_IRQ);
# warning "No support for timer 0 as the system timer"
#endif
}