diff --git a/ChangeLog b/ChangeLog index 2366581c7cbd12b18cc86689d894b8826a8b798f..36b6e689bdb0fae35f583cbc997ffa8bb549ac49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,8 @@ * Added fgets() and gets() logic; verified c5471 console read. * Corrected error in reading from serial port. Improper use of semaphore can cause deadlock. + * Tasks can now accept a configurable maximum number of + input parameters (argc) * Attempts to use C5471 console from interrupt handlers can casue errors. Added a special path for this case. * Refuse calls to sem_wait and sem_trywait from interrupt diff --git a/Documentation/NuttxUserGuide.html b/Documentation/NuttxUserGuide.html index b7055adbcf722af4247ec034479deb3b0bd83336..48be3bee8520556d0faaa1decf8c79aea13edbc1 100644 --- a/Documentation/NuttxUserGuide.html +++ b/Documentation/NuttxUserGuide.html @@ -12,7 +12,7 @@ <hr> <hr> <CENTER><BIG><B> -Nuttx Operating System +NuttX Operating System <P> User's Manual </B></BIG> @@ -30,9 +30,9 @@ Gregory Nutt This user's manual is divided into three sections: <UL> <LI><B>Section 1.0, <A HREF="#Introduction">Introduction</A></B>: -This section provides an overview of the Nuttx user's manual. +This section provides an overview of the NuttX user's manual. <LI><B>Section 2.0, <A HREF="#OS_Interfaces">OS Interfaces</A></B>: -This section details the interfaces provided by Nuttx from the +This section details the interfaces provided by NuttX from the perspective of the firmware developer. This section is divided into several paragraphs that describe different groups of OS interfaces: <UL> @@ -46,7 +46,7 @@ into several paragraphs that describe different groups of OS interfaces: <LI>Paragraph 2.8 <A HREF="#Pthread">Pthread Interfaces</A> </UL> <LI><B>Section 3.0, <A HREF="#Data_Structures">OS Data Structures</A></B>: -This section documents the data structures that are used at the Nuttx +This section documents the data structures that are used at the NuttX interface. </UL> <HR> @@ -54,7 +54,7 @@ interface. <H1>2.0 <A NAME="OS_Interfaces">OS Interfaces</A></H1> <P> -This section describes each C-callable interface to the Nuttx +This section describes each C-callable interface to the NuttX Operating System. The description of each interface is presented in the following format: <P> @@ -77,10 +77,10 @@ the interface function or any non-obvious limitations to the use of the interface function will be indicated here. <P> <B>POSIX Compatibility:</B> Any significant differences between the -Nuttx interface and its corresponding POSIX interface will be noted +NuttX interface and its corresponding POSIX interface will be noted here. <P> -NOTE: In order to achieve an independent name space for the Nuttx +NOTE: In order to achieve an independent name space for the NuttX interface functions, differences in function names and types are to be expected and will not be identified as differences in these paragraphs. @@ -90,9 +90,9 @@ paragraphs. <p> <b>Tasks</b>. -Nuttx is a flat address OS. As such it does not support "processes" +NuttX is a flat address OS. As such it does not support "processes" in the way that, say, Linux does. -Nuttx only supports simple threads running within the same address space. +NuttX only supports simple threads running within the same address space. However, the programming model makes a distinction between "tasks" and pthreads: <ul> @@ -129,7 +129,7 @@ were started from the same parent thread. int priority, int stack_size, main_t entry, - char *arg1, char *arg2, char *arg3, char *arg4); + const char *argv[]); </PRE> <P> @@ -144,17 +144,28 @@ were started from the same parent thread. The specified function will be called with four arguments. Should the specified routine return, a call to exit() will automatically be made. </P> -<P> - Note that four (and only four) arguments must be passed for the - spawned functions. -</P> <p> - The newly created task does not inherity characteristics + Note that an arbitrary number of arguments may be passed to the + spawned functions. The maximum umber of arguments is an OS + configuration parameter (<code>CONFIG_MAX_TASK_ARGS</code>). +</p> +<p> + The arguments are copied (via <code>strdup</code>) so that the + life of the passed strings is not dependent on the life of the + caller to <code>task_create()</code>. +</p> +<p> + The newly created task does not inherit scheduler characteristics from the parent task: The new task is started at the default system priority and with the SCHED_FIFO scheduling policy. These characteristcs may be modified after the new task has been started. </p> +<p> + The newly created task does inherit the first three file + descriptors (corresponding to stdin, stdout, and stderr) and + redirection of standard I/O is supported. +</p> <P> <B>Input Parameters:</B> <UL> @@ -162,7 +173,11 @@ were started from the same parent thread. <LI><I>priority</I>. Priority of the new task</LI> <LI><I>stack_size</I>. size (in bytes) of the stack needed</LI> <LI><I>entry</I>. Entry point of a new task</LI> - <LI><I>arg1, arg2, arg3, and arg4</I>. Four required task arguments to pass to the task</LI> + <LI><I>argv</I>. A pointer to an array of input parameters. Up to + <code>CONFIG_MAX_TASK_ARG</code> parameters may be provided. + If fewer than <code>CONFIG_MAX_TASK_ARG</code> parameters are + passed, the list should be terminated with a NULL argv[] value. + If no parameters are required, argv may be NULL. </UL> <P> <B>Returned Values:</B> @@ -192,14 +207,13 @@ VxWorks provides the following similar interface: </PRE> <P> -The Nuttx task_create() differs from VxWorks' taskSpawn() in the +The NuttX task_create() differs from VxWorks' taskSpawn() in the following ways: <UL> -<LI>Function name -<LI>Various differences in types or arguments +<LI>Interface name +<LI>Various differences in types of arguments <LI>There is no options arguement. -<LI>One four parameters can be passed to a task (VxWorks allows -ten). +<LI>A variable number of parameters can be passed to a task (VxWorks supports ten). </UL> <H3>2.1.2 task_init</H3> @@ -209,20 +223,21 @@ ten). <PRE> #include <sched.h> STATUS task_init( - _TCB *tcb, - char *name, - int priority, - uint32 *stack, - uint32 stack_size, - maint_t entry, - int arg1, int arg2, int arg3, int arg4); + _TCB *tcb, + char *name, + int priority, + uint32 *stack, + uint32 stack_size, + maint_t entry, + const char *argv[]); </PRE> <P> <B>Description:</B> <P> This function initializes a Task Control Block (TCB) - in preparation for starting a new thread. + in preparation for starting a new thread. It performs a subset + of the functionality of <code>task_create()</code> (see above). </P> <P> Unlike task_create(), task_init() does not activate the task. @@ -237,7 +252,11 @@ ten). <LI><I>stack</I>. Start of the pre-allocated stack <LI><I>stack_size</I>. size (in bytes) of the pre-allocated stack <LI><I>entry</I>. Entry point of a new task - <LI><I>arg1, arg2, arg3, and arg4</I>. Four required task arguments to pass to the task + <LI><I>argv</I>. A pointer to an array of input parameters. Up to + <code>CONFIG_MAX_TASK_ARG</code> parameters may be provided. + If fewer than <code>CONFIG_MAX_TASK_ARG</code> parameters are + passed, the list should be terminated with a NULL argv[] value. + If no parameters are required, argv may be NULL. </UL> </p> <P> @@ -272,13 +291,13 @@ VxWorks provides the following similar interface: </PRE> <P> -The Nuttx task_init() differs from VxWorks' taskInit() in the +The NuttX task_init() differs from VxWorks' taskInit() in the following ways: <UL> -<LI>Function name +<LI>Interface name <LI>Various differences in types or arguments <LI>There is no options argument. -<LI>One four parameters can be passed to a task (VxWorks allows ten). +<LI>A variable number of parameters can be passed to a task (VxWorks supports ten). </UL> <H3>2.1.3 task_activate</H3> @@ -322,7 +341,7 @@ VxWorks provides the following similar interface: </PRE> <P> -The Nuttx task_activate() differs from VxWorks' taskActivate() in the +The NuttX task_activate() differs from VxWorks' taskActivate() in the following ways: <UL> <LI>Function name @@ -371,7 +390,7 @@ VxWorks provides the following similar interface: </PRE> <P> -The Nuttx task_delete() differs from VxWorks' taskDelete() in +The NuttX task_delete() differs from VxWorks' taskDelete() in the following ways: <UL> <LI>No support is provided for calling the tasks deletion routines @@ -419,7 +438,7 @@ And the unix interface: </PRE> <P> -The Nuttx exit() differs from ANSI exit() in +The NuttX exit() differs from ANSI exit() in the following ways: <UL> <LI>The <I>code</I> parameter is ignored. @@ -468,7 +487,7 @@ VxWorks provides the following similar interface: </PRE> <P> -The Nuttx task_restart() differs from VxWorks' taskRestart() in +The NuttX task_restart() differs from VxWorks' taskRestart() in the following ways: <UL> <LI>Restart of the currently running task is not supported. @@ -506,15 +525,15 @@ Compatible with the POSIX interface of the same name. <H2>2.2 <A NAME="Task_Schedule">Task Scheduling Interfaces</A></H2> <P> -Nuttx performs strict priority scheduling: Tasks of higher +NuttX performs strict priority scheduling: Tasks of higher priority have exclusive access to the CPU until they become blocked. At that time, the CPU is available to tasks of lower priority. Tasks of equal priority are scheduled FIFO. <P> The OS interfaces described in the following paragraphs provide -a POSIX- compliant interface to the Nuttx scheduler. However, these +a POSIX- compliant interface to the NuttX scheduler. However, these POSIX interfaces assume a greater range of scheduling options -than those provided by the Nuttx scheduler. As a result, many of +than those provided by the NuttX scheduler. As a result, many of these POSIX interfaces are little more than stubs. <H3>2.2.1 sched_setparam</H3> @@ -921,7 +940,7 @@ on this thread of execution. <H2>2.4 <A NAME="Message_Queue">Named Message Queue Interfaces</A></H2> <P> -The Nuttx supports POSIX named message queues for intertask communication. +The NuttX supports POSIX named message queues for intertask communication. Any task may send or receive messages on named message queues. Interrupt handlers may send messages via named message queues. @@ -1305,7 +1324,7 @@ interface of the same name. <P> <B>Semaphores</B>. Semaphores are the basis for -synchronization and mutual exclusion in Nuttx. Nuttx supports +synchronization and mutual exclusion in NuttX. NuttX supports POSIX semaphores. <P> Semaphores are the preferred mechanism for gaining exclusive access to a @@ -1336,7 +1355,7 @@ inversion</I>. <P> Some operating systems avoid priority inversion by <I>automatically</I> increasing the priority of the low-priority <I>Task C</I> (the operable -buzz-word for this behavior is <I>mutex</I> semaphores). The Nuttx does not +buzz-word for this behavior is <I>mutex</I> semaphores). The NuttX does not support this behavior. As a consequence, it is left to the designer to provide implementations that will not suffer from priority inversion. The designer may, as examples: @@ -1757,13 +1776,13 @@ interface of the same name. <H2>2.6 <A NAME="Watchdogs">Watchdog Timer Interfaces</A></H2> <P> -The Nuttx provides a general watchdog timer facility. This -facility allows the Nuttx user to specify a watchdog timer function +The NuttX provides a general watchdog timer facility. This +facility allows the NuttX user to specify a watchdog timer function that will run after a specified delay. The watchdog timer function will run in the context of the timer interrupt handler. Because -of this, a limited number of Nuttx interfaces are available to +of this, a limited number of NuttX interfaces are available to the watchdog timer function. However, the watchdog timer function -may use mq_send(), and sigqueue() to communicate with Nuttx tasks. +may use mq_send(), and sigqueue() to communicate with NuttX tasks. <H3>2.6.1 wd_create</H3> @@ -1783,7 +1802,7 @@ by allocating the appropriate resources for the watchdog. <B>Returned Values:</B> <UL> <LI>Pointer to watchdog that may be used as a handle in subsequent -Nuttx calls (i.e., the watchdog ID), or NULL if insufficient resources +NuttX calls (i.e., the watchdog ID), or NULL if insufficient resources are available to create the watchdogs. </UL> @@ -1946,7 +1965,7 @@ VxWorks provides the following comparable interface: <H2>2.7 <A NAME="Signals">Signal Interfaces</A></H2> <P> -The Nuttx provides signal interfaces for tasks. Signals are +The NuttX provides signal interfaces for tasks. Signals are used to alter the flow control of tasks by communicating asynchronous events within or between task contexts. Any task or interrupt handler can post (or send) a signal to a particular task. The @@ -3913,9 +3932,9 @@ interface of the same name. <H1>3.0 <A NAME="Data_Structures">OS Data Structures</A></H1> <H2>3.1 Scalar types</H2> <P> -Many of the types used to communicate with Nuttx are simple +Many of the types used to communicate with NuttX are simple scalar types. These types are used to provide architecture independence -of the OS from the application. The scalar types used at the Nuttx +of the OS from the application. The scalar types used at the NuttX interface include: <UL> <LI>pid_t @@ -3927,7 +3946,7 @@ interface include: <H2>3.2 Hidden Interface Structures</H2> <P> -Several of the types used to interface with Nuttx are +Several of the types used to interface with NuttX are structures that are intended to be hidden from the application. From the standpoint of the application, these structures (and structure pointers) should be treated as simple handles to reference @@ -3984,7 +4003,7 @@ in sys/types.h as: <P> This structure is used to pass scheduling priorities to and from -Nuttx; +NuttX; <PRE> struct sched_param { @@ -3996,7 +4015,7 @@ Nuttx; <P> This structure is used to pass timing information between the -Nuttx and a user application: +NuttX and a user application: <PRE> struct timespec { @@ -4009,7 +4028,7 @@ Nuttx and a user application: <P> This structure is used to communicate message queue attributes -between Nuttx and a MoBY application: +between NuttX and a MoBY application: <PRE> struct mq_attr { size_t mq_maxmsg; /* Max number of messages in queue */ diff --git a/arch/c5471/defconfig b/arch/c5471/defconfig index 91e81a952ad476f9224ae57546213e8a9609d73e..641f1ca548955451d11427956e0c08b425a417c5 100644 --- a/arch/c5471/defconfig +++ b/arch/c5471/defconfig @@ -182,6 +182,9 @@ CONFIG_RRLOAD_BINARY=y # # CONFIG_MAX_TASKS - The maximum number of simultaneously # active tasks. This value must be a power of two. +# CONFIG_MAX_TASK_ARGS - This controls the maximum number of +# of parameters that a task may receive (i.e., maxmum value +# of 'argc') # CONFIG_NPTHREAD_KEYS - The number of items of thread- # specific data that can be retained # CONFIG_NFILE_DESCRIPTORS - The maximum number of file @@ -205,6 +208,7 @@ CONFIG_RRLOAD_BINARY=y # watchdog structures to minimize dynamic allocations # CONFIG_MAX_TASKS=64 +CONFIG_MAX_TASK_ARGS=4 CONFIG_NPTHREAD_KEYS=4 CONFIG_NFILE_DESCRIPTORS=32 CONFIG_NFILE_STREAMS=16 diff --git a/arch/pjrc-8051/defconfig b/arch/pjrc-8051/defconfig index c24f0a08d703cce65230cd613b836777a53e7d30..2d722230563a001bb7e77976a9fc12a149291d8f 100644 --- a/arch/pjrc-8051/defconfig +++ b/arch/pjrc-8051/defconfig @@ -37,9 +37,11 @@ # # 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=pjrc-8051 CONFIG_ARCH_8051=y +CONFIG_8051_LEDS=n # # General OS setup @@ -142,6 +144,9 @@ CONFIG_RRLOAD_BINARY=n # # CONFIG_MAX_TASKS - The maximum number of simultaneously # actived tasks. This value must be a power of two. +# CONFIG_MAX_TASK_ARGS - This controls the maximum number of +# of parameters that a task may receive (i.e., maxmum value +# of 'argc') # CONFIG_NPTHREAD_KEYS - The number of items of thread- # specific data that can be retained # CONFIG_NFILE_DESCRIPTORS - The maximum number of file @@ -165,6 +170,7 @@ CONFIG_RRLOAD_BINARY=n # watchdog structures to minimize dynamic allocations # CONFIG_MAX_TASKS=8 +CONFIG_MAX_TASK_ARGS=4 CONFIG_NPTHREAD_KEYS=0 CONFIG_NFILE_DESCRIPTORS=0 CONFIG_NFILE_STREAMS=0 diff --git a/arch/pjrc-8051/src/Makefile b/arch/pjrc-8051/src/Makefile index b05d231f9f2ddcc89feec5d3a5de1c56b9c03f2d..628d239a2377b9b75fa1da6427803bdfc19439b1 100644 --- a/arch/pjrc-8051/src/Makefile +++ b/arch/pjrc-8051/src/Makefile @@ -48,7 +48,8 @@ CSRCS = up_initialize.c up_idle.c up_interruptcontext.c \ up_releasepending.c up_reprioritizertr.c \ up_exit.c up_assert.c up_allocateheap.c \ up_irq.c up_savecontext.c up_restorecontext.c \ - up_timerisr.c up_putc.c up_debug.c + up_timerisr.c up_putc.c up_debug.c up_leds.c \ + up_delay.c COBJS = $(CSRCS:.c=$(OBJEXT)) SRCS = $(SSRCS) $(CSRCS) OBJS = $(AOBJS) $(COBJS) @@ -64,16 +65,40 @@ LINKLIBS = LDPATHES = $(addprefix -L$(TOPDIR)/,$(dir $(LINKLIBS))) LDLIBS = $(addprefix -l,$(notdir $(LINKLIBS))) +IRAM_SIZE = 0x100 +DEF_STACK_BASE = 0x24 LDFLAGS = --model-large --nostdlib \ - --data-loc 0x30 --iram-size 0x100 \ + --data-loc $(DEF_STACK_BASE) --iram-size $(IRAM_SIZE) \ --code-loc 0x2100 --code-size 0x5f40 \ - --xram-loc 0x0100 --xram-size 0x1f00 + --xram-loc $(IRAM_SIZE) --xram-size 0x1f00 DEPSRCS = $(SRCS) $(LINKSSRCS) -HEAP1_BASE = ${shell cat pass1.mem | grep "EXTERNAL RAM" | sed -e "s/[ ][ ]*/ /g" | cut -d' ' -f5} -HEAP2_BASE = ${shell cat pass1.mem | grep "ROM/EPROM/FLASH" | sed -e "s/[ ][ ]*/ /g" | cut -d' ' -f4} -STACK_BASE = ${shell cat pass1.mem | grep "Stack starts" | cut -d' ' -f4} +HEAP1_BASE = ${shell \ + if [ -e pass1.mem ]; then \ + cat pass1.mem | grep "EXTERNAL RAM" | \ + sed -e "s/[ ][ ]*/ /g" | cut -d' ' -f5 ; \ + else \ + echo $(IRAM_SIZE) ; \ + fi \ + } +DEF_HEAP2_BASE = 0x6000 +HEAP2_BASE = ${shell \ + if [ -e pass1.mem ]; then \ + cat pass1.mem | grep "ROM/EPROM/FLASH" | \ + sed -e "s/[ ][ ]*/ /g" | cut -d' ' -f4 ; \ + else \ + echo $(DEF_HEAP2_BASE) ; \ + fi \ + } +STACK_BASE = ${shell \ + if [ -e pass1.mem ]; then \ + cat pass1.mem | grep "Stack starts" | \ + cut -d' ' -f4 ; \ + else \ + echo $(DEF_STACK_BASE) ; \ + fi \ + } all: up_head$(OBJEXT) libarch$(LIBEXT) @@ -93,19 +118,24 @@ pass1.mem: up_mem.h: pass1.mem @echo "#ifndef __ARCH_MEM_H" >up_mem.h @echo "#define __ARCH_MEM_H" >>up_mem.h - @if [ -e pass1.mem ]; then \ - echo "#define UP_STACK_BASE $(STACK_BASE)" >>up_mem.h ; \ - echo "#define UP_HEAP1_BASE $(HEAP1_BASE)" >> up_mem.h ; \ - echo "#define UP_HEAP1_END 0x2000" >> up_mem.h ; \ - echo "#define UP_HEAP2_BASE $(HEAP2_BASE)" >> up_mem.h ; \ - echo "#define UP_HEAP2_END 0x8000" >> up_mem.h ; \ - else \ - echo "#define UP_STACK_BASE 0x30" >>up_mem.h ; \ - echo "#define UP_HEAP1_BASE 0x0100" >> up_mem.h ; \ - echo "#define UP_HEAP1_END 0x2000" >> up_mem.h ; \ - echo "#define UP_HEAP2_BASE 0x6000" >> up_mem.h ; \ - echo "#define UP_HEAP2_END 0x8000" >> up_mem.h ; \ - fi + @echo "" >>up_mem.h + @echo "#define UP_DEFAULT_STACK_BASE $(DEF_STACK_BASE)" >>up_mem.h + @echo "#define UP_DEFAULT_HEAP1_BASE $(IRAM_SIZE)" >> up_mem.h + @echo "#define UP_DEFAULT_HEAP2_BASE $(DEF_HEAP2_BASE)" >> up_mem.h + @echo "" >>up_mem.h + @echo "#define UP_STACK_BASE $(STACK_BASE)" >>up_mem.h + @echo "#if UP_STACK_BASE > UP_DEFAULT_STACK_BASE" >>up_mem.h + @echo "# error \"Stack overlap: $(DEF_STACK_BASE) < $(STACK_BASE)\"" >>up_mem.h + @echo "#elif UP_STACK_BASE < UP_DEFAULT_STACK_BASE" >>up_mem.h + @echo "# warning \"Wasted stack: $(DEF_STACK_BASE) > $(STACK_BASE)\"" >>up_mem.h + @echo "#endif" >>up_mem.h + @echo "" >>up_mem.h + @echo "#define UP_HEAP1_BASE $(HEAP1_BASE)" >> up_mem.h + @echo "#define UP_HEAP1_END 0x2000" >> up_mem.h + @echo "" >>up_mem.h + @echo "#define UP_HEAP2_BASE $(HEAP2_BASE)" >> up_mem.h + @echo "#define UP_HEAP2_END 0x8000" >> up_mem.h + @echo "" >>up_mem.h @echo "#endif /* __ARCH_MEM_H */" >>up_mem.h # Combine all objects in this directory into a library diff --git a/arch/pjrc-8051/src/pjrc.h b/arch/pjrc-8051/src/pjrc.h new file mode 100644 index 0000000000000000000000000000000000000000..41f5a7e21f806a811ad757f8f1f650790945b3be --- /dev/null +++ b/arch/pjrc-8051/src/pjrc.h @@ -0,0 +1,218 @@ +/************************************************************************** + * pjrc.h + * + * 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. + * + **************************************************************************/ + +#ifndef __PJRC_H +#define __PJRC_H + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include <sys/types.h> + +/************************************************************************** + * Public Definitions + **************************************************************************/ + +/************************************************************************** + * Public Types + **************************************************************************/ + +/************************************************************************** + * Public Variables + **************************************************************************/ + +/* Memory Map + * + * BEGIN END DESCRIPTION + * 0x0000 0x1fff CODE: ROM containg PAULMON2 + * DATA: RAM for program variables + * 0x2000 0x7fff COMMON: RAM for program code or + * variables + * 0x8000 0xf7ff COMMON: FLASH for program code + * 0xf800 0xfeff COMMON: Peripherals + * 0xff00 0xffff COMMON: unused + * + * Program code may be loaded at the RAM location 0x2000-0x7fff + * for testing. If loaded into the FLASH location at + * 0x8000-0xf7ff, PAULMON2 will automatically write the program + * into flash. The program is configured in the RAM-based test + * configuration: + */ + +#define RAM_BLOCK_START IRAM_SIZE +#define RAM_BLOCK_END 0x1fff + +#define PROGRAM_BASE 0x2000 +#define PROGRAM_END 0x7fff + +#define FLASH_BASE 0x8000 +#define FLASH_END 0xf7ff + +/* Well-known entry points to access PAULMON2's built-in functions */ + +#define PM2_ENTRY_PHEX1 0x002e +#define PM2_ENTRY_COUT 0x0030 +#define PM2_ENTRY_CIN 0x0032 +#define PM2_ENTRY_PHEX 0x0034 +#define PM2_ENTRY_PHEX16 0x0036 +#define PM2_ENTRY_PSTR 0x0038 +#define PM2_ENTRY_ESC 0x003e +#define PM2_ENTRY_UPPER 0x0040 +#define PM2_ENTRY_PINT8U 0x004D +#define PM2_ENTRY_PINT8 0x0050 +#define PM2_ENTRY_PINT16U 0x0053 +#define PM2_ENTRY_NEWLINE 0x0048 +#define PM2_ENTRY_PRGM 0x0059 +#define PM2_ENTRY_ERBLOCK 0x0067 + +/* PAULMON2 captures all interrupt vectors in ROM but relays them + * through the following RAM addresses: + */ + +#define PM2_VECTOR_BASE PROGRAM_BASE +#define PM2_VECTOR_EXTINT0 (PM2_VECTOR_BASE + 3) +#define PM2_VECTOR_TIMER0 (PM2_VECTOR_BASE + 11) +#define PM2_VECTOR_EXTINT1 (PM2_VECTOR_BASE + 19) +#define PM2_VECTOR_TIMER1 (PM2_VECTOR_BASE + 27) +#define PM2_VECTOR_UART (PM2_VECTOR_BASE + 35) +#define PM2_VECTOR_TIMER2 (PM2_VECTOR_BASE + 43) + +/* Peripheral Mapping + * + * Begin End Peripheral Addr Acc Function + * F800 F8FF 82C55 (A, B, C) F800 R/W Port A + * F801 R/W Port B + * F802 R/W Port C + * F803 W Config A,B,C + * F900 F9FF 82C55 (D, E, F) F900 R/W Port D + * F901 R/W Port E (LEDs) + * F902 R/W Port F + * F903 W Config D,E,F + * FA00 FAFF User Expansion + * FB00 FBFF User Expansion + * FC00 FCFF User Expansion + * FD00 FDFF User Expansion + * FE00 FEFF LCD Port FE00 W Command Register + * FE01 R Status Register + * FE02 W Display or CGRAM Buffer + * FE03 R " " "" " " " " + * + * These are the memory-mapped locations used to access the two 82C55 + * chips + */ + +#ifndef __ASSEMBLY__ +xdata at 0xF800 ubyte p82c55_port_a; +xdata at 0xF801 ubyte p82c55_port_b; +xdata at 0xF802 ubyte p82c55_port_c; +xdata at 0xF803 ubyte p82c55_abc_config; +xdata at 0xF900 ubyte p82c55_port_d; +xdata at 0xF901 ubyte p82c55_port_e; +xdata at 0xF902 ubyte p82c55_port_f; +xdata at 0xF903 ubyte p82c55_def_config; +#endif + +/* LED (Port E) bit definitions */ + +#define LED_STARTED 0 +#define LED_HEAPALLOCATE 1 +#define LED_IRQSENABLED 2 +#define LED_UNUSED1 3 +#define LED_UNUSED2 4 +#define LED_INIRQ 5 +#define LED_ASSERTION 6 +#define LED_PANIC 7 + +/* Registers. 8052 regiser definitions are provided in the SDCC header + * file 8052.h. However, a few SFR registers are missing from that + * file (they can be found in mcs51reg.h, but that file is too much + * when the following simple addtions do the job). + */ + +#ifndef __ASSEMBLY__ +sfr at 0xc9 T2MOD ; +#endif + +/* Timing information. + * + * The PJRC board is based on a standard 87C52 CPU clocked at 22.1184 MHz. + * The CPU clock is divided by 12 to yield a clock frequency of 1.8432 MHz. + */ + +#define CPU_CLOCK_HZ 22118400L +#define TIMER_CLOCK_HZ 1843200L + +/* The 87C52 has three timers, timer 0, timer 1, and timer 2. On the PJRC + * board, timer 1 and 2 have dedicated functions. They provide baud support + * support for the boards two serial ports. Unfortunately, only timer 2 + * can generate the accurate 100Hz timer desired by the OS. + * + * Timer 0 provides only a 8-bit auto-reload mode. + */ + +#define CONFIG_80C52_TIMER2 1 +#ifdef CONFIG_80C52_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 + * is given by: + * + * Timer ticks = TIMER_CLOCK_HZ / (desired ticks-per-second) + * = 18432 + * Capture value = 0xffff - (Timer ticks) + * = 47103 = 0x67ff + */ + +# define TIMER2_CAPTURE_LOW 0xff +# define TIMER2_CAPTURE_HIGH 0x67 + +#else + +/* Timer 0, mode 0 can be used as a system timer. In that mode, the + * 1.8432 is further divided by 32. A single 8-bit value is incremented + * at 57600 Hz, which results in 225 Timer 0 overflow interrupts per + * second. + */ + +# warning "No support for timer 0 as the system timer" + +#endif + +/************************************************************************** + * Public Function Prototypes + **************************************************************************/ + +#endif /* __PJRC_H */ diff --git a/arch/pjrc-8051/src/up_allocateheap.c b/arch/pjrc-8051/src/up_allocateheap.c index bdbe464b4a11e1dae81e8774a901fc23d582ef55..745cadb60853e9ff3cd995770be581c26cb7baca 100644 --- a/arch/pjrc-8051/src/up_allocateheap.c +++ b/arch/pjrc-8051/src/up_allocateheap.c @@ -77,6 +77,7 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size) { *heap_start = (FAR void*)UP_HEAP1_BASE; *heap_size = UP_HEAP1_END - UP_HEAP1_BASE; + up_ledon(LED_HEAPALLOCATE); } #if CONFIG_MM_REGIONS > 1 diff --git a/arch/pjrc-8051/src/up_assert.c b/arch/pjrc-8051/src/up_assert.c index 277494c429204ddd487dbeff8c5f4f9170fd2b67..6fc77bec9ef421582c1eceac465d2891df56167a 100644 --- a/arch/pjrc-8051/src/up_assert.c +++ b/arch/pjrc-8051/src/up_assert.c @@ -41,8 +41,10 @@ #include <sys/types.h> #include <stdlib.h> #include <assert.h> +#include <sched.h> #include <debug.h> #include <8052.h> +#include "os_internal.h" #include "up_internal.h" #include "up_mem.h" @@ -58,6 +60,33 @@ * Private Functions ************************************************************/ +/************************************************************ + * Name: _up_assert + ************************************************************/ + +static void _up_assert(int errorcode) /* __attribute__ ((noreturn)) */ +{ + /* Are we in an interrupt handler or the idle task? */ + + if (g_irqtos || ((FAR _TCB*)g_readytorun.head)->pid == 0) + { + (void)irqsave(); + for(;;) + { +#ifdef CONFIG_8051_LEDS + up_ledon(LED_PANIC); + up_delay(250); + up_ledoff(LED_PANIC); + up_delay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + /************************************************************ * Public Functions ************************************************************/ @@ -68,9 +97,20 @@ void up_assert(void) { - dbg("Assertion failed\n"); +#if CONFIG_TASK_NAME_SIZE > 0 + _TCB *rtcb = (_TCB*)g_readytorun.head; +#endif + + up_ledon(LED_ASSERTION); + +#if CONFIG_TASK_NAME_SIZE > 0 + lldbg("%s: Assertion failed\n", rtcb->name); +#else + lldbg("Assertion failed\n"); +#endif + up_dumpstack(); - exit(EXIT_FAILURE); + _up_assert(EXIT_FAILURE); } /************************************************************ @@ -79,7 +119,18 @@ void up_assert(void) void up_assert_code(int errorcode) { - dbg("Assertion failed with error code: %d\n", errorcode); +#if CONFIG_TASK_NAME_SIZE > 0 + _TCB *rtcb = (_TCB*)g_readytorun.head; +#endif + + up_ledon(LED_ASSERTION); + +#if CONFIG_TASK_NAME_SIZE > 0 + lldbg("%s: Assertion failed, error=%d\n", rtcb->name, errorcode); +#else + lldbg("Assertion failed , error=%d\n", errorcode); +#endif + up_dumpstack(); - exit(errorcode); + _up_assert(errorcode); } diff --git a/arch/pjrc-8051/src/up_delay.c b/arch/pjrc-8051/src/up_delay.c new file mode 100644 index 0000000000000000000000000000000000000000..7b682033f606100961f91eb8c1d3770d3fc5325e --- /dev/null +++ b/arch/pjrc-8051/src/up_delay.c @@ -0,0 +1,92 @@ +/************************************************************ + * up_delay.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 "up_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Types + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + + +/************************************************************ + * Public Funtions + ************************************************************/ + +/************************************************************ + * Name: up_delay + * + * Description: + * Delay inline for the requested number of milliseconds. + * NOT multi-tasking friendly. + * + ************************************************************/ + +void up_delay(ubyte milliseconds) __naked +{ + _asm + mov r0, dpl +00001$: mov r1, #230 +00002$: nop + nop + nop + nop + nop + nop + djnz r1, 00002$ + djnz r0, 00001$ + ret + _endasm; +} diff --git a/arch/pjrc-8051/src/up_head.S b/arch/pjrc-8051/src/up_head.S index 35acea2dbf3cdebfaf0d7349a496b64e04637da7..33d9db3ddf918ee1b5f7b02b710338c2b1b5109d 100644 --- a/arch/pjrc-8051/src/up_head.S +++ b/arch/pjrc-8051/src/up_head.S @@ -37,6 +37,7 @@ * Included Files ************************************************************/ +#include <nuttx/config.h> #include <nuttx/irq.h> #include "up_internal.h" @@ -123,6 +124,11 @@ start: mov sp, #(STACK_BASE-1) + +#ifdef CONFIG_8051_LEDS + lcall _up_ledinit +#endif + ljmp _os_start /************************************************************ @@ -170,8 +176,14 @@ _up_interrupt: /* Save the IRQ number in r3 */ +#ifdef CONFIG_8051_LEDS + push acc + mov dpl, #LED_INIRQ + lcall _up_ledon + pop ar2 +#else mov r2, a - +#endif /* Mark that we are in an interrupt and provide the top * of stack pointer to the context switching logic. */ @@ -229,7 +241,7 @@ _up_interrupt: orl a, r2 jz 00003$ - /* A conext switch is pending Clear g_irqcontext */ + /* A context switch is pending, clear g_irqcontext */ mov dpl, r2 mov dph, r3 @@ -319,6 +331,10 @@ _up_interrupt: */ 00003$: +#ifdef CONFIG_8051_LEDS + mov dpl, #LED_INIRQ + lcall _up_ledoff +#endif pop _bp pop psw pop ar1 diff --git a/arch/pjrc-8051/src/up_initialize.c b/arch/pjrc-8051/src/up_initialize.c index c8f2ef01d9c4667276a6cd80216a89453e78adf3..d0680b6cf3059f10f540d7a23f85de0321dc3ded 100644 --- a/arch/pjrc-8051/src/up_initialize.c +++ b/arch/pjrc-8051/src/up_initialize.c @@ -119,6 +119,6 @@ void up_initialize(void) up_timerinit(); #endif - /* Initialize the serial console support */ + up_ledon(LED_IRQSENABLED); } diff --git a/arch/pjrc-8051/src/up_internal.h b/arch/pjrc-8051/src/up_internal.h index 8f27179cb2132a797163e4001a4d3a7f4c06e8d2..95fb9774524104b0db8e4d3cbb8f897c0e34e8f9 100644 --- a/arch/pjrc-8051/src/up_internal.h +++ b/arch/pjrc-8051/src/up_internal.h @@ -40,6 +40,8 @@ * Included Files **************************************************************************/ +#include "pjrc.h" + /************************************************************************** * Public Definitions **************************************************************************/ @@ -51,113 +53,6 @@ #define CONFIG_SWITCH_FRAME_DUMP 1 /* Dump frames from normal switches */ #undef CONFIG_INTERRUPT_FRAME_DUMP /* Dump frames from interrupt switches */ -/* Memory Map - * - * BEGIN END DESCRIPTION - * 0x0000 0x1fff CODE: ROM containg PAULMON2 - * DATA: RAM for program variables - * 0x2000 0x7fff COMMON: RAM for program code or - * variables - * 0x8000 0xf7ff COMMON: FLASH for program code - * 0xf800 0xfeff COMMON: Peripherals - * 0xff00 0xffff COMMON: unused - * - * Program code may be loaded at the RAM location 0x2000-0x7fff - * for testing. If loaded into the FLASH location at - * 0x8000-0xf7ff, PAULMON2 will automatically write the program - * into flash. The program is configured in the RAM-based test - * configuration: - */ - -#define RAM_BLOCK_START IRAM_SIZE -#define RAM_BLOCK_END 0x1fff - -#define PROGRAM_BASE 0x2000 -#define PROGRAM_END 0x7fff - -#define FLASH_BASE 0x8000 -#define FLASH_END 0xf7ff - -/* Well-known entry points to access PAULMON2's built-in functions */ - -#define PM2_ENTRY_PHEX1 0x002e -#define PM2_ENTRY_COUT 0x0030 -#define PM2_ENTRY_CIN 0x0032 -#define PM2_ENTRY_PHEX 0x0034 -#define PM2_ENTRY_PHEX16 0x0036 -#define PM2_ENTRY_PSTR 0x0038 -#define PM2_ENTRY_ESC 0x003e -#define PM2_ENTRY_UPPER 0x0040 -#define PM2_ENTRY_PINT8U 0x004D -#define PM2_ENTRY_PINT8 0x0050 -#define PM2_ENTRY_PINT16U 0x0053 -#define PM2_ENTRY_NEWLINE 0x0048 -#define PM2_ENTRY_PRGM 0x0059 -#define PM2_ENTRY_ERBLOCK 0x0067 - -#define PM2_VECTOR_BASE PROGRAM_BASE -#define PM2_VECTOR_EXTINT0 (PM2_VECTOR_BASE + 3) -#define PM2_VECTOR_TIMER0 (PM2_VECTOR_BASE + 11) -#define PM2_VECTOR_EXTINT1 (PM2_VECTOR_BASE + 19) -#define PM2_VECTOR_TIMER1 (PM2_VECTOR_BASE + 27) -#define PM2_VECTOR_UART (PM2_VECTOR_BASE + 35) -#define PM2_VECTOR_TIMER2 (PM2_VECTOR_BASE + 43) - -/* Registers. 8052 regiser definitions are provided in the SDCC header - * file 8052.h. However, a few SFR registers are missing from that - * file (they can be found in mcs51reg.h, but that file is too much - * when the following simple addtions do the job). - */ - -#ifndef __ASSEMBLY__ -sfr at 0xc9 T2MOD ; -#endif - -/* Timing information. - * - * The PJRC board is based on a standard 87C52 CPU clocked at 22.1184 MHz. - * The CPU clock is divided by 12 to yield a clock frequency of 1.8432 MHz. - */ - -#define CPU_CLOCK_HZ 22118400L -#define TIMER_CLOCK_HZ 1843200L - -/* The 87C52 has three timers, timer 0, timer 1, and timer 2. On the PJRC - * board, timer 1 and 2 have dedicated functions. They provide baud support - * support for the boards two serial ports. Unfortunately, only timer 2 - * can generate the accurate 100Hz timer desired by the OS. - * - * Timer 0 provides only a 8-bit auto-reload mode. - */ - -#define CONFIG_80C52_TIMER2 1 -#ifdef CONFIG_80C52_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 - * is given by: - * - * Timer ticks = TIMER_CLOCK_HZ / (desired ticks-per-second) - * = 18432 - * Capture value = 0xffff - (Timer ticks) - * = 47103 = 0x67ff - */ - -# define TIMER2_CAPTURE_LOW 0xff -# define TIMER2_CAPTURE_HIGH 0x67 - -#else - -/* Timer 0, mode 0 can be used as a system timer. In that mode, the - * 1.8432 is further divided by 32. A single 8-bit value is incremented - * at 57600 Hz, which results in 225 Timer 0 overflow interrupts per - * second. - */ - -# warning "No support for timer 0 as the system timer" - -#endif - /************************************************************************** * Public Types **************************************************************************/ @@ -197,12 +92,15 @@ extern FAR struct xcptcontext *g_irqcontext; #if CONFIG_MM_REGIONS > 1 extern void up_addregion(void); #endif +extern void up_delay(ubyte milliseconds) __naked; extern void up_irqinitialize(void); extern void up_restorecontext(FAR struct xcptcontext *context) _naked; extern ubyte up_savecontext(FAR struct xcptcontext *context) __naked; extern void up_savestack(FAR struct xcptcontext *context, ubyte tos); extern void up_timerinit(void); +/* Defined in up_assert.c */ + #ifdef CONFIG_FRAME_DUMP extern void up_dumpstack(void); extern void up_dumpframe(FAR struct xcptcontext *context); @@ -211,5 +109,17 @@ extern void up_dumpframe(FAR struct xcptcontext *context); # define up_dumpframe(x) #endif +/* Defined in up_leds.c */ + +#ifdef CONFIG_8051_LEDS +extern void up_ledinit(void); +extern void up_ledon(int led); +extern void up_ledoff(int led); +#else +# define up_ledinit() +# define up_ledon(led) +# define up_ledoff(led) +#endif + #endif /* __ASSEMBLY */ #endif /* __ARCH_UP_INTERNAL_H */ diff --git a/arch/pjrc-8051/src/up_leds.c b/arch/pjrc-8051/src/up_leds.c new file mode 100644 index 0000000000000000000000000000000000000000..2c124360166999f2fa85d384dcdd5a87ae54240d --- /dev/null +++ b/arch/pjrc-8051/src/up_leds.c @@ -0,0 +1,105 @@ +/************************************************************ + * up_leds.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 "up_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Data + ************************************************************/ + +static uint32 g_ledstate; + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Funtions + ************************************************************/ + +/************************************************************ + * Name: up_ledinit + ************************************************************/ + +#ifdef CONFIG_8051_LEDS +void up_ledinit(void) +{ + /* Set all ports as outputs */ + + p82c55_abc_config = 128; + p82c55_def_config = 128; + + /* Turn LED 1-7 off; turn LED 0 on */ + + g_ledstate = 0x000000fe; + p82c55_port_e = g_ledstate; +} + +/************************************************************ + * Name: up_ledon + ************************************************************/ + +void up_ledon(int led) +{ + if (led < 8) + { + g_ledstate &= ~(1 << led); + p82c55_port_e = g_ledstate; + } +} + +/************************************************************ + * Name: up_ledoff + ************************************************************/ + +void up_ledoff(int led) +{ + if (led < 8) + { + g_ledstate |= (1 << led); + p82c55_port_e = g_ledstate; + } +} +#endif /* CONFIG_8051_LEDS */ diff --git a/arch/sim/defconfig b/arch/sim/defconfig index 1dbd2365df4fc9bc3d1a59c65ad8193841ca6e5f..7ec6f01d35eba4adc27e1e7f6c49ee543d080520 100644 --- a/arch/sim/defconfig +++ b/arch/sim/defconfig @@ -142,6 +142,9 @@ CONFIG_RRLOAD_BINARY=n # # CONFIG_MAX_TASKS - The maximum number of simultaneously # active tasks. This value must be a power of two. +# CONFIG_MAX_TASK_ARGS - This controls the maximum number of +# of parameters that a task may receive (i.e., maxmum value +# of 'argc') # CONFIG_NPTHREAD_KEYS - The number of items of thread- # specific data that can be retained # CONFIG_NFILE_DESCRIPTORS - The maximum number of file @@ -165,6 +168,7 @@ CONFIG_RRLOAD_BINARY=n # watchdog structures to minimize dynamic allocations # CONFIG_MAX_TASKS=64 +CONFIG_MAX_TASK_ARGS=4 CONFIG_NPTHREAD_KEYS=4 CONFIG_NFILE_DESCRIPTORS=32 CONFIG_NFILE_STREAMS=16 diff --git a/arch/sim/src/up_usestack.c b/arch/sim/src/up_usestack.c index 0c6e7650f3db6dd65fd38df75cabb9f3bfe7c48e..ca1c2ac535c45d8b904e5a26832829a06f3a9f75 100644 --- a/arch/sim/src/up_usestack.c +++ b/arch/sim/src/up_usestack.c @@ -90,7 +90,7 @@ STATUS up_use_stack(_TCB *tcb, void *stack, size_t stack_size) /* This is the address of the last word in the allocation */ - size_t *adj_stack_ptr = &stack[adj_stack_words - 1]; + size_t *adj_stack_ptr = &((size_t*)stack)[adj_stack_words - 1]; /* Save the values in the TCB */ diff --git a/examples/nsh/nsh_main.c b/examples/nsh/nsh_main.c index aa98a4e74021106f10654cc1f32dd72f19d4aef4..4135b28282491972b2d39472c663c1a109d220c1 100644 --- a/examples/nsh/nsh_main.c +++ b/examples/nsh/nsh_main.c @@ -233,7 +233,7 @@ static void ps_task(FAR _TCB *tcb, FAR void *arg) g_statenames[tcb->task_state]); printf("%s(", tcb->argv[0]); - for (i = 1; i < NUM_TASK_ARGS+1 && tcb->argv[i]; i++) + for (i = 1; i < CONFIG_MAX_TASK_ARGS+1 && tcb->argv[i]; i++) { if (needcomma) { @@ -283,7 +283,7 @@ void user_initialize(void) * Name: user_start ************************************************************/ -int user_start(int parm1, int parm2, int parm3, int parm4) +int user_start(int argc, char *argv[]) { printf("NuttShell (NSH)\n"); fflush(stdout); diff --git a/examples/ostest/main.c b/examples/ostest/main.c index 10f4ac2c65566a185e17155ddee6bd3a572d3f6e..c68aaee89437e27609123a7a98ffaa28ae38d011 100644 --- a/examples/ostest/main.c +++ b/examples/ostest/main.c @@ -68,7 +68,7 @@ static FAR char arg4[] = "Arg4"; static char write_data1[] = "Standard I/O Check: write fd=1\n"; static char write_data2[] = "Standard I/O Check: write fd=2\n"; #endif -static char *args[NARGS] = { arg1, arg2, arg3, arg4 }; +static const char *g_argv[NARGS] = { arg1, arg2, arg3, arg4 }; /************************************************************ * Private Functions @@ -90,15 +90,15 @@ static int user_main(int argc, char *argv[]) for (i = 0; i <= NARGS; i++) { - printf("user_main: argv[%d]=\"%s\"\n", i, argv[i]); + printf("user_main: argv[%d]=\"%s\"\n", i, (FAR char*)argv[i]); } for (i = 1; i <= NARGS; i++) { - if (strcmp(argv[i], args[i-1]) != 0) + if (strcmp(argv[i], g_argv[i-1]) != 0) { printf("user_main: ERROR argv[%d]: Expected \"%s\" found \"%s\"\n", - i, argv[i], args[i-1]); + i, g_argv[i-1], argv[i]); } } @@ -171,7 +171,7 @@ void user_initialize(void) * user_start ************************************************************/ -int user_start(int parm1, int parm2, int parm3, int parm4) +int user_start(int argc, char *argv[]) { int result; @@ -192,11 +192,9 @@ int user_start(int parm1, int parm2, int parm3, int parm4) /* Verify that we can spawn a new task */ #ifndef CONFIG_CUSTOM_STACK - result = task_create("ostest", PRIORITY, STACKSIZE, user_main, - arg1, arg2, arg3, arg4); + result = task_create("ostest", PRIORITY, STACKSIZE, user_main, g_argv); #else - result = task_create("ostest", PRIORITY, user_main, - arg1, arg2, arg3, arg4); + result = task_create("ostest", PRIORITY, user_main, g_argv); #endif if (result == ERROR) { diff --git a/examples/ostest/sighand.c b/examples/ostest/sighand.c index b5b1ad806c8632252879a938a1738b8cefe5e65f..4ea55661215c9434c31d661aaadf9b2fccb00fb7 100644 --- a/examples/ostest/sighand.c +++ b/examples/ostest/sighand.c @@ -209,7 +209,7 @@ void sighand_test(void) } waiterpid = task_create("waiter", param.sched_priority, - PTHREAD_STACK_DEFAULT, waiter_main, 0, 0, 0, 0); + PTHREAD_STACK_DEFAULT, waiter_main, NULL); if (waiterpid == ERROR) { printf("sighand_test: ERROR failed to start waiter_main\n" ); diff --git a/include/nuttx/os_external.h b/include/nuttx/os_external.h index 09557595c0e3c94bcdac078518aa108f0893b9dc..48ee8e4402cfbb2abf05d2e108b5c3aafc0248b9 100644 --- a/include/nuttx/os_external.h +++ b/include/nuttx/os_external.h @@ -67,7 +67,7 @@ extern "C" { /* These are functions that must be supplied by the application */ EXTERN void weak_function user_initialize(void); -EXTERN int user_start(int parm1, int parm2, int parm3, int parm4); +EXTERN int user_start(int argc, char *argv[]); /* Functions contained in os_task.c *************************/ diff --git a/include/sched.h b/include/sched.h index 12cc290467a8399b3999f46ea9a940f9907d2643..39945c69c8c32ec765c6134391f07b43d159be96 100644 --- a/include/sched.h +++ b/include/sched.h @@ -55,14 +55,6 @@ /* Task Management Definitins *******************************/ -/* This is the number of arguments that are passed to tasks - * on start-up. This number was selected because this is the - * number of parameters that can be passed to a MIPS function - * in registers - . */ - -#define NUM_TASK_ARGS 4 - /* This is the maximum number of times that a lock can be set */ #define MAX_LOCK_COUNT 127 @@ -186,7 +178,7 @@ struct _TCB /* Values needed to restart a task **********************************/ ubyte init_priority; /* Initial priority of the task */ - FAR char *argv[NUM_TASK_ARGS+1]; /* Name + start-up parameters */ + char *argv[CONFIG_MAX_TASK_ARGS+1]; /* Name+start-up parameters */ /* Stack-Related Fields *********************************************/ @@ -278,24 +270,19 @@ extern "C" { #ifndef CONFIG_CUSTOM_STACK EXTERN STATUS task_init(FAR _TCB *tcb, const char *name, int priority, - FAR uint32 *stack, uint32 stack_size, main_t entry, - FAR char *arg1, FAR char *arg2, - FAR char *arg3, FAR char *arg4); + FAR uint32 *stack, uint32 stack_size, + main_t entry, char *argv[]); #else EXTERN STATUS task_init(FAR _TCB *tcb, const char *name, int priority, - main_t entry, - FAR char *arg1, FAR char *arg2, - FAR char *arg3, FAR char *arg4); + main_t entry, char *argv[]); #endif EXTERN STATUS task_activate(FAR _TCB *tcb); #ifndef CONFIG_CUSTOM_STACK -EXTERN int task_create(const char *name, int priority, int stack_size, main_t main, - FAR char *arg1, FAR char *arg2, - FAR char *arg3, FAR char *arg4); +EXTERN int task_create(const char *name, int priority, int stack_size, + main_t entry, char *argv[]); #else -EXTERN int task_create(const char *name, int priority, main_t main, - FAR char *arg1, FAR char *arg2, - FAR char *arg3, FAR char *arg4); +EXTERN int task_create(const char *name, int priority, + main_t entry, char *argv[]); #endif EXTERN STATUS task_delete(pid_t pid); EXTERN STATUS task_restart(pid_t pid); diff --git a/lib/lib_fgets.c b/lib/lib_fgets.c index 3076859f0039e4353df17af750cff6e68d20c032..27f9ecdcd46289de7fb4459faaa6441a12f86ef1 100644 --- a/lib/lib_fgets.c +++ b/lib/lib_fgets.c @@ -42,6 +42,8 @@ #include <ctype.h> #include <debug.h> +#if CONFIG_NFILE_STREAMS > 0 + /************************************************************ * Definitions ************************************************************/ @@ -71,24 +73,16 @@ ************************************************************/ /************************************************************ - * Global Function Prototypes + * Public Data ************************************************************/ /************************************************************ - * Global Constant Data + * Private Data ************************************************************/ -/************************************************************ - * Global Variables - ************************************************************/ +/* <esc>[K is the VT100 command erases to the end of the line. */ -/************************************************************ - * Private Constant Data - ************************************************************/ - -/************************************************************ - * Private Variables - ************************************************************/ +static const char g_erasetoeol[] = "\033[K"; /************************************************************ * Private Functions @@ -122,7 +116,7 @@ static inline void _lib_consoleputc(int ch) ************************************************************/ #ifdef CONFIG_FGETS_ECHO -static inline void _lib_consoleputs(char *s) +static inline void _lib_consoleputs(const char *s) { (void)write(1, s, strlen(s)); } @@ -182,7 +176,7 @@ char *fgets(FAR char *s, int n, FILE *stream) if (console) { - _lib_consoleputs("\033[K"); + _lib_consoleputs(g_erasetoeol); } #endif @@ -239,6 +233,7 @@ char *fgets(FAR char *s, int n, FILE *stream) /* Echo the backspace character on the console */ _lib_consoleputc(ch); + _lib_consoleputs(g_erasetoeol); } #endif } @@ -324,3 +319,5 @@ char *fgets(FAR char *s, int n, FILE *stream) } } + +#endif /* CONFIG_NFILE_STREAMS */ diff --git a/lib/lib_gets.c b/lib/lib_gets.c index 8574a6691e8bebe034941f7b0e05062780cabfa6..db2145cfa7b4948997139ff028df45837635cbe0 100644 --- a/lib/lib_gets.c +++ b/lib/lib_gets.c @@ -41,6 +41,8 @@ #include <limits.h> #include <string.h> +#if CONFIG_NFILE_STREAMS > 0 + /************************************************************ * Definitions ************************************************************/ @@ -120,3 +122,5 @@ char *gets(char *s) } return ret; } + +#endif /* CONFIG_NFILE_STREAMS */ diff --git a/mm/mm_initialize.c b/mm/mm_initialize.c index 65be6a4b7ac1ed1ba9d80e913d5fa5b631fab51d..ff02cd59c84aae5aaa9562b424d7ca5c70425d39 100644 --- a/mm/mm_initialize.c +++ b/mm/mm_initialize.c @@ -92,9 +92,6 @@ FAR struct mm_freenode_s g_nodelist[MM_NNODES]; void mm_initialize(FAR void *heapstart, size_t heapsize) { - FAR struct mm_freenode_s *node; - size_t heapbase; - size_t heapend; int i; CHECK_ALLOCNODE_SIZE; diff --git a/sched/os_internal.h b/sched/os_internal.h index 26a709a99add204f11f7e9f3883c4280b51861f3..222e0ba880860b13587aaceffadf6da671c5ba9f 100644 --- a/sched/os_internal.h +++ b/sched/os_internal.h @@ -241,10 +241,8 @@ extern const tasklist_t g_tasklisttable[NUM_TASK_STATES]; extern void task_start(void); extern STATUS _task_init(FAR _TCB *tcb, const char *name, int priority, - start_t start, main_t main, - boolean pthread, - FAR char *arg1, FAR char *arg2, - FAR char *arg3, FAR char *arg4); + start_t start, main_t main, boolean pthread, + char *argv[]); extern boolean sched_addreadytorun(FAR _TCB *rtrtcb); extern boolean sched_removereadytorun(FAR _TCB *rtrtcb); diff --git a/sched/os_start.c b/sched/os_start.c index 18b8945ee05c05ed12883451b9f3039d31862acf..9036f17bda7a4858d8c4a58b36ab84eda54406aa 100644 --- a/sched/os_start.c +++ b/sched/os_start.c @@ -408,10 +408,10 @@ void os_start(void) #ifndef CONFIG_CUSTOM_STACK init_taskid = task_create("init", SCHED_PRIORITY_DEFAULT, CONFIG_PROC_STACK_SIZE, - (main_t)user_start, 0, 0, 0, 0); + (main_t)user_start, (char **)NULL); #else init_taskid = task_create("init", SCHED_PRIORITY_DEFAULT, - (main_t)user_start, 0, 0, 0, 0); + (main_t)user_start, (char **)NULL); #endif ASSERT(init_taskid != ERROR); diff --git a/sched/pthread_create.c b/sched/pthread_create.c index ebf212516a1ec4e99bc5dcabe17c6a98f7096f23..72a5b4a81306b0011504767c04ff0ed8881337c9 100644 --- a/sched/pthread_create.c +++ b/sched/pthread_create.c @@ -178,6 +178,7 @@ int pthread_create(pthread_t *thread, pthread_attr_t *attr, FAR _TCB *ptcb; FAR join_t *pjoin; STATUS status; + char *argv[2]; int priority; #if CONFIG_RR_INTERVAL > 0 int policy; @@ -269,8 +270,10 @@ int pthread_create(pthread_t *thread, pthread_attr_t *attr, /* Initialize the task */ - status = _task_init(ptcb, NULL, priority, pthread_start, (main_t)startRoutine, - TRUE, (FAR char*)arg, NULL, NULL, NULL); + argv[0] = (char *)arg; + argv[1] = NULL; + status = _task_init(ptcb, NULL, priority, pthread_start, + (main_t)startRoutine, TRUE, argv); if (status != OK) { diff --git a/sched/sched_foreach.c b/sched/sched_foreach.c index f1c1dc05c003e4307cb24c1149090a887ff37259..f662846857beeb9b0639b4d925b733c554c7c7c1 100644 --- a/sched/sched_foreach.c +++ b/sched/sched_foreach.c @@ -65,7 +65,6 @@ void sched_foreach(sched_foreach_t handler, FAR void *arg) { - FAR _TCB *tcb; irqstate_t flags = irqsave(); int ndx; diff --git a/sched/sched_releasetcb.c b/sched/sched_releasetcb.c index 6415fba2b70f309cc15c7f4468145352b49706f8..e37e2bab32b2d91db474c198ecf61264e22df86b 100644 --- a/sched/sched_releasetcb.c +++ b/sched/sched_releasetcb.c @@ -123,9 +123,9 @@ int sched_releasetcb(FAR _TCB *tcb) if ((tcb->flags & TCB_FLAG_PTHREAD) == 0) { - for (i = 1; i < NUM_TASK_ARGS+1 && tcb->argv[i]; i++) + for (i = 1; i < CONFIG_MAX_TASK_ARGS+1 && tcb->argv[i]; i++) { - sched_free(tcb->argv[i]); + sched_free((FAR void*)tcb->argv[i]); } } diff --git a/sched/sched_setuptaskfiles.c b/sched/sched_setuptaskfiles.c index 25275e89b6682929813be693477521a663faced4..2aee2e3d1f8aa8f4ead9169aed6de4dbbec2c963 100644 --- a/sched/sched_setuptaskfiles.c +++ b/sched/sched_setuptaskfiles.c @@ -99,7 +99,7 @@ int sched_setuptaskfiles(FAR _TCB *tcb) } #if CONFIG_NFILE_STREAMS > 0 - /* Allocate file strems for the TCB */ + /* Allocate file streams for the TCB */ return sched_setupstreams(tcb); #else diff --git a/sched/task_create.c b/sched/task_create.c index 7b73c15fa79255a46fe53d3e5e97eb350d80cb69..70e220fddcc1c9a48a88b19b0a4f09b8eca0a617 100644 --- a/sched/task_create.c +++ b/sched/task_create.c @@ -170,7 +170,7 @@ void task_start(void) /* Count how many non-null arguments we are passing */ - for (argc = 1; argc <= NUM_TASK_ARGS; argc++) + for (argc = 1; argc <= CONFIG_MAX_TASK_ARGS; argc++) { /* The first non-null argument terminates the list */ @@ -212,8 +212,12 @@ void task_start(void) * entry - Entry point of a new task * main - Application start point of the new task * pthread - TRUE is the task emulates pthread behavior - * arg1-4 - Four required task arguments to pass to - * the task when it is started. + * 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 on success; ERROR on failure. @@ -225,10 +229,10 @@ void task_start(void) STATUS _task_init(FAR _TCB *tcb, const char *name, int priority, start_t start, main_t main, boolean pthread, - FAR char *arg1, FAR char *arg2, - FAR char *arg3, FAR char *arg4) + char *argv[]) { STATUS ret; + int i; /* Assign a unique task ID to the task. */ @@ -273,23 +277,16 @@ STATUS _task_init(FAR _TCB *tcb, const char *name, int priority, if (!pthread) { /* The first NULL argument terminates the list of - * arguments. + * arguments. The argv pointer may be NULL if no + * parameters are passed. */ - if (arg1) + i = 1; + if (argv) { - tcb->argv[1] = strdup(arg1); - if (arg2) + for (; i < CONFIG_MAX_TASK_ARGS+1 && argv[i-1]; i++) { - tcb->argv[2] = strdup(arg2); - if (arg3) - { - tcb->argv[3] = strdup(arg3); - if (arg4) - { - tcb->argv[4] = strdup(arg4); - } - } + tcb->argv[i] = strdup(argv[i-1]); } } } @@ -299,14 +296,20 @@ STATUS _task_init(FAR _TCB *tcb, const char *name, int priority, tcb->flags |= TCB_FLAG_PTHREAD; - /* And just copy the argument. (For pthreads, there - * is really only a single argument, arg1). + /* And just copy the argument. For pthreads, there + * is really only a single argument, argv[0]. It is + * copy as a value -- NOT duplicated. */ - tcb->argv[1] = arg1; - tcb->argv[2] = arg2; - tcb->argv[3] = arg3; - tcb->argv[4] = arg4; + i = 2; + tcb->argv[1] = argv[0]; + } + + /* Nullify any unused argument storage */ + + for (; i < CONFIG_MAX_TASK_ARGS+1; i++) + { + tcb->argv[i] = NULL; } /* Initialize other (non-zero) elements of the TCB */ @@ -409,14 +412,10 @@ STATUS task_activate(FAR _TCB *tcb) #ifndef CONFIG_CUSTOM_STACK int task_create(const char *name, int priority, - int stack_size, main_t entry, - FAR char *arg1, FAR char *arg2, - FAR char *arg3, FAR char *arg4) + int stack_size, main_t entry, char *argv[]) #else int task_create(const char *name, int priority, - main_t entry, - FAR char *arg1, FAR char *arg2, - FAR char *arg3, FAR char *arg4) + main_t entry, char *argv[]) #endif { FAR _TCB *tcb; @@ -454,7 +453,7 @@ int task_create(const char *name, int priority, /* Initialize the task control block */ status = _task_init(tcb, name, priority, task_start, entry, - FALSE, arg1, arg2, arg3, arg4); + FALSE, argv); if (status != OK) { sched_releasetcb(tcb); diff --git a/sched/task_init.c b/sched/task_init.c index 17596378b047d771e4943c264a868c3cadd22c85..b603ddc805130fe67f12855ba6429c82ce0daf01 100644 --- a/sched/task_init.c +++ b/sched/task_init.c @@ -39,6 +39,7 @@ #include <sys/types.h> #include <sched.h> +#include <nuttx/arch.h> #include "os_internal.h" /************************************************************ @@ -94,21 +95,18 @@ #ifndef CONFIG_CUSTOM_STACK STATUS task_init(FAR _TCB *tcb, const char *name, int priority, - FAR uint32 *stack, uint32 stack_size, main_t entry, - FAR char *arg1, FAR char *arg2, - FAR char *arg3, FAR char *arg4) + FAR uint32 *stack, uint32 stack_size, + main_t entry, char *argv[]) { up_use_stack(tcb, stack, stack_size); return _task_init(tcb, name, priority, task_start, entry, - FALSE, arg1, arg2, arg3, arg4); + FALSE, argv); } #else STATUS task_init(FAR _TCB *tcb, const char *name, int priority, - main_t entry, - FAR char *arg1, FAR char *arg2, - FAR char *arg3, FAR char *arg4) + main_t entry, char *argv[]) { return _task_init(tcb, name, priority, task_start, entry, - FALSE, arg1, arg2, arg3, arg4); + FALSE, argv); } #endif