Add 8052 IRQ test; Fix places where IDLE task could try to wait on semaphores
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@61 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
8f7e5ad85e
commit
08199e1216
13
ChangeLog
13
ChangeLog
@ -4,13 +4,16 @@
|
|||||||
* Support for Linux user mode simulation and TI
|
* Support for Linux user mode simulation and TI
|
||||||
TMS320C5471 (Arm7) provided
|
TMS320C5471 (Arm7) provided
|
||||||
|
|
||||||
0.1.1 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
0.1.1 2007-03-14 Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
* Corrected an error in interrupt level context switching
|
* Corrected an error in interrupt level context switching
|
||||||
for C5471
|
for C5471
|
||||||
* Added fgets() and gets() logic; verified c5471 console read.
|
* Added fgets() and gets() logic; verified c5471 console read.
|
||||||
* Corrected error in reading from serial port. Improper
|
* Corrected error in reading from the C5471 serial port:
|
||||||
use of semaphore can cause deadlock.
|
Improper use of semaphore can cause deadlock.
|
||||||
|
* Fixed an error in the memory cleanup: The idle task
|
||||||
|
cannot take sempahores (because it must always be ready
|
||||||
|
to run).
|
||||||
* Tasks can now accept a configurable maximum number of
|
* Tasks can now accept a configurable maximum number of
|
||||||
input parameters (argc)
|
input parameters (argc)
|
||||||
* _task_init() was divided into separate functions that
|
* _task_init() was divided into separate functions that
|
||||||
@ -24,5 +27,7 @@
|
|||||||
were calling printf-like functions.
|
were calling printf-like functions.
|
||||||
* Added strtok() and strtok_r()
|
* Added strtok() and strtok_r()
|
||||||
* Added a simple shell called nsh (see examples/nsh).
|
* Added a simple shell called nsh (see examples/nsh).
|
||||||
* Many changes as part of 8052 bringup
|
* Platform support for 8052 is complete but not stable
|
||||||
|
when the timer interrupt is enabled. Seems to be an
|
||||||
|
issue when SP enters indirect address space.
|
||||||
* Documentation updates
|
* Documentation updates
|
||||||
|
@ -3,12 +3,22 @@
|
|||||||
<title>NuttX</title>
|
<title>NuttX</title>
|
||||||
</head>
|
</head>
|
||||||
<body background="backgd.gif">
|
<body background="backgd.gif">
|
||||||
<hr>
|
<center>
|
||||||
<hr>
|
<hr><hr>
|
||||||
<center><h1><i>Under Construction</i></h1></center>
|
<h1><big><i>NuttX RTOS</i></big></h1>
|
||||||
<hr>
|
<p>Last Updated: March 14, 2007</p>
|
||||||
<hr>
|
<hr><hr>
|
||||||
<h1>Overview</h1>
|
<h1>Table of Contents</h1>
|
||||||
|
</center>
|
||||||
|
<li><a href="#overview">Overview</a></li>
|
||||||
|
<li><a href="#downloads">Downloads</a></li>
|
||||||
|
<li><a href="#platforms">Supported Platforms</a></li>
|
||||||
|
<li><a href="#footprint">Memory Footprint</a></li>
|
||||||
|
<li><a href="#licensing">Licensing</a></li>
|
||||||
|
<li><a href="#history">Release History</a></li>
|
||||||
|
<li><a href="#documentation">Other Documentation</a></li>
|
||||||
|
|
||||||
|
<a name="overview"><h1>Overview</h1></a>
|
||||||
<p>
|
<p>
|
||||||
<b>Goals</b>.
|
<b>Goals</b>.
|
||||||
Nuttx is a real timed embedded operating system (RTOS).
|
Nuttx is a real timed embedded operating system (RTOS).
|
||||||
@ -60,7 +70,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<h1>Downloads</h1>
|
<a name="downloads"><h1>Downloads</h1></a>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The initial release of NuttX (nuttx-0.1.0) is avalable for download
|
The initial release of NuttX (nuttx-0.1.0) is avalable for download
|
||||||
@ -68,7 +78,7 @@
|
|||||||
website.
|
website.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h1>Supported Platforms</h1>
|
<a name="platforms"><h1>Supported Platforms</h1></a>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Linux User Mode</b></li>
|
<li><b>Linux User Mode</b></li>
|
||||||
@ -95,7 +105,9 @@
|
|||||||
and the <a href="http://sdcc.sourceforge.net/">SDCC</a> toolchain.
|
and the <a href="http://sdcc.sourceforge.net/">SDCC</a> toolchain.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
STATUS: This port will require a few more weeks before it is ready for prime time.
|
STATUS: This port is complete but not stable with timer interrupts enabled.
|
||||||
|
There seems to be some issue when the stack pointer enters into the indirect IRAM
|
||||||
|
address space during interrupt handling.
|
||||||
</p>
|
</p>
|
||||||
<li><b>Other ports</b></li>
|
<li><b>Other ports</b></li>
|
||||||
<p>
|
<p>
|
||||||
@ -106,7 +118,7 @@
|
|||||||
<blockquote>* A highly modified <a href="http://buildroot.uclibc.org/">buildroot</a>
|
<blockquote>* A highly modified <a href="http://buildroot.uclibc.org/">buildroot</a>
|
||||||
is available that be used to build a NuttX-compatible arm-elf toolchain.</blockquote>
|
is available that be used to build a NuttX-compatible arm-elf toolchain.</blockquote>
|
||||||
|
|
||||||
<h1>Memory Footprint</h1>
|
<a name="footprint"><h1>Memory Footprint</h1></a>
|
||||||
|
|
||||||
<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
|
||||||
@ -118,11 +130,21 @@ is available that be used to build a NuttX-compatible arm-elf toolchain.</blockq
|
|||||||
53272 428 3568 57268 dfb4 nuttx
|
53272 428 3568 57268 dfb4 nuttx
|
||||||
</pre>
|
</pre>
|
||||||
<p><b>87C52</b>
|
<p><b>87C52</b>
|
||||||
A reduced functionality OS test for the 8051 target requires only
|
A reduced functionality OS test for the 8052 target requires only
|
||||||
about 18Kb (see <a href="codesize-070301.xls">spreadsheet</a> for details).
|
about 18-19Kb:
|
||||||
</p>
|
</p>
|
||||||
|
<pre>
|
||||||
|
Stack starts at: 0x21 (sp set to 0x20) with 223 bytes available.
|
||||||
|
|
||||||
<h1>Licensing</h1>
|
Other memory:
|
||||||
|
Name Start End Size Max
|
||||||
|
---------------- -------- -------- -------- --------
|
||||||
|
PAGED EXT. RAM 0 256
|
||||||
|
EXTERNAL RAM 0x0100 0x02fd 510 7936
|
||||||
|
ROM/EPROM/FLASH 0x2100 0x6e55 19798 24384
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<a name="licensing"><h1>Licensing</h1></a>
|
||||||
|
|
||||||
<p>NuttX is available under the highly permissive
|
<p>NuttX is available under the highly permissive
|
||||||
<a href="http://en.wikipedia.org/wiki/BSD_license">BSD license</a>.
|
<a href="http://en.wikipedia.org/wiki/BSD_license">BSD license</a>.
|
||||||
@ -131,7 +153,45 @@ is available that be used to build a NuttX-compatible arm-elf toolchain.</blockq
|
|||||||
without any concern for jeopardizing any proprietary software that
|
without any concern for jeopardizing any proprietary software that
|
||||||
you may link with it.</p>
|
you may link with it.</p>
|
||||||
|
|
||||||
<h1>Other Documentation</h1>
|
<a name="history"><h1>Release History</h1></a>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
0.1.0 2007-03-09 Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
|
* Initial Release
|
||||||
|
* Support for Linux user mode simulation and TI
|
||||||
|
TMS320C5471 (Arm7) provided
|
||||||
|
|
||||||
|
0.1.1 2007-03-14 Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
|
* Corrected an error in interrupt level context switching
|
||||||
|
for C5471
|
||||||
|
* Added fgets() and gets() logic; verified c5471 console read.
|
||||||
|
* Corrected error in reading from the C5471 serial port:
|
||||||
|
Improper use of semaphore can cause deadlock.
|
||||||
|
* Fixed an error in the memory cleanup: The idle task
|
||||||
|
cannot take sempahores (because it must always be ready
|
||||||
|
to run).
|
||||||
|
* Tasks can now accept a configurable maximum number of
|
||||||
|
input parameters (argc)
|
||||||
|
* _task_init() was divided into separate functions that
|
||||||
|
require fewer parameters. This was necessary to keep
|
||||||
|
the stack usage down for the 8051/2 (which has only
|
||||||
|
256 bytes of stack).
|
||||||
|
* 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
|
||||||
|
handlers. This was happening because interrupt handlers
|
||||||
|
were calling printf-like functions.
|
||||||
|
* Added strtok() and strtok_r()
|
||||||
|
* Added a simple shell called nsh (see examples/nsh).
|
||||||
|
* Platform support for 8052 is complete but not stable
|
||||||
|
when the timer interrupt is enabled. Seems to be an
|
||||||
|
issue when SP enters indirect address space.
|
||||||
|
* Documentation updates
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<a name="documentation"><h1>Other Documentation</h1></a>
|
||||||
|
|
||||||
<li><a href="NuttxUserGuide.html">User Guide</li>
|
<li><a href="NuttxUserGuide.html">User Guide</li>
|
||||||
<li><a href="NuttxPortingGuide.html">Porting Guide</li>
|
<li><a href="NuttxPortingGuide.html">Porting Guide</li>
|
||||||
|
Binary file not shown.
23
ReleaseNotes
23
ReleaseNotes
@ -1,12 +1,19 @@
|
|||||||
Nuttx-0.1.0
|
Nuttx-0.1.1
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
|
||||||
This is the initial. This initial includes the complete NuttX RTOS
|
This is the second release of NuttX. This release includes the
|
||||||
with support for the Linux user mode simulation and the TI TMS320C5471
|
following. See the ChangeLog for more detailed description of
|
||||||
(Arm7) processor. Partial support for the 87C52 is included.
|
the changes.
|
||||||
|
|
||||||
This release has been verified on both the Linux user-mode and C5471
|
(1) General OS bugfixes (see the ChangeLog for details),
|
||||||
platforms using the test program under examples/ostest. Test results
|
(2) bugfixes for the TI TMS320C5471 (Arm7) platform (see the
|
||||||
for the C5471 can be found in arch/c5471/doc/test-results.txt.
|
ChangeLog)
|
||||||
|
(3) Complete support for the 87C52. (However, the 87C52 release
|
||||||
|
is not stable enough for general usage).
|
||||||
|
(4) Added the beginning of a shell call NuttShell (nsh)
|
||||||
|
|
||||||
This tarball contains a complete CVS snapshot from March 9,2007.
|
This release has been verified on the Linux user-mode platform,
|
||||||
|
the Spectrum Digital TMS320C5471 EVM, and the PJRC 87C52 development
|
||||||
|
board using the test program under examples/ostest.
|
||||||
|
|
||||||
|
This tarball contains a complete CVS snapshot from March 14, 2007.
|
||||||
|
@ -837,15 +837,19 @@ static ssize_t up_write(struct file *filep, const char *buffer, size_t buflen)
|
|||||||
ssize_t ret = buflen;
|
ssize_t ret = buflen;
|
||||||
|
|
||||||
/* We may receive console writes through this path from
|
/* We may receive console writes through this path from
|
||||||
* interrupt handlers! In this case, we will need to do
|
* interrupt handlers and from debug output in the IDLE task!
|
||||||
* things a little differently.
|
* In these cases, we will need to do things a little
|
||||||
|
* differently.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (up_interrupt_context())
|
if (up_interrupt_context() || getpid() == 0)
|
||||||
{
|
{
|
||||||
if (dev->isconsole)
|
if (dev->isconsole)
|
||||||
{
|
{
|
||||||
return up_irqwrite(dev, buffer, buflen);
|
irqstate_t flags = irqsave();
|
||||||
|
ret = up_irqwrite(dev, buffer, buflen);
|
||||||
|
irqrestore(flags);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -68,10 +68,10 @@ CONFIG_ARCH_LEDS=y
|
|||||||
CONFIG_8052_TIMER2=y
|
CONFIG_8052_TIMER2=y
|
||||||
|
|
||||||
CONFIG_ARCH_BRINGUP=y
|
CONFIG_ARCH_BRINGUP=y
|
||||||
CONFIG_FRAME_DUMP=y
|
CONFIG_FRAME_DUMP=n
|
||||||
CONFIG_FRAME_DUMP_SHORT=n
|
CONFIG_FRAME_DUMP_SHORT=n
|
||||||
CONFIG_SUPPRESS_INTERRUPTS=y
|
CONFIG_SUPPRESS_INTERRUPTS=y
|
||||||
CONFIG_SWITCH_FRAME_DUMP=y
|
CONFIG_SWITCH_FRAME_DUMP=n
|
||||||
CONFIG_INTERRUPT_FRAME_DUMP=n
|
CONFIG_INTERRUPT_FRAME_DUMP=n
|
||||||
CONFIG_LED_DEBUG=n
|
CONFIG_LED_DEBUG=n
|
||||||
|
|
||||||
|
@ -65,7 +65,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define IRAM_BASE 0x0000
|
#define IRAM_BASE 0x0000
|
||||||
#define IRAM_SIZE 0x0100
|
#ifdef CONFIG_ARCH_8052
|
||||||
|
# define IRAM_SIZE 0x0100
|
||||||
|
#else
|
||||||
|
# define IRAM_SIZE 0x0080
|
||||||
|
#endif
|
||||||
|
|
||||||
#define STACK_BASE 0x0024
|
#define STACK_BASE 0x0024
|
||||||
#define STACK_SIZE (IRAM_SIZE - STACK_BASE)
|
#define STACK_SIZE (IRAM_SIZE - STACK_BASE)
|
||||||
|
@ -65,6 +65,11 @@ LINKLIBS =
|
|||||||
LDPATHES = $(addprefix -L$(TOPDIR)/,$(dir $(LINKLIBS)))
|
LDPATHES = $(addprefix -L$(TOPDIR)/,$(dir $(LINKLIBS)))
|
||||||
LDLIBS = $(addprefix -l,$(notdir $(LINKLIBS)))
|
LDLIBS = $(addprefix -l,$(notdir $(LINKLIBS)))
|
||||||
|
|
||||||
|
TESTSRCS = up_irqtest.c
|
||||||
|
TESTOBJS = $(TESTSRCS:.c=$(OBJEXT))
|
||||||
|
TESTLINKOBJS = up_head$(OBJEXT)
|
||||||
|
TESTEXTRAOBJS = up_savecontext$(OBJEXT) up_restorecontext$(OBJEXT)
|
||||||
|
|
||||||
IRAM_SIZE = 0x100
|
IRAM_SIZE = 0x100
|
||||||
DEF_STACK_BASE = 0x24
|
DEF_STACK_BASE = 0x24
|
||||||
LDFLAGS = --model-large --nostdlib \
|
LDFLAGS = --model-large --nostdlib \
|
||||||
@ -108,7 +113,7 @@ $(ASRCS) $(LINKASRCS): %$(ASMEXT): %.S
|
|||||||
$(AOBJS) $(LINKOBJS): $(ASRCS) $(LINKASRCS)
|
$(AOBJS) $(LINKOBJS): $(ASRCS) $(LINKASRCS)
|
||||||
$(AS) $(ASFLAGS) $<
|
$(AS) $(ASFLAGS) $<
|
||||||
|
|
||||||
$(COBJS): %$(OBJEXT): %.c
|
$(COBJS) $(TESTOBJS): %$(OBJEXT): %.c
|
||||||
$(CC) -c $(CFLAGS) $< -o $@
|
$(CC) -c $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
# Create a header file that contains addressing information needed by the code
|
# Create a header file that contains addressing information needed by the code
|
||||||
@ -174,6 +179,15 @@ nuttx$(EXEEXT): pass1.ihx nuttx.ihx
|
|||||||
packihx nuttx.ihx > $(TOPDIR)/nuttx$(EXEEXT)
|
packihx nuttx.ihx > $(TOPDIR)/nuttx$(EXEEXT)
|
||||||
@cp -f nuttx.map $(TOPDIR)/.
|
@cp -f nuttx.map $(TOPDIR)/.
|
||||||
|
|
||||||
|
# This target builds a test program to verify interrupt context switching. irqtest is
|
||||||
|
# a PHONY target that just sets upt the up_irqtest build correctly
|
||||||
|
|
||||||
|
up_irqtest.ihx: $(TESTOBJS)
|
||||||
|
$(CC) $(LDFLAGS) -L. $(SDCCPATH) $(TESTLINKOBJS) $(TESTOBJS) $(TESTEXTRAOBJS) $(SDCCLIBS) -o $@
|
||||||
|
|
||||||
|
irqtest:
|
||||||
|
$(MAKE) TOPDIR=../../.. up_irqtest.ihx
|
||||||
|
|
||||||
# Build dependencies
|
# Build dependencies
|
||||||
|
|
||||||
.depend: Makefile up_mem.h $(DEPSRCS)
|
.depend: Makefile up_mem.h $(DEPSRCS)
|
||||||
|
269
arch/pjrc-8051/src/up_irqtest.c
Normal file
269
arch/pjrc-8051/src/up_irqtest.c
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
/************************************************************
|
||||||
|
* up_putc.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 <nuttx/arch.h>
|
||||||
|
#include <8052.h>
|
||||||
|
#include "up_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Definitions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#define up_extint0 ((vector_t)PM2_VECTOR_EXTINT0)
|
||||||
|
#define up_timer0 ((vector_t)PM2_VECTOR_TIMER0)
|
||||||
|
#define up_extint1 ((vector_t)PM2_VECTOR_EXTINT1)
|
||||||
|
#define up_timer1 ((vector_t)PM2_VECTOR_TIMER1)
|
||||||
|
#define up_uart ((vector_t)PM2_VECTOR_UART)
|
||||||
|
#define up_timer2 ((vector_t)PM2_VECTOR_TIMER2)
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Types
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
typedef void (*vector_t)(void);
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
boolean g_irqtest;
|
||||||
|
ubyte g_irqtos;
|
||||||
|
ubyte g_irqregs[REGS_SIZE];
|
||||||
|
int g_nirqs;
|
||||||
|
FAR struct xcptcontext *g_irqcontext;
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: utility functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
static void _up_putc(ubyte ch) __naked
|
||||||
|
{
|
||||||
|
ch; /* To avoid unreferenced argument warning */
|
||||||
|
_asm
|
||||||
|
mov a, dpl
|
||||||
|
ljmp PM2_ENTRY_COUT
|
||||||
|
_endasm;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: os_start
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* "Fake" OS entry point.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
void os_start(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Disable all interrupts */
|
||||||
|
|
||||||
|
IE = 0;
|
||||||
|
|
||||||
|
/* Then verify all of the interrupt */
|
||||||
|
|
||||||
|
g_irqtest = FALSE;
|
||||||
|
|
||||||
|
up_extint0();
|
||||||
|
up_timer0();
|
||||||
|
#ifndef CONFIG_8052_TIMER2
|
||||||
|
up_timer0();
|
||||||
|
#endif
|
||||||
|
up_extint1();
|
||||||
|
up_timer1();
|
||||||
|
up_uart();
|
||||||
|
up_timer2();
|
||||||
|
|
||||||
|
/* Now a real interrupt ... */
|
||||||
|
|
||||||
|
/* Configure 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;
|
||||||
|
TR0 = 1; /* Start the timer */
|
||||||
|
|
||||||
|
/* Start timer interrupts */
|
||||||
|
|
||||||
|
g_irqtest = TRUE;
|
||||||
|
g_nirqs = 0;
|
||||||
|
IE = 0x82; /* Enable interrupts */
|
||||||
|
|
||||||
|
/* Wait a about 500 MS */
|
||||||
|
|
||||||
|
_up_delay(500);
|
||||||
|
|
||||||
|
/* Disable the timer */
|
||||||
|
|
||||||
|
TR0 = 0; /* Stop timer 0 */
|
||||||
|
IE = 0; /* Disable interrupts */
|
||||||
|
|
||||||
|
_up_puts("IRQs in 500 MS=");
|
||||||
|
_up_puthex16(g_nirqs);
|
||||||
|
_up_putnl();
|
||||||
|
|
||||||
|
/* end of test */
|
||||||
|
|
||||||
|
_up_puts("Test complete");
|
||||||
|
_up_putnl();
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: irq_dispatch
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* "Fake" IRQ dispatcher
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void irq_dispatch(int irq, FAR void *context)
|
||||||
|
{
|
||||||
|
context;
|
||||||
|
if (g_irqtest)
|
||||||
|
{
|
||||||
|
g_nirqs++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_up_puts("Dispatch IRQ=");
|
||||||
|
_up_puthex(irq);
|
||||||
|
_up_putnl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: up_dumpstack / up_dumpframe
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* "Fake" debug routines if needed.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
void up_dumpstack(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void up_dumpframe(FAR struct xcptcontext *context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: up_ledinit, up_ledon, up_ledoff
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* "Fake" LED routines if needed
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
void up_ledinit(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void up_ledon(ubyte led)
|
||||||
|
{
|
||||||
|
led;
|
||||||
|
}
|
||||||
|
|
||||||
|
void up_ledoff(ubyte led)
|
||||||
|
{
|
||||||
|
led;
|
||||||
|
}
|
@ -274,7 +274,7 @@ ubyte up_savecontext(FAR struct xcptcontext *context) _naked
|
|||||||
|
|
||||||
/* Push the top of frame stack pointer. We need to
|
/* Push the top of frame stack pointer. We need to
|
||||||
* decrement the current SP value by three to account
|
* decrement the current SP value by three to account
|
||||||
* for dpst+IE on the stack above the end of the frame.
|
* for dptr+IE on the stack above the end of the frame.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mov a, sp
|
mov a, sp
|
||||||
|
@ -139,7 +139,6 @@ void up_timerinit(void)
|
|||||||
TR0 = 1; /* Start the timer */
|
TR0 = 1; /* Start the timer */
|
||||||
up_enable_irq(TIMER0_IRQ);
|
up_enable_irq(TIMER0_IRQ);
|
||||||
|
|
||||||
# warning "No support for timer 0 as the system timer"
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,11 +122,17 @@ int files_addreflist(FAR struct filelist *list)
|
|||||||
{
|
{
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
/* Increment the reference count on the list */
|
/* Increment the reference count on the list.
|
||||||
|
* NOTE: that we disable interrupts to do this
|
||||||
|
* (vs. taking the list semaphore). We do this
|
||||||
|
* because file cleanup operations often must be
|
||||||
|
* done from the IDLE task which cannot wait
|
||||||
|
* on semaphores.
|
||||||
|
*/
|
||||||
|
|
||||||
_files_semtake(list);
|
register irqstate_t flags = irqsave();
|
||||||
list->fl_crefs++;
|
list->fl_crefs++;
|
||||||
_files_semgive(list);
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -138,14 +144,22 @@ int files_releaselist(FAR struct filelist *list)
|
|||||||
int crefs;
|
int crefs;
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
/* Decrement the reference count */
|
/* Decrement the reference count on the list.
|
||||||
|
* NOTE: that we disable interrupts to do this
|
||||||
|
* (vs. taking the list semaphore). We do this
|
||||||
|
* because file cleanup operations often must be
|
||||||
|
* done from the IDLE task which cannot wait
|
||||||
|
* on semaphores.
|
||||||
|
*/
|
||||||
|
|
||||||
_files_semtake(list);
|
register irqstate_t flags = irqsave();
|
||||||
crefs = --(list->fl_crefs);
|
crefs = --(list->fl_crefs);
|
||||||
_files_semgive(list);
|
irqrestore(flags);
|
||||||
|
|
||||||
/* If the count decrements to zero, then there is no reference
|
/* If the count decrements to zero, then there is no reference
|
||||||
* to the structure and it should be deallocated.
|
* to the structure and it should be deallocated. Since there
|
||||||
|
* are references, it would be an error if any task still held
|
||||||
|
* a reference to the list's semaphore.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (crefs <= 0)
|
if (crefs <= 0)
|
||||||
|
@ -78,6 +78,11 @@ EXTERN void os_start(void); /* OS entry point called by boot logic */
|
|||||||
EXTERN void mm_initialize(FAR void *heap_start, size_t heap_size);
|
EXTERN void mm_initialize(FAR void *heap_start, size_t heap_size);
|
||||||
EXTERN void mm_addregion(FAR void *heapstart, size_t heapsize);
|
EXTERN void mm_addregion(FAR void *heapstart, size_t heapsize);
|
||||||
|
|
||||||
|
/* Functions contained in mm_sem.c **************************/
|
||||||
|
|
||||||
|
EXTERN int mm_trysemaphore(void);
|
||||||
|
EXTERN void mm_givesemaphore(void);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -145,11 +145,17 @@ void lib_addreflist(FAR struct streamlist *list)
|
|||||||
{
|
{
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
/* Increment the reference count on the list */
|
/* Increment the reference count on the list.
|
||||||
|
* NOTE: that we disable interrupts to do this
|
||||||
|
* (vs. taking the list semaphore). We do this
|
||||||
|
* because file cleanup operations often must be
|
||||||
|
* done from the IDLE task which cannot wait
|
||||||
|
* on semaphores.
|
||||||
|
*/
|
||||||
|
|
||||||
_lib_semtake(list);
|
register irqstate_t flags = irqsave();
|
||||||
list->sl_crefs++;
|
list->sl_crefs++;
|
||||||
_lib_semgive(list);
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,14 +169,22 @@ void lib_releaselist(FAR struct streamlist *list)
|
|||||||
int crefs;
|
int crefs;
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
/* Decrement the reference count */
|
/* Decrement the reference count on the list.
|
||||||
|
* NOTE: that we disable interrupts to do this
|
||||||
|
* (vs. taking the list semaphore). We do this
|
||||||
|
* because file cleanup operations often must be
|
||||||
|
* done from the IDLE task which cannot wait
|
||||||
|
* on semaphores.
|
||||||
|
*/
|
||||||
|
|
||||||
_lib_semtake(list);
|
register irqstate_t flags = irqsave();
|
||||||
crefs = --(list->sl_crefs);
|
crefs = --(list->sl_crefs);
|
||||||
_lib_semgive(list);
|
irqrestore(flags);
|
||||||
|
|
||||||
/* If the count decrements to zero, then there is no reference
|
/* If the count decrements to zero, then there is no reference
|
||||||
* to the structure and it should be deallocated.
|
* to the structure and it should be deallocated. Since there
|
||||||
|
* are references, it would be an error if any task still held
|
||||||
|
* a reference to the list's semaphore.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (crefs <= 0)
|
if (crefs <= 0)
|
||||||
|
74
mm/mm_sem.c
74
mm/mm_sem.c
@ -78,7 +78,11 @@ static int g_counts_held;
|
|||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* mm_seminitialize
|
* Name: mm_seminitialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize the MM mutex
|
||||||
|
*
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
void mm_seminitialize(void)
|
void mm_seminitialize(void)
|
||||||
@ -94,7 +98,56 @@ void mm_seminitialize(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* mm_takesemaphore
|
* Name: mm_trysemaphore
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Try to take the MM mutex. This is called only from the
|
||||||
|
* OS in certain conditions when it is necessary to have
|
||||||
|
* exclusive access to the memory manager but it is
|
||||||
|
* impossible to wait on a semaphore (e.g., the idle process
|
||||||
|
* when it performs its background memory cleanup).
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#ifndef MM_TEST
|
||||||
|
int mm_trysemaphore(void)
|
||||||
|
{
|
||||||
|
pid_t my_pid = getpid();
|
||||||
|
|
||||||
|
/* Do I already have the semaphore? */
|
||||||
|
|
||||||
|
if (g_holder == my_pid)
|
||||||
|
{
|
||||||
|
/* Yes, just increment the number of references that I have */
|
||||||
|
|
||||||
|
g_counts_held++;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Try to tak the semaphore (perhaps waiting) */
|
||||||
|
|
||||||
|
if (sem_trywait(&g_mm_semaphore) != 0)
|
||||||
|
{
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have it. Claim the stak and return */
|
||||||
|
|
||||||
|
g_holder = my_pid;
|
||||||
|
g_counts_held = 1;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: mm_takesemaphore
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Take the MM mutex. This is the normal action before all
|
||||||
|
* memory management actions.
|
||||||
|
*
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
void mm_takesemaphore(void)
|
void mm_takesemaphore(void)
|
||||||
@ -134,7 +187,11 @@ void mm_takesemaphore(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* mm_givesemaphore
|
* Name: mm_givesemaphore
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Release the MM mutex when it is not longer needed.
|
||||||
|
*
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
void mm_givesemaphore(void)
|
void mm_givesemaphore(void)
|
||||||
@ -160,12 +217,21 @@ void mm_givesemaphore(void)
|
|||||||
/* Nope, this is the last reference I have */
|
/* Nope, this is the last reference I have */
|
||||||
|
|
||||||
msemdbg("PID=%d giving\n", my_pid);
|
msemdbg("PID=%d giving\n", my_pid);
|
||||||
g_holder = -1;
|
g_holder = -1;
|
||||||
g_counts_held = 0;
|
g_counts_held = 0;
|
||||||
ASSERT(sem_post(&g_mm_semaphore) == 0);
|
ASSERT(sem_post(&g_mm_semaphore) == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: mm_getsemaphore
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Return the current value of the MM semaphore (for test
|
||||||
|
* purposes only)
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
#ifdef MM_TEST
|
#ifdef MM_TEST
|
||||||
int mm_getsemaphore(void)
|
int mm_getsemaphore(void)
|
||||||
{
|
{
|
||||||
|
@ -80,5 +80,5 @@ pid_t getpid(void)
|
|||||||
* ready-to-run task list
|
* ready-to-run task list
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return ((_TCB*)g_readytorun.head)->pid;
|
return ((FAR _TCB*)g_readytorun.head)->pid;
|
||||||
}
|
}
|
||||||
|
@ -134,8 +134,8 @@ typedef struct pidhash_s pidhash_t;
|
|||||||
|
|
||||||
struct tasklist_s
|
struct tasklist_s
|
||||||
{
|
{
|
||||||
DSEG dq_queue_t *list; /* Pointer to the task list */
|
DSEG volatile dq_queue_t *list; /* Pointer to the task list */
|
||||||
boolean prioritized; /* TRUE if the list is prioritized */
|
boolean prioritized; /* TRUE if the list is prioritized */
|
||||||
};
|
};
|
||||||
typedef struct tasklist_s tasklist_t;
|
typedef struct tasklist_s tasklist_t;
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ typedef struct tasklist_s tasklist_t;
|
|||||||
* list is always the idle task.
|
* list is always the idle task.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern dq_queue_t g_readytorun;
|
extern volatile dq_queue_t g_readytorun;
|
||||||
|
|
||||||
/* This is the list of all tasks that are ready-to-run, but
|
/* This is the list of all tasks that are ready-to-run, but
|
||||||
* cannot be placed in the g_readytorun list because: (1) They
|
* cannot be placed in the g_readytorun list because: (1) They
|
||||||
@ -168,16 +168,16 @@ extern dq_queue_t g_readytorun;
|
|||||||
* disabled pre-emption.
|
* disabled pre-emption.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern dq_queue_t g_pendingtasks;
|
extern volatile dq_queue_t g_pendingtasks;
|
||||||
|
|
||||||
/* This is the list of all tasks that are blocked waiting for a semaphore */
|
/* This is the list of all tasks that are blocked waiting for a semaphore */
|
||||||
|
|
||||||
extern dq_queue_t g_waitingforsemaphore;
|
extern volatile dq_queue_t g_waitingforsemaphore;
|
||||||
|
|
||||||
/* This is the list of all tasks that are blocked waiting for a signal */
|
/* This is the list of all tasks that are blocked waiting for a signal */
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
extern dq_queue_t g_waitingforsignal;
|
extern volatile dq_queue_t g_waitingforsignal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is the list of all tasks that are blocked waiting for a message
|
/* This is the list of all tasks that are blocked waiting for a message
|
||||||
@ -185,7 +185,7 @@ extern dq_queue_t g_waitingforsignal;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_MQUEUE
|
#ifndef CONFIG_DISABLE_MQUEUE
|
||||||
extern dq_queue_t g_waitingformqnotempty;
|
extern volatile dq_queue_t g_waitingformqnotempty;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is the list of all tasks that are blocked waiting for a message
|
/* This is the list of all tasks that are blocked waiting for a message
|
||||||
@ -193,14 +193,14 @@ extern dq_queue_t g_waitingformqnotempty;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_MQUEUE
|
#ifndef CONFIG_DISABLE_MQUEUE
|
||||||
extern dq_queue_t g_waitingformqnotfull;
|
extern volatile dq_queue_t g_waitingformqnotfull;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This the list of all tasks that have been initialized, but not yet
|
/* This the list of all tasks that have been initialized, but not yet
|
||||||
* activated. NOTE: This is the only list that is not prioritized.
|
* activated. NOTE: This is the only list that is not prioritized.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern dq_queue_t g_inactivetasks;
|
extern volatile dq_queue_t g_inactivetasks;
|
||||||
|
|
||||||
/* This is the list of dayed memory deallocations that need to be handled
|
/* This is the list of dayed memory deallocations that need to be handled
|
||||||
* within the IDLE loop. These deallocations get queued by sched_free()
|
* within the IDLE loop. These deallocations get queued by sched_free()
|
||||||
@ -208,11 +208,11 @@ extern dq_queue_t g_inactivetasks;
|
|||||||
* handler.
|
* handler.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern sq_queue_t g_delayeddeallocations;
|
extern volatile sq_queue_t g_delayeddeallocations;
|
||||||
|
|
||||||
/* This is the value of the last process ID assigned to a task */
|
/* This is the value of the last process ID assigned to a task */
|
||||||
|
|
||||||
extern pid_t g_lastpid;
|
extern volatile pid_t g_lastpid;
|
||||||
|
|
||||||
/* The following hash table is used for two things:
|
/* The following hash table is used for two things:
|
||||||
*
|
*
|
||||||
|
@ -86,7 +86,7 @@
|
|||||||
* list is always the idle task.
|
* list is always the idle task.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dq_queue_t g_readytorun;
|
volatile dq_queue_t g_readytorun;
|
||||||
|
|
||||||
/* This is the list of all tasks that are ready-to-run, but
|
/* This is the list of all tasks that are ready-to-run, but
|
||||||
* cannot be placed in the g_readytorun list because: (1) They
|
* cannot be placed in the g_readytorun list because: (1) They
|
||||||
@ -95,16 +95,16 @@ dq_queue_t g_readytorun;
|
|||||||
* disabled pre-emption.
|
* disabled pre-emption.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dq_queue_t g_pendingtasks;
|
volatile dq_queue_t g_pendingtasks;
|
||||||
|
|
||||||
/* This is the list of all tasks that are blocked waiting for a semaphore */
|
/* This is the list of all tasks that are blocked waiting for a semaphore */
|
||||||
|
|
||||||
dq_queue_t g_waitingforsemaphore;
|
volatile dq_queue_t g_waitingforsemaphore;
|
||||||
|
|
||||||
/* This is the list of all tasks that are blocked waiting for a signal */
|
/* This is the list of all tasks that are blocked waiting for a signal */
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
dq_queue_t g_waitingforsignal;
|
volatile dq_queue_t g_waitingforsignal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is the list of all tasks that are blocked waiting for a message
|
/* This is the list of all tasks that are blocked waiting for a message
|
||||||
@ -112,7 +112,7 @@ dq_queue_t g_waitingforsignal;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_MQUEUE
|
#ifndef CONFIG_DISABLE_MQUEUE
|
||||||
dq_queue_t g_waitingformqnotempty;
|
volatile dq_queue_t g_waitingformqnotempty;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is the list of all tasks that are blocked waiting for a message
|
/* This is the list of all tasks that are blocked waiting for a message
|
||||||
@ -120,14 +120,14 @@ dq_queue_t g_waitingformqnotempty;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_MQUEUE
|
#ifndef CONFIG_DISABLE_MQUEUE
|
||||||
dq_queue_t g_waitingformqnotfull;
|
volatile dq_queue_t g_waitingformqnotfull;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This the list of all tasks that have been initialized, but not yet
|
/* This the list of all tasks that have been initialized, but not yet
|
||||||
* activated. NOTE: This is the only list that is not prioritized.
|
* activated. NOTE: This is the only list that is not prioritized.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dq_queue_t g_inactivetasks;
|
volatile dq_queue_t g_inactivetasks;
|
||||||
|
|
||||||
/* This is the list of dayed memory deallocations that need to be handled
|
/* This is the list of dayed memory deallocations that need to be handled
|
||||||
* within the IDLE loop. These deallocations get queued by sched_free()
|
* within the IDLE loop. These deallocations get queued by sched_free()
|
||||||
@ -135,11 +135,11 @@ dq_queue_t g_inactivetasks;
|
|||||||
* handler.
|
* handler.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sq_queue_t g_delayeddeallocations;
|
volatile sq_queue_t g_delayeddeallocations;
|
||||||
|
|
||||||
/* This is the value of the last process ID assigned to a task */
|
/* This is the value of the last process ID assigned to a task */
|
||||||
|
|
||||||
pid_t g_lastpid;
|
volatile pid_t g_lastpid;
|
||||||
|
|
||||||
/* The following hash table is used for two things:
|
/* The following hash table is used for two things:
|
||||||
*
|
*
|
||||||
@ -420,22 +420,35 @@ void os_start(void)
|
|||||||
dbg("Beginning Idle Loop\n");
|
dbg("Beginning Idle Loop\n");
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/* Check if there is anything in the delayed deallocation list. */
|
/* Check if there is anything in the delayed deallocation list.
|
||||||
|
* If there is deallocate it now. We must have exclusive access
|
||||||
|
* to the memory manager to do this BUT the idle task cannot
|
||||||
|
* wait on a semaphore. So we only do the cleanup now if we
|
||||||
|
* can get the semaphore -- and this should be possible because
|
||||||
|
* since we are running, no other task is!
|
||||||
|
*/
|
||||||
|
|
||||||
while (g_delayeddeallocations.head)
|
if (mm_trysemaphore() == 0)
|
||||||
{
|
{
|
||||||
/* Remove the first delayed deallocation. */
|
while (g_delayeddeallocations.head)
|
||||||
|
{
|
||||||
|
/* Remove the first delayed deallocation. */
|
||||||
|
|
||||||
irqstate_t saved_state = irqsave();
|
irqstate_t saved_state = irqsave();
|
||||||
void *address = (void*)sq_remfirst(&g_delayeddeallocations);
|
void *address = (void*)sq_remfirst(&g_delayeddeallocations);
|
||||||
irqrestore(saved_state);
|
irqrestore(saved_state);
|
||||||
|
|
||||||
/* Then deallocate it */
|
/* Then deallocate it */
|
||||||
|
|
||||||
if (address) sched_free(address);
|
if (address)
|
||||||
}
|
{
|
||||||
|
sched_free(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mm_givesemaphore();
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform idle state operations */
|
/* Perform any processor-specific idle state operations */
|
||||||
|
|
||||||
up_idle();
|
up_idle();
|
||||||
}
|
}
|
||||||
|
@ -83,10 +83,12 @@
|
|||||||
void sched_free(FAR void *address)
|
void sched_free(FAR void *address)
|
||||||
{
|
{
|
||||||
/* Check if this is an attempt to deallocate memory from
|
/* Check if this is an attempt to deallocate memory from
|
||||||
* an exception handler.
|
* an exception handler. If this function is called from the
|
||||||
|
* IDLE task, then we must have exclusive access to the memory
|
||||||
|
* manager to do this.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (up_interrupt_context())
|
if (up_interrupt_context() || mm_trysemaphore() != 0)
|
||||||
{
|
{
|
||||||
/* Yes.. Delay the deallocation until a more appropriate time. */
|
/* Yes.. Delay the deallocation until a more appropriate time. */
|
||||||
|
|
||||||
@ -99,6 +101,7 @@ void sched_free(FAR void *address)
|
|||||||
/* No.. just deallocate the memory now. */
|
/* No.. just deallocate the memory now. */
|
||||||
|
|
||||||
kfree(address);
|
kfree(address);
|
||||||
|
mm_givesemaphore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user