mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 05:55:46 +08:00
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:
@@ -111,7 +111,7 @@ is available that be used to build a NuttX-compatible arm-elf toolchain.</blockq
|
|||||||
<p><b>C5471 (Arm7)</b>
|
<p><b>C5471 (Arm7)</b>
|
||||||
The build for this ARM7 target that includes most of the OS features and
|
The build for this ARM7 target that includes most of the OS features and
|
||||||
a broad range of OS tests. The size of this executable as given by the
|
a broad range of OS tests. The size of this executable as given by the
|
||||||
Linux <tt>size</tt> command is:
|
Linux <tt>size</tt> command is (3/9/07):
|
||||||
</p>
|
</p>
|
||||||
<pre>
|
<pre>
|
||||||
text data bss dec hex filename
|
text data bss dec hex filename
|
||||||
|
|||||||
@@ -33,16 +33,47 @@
|
|||||||
#
|
#
|
||||||
############################################################
|
############################################################
|
||||||
#
|
#
|
||||||
# architecture selection
|
# Architecture selection
|
||||||
#
|
#
|
||||||
# CONFIG_ARCH - identifies the arch subdirectory
|
# CONFIG_ARCH - identifies the arch subdirectory
|
||||||
# CONFIG_ARCH_name - for use in C code
|
# CONFIG_ARCH_8051 - Set if processor is 8051 family
|
||||||
# CONFIG_PJRC_LEDS - Use LEDs to show state. Unique to 8051.
|
# CONFIG_ARCH_8052 = Set if processor is 8052 family
|
||||||
#
|
#
|
||||||
CONFIG_ARCH=pjrc-8051
|
CONFIG_ARCH=pjrc-8051
|
||||||
|
CONFIG_ARCH_8051=n
|
||||||
CONFIG_ARCH_8052=y
|
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_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
|
# General OS setup
|
||||||
|
|||||||
@@ -183,8 +183,7 @@ sfr at 0xc9 T2MOD ;
|
|||||||
* Timer 0 provides only a 8-bit auto-reload mode.
|
* Timer 0 provides only a 8-bit auto-reload mode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CONFIG_80C52_TIMER2 1
|
#ifdef CONFIG_8052_TIMER2
|
||||||
#ifdef CONFIG_80C52_TIMER2
|
|
||||||
|
|
||||||
/* To use timer 2 as the 100Hz system timer, we need to calculate a 16-bit
|
/* 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
|
* reload value that results in 100Hz overflow interrupts. That value
|
||||||
@@ -207,8 +206,6 @@ sfr at 0xc9 T2MOD ;
|
|||||||
* second.
|
* second.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# warning "No support for timer 0 as the system timer"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ static void _up_assert(int errorcode) /* __attribute__ ((noreturn)) */
|
|||||||
(void)irqsave();
|
(void)irqsave();
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_8051_LEDS
|
#ifdef CONFIG_ARCH_LEDS
|
||||||
up_ledon(LED_PANIC);
|
up_ledon(LED_PANIC);
|
||||||
up_delay(250);
|
up_delay(250);
|
||||||
up_ledoff(LED_PANIC);
|
up_ledoff(LED_PANIC);
|
||||||
|
|||||||
@@ -58,17 +58,8 @@
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_FRAME_DUMP
|
#if defined(CONFIG_FRAME_DUMP) && defined(CONFIG_ARCH_BRINGUP)
|
||||||
static void _up_puthex(ubyte hex) __naked
|
static void up_putspace(void) __naked
|
||||||
{
|
|
||||||
hex; /* To avoid unreferenced argument warning */
|
|
||||||
_asm
|
|
||||||
mov a, dpl
|
|
||||||
ljmp PM2_ENTRY_PHEX
|
|
||||||
_endasm;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _up_putspace(void) __naked
|
|
||||||
{
|
{
|
||||||
_asm
|
_asm
|
||||||
mov a, #0x20
|
mov a, #0x20
|
||||||
@@ -84,34 +75,19 @@ static void _up_putcolon(void) __naked
|
|||||||
_endasm;
|
_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)
|
static void _up_dump16(__code char *ptr, ubyte msb, ubyte lsb)
|
||||||
{
|
{
|
||||||
_up_puts(ptr);
|
up_puts(ptr);
|
||||||
_up_puthex(msb);
|
up_puthex(msb);
|
||||||
_up_puthex(lsb);
|
up_puthex(lsb);
|
||||||
_up_putnl();
|
up_putnl();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _up_dump8(__code char *ptr, ubyte b)
|
static void _up_dump8(__code char *ptr, ubyte b)
|
||||||
{
|
{
|
||||||
_up_puts(ptr);
|
up_puts(ptr);
|
||||||
_up_puthex(b);
|
up_puthex(b);
|
||||||
_up_putnl();
|
up_putnl();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -119,11 +95,49 @@ static void _up_dump8(__code char *ptr, ubyte b)
|
|||||||
* Public Functions
|
* 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
|
* Name: up_dumpstack
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_FRAME_DUMP
|
#if defined(CONFIG_FRAME_DUMP) && defined(CONFIG_ARCH_BRINGUP)
|
||||||
void up_dumpstack(void)
|
void up_dumpstack(void)
|
||||||
{
|
{
|
||||||
NEAR ubyte *start = (NEAR ubyte *)(STACK_BASE & 0xf0);
|
NEAR ubyte *start = (NEAR ubyte *)(STACK_BASE & 0xf0);
|
||||||
@@ -132,25 +146,25 @@ void up_dumpstack(void)
|
|||||||
|
|
||||||
while (start < end)
|
while (start < end)
|
||||||
{
|
{
|
||||||
_up_puthex((ubyte)start);
|
up_puthex((ubyte)start);
|
||||||
_up_putcolon();
|
_up_putcolon();
|
||||||
|
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
_up_putspace();
|
up_putspace();
|
||||||
if (start < (NEAR ubyte *)(STACK_BASE) ||
|
if (start < (NEAR ubyte *)(STACK_BASE) ||
|
||||||
start > end)
|
start > end)
|
||||||
{
|
{
|
||||||
_up_putspace();
|
up_putspace();
|
||||||
_up_putspace();
|
up_putspace();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_up_puthex(*start);
|
up_puthex(*start);
|
||||||
}
|
}
|
||||||
start++;
|
start++;
|
||||||
}
|
}
|
||||||
_up_putnl();
|
up_putnl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -159,7 +173,7 @@ void up_dumpstack(void)
|
|||||||
* Name: up_dumpframe
|
* Name: up_dumpframe
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_FRAME_DUMP
|
#if defined(CONFIG_FRAME_DUMP) && defined(CONFIG_ARCH_BRINGUP)
|
||||||
void up_dumpframe(FAR struct xcptcontext *context)
|
void up_dumpframe(FAR struct xcptcontext *context)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_FRAME_DUMP_SHORT
|
#ifdef CONFIG_FRAME_DUMP_SHORT
|
||||||
@@ -180,33 +194,33 @@ void up_dumpframe(FAR struct xcptcontext *context)
|
|||||||
|
|
||||||
for (i = 0; i < context->nbytes; i += 8)
|
for (i = 0; i < context->nbytes; i += 8)
|
||||||
{
|
{
|
||||||
_up_puthex(i);
|
up_puthex(i);
|
||||||
_up_putcolon();
|
_up_putcolon();
|
||||||
|
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
k = i + j;
|
k = i + j;
|
||||||
_up_putspace();
|
up_putspace();
|
||||||
if (k >= context->nbytes)
|
if (k >= context->nbytes)
|
||||||
{
|
{
|
||||||
_up_putspace();
|
up_putspace();
|
||||||
_up_putspace();
|
up_putspace();
|
||||||
}
|
}
|
||||||
else
|
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++)
|
for (i = 0; i < REGS_SIZE; i++)
|
||||||
{
|
{
|
||||||
_up_putspace();
|
up_putspace();
|
||||||
_up_puthex(context->regs[i]);
|
up_puthex(context->regs[i]);
|
||||||
}
|
}
|
||||||
_up_putnl();
|
up_putnl();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -51,6 +51,12 @@
|
|||||||
.area REG_BANK_0 (REL,OVR,DATA)
|
.area REG_BANK_0 (REL,OVR,DATA)
|
||||||
.ds 8
|
.ds 8
|
||||||
|
|
||||||
|
#ifndef CONFIG_8052_TIMER2
|
||||||
|
.area XSEG
|
||||||
|
_g_timer0tick:
|
||||||
|
.ds 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
************************************************************/
|
************************************************************/
|
||||||
@@ -93,9 +99,12 @@
|
|||||||
|
|
||||||
.org PM2_VECTOR_TIMER0
|
.org PM2_VECTOR_TIMER0
|
||||||
push acc
|
push acc
|
||||||
|
#ifdef CONFIG_8052_TIMER2
|
||||||
mov a, #TIMER0_IRQ
|
mov a, #TIMER0_IRQ
|
||||||
ljmp _up_interrupt
|
ljmp _up_interrupt
|
||||||
|
#else
|
||||||
|
ljmp _up_timer0
|
||||||
|
#endif
|
||||||
.org PM2_VECTOR_EXTINT1
|
.org PM2_VECTOR_EXTINT1
|
||||||
push acc
|
push acc
|
||||||
mov a, #EXT_INT1_IRQ
|
mov a, #EXT_INT1_IRQ
|
||||||
@@ -127,12 +136,76 @@
|
|||||||
start:
|
start:
|
||||||
mov sp, #(STACK_BASE-1)
|
mov sp, #(STACK_BASE-1)
|
||||||
|
|
||||||
#ifdef CONFIG_8051_LEDS
|
#ifdef CONFIG_ARCH_LEDS
|
||||||
lcall _up_ledinit
|
lcall _up_ledinit
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ljmp _os_start
|
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
|
* Name: up_interrupt
|
||||||
*
|
*
|
||||||
@@ -167,6 +240,7 @@ _up_interrupt:
|
|||||||
push dpl
|
push dpl
|
||||||
push dph
|
push dph
|
||||||
|
|
||||||
|
_up_timer0join:
|
||||||
/* Other registers go into the IRQ register save area */
|
/* Other registers go into the IRQ register save area */
|
||||||
|
|
||||||
push acc
|
push acc
|
||||||
@@ -175,7 +249,7 @@ _up_interrupt:
|
|||||||
|
|
||||||
/* Show interrupt status on the LEDs */
|
/* Show interrupt status on the LEDs */
|
||||||
|
|
||||||
#ifdef CONFIG_8051_LEDS
|
#ifdef CONFIG_ARCH_LEDS
|
||||||
mov dpl, #LED_INIRQ
|
mov dpl, #LED_INIRQ
|
||||||
lcall _up_ledon
|
lcall _up_ledon
|
||||||
#endif
|
#endif
|
||||||
@@ -343,12 +417,12 @@ _up_interrupt:
|
|||||||
push dpl
|
push dpl
|
||||||
push dph
|
push dph
|
||||||
lcall _up_dumpstack
|
lcall _up_dumpstack
|
||||||
pop dpl
|
|
||||||
pop dph
|
pop dph
|
||||||
|
pop dpl
|
||||||
#endif
|
#endif
|
||||||
/* Get the pointer to the register save area */
|
/* Get the pointer to the register save area */
|
||||||
|
|
||||||
mov a, #FRAME_SIZE
|
mov a, #STACK_SIZE
|
||||||
add a, dpl
|
add a, dpl
|
||||||
mov dpl, a
|
mov dpl, a
|
||||||
clr a
|
clr a
|
||||||
@@ -365,18 +439,19 @@ _up_interrupt:
|
|||||||
* (context switch).
|
* (context switch).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_8051_LEDS
|
#ifdef CONFIG_ARCH_LEDS
|
||||||
push dpl
|
push dpl
|
||||||
push dph
|
push dph
|
||||||
mov dpl, #LED_INIRQ
|
mov dpl, #LED_INIRQ
|
||||||
lcall _up_ledoff
|
lcall _up_ledoff
|
||||||
pop dpl
|
|
||||||
pop dph
|
pop dph
|
||||||
|
pop dpl
|
||||||
#endif
|
#endif
|
||||||
/* Restore registers from the register save area */
|
/* Restore registers from the register save area */
|
||||||
|
|
||||||
lcall _up_restoreregisters
|
lcall _up_restoreregisters
|
||||||
|
|
||||||
|
_up_timer0exit:
|
||||||
/* Restore registers from the stack and return */
|
/* Restore registers from the stack and return */
|
||||||
|
|
||||||
pop dph
|
pop dph
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
* Private Data
|
* 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;
|
static ubyte g_ledtoggle = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ static ubyte g_ledtoggle = 0;
|
|||||||
|
|
||||||
void up_idle(void)
|
void up_idle(void)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_8051_LEDS) && defined(CONFIG_8051_BRINGUP)
|
#if defined(CONFIG_ARCH_LEDS) && defined(CONFIG_ARCH_BRINGUP)
|
||||||
g_ledtoggle++;
|
g_ledtoggle++;
|
||||||
if (g_ledtoggle == 0x80)
|
if (g_ledtoggle == 0x80)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,16 +50,6 @@
|
|||||||
* Public Definitions
|
* 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
|
* 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_saveirqcontext(FAR struct xcptcontext *context);
|
||||||
extern void up_timerinit(void);
|
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_dumpstack(void);
|
||||||
extern void up_dumpframe(FAR struct xcptcontext *context);
|
extern void up_dumpframe(FAR struct xcptcontext *context);
|
||||||
#else
|
#else
|
||||||
@@ -136,7 +133,7 @@ extern void up_dumpframe(FAR struct xcptcontext *context);
|
|||||||
|
|
||||||
/* Defined in up_leds.c */
|
/* Defined in up_leds.c */
|
||||||
|
|
||||||
#ifdef CONFIG_8051_LEDS
|
#ifdef CONFIG_ARCH_LEDS
|
||||||
extern void up_ledinit(void);
|
extern void up_ledinit(void);
|
||||||
extern void up_ledon(ubyte led);
|
extern void up_ledon(ubyte led);
|
||||||
extern void up_ledoff(ubyte led);
|
extern void up_ledoff(ubyte led);
|
||||||
|
|||||||
@@ -71,6 +71,10 @@ extern int g_nints;
|
|||||||
|
|
||||||
void up_irqinitialize(void)
|
void up_irqinitialize(void)
|
||||||
{
|
{
|
||||||
|
/* Set interrupt priorities (all low) */
|
||||||
|
|
||||||
|
IP = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Disable all interrupts */
|
/* Disable all interrupts */
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ static ubyte g_ledstate;
|
|||||||
* Private Functions
|
* 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
|
static void _up_puthex(ubyte hex) __naked
|
||||||
{
|
{
|
||||||
hex; /* To avoid unreferenced argument warning */
|
hex; /* To avoid unreferenced argument warning */
|
||||||
@@ -122,7 +122,7 @@ static void _up_putnl(void) __naked
|
|||||||
* Name: up_ledinit
|
* Name: up_ledinit
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_8051_LEDS
|
#ifdef CONFIG_ARCH_LEDS
|
||||||
void up_ledinit(void)
|
void up_ledinit(void)
|
||||||
{
|
{
|
||||||
/* Set all ports as outputs */
|
/* Set all ports as outputs */
|
||||||
@@ -143,6 +143,10 @@ void up_ledinit(void)
|
|||||||
|
|
||||||
void up_ledon(ubyte led)
|
void up_ledon(ubyte led)
|
||||||
{
|
{
|
||||||
|
/* This may be called from an interrupt handler */
|
||||||
|
|
||||||
|
irqstate_t flags = irqsave();
|
||||||
|
|
||||||
#ifdef RESET_KLUDGE_NEEDED
|
#ifdef RESET_KLUDGE_NEEDED
|
||||||
/* I don't understand why this happens yet, but sometimes
|
/* I don't understand why this happens yet, but sometimes
|
||||||
* it is necessary to reconfigure port E.
|
* it is necessary to reconfigure port E.
|
||||||
@@ -164,6 +168,7 @@ void up_ledon(ubyte led)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_up_showledon();
|
_up_showledon();
|
||||||
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
@@ -172,6 +177,10 @@ void up_ledon(ubyte led)
|
|||||||
|
|
||||||
void up_ledoff(ubyte led)
|
void up_ledoff(ubyte led)
|
||||||
{
|
{
|
||||||
|
/* This may be called from an interrupt handler */
|
||||||
|
|
||||||
|
irqstate_t flags = irqsave();
|
||||||
|
|
||||||
#ifdef RESET_KLUDGE_NEEDED
|
#ifdef RESET_KLUDGE_NEEDED
|
||||||
/* I don't understand why this happens yet, but sometimes
|
/* I don't understand why this happens yet, but sometimes
|
||||||
* it is necessary to reconfigure port E.
|
* it is necessary to reconfigure port E.
|
||||||
@@ -193,5 +202,6 @@ void up_ledoff(ubyte led)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_up_showledoff();
|
_up_showledoff();
|
||||||
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_8051_LEDS */
|
#endif /* CONFIG_ARCH_LEDS */
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
* Included Files
|
* Included Files
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include "up_internal.h"
|
#include "up_internal.h"
|
||||||
|
|
||||||
@@ -260,7 +261,7 @@ void up_restorecontext(FAR struct xcptcontext *context) __naked
|
|||||||
#endif
|
#endif
|
||||||
/* Get the pointer to the register save area */
|
/* Get the pointer to the register save area */
|
||||||
|
|
||||||
mov a, #FRAME_SIZE
|
mov a, #STACK_SIZE
|
||||||
add a, dpl
|
add a, dpl
|
||||||
mov dpl, a
|
mov dpl, a
|
||||||
clr a
|
clr a
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
* Included Files
|
* Included Files
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include "up_internal.h"
|
#include "up_internal.h"
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ int up_timerisr(int irq, FAR ubyte *frame)
|
|||||||
|
|
||||||
void up_timerinit(void)
|
void up_timerinit(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_80C52_TIMER2
|
#ifdef CONFIG_8052_TIMER2
|
||||||
up_disable_irq(TIMER2_IRQ);
|
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;
|
T2MOD = 0;
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ void up_timerinit(void)
|
|||||||
|
|
||||||
/* Configure for interrupts */
|
/* Configure for interrupts */
|
||||||
|
|
||||||
T2CON = 0x40;
|
T2CON = 0x04;
|
||||||
|
|
||||||
/* Attach and enable the timer interrupt */
|
/* Attach and enable the timer interrupt */
|
||||||
|
|
||||||
@@ -116,6 +116,29 @@ void up_timerinit(void)
|
|||||||
up_enable_irq(TIMER2_IRQ);
|
up_enable_irq(TIMER2_IRQ);
|
||||||
|
|
||||||
#else
|
#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"
|
# warning "No support for timer 0 as the system timer"
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -243,7 +243,7 @@ extern void task_start(void);
|
|||||||
extern STATUS task_schedsetup(FAR _TCB *tcb, int priority,
|
extern STATUS task_schedsetup(FAR _TCB *tcb, int priority,
|
||||||
start_t start, main_t main);
|
start_t start, main_t main);
|
||||||
extern STATUS task_argsetup(FAR _TCB *tcb, const char *name,
|
extern STATUS task_argsetup(FAR _TCB *tcb, const char *name,
|
||||||
boolean pthread, char *argv[]);
|
char *argv[]);
|
||||||
|
|
||||||
extern boolean sched_addreadytorun(FAR _TCB *rtrtcb);
|
extern boolean sched_addreadytorun(FAR _TCB *rtrtcb);
|
||||||
extern boolean sched_removereadytorun(FAR _TCB *rtrtcb);
|
extern boolean sched_removereadytorun(FAR _TCB *rtrtcb);
|
||||||
|
|||||||
+68
-4
@@ -75,10 +75,73 @@ FAR pthread_attr_t g_default_pthread_attr =
|
|||||||
* Private Variables
|
* Private Variables
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
|
/* This is the name for name-less pthreads */
|
||||||
|
|
||||||
|
static const char g_pthreadname[] = "<pthread>";
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: pthread_argsetup
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This functions sets up parameters in the Task Control
|
||||||
|
* Block (TCB) in preparation for starting a new thread.
|
||||||
|
*
|
||||||
|
* pthread_argsetup() is called from task_init() and task_start()
|
||||||
|
* to create a new task (with arguments cloned via strdup)
|
||||||
|
* or pthread_create() which has one argument passed by
|
||||||
|
* value (distinguished by the pthread boolean argument).
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* tcb - Address of the new task's TCB
|
||||||
|
* name - Name of the new task (not used)
|
||||||
|
* argv - A pointer to an array of input parameters.
|
||||||
|
* Up to CONFIG_MAX_TASK_ARG parameters may be
|
||||||
|
* provided. If fewer than CONFIG_MAX_TASK_ARG
|
||||||
|
* parameters are passed, the list should be
|
||||||
|
* terminated with a NULL argv[] value.
|
||||||
|
* If no parameters are required, argv may be NULL.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* OK
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
static void pthread_argsetup(FAR _TCB *tcb, pthread_addr_t arg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#if CONFIG_TASK_NAME_SIZE > 0
|
||||||
|
/* Copy the pthread name into the TCB */
|
||||||
|
|
||||||
|
strncpy(tcb->name, g_pthreadname, CONFIG_TASK_NAME_SIZE);
|
||||||
|
|
||||||
|
/* Save the name as the first argument in the TCB */
|
||||||
|
|
||||||
|
tcb->argv[0] = tcb->name;
|
||||||
|
#else
|
||||||
|
/* Save the name as the first argument in the TCB */
|
||||||
|
|
||||||
|
tcb->argv[0] = (char *)g_pthreadname;
|
||||||
|
#endif /* CONFIG_TASK_NAME_SIZE */
|
||||||
|
|
||||||
|
/* For pthreads, args are strictly pass-by-value; that actual
|
||||||
|
* type wrapped by pthread_addr_t is unknown.
|
||||||
|
*/
|
||||||
|
|
||||||
|
tcb->argv[1] = (char*)arg;
|
||||||
|
|
||||||
|
/* Nullify the remaining, unused argument storage */
|
||||||
|
|
||||||
|
for (i = 2; i < CONFIG_MAX_TASK_ARGS+1; i++)
|
||||||
|
{
|
||||||
|
tcb->argv[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Function: pthread_addjoininfo
|
* Function: pthread_addjoininfo
|
||||||
*
|
*
|
||||||
@@ -178,7 +241,6 @@ int pthread_create(pthread_t *thread, pthread_attr_t *attr,
|
|||||||
FAR _TCB *ptcb;
|
FAR _TCB *ptcb;
|
||||||
FAR join_t *pjoin;
|
FAR join_t *pjoin;
|
||||||
STATUS status;
|
STATUS status;
|
||||||
char *argv[2];
|
|
||||||
int priority;
|
int priority;
|
||||||
#if CONFIG_RR_INTERVAL > 0
|
#if CONFIG_RR_INTERVAL > 0
|
||||||
int policy;
|
int policy;
|
||||||
@@ -280,13 +342,15 @@ int pthread_create(pthread_t *thread, pthread_attr_t *attr,
|
|||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark this task as a pthread */
|
||||||
|
|
||||||
|
ptcb->flags |= TCB_FLAG_PTHREAD;
|
||||||
|
|
||||||
/* Configure the TCB for a pthread receiving on parameter
|
/* Configure the TCB for a pthread receiving on parameter
|
||||||
* passed by value
|
* passed by value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
argv[0] = (char *)arg;
|
(void)pthread_argsetup(ptcb, arg);
|
||||||
argv[1] = NULL;
|
|
||||||
(void)task_argsetup(ptcb, NULL, TRUE, argv);
|
|
||||||
|
|
||||||
/* Attach the join info to the TCB. */
|
/* Attach the join info to the TCB. */
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -159,7 +159,7 @@ int task_create(const char *name, int priority,
|
|||||||
|
|
||||||
/* Setup to pass parameters to the new task */
|
/* Setup to pass parameters to the new task */
|
||||||
|
|
||||||
(void)task_argsetup(tcb, name, FALSE, argv);
|
(void)task_argsetup(tcb, name, argv);
|
||||||
|
|
||||||
/* Get the assigned pid before we start the task */
|
/* Get the assigned pid before we start the task */
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -127,7 +127,7 @@ STATUS task_init(FAR _TCB *tcb, const char *name, int priority,
|
|||||||
{
|
{
|
||||||
/* Setup to pass parameters to the new task */
|
/* Setup to pass parameters to the new task */
|
||||||
|
|
||||||
(void)task_argsetup(tcb, name, FALSE, argv);
|
(void)task_argsetup(tcb, name, argv);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-45
@@ -64,13 +64,13 @@
|
|||||||
|
|
||||||
/* This is the name for un-named tasks */
|
/* This is the name for un-named tasks */
|
||||||
|
|
||||||
static const char g_noname[] = "no name";
|
static const char g_noname[] = "<noname>";
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
static STATUS task_assignpid(FAR _TCB* tcb);
|
static STATUS task_assignpid(FAR _TCB* tcb);
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
@@ -216,15 +216,13 @@ STATUS task_schedsetup(FAR _TCB *tcb, int priority,
|
|||||||
* This functions sets up parameters in the Task Control
|
* This functions sets up parameters in the Task Control
|
||||||
* Block (TCB) in preparation for starting a new thread.
|
* Block (TCB) in preparation for starting a new thread.
|
||||||
*
|
*
|
||||||
* task_argsetup() is called from task_init() and task_start()
|
* task_argsetup() is called only from task_init() and
|
||||||
* to create a new task (with arguments cloned via strdup)
|
* task_start() to create a new task. Argumens are
|
||||||
* or pthread_create() which has one argument passed by
|
* cloned via strdup.
|
||||||
* value (distinguished by the pthread boolean argument).
|
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* tcb - Address of the new task's TCB
|
* tcb - Address of the new task's TCB
|
||||||
* name - Name of the new task (not used)
|
* name - Name of the new task (not used)
|
||||||
* pthread - TRUE is the task emulates pthread behavior
|
|
||||||
* argv - A pointer to an array of input parameters.
|
* argv - A pointer to an array of input parameters.
|
||||||
* Up to CONFIG_MAX_TASK_ARG parameters may be
|
* Up to CONFIG_MAX_TASK_ARG parameters may be
|
||||||
* provided. If fewer than CONFIG_MAX_TASK_ARG
|
* provided. If fewer than CONFIG_MAX_TASK_ARG
|
||||||
@@ -237,69 +235,48 @@ STATUS task_schedsetup(FAR _TCB *tcb, int priority,
|
|||||||
*
|
*
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
STATUS task_argsetup(FAR _TCB *tcb, const char *name,
|
STATUS task_argsetup(FAR _TCB *tcb, const char *name, char *argv[])
|
||||||
boolean pthread, char *argv[])
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#if CONFIG_TASK_NAME_SIZE > 0
|
#if CONFIG_TASK_NAME_SIZE > 0
|
||||||
/* Give a name to the unnamed threads */
|
/* Give a name to the unnamed tasks */
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
{
|
{
|
||||||
name = (char *)g_noname;
|
name = (char *)g_noname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy the name into the TCB */
|
/* Copy the name into the TCB */
|
||||||
|
|
||||||
strncpy(tcb->name, name, CONFIG_TASK_NAME_SIZE);
|
strncpy(tcb->name, name, CONFIG_TASK_NAME_SIZE);
|
||||||
#endif /* CONFIG_TASK_NAME_SIZE */
|
|
||||||
|
|
||||||
/* Save the arguments in the TCB */
|
/* Save the name as the first argument */
|
||||||
|
|
||||||
#if CONFIG_TASK_NAME_SIZE > 0
|
|
||||||
tcb->argv[0] = tcb->name;
|
tcb->argv[0] = tcb->name;
|
||||||
#else
|
#else
|
||||||
tcb->argv[0] = (char *)g_noname;
|
/* Save the name as the first argument */
|
||||||
#endif
|
|
||||||
|
|
||||||
/* For pthreads, args are strictly pass-by-value; the char*
|
tcb->argv[0] = (char *)g_noname;
|
||||||
* arguments wrap some unknown value cast to char*. However,
|
#endif /* CONFIG_TASK_NAME_SIZE */
|
||||||
* for tasks, the life of the argument must be as long as
|
|
||||||
|
/* For tasks, the life of the argument must be as long as
|
||||||
* the life of the task and the arguments must be strings.
|
* the life of the task and the arguments must be strings.
|
||||||
* So for tasks, we have to to dup the strings.
|
* So for tasks, we have to to dup the strings.
|
||||||
|
*
|
||||||
|
* The first NULL argument terminates the list of
|
||||||
|
* arguments. The argv pointer may be NULL if no
|
||||||
|
* parameters are passed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!pthread)
|
i = 1;
|
||||||
|
if (argv)
|
||||||
{
|
{
|
||||||
/* The first NULL argument terminates the list of
|
for (; i < CONFIG_MAX_TASK_ARGS+1 && argv[i-1]; i++)
|
||||||
* arguments. The argv pointer may be NULL if no
|
|
||||||
* parameters are passed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
i = 1;
|
|
||||||
if (argv)
|
|
||||||
{
|
{
|
||||||
for (; i < CONFIG_MAX_TASK_ARGS+1 && argv[i-1]; i++)
|
tcb->argv[i] = strdup(argv[i-1]);
|
||||||
{
|
|
||||||
tcb->argv[i] = strdup(argv[i-1]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Mark this task as a pthread */
|
|
||||||
|
|
||||||
tcb->flags |= TCB_FLAG_PTHREAD;
|
|
||||||
|
|
||||||
/* And just copy the argument. For pthreads, there
|
|
||||||
* is really only a single argument, argv[0]. It is
|
|
||||||
* copied as a value -- NOT duplicated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
i = 2;
|
|
||||||
tcb->argv[1] = argv[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nullify any unused argument storage */
|
/* Nullify any unused argument storage */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user