mirror of
https://github.com/apache/nuttx.git
synced 2025-12-08 19:02:43 +08:00
Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13f01b4cf3 | ||
|
|
d2410c93c6 | ||
|
|
f29250c671 | ||
|
|
2a929796b9 | ||
|
|
b1127822ed | ||
|
|
448c7f4618 | ||
|
|
ed4fe71b96 | ||
|
|
63f134f988 | ||
|
|
8b9fcf354e | ||
|
|
b1d5b6899a | ||
|
|
2aab4d3c3a | ||
|
|
b765d17818 | ||
|
|
54339607da | ||
|
|
0c2ff4a47c | ||
|
|
23dffb8f23 | ||
|
|
0db3f5c256 | ||
|
|
56f7399200 | ||
|
|
5f5d5496d9 | ||
|
|
3e352ca10b | ||
|
|
c5971231da | ||
|
|
b7a85058a4 | ||
|
|
4ee22e2307 | ||
|
|
daffb73624 | ||
|
|
c5af51943b | ||
|
|
795ffc3829 | ||
|
|
efa97ac0f5 | ||
|
|
b441f43a6e | ||
|
|
c9011c0f30 | ||
|
|
03771dd514 | ||
|
|
18149c3b98 | ||
|
|
aa56898b82 | ||
|
|
8e8fc062a5 | ||
|
|
c0934f429d | ||
|
|
bf9cc8b7ab | ||
|
|
47118057ea | ||
|
|
468beb1305 | ||
|
|
df2a08cf9b | ||
|
|
a02374bb45 | ||
|
|
3631d1e1ad | ||
|
|
16e8906ed5 | ||
|
|
d551204f84 | ||
|
|
3d5eebad25 | ||
|
|
b9d2a2b971 | ||
|
|
768a214d63 | ||
|
|
b282cd3f42 | ||
|
|
e689e148e8 | ||
|
|
7a1f5f61bd | ||
|
|
1e8eaa90c1 | ||
|
|
5af89ab5eb | ||
|
|
a2ed490c11 | ||
|
|
a2c26f080a | ||
|
|
30c1d1028d | ||
|
|
0baf1522b1 | ||
|
|
5325f906c7 | ||
|
|
ef4d567b78 | ||
|
|
aae8532783 | ||
|
|
1367c062f7 | ||
|
|
136e3d9fca | ||
|
|
8abec4bbb0 |
45
ChangeLog
45
ChangeLog
@@ -69,3 +69,48 @@
|
||||
* Some Documentation updates
|
||||
* Added support for the Neuros OSD / DM320
|
||||
|
||||
0.2.2 2007-03-26 Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Created the configs/ directory; separated board configuration
|
||||
from processor architecture logic
|
||||
* Add memory leak detection test to examples/ostest
|
||||
* Corrected memory leak in OS pthread join logic
|
||||
* Corrected memory leaks in examples/ostest due to failures
|
||||
to join or detach from pthreads.
|
||||
* Added pthread_once(), pthread_kill(), pthread_sigmask()
|
||||
* Added pthread_barrierattr_*() APIs
|
||||
* Added pthread_barrier_init(), pthread_barrier_destroy(), and
|
||||
pthread_barrier_wait();
|
||||
* Added pthread barrier test
|
||||
* Added protection so that errno cannot be modified from
|
||||
interrupt handling.
|
||||
* sched_setparam(), sched_setscheduler() now correctly set
|
||||
errno; pthread_setscheduler() now returns the correct errno.
|
||||
* Added pthread_setschedprio().
|
||||
* Added directories to hold board-specific header files
|
||||
* Added directories to hold board-specific drivers
|
||||
|
||||
0.2.3 2007-03-29 Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
* mq_receive and mq_send now return errno's appropriately
|
||||
* mq_receive and mq_send are now correctly awakened by signals.
|
||||
* Fixed an unmatched sched_lock/unlock pair in task_delete().
|
||||
* sched_lock must be called in _exit() because operation of
|
||||
task_delete() can cause pending tasks to be merged and a
|
||||
context switch to occur.
|
||||
* Added mq_timedreceive() and mq_timedsend()
|
||||
* signal mask is now inherited by both child tasks and threads.
|
||||
* Improved sharebility of stdout among pthreads (only). Nothing
|
||||
was broken, but by moving the mutual exclusion logic to a
|
||||
higher level, the printf output is more readable.
|
||||
* Fixed a bug in file system cleanup: A list was being deleted
|
||||
before the buffers contained in the list.
|
||||
* Fixed a bug in the wait-for-message-queue-not-empty logic.
|
||||
* Added a test of timed mqueue operations; detected and corrected
|
||||
some mqueue errors.
|
||||
* Identified and corrected a race condition associated with
|
||||
pthread_join. In the failure condition, memory was being
|
||||
deallocated while still in use.
|
||||
|
||||
0.2.4 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
* Started m68322
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||
<p>Last Updated: March 21, 2007</p>
|
||||
<p>Last Updated: March 28, 2007</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -180,7 +180,7 @@
|
||||
</table>
|
||||
|
||||
<p>
|
||||
The third release of NuttX (nuttx-0.1.2) is avalable for download
|
||||
The sixth release of NuttX (nuttx-0.2.3) is available for download
|
||||
from the <a href="http://sourceforge.net/project/showfiles.php?group_id=189573">SourceForge</a>
|
||||
website.
|
||||
</p>
|
||||
@@ -430,6 +430,51 @@ Other memory:
|
||||
* Some Documentation updates
|
||||
* Added support for the Neuros OSD / DM320
|
||||
|
||||
0.2.2 2007-03-26 Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Created the configs/ directory; separated board configuration
|
||||
from processor architecture logic
|
||||
* Add memory leak detection test to examples/ostest
|
||||
* Corrected memory leak in OS pthread join logic
|
||||
* Corrected memory leaks in examples/ostest due to failures
|
||||
to join or detach from pthreads.
|
||||
* Added pthread_once(), pthread_kill(), pthread_sigmask()
|
||||
* Added pthread_barrierattr_*() APIs
|
||||
* Added pthread_barrier_init(), pthread_barrier_destroy(), and
|
||||
pthread_barrier_wait();
|
||||
* Added pthread barrier test
|
||||
* Added protection so that errno cannot be modified from
|
||||
interrupt handling.
|
||||
* sched_setparam(), sched_setscheduler() now correctly set
|
||||
errno; pthread_setscheduler() now returns the correct errno.
|
||||
* Added pthread_setschedprio().
|
||||
* Added directories to hold board-specific header files
|
||||
* Added directories to hold board-specific drivers
|
||||
|
||||
0.2.3 2007-03-29 Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
* mq_receive and mq_send now return errno's appropriately
|
||||
* mq_receive and mq_send are now correctly awakened by signals.
|
||||
* Fixed an unmatched sched_lock/unlock pair in task_delete().
|
||||
* sched_lock must be called in _exit() because operation of
|
||||
task_delete() can cause pending tasks to be merged and a
|
||||
context switch to occur.
|
||||
* Added mq_timedreceive() and mq_timedsend()
|
||||
* signal mask is now inherited by both child tasks and threads.
|
||||
* Improved sharebility of stdout among pthreads (only). Nothing
|
||||
was broken, but by moving the mutual exclusion logic to a
|
||||
higher level, the printf output is more readable.
|
||||
* Fixed a bug in file system cleanup: A list was being deleted
|
||||
before the buffers contained in the list.
|
||||
* Fixed a bug in the wait-for-message-queue-not-empty logic.
|
||||
* Added a test of timed mqueue operations; detected and corrected
|
||||
some mqueue errors.
|
||||
* Identified and corrected a race condition associated with
|
||||
pthread_join. In the failure condition, memory was being
|
||||
deallocated while still in use.
|
||||
|
||||
0.2.4 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
* Started m68322
|
||||
</pre></ul>
|
||||
|
||||
<table width ="100%">
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</b></big>
|
||||
<p><small>by</small></p>
|
||||
<p>Gregory Nutt</p>
|
||||
<p><small>Last Update: March 20, 2007</small></p>
|
||||
<p><small>Last Update: March 26, 2007</small></p>
|
||||
</center>
|
||||
|
||||
<center><h1>Table of Contents</h1></center>
|
||||
@@ -26,21 +26,35 @@
|
||||
<li>2.1 <a href="#DirStructDocumentation">Documentation</a></li>
|
||||
<l1>2.2 <a href="#DirStructArch">arch</a></li>
|
||||
<ul>
|
||||
<li><a href="#sudirectorystructure">2.2.1 Subdirectory Structure</a></li>
|
||||
<li><a href="#summaryoffiles">2.2.2 Summary of Files</a></li>
|
||||
<li><a href="#archdirectorystructure">2.2.1 Subdirectory Structure</a></li>
|
||||
<li><a href="#summaryofarchfiles">2.2.2 Summary of Files</a></li>
|
||||
<li><a href="#supportedarchitectures">2.2.3 Supported Architectures</a></li>
|
||||
<li><a href="#configuringnuttx">2.2.4 Configuring NuttX</a></li>
|
||||
</ul>
|
||||
<li>2.3 <a href="#DirStructDrivers">drivers</a></li>
|
||||
<li>2.4 <a href="#DirStructExamples">examples</a></li>
|
||||
<li>2.5 <a href="#DirStructFs">fs</a></li>
|
||||
<li>2.6 <a href="#DirStructInclude">include</a></li>
|
||||
<li>2.7 <a href="#DirStructLib">lib</a></li>
|
||||
<li>2.8 <a href="#DirStructMm">mm</a></li>
|
||||
<li>2.9 <a href="#DirStructSched">sched</a></li>
|
||||
<li>2.10 <a href="#DirStructDrivers">tools</a></li>
|
||||
<li>2.3 <a href="#DirStructConfigs">configs/</a></li>
|
||||
<ul>
|
||||
<li><a href="#configsdirectorystructure">2.3.1 Subdirectory Structure</a></li>
|
||||
<li><a href="#summaryofconfigfiles">2.3.2 Summary of Files</a></li>
|
||||
<ul>
|
||||
<li><a href="#boardlogic">2.3.2.1 Board Specific Logic</a></li>
|
||||
<li><a href="#boardconfigfiles">2.3.2.2 Board Specific Configuration Files</a></li>
|
||||
</ul>
|
||||
<li><a href="#supportedboards">2.3.3 Supported Boards</a></li>
|
||||
</ul>
|
||||
<li>2.4 <a href="#DirStructDrivers">drivers</a></li>
|
||||
<li>2.5 <a href="#DirStructExamples">examples</a></li>
|
||||
<li>2.6 <a href="#DirStructFs">fs</a></li>
|
||||
<li>2.7 <a href="#DirStructInclude">include</a></li>
|
||||
<li>2.8 <a href="#DirStructLib">lib</a></li>
|
||||
<li>2.9 <a href="#DirStructMm">mm</a></li>
|
||||
<li>2.10 <a href="#DirStructSched">sched</a></li>
|
||||
<li>2.11 <a href="#DirStructTools">tools</a></li>
|
||||
<li>2.12 <a href="#topmakefile">Makefile</a></li>
|
||||
</ul>
|
||||
<li>3.0 <a href="#configandbuild">Configuring and Building</a></li>
|
||||
<ul>
|
||||
<li><a href="#configuringnuttx">3.1 Configuring NuttX</a></li>
|
||||
<li><a href="#buildingnuttx">3.2 Building NuttX</a></li>
|
||||
</ul>
|
||||
<li>3.0 <a href="#DirectoryConfiAndBuild">Configuring and Building</a></li>
|
||||
<li>4.0 <a href="#ArchAPIs">Architecture APIs</a></li>
|
||||
<ul>
|
||||
<li><a href="#imports">4.1 APIs Exported by Architecture-Specific Logic to NuttX</a></li>
|
||||
@@ -82,7 +96,7 @@
|
||||
into the build.
|
||||
</p>
|
||||
<p>
|
||||
See also arch/README.txt.
|
||||
See also <code>arch/README.txt</code> and <code>configs/README.txt</code>.
|
||||
</p>
|
||||
|
||||
<p><b>General Philosophy</b>.
|
||||
@@ -90,50 +104,66 @@
|
||||
<hr>
|
||||
<h1>2.0 <a name="DirectoryStructure">Directory Structure</a></h1>
|
||||
|
||||
<p>The general directly layout for NuttX is very similar to the directory structure
|
||||
of the Linux kernel -- at least at the most superficial layers.
|
||||
At the top level is the main makefile and a series of sub-directories identified
|
||||
below and discussed in the following paragraphs:</p>
|
||||
|
||||
<p>
|
||||
<b>Directory Structure</b>.
|
||||
The general directly layout for NuttX is very similar to the directory structure
|
||||
of the Linux kernel -- at least at the most superficial layers.
|
||||
At the top level is the main makefile and a series of sub-directories identified
|
||||
below and discussed in the following paragraphs:
|
||||
</p>
|
||||
<ul><pre>
|
||||
.
|
||||
|-- Makefile
|
||||
|-- <a href="#topmakefile">Makefile</a>
|
||||
|-- <a href="#DirStructDocumentation">Documentation</a>
|
||||
| `-- <i>(documentation files)</i>
|
||||
|-- <a href="#DirStructArch">arch</a>
|
||||
| |-- <i>(architecture)</i>
|
||||
| | |-- Make.defs
|
||||
| | |-- defconfig
|
||||
| | |-- include
|
||||
| | |-- setenv.sh
|
||||
| | `-- src
|
||||
| `-- <i>(other architectures)</i>
|
||||
| `-- <i>(documentation files)</i>/
|
||||
|-- <a href="#DirStructArch">arch</a>/
|
||||
| |-- <i><arch-name></i>/
|
||||
| | |-- include/
|
||||
| | | |--<i><chip-name></i>/
|
||||
| | | | `-- <i>(chip-specific header files)</i>
|
||||
| | | |--<i><other-chips></i>/
|
||||
| | | `-- <i>(architecture-specific header files)</i>
|
||||
| | `-- src/
|
||||
| | |--<i><chip-name></i>/
|
||||
| | | `-- <i>(chip-specific source files)</i>
|
||||
| | |--<i><other-chips></i>/
|
||||
| | `-- <i>(architecture-specific source files)</i>
|
||||
| `-- <i><other-architectures></i>/
|
||||
|-- <a href="#DirStructConfigs">configs</a>/
|
||||
| |-- <i><board-name></i>/
|
||||
| | |-- include/
|
||||
| | | `-- <i>(board-specific header files)</i>
|
||||
| | |-- src/
|
||||
| | | |-- Makefile
|
||||
| | | `-- <i>(board-specific source files)</i>
|
||||
| | `-- <i>(board-specific configuration files)</i>
|
||||
| `-- <i><other-boards></i>/
|
||||
|-- <a href="#DirStructDrivers">drivers</a>
|
||||
| |-- Makefile
|
||||
| `-- <i>(driver source files)</i>
|
||||
|-- <a href="#DirStructExamples">examples</a>
|
||||
| `-- <i>(example)</i>
|
||||
| |-- Makefile/
|
||||
| `-- <i>(common driver source files)</i>
|
||||
|-- <a href="#DirStructExamples">examples</a>/
|
||||
| `-- <i>(example)</i>/
|
||||
| |-- Makefile
|
||||
| `-- <i>(example source files)</i>
|
||||
|-- <a href="#DirStructFs">fs</a>
|
||||
|-- <a href="#DirStructFs">fs</a>/
|
||||
| |-- Makefile
|
||||
| `-- <i>(fs source files)</i>
|
||||
|-- <a href="#DirStructInclude">include</a>
|
||||
|-- <a href="#DirStructInclude">include</a>/
|
||||
| |-- <i>(standard header files)</i>
|
||||
| |-- nuttx
|
||||
| |-- nuttx/
|
||||
| | `-- <i>(nuttx specific header files)</i>
|
||||
| `- sys
|
||||
| `- sys/
|
||||
| | `-- <i>(more standard header files)</i>
|
||||
|-- <a href="#DirStructLib">lib</a>
|
||||
|-- <a href="#DirStructLib">lib</a>/
|
||||
| |-- Makefile
|
||||
| `-- <i>(lib source files)</i>
|
||||
|-- <a href="#DirStructMm">mm</a>
|
||||
|-- <a href="#DirStructMm">mm</a>/
|
||||
| |-- Makefile
|
||||
| `-- <i>(mm source files)</i>
|
||||
|-- <a href="#DirStructSched">sched</a>
|
||||
|-- <a href="#DirStructSched">sched</a>/
|
||||
| |-- Makefile
|
||||
| `-- <i>(sched source files)</i>
|
||||
`-- <a href="#DirStructDrivers">tools</a>
|
||||
`-- <a href="#DirStructDrivers">tools</a>/
|
||||
|-- Makefile.mkconfig
|
||||
|-- configure.sh
|
||||
|-- mkconfig.c
|
||||
@@ -141,6 +171,40 @@ below and discussed in the following paragraphs:</p>
|
||||
`-- zipme
|
||||
</pre></ul>
|
||||
|
||||
<p>
|
||||
<b>Configuration Files</b>.
|
||||
The NuttX configuration consists of:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<i>Processor architecture specific files</i>.
|
||||
These are the files contained in the <code>arch/</code><i><arch-name></i><code>/</code> directory
|
||||
and are discussed in a paragraph <a href="#archdirectorystructure">below</a>.
|
||||
</li>
|
||||
<li>
|
||||
<i>Chip/SoC specific files</i>.
|
||||
Each processor processor architecture is embedded in chip or <i>System-on-a-Chip</i> (SoC) architecture.
|
||||
The full chip architecture includes the processor architecture plus chip-specific interrupt logic,
|
||||
clocking logic, general purpose I/O (GIO) logic, and specialized, internal peripherals (such as UARTs, USB, etc.).
|
||||
<p>
|
||||
These chip-specific files are contained within chip-specific sub-directories in the
|
||||
<code>arch/</code><i><arch-name></i><code>/</code> directory and are selected via
|
||||
the <code>CONFIG_ARCH_name</code> selection.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<i>Board specific files</i>.
|
||||
In order to be usable, the chip must be contained in a board environment.
|
||||
The board configuration defines additional properties of the board including such things as
|
||||
peripheral LEDs, external peripherals (such as network, USB, etc.).
|
||||
<p>
|
||||
These board-specific configuration files can be found in the
|
||||
<code>configs/</code><i><board-name></i><code>/</code> sub-directories and are discussed
|
||||
in a a paragraph <a href="#configsdirectorystructure">below</a>.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>2.1 <a name="DirStructDocumentation">Documentation</a></h2>
|
||||
|
||||
<p>
|
||||
@@ -149,67 +213,42 @@ below and discussed in the following paragraphs:</p>
|
||||
|
||||
<h2>2.2 <a name="DirStructArch">arch</a></h2>
|
||||
|
||||
<h3><a name="sudirectorystructure">2.2.1 Subdirectory Structure</a></h3>
|
||||
<h3><a name="archdirectorystructure">2.2.1 Subdirectory Structure</a></h3>
|
||||
<p>
|
||||
This directory contains several sub-directories, each containing
|
||||
architecture-specific logic.
|
||||
The task of porting NuttX to a new processor or board consists of
|
||||
The task of porting NuttX to a new processor consists of
|
||||
add a new sudirectory under <code>arch/</code> containing logic specific
|
||||
to the new architecuture.
|
||||
Each architecture must provide a subdirectory, <<i>arch-name</i>>
|
||||
under <code>arch/</code> with the folling characteristics:
|
||||
The complete board port in is defined by the architecture-specific code in this
|
||||
directory (plus the board-specific configurations in the <code>config/</code>
|
||||
subdirectory).
|
||||
Each architecture must provide a subdirectory, <i><arch-name></i>
|
||||
under <code>arch/</code> with the following characteristics:
|
||||
</p>
|
||||
<ul><pre>
|
||||
<<i>arch-name</i>>
|
||||
|-- Make.defs
|
||||
|-- defconfig
|
||||
|-- setenv.sh
|
||||
|-- include
|
||||
<i><arch-name></i>/
|
||||
|-- include/
|
||||
| |--<i><chip-name></i>/
|
||||
| | `-- <i>(chip-specific header files)</i>
|
||||
| |--<i><other-chips></i>/
|
||||
| |-- arch.h
|
||||
| |-- irq.h
|
||||
| `-- types.h
|
||||
`-- src
|
||||
| |-- types.h
|
||||
| `-- limits.h
|
||||
`-- src/
|
||||
|--<i><chip-name></i>/
|
||||
| `-- <i>(chip-specific source files)</i>
|
||||
|--<i><other-chips></i>/
|
||||
|-- Makefile
|
||||
`-- (architecture-specific source files)
|
||||
`-- <i>(architecture-specific source files)</i>
|
||||
</pre></ul>
|
||||
|
||||
<h3><a name="summaryoffiles">2.2.2 Summary of Files</a></h3>
|
||||
<h3><a name="summaryofarchfiles">2.2.2 Summary of Files</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<code>Make.defs</code>: This makefile fragment provides architecture and
|
||||
tool-specific build options. It will be included by all other
|
||||
makefiles in the build (once it is installed). This make fragment
|
||||
should define:
|
||||
<ul>
|
||||
<li>Tools: CC, LD, AR, NM, OBJCOPY, OBJDUMP</li>
|
||||
<li>Tool options: CFLAGS, LDFLAGS</li>
|
||||
</ul>
|
||||
<p>
|
||||
When this makefile fragment runs, it will be passed TOPDIR which
|
||||
is the path to the root directory of the build. This makefile
|
||||
fragment may include ${TOPDIR}/.config to perform configuration
|
||||
specific settings. For example, the CFLAGS will most likely be
|
||||
different if CONFIG_DEBUG=y.
|
||||
</li>
|
||||
<li>
|
||||
<code>defconfig</code>: This is a configuration file similar to the Linux
|
||||
configuration file. In contains varialble/value pairs like:
|
||||
<ul>
|
||||
<li><code>CONFIG_VARIABLE</code>=value</li>
|
||||
</ul>
|
||||
<p>
|
||||
This configuration file will be used at build time:
|
||||
</p>
|
||||
<ol>
|
||||
<li>As a makefile fragment included in other makefiles, and</li>
|
||||
<li>to generate <code>include/nuttx/config.h</code> which is included by
|
||||
most C files in the system.</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>
|
||||
<code>setenv.sh</code>: This is a script that you can include that will be installed at
|
||||
the toplevel of the directory structure and can be sourced to set any
|
||||
necessary environment variables.
|
||||
<code>include/</code><i><chip-name></i><code>/</code>
|
||||
This sub-directory contains chip-specific header files.
|
||||
</li>
|
||||
<li>
|
||||
<code>include/arch.h</code>:
|
||||
@@ -265,6 +304,10 @@ below and discussed in the following paragraphs:</p>
|
||||
by the board.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<code>src/</code><i><chip-name></i><code>/</code>
|
||||
This sub-directory contains chip-specific source files.
|
||||
</li>
|
||||
<li>
|
||||
<code>src/Makefile</code>:
|
||||
This makefile will be executed to build the targets <code>src/libup.a</code> and
|
||||
@@ -273,6 +316,12 @@ below and discussed in the following paragraphs:</p>
|
||||
the final link with <code>libup.a</code> and other system archives to generate the
|
||||
final executable.
|
||||
</li>
|
||||
<li>
|
||||
<i>(architecture-specific source files)</i>.
|
||||
The file <code>include/nuttx/arch.h</code> identifies all of the APIs that must
|
||||
be provided by the architecture specific logic. (It also includes
|
||||
<code>arch/</code><i><arch-name></i><code>/arch.h</code> as described above).
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3><a name="supportedarchitectures">2.2.3 Supported Architectures</a></h3>
|
||||
@@ -284,56 +333,171 @@ below and discussed in the following paragraphs:</p>
|
||||
round robin scheduler) Otherwise, it is complete.
|
||||
<li><code>arch/c5471</code>:
|
||||
TI TMS320C5471 (also called TMS320DM180 or just C5471).
|
||||
NuttX operates on the ARM7 of this dual core processor. This port
|
||||
uses the Spectrum Digital evaluation board with a GNU arm-elf toolchain*.
|
||||
This port is complete, verified, and included in the NuttX release.
|
||||
NuttX operates on the ARM7 of this dual core processor.
|
||||
This port is complete, verified, and included in the NuttX release 0.1.1.
|
||||
<li><code>arch/dm320</code>:
|
||||
TI TMS320DM320 (also called just DM320).
|
||||
NuttX operates on the ARM9EJS of this dual core processor.
|
||||
This port uses the Neuros OSD with a GNU arm-elf toolchain*:
|
||||
see http://wiki.neurostechnology.com/index.php/Developer_Welcome .
|
||||
STATUS: This port is code complete but totally untested due to
|
||||
hardware issues with my OSD.
|
||||
This port complete, verified, and included in the NuttX release 0.2.1.
|
||||
<li><code>arch/m68322</code>
|
||||
A work in progress.</li>
|
||||
<li><code>arch/pjrc-8051</code>:
|
||||
8051 Microcontroller. This port uses the PJRC 87C52 development system
|
||||
and the SDCC toolchain. This port is not quite ready for prime time.
|
||||
8051 Microcontroller. This port is not quite ready for prime time.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Other ports for the for the TI TMS320DM270 and for MIPS are in various states
|
||||
of progress
|
||||
</p>
|
||||
|
||||
<h3><a name="configuringnuttx">2.2.4 Configuring NuttX</a></h3>
|
||||
<h2>2.3 <a name="DirStructConfigs">configs</a></h2>
|
||||
<p>
|
||||
Configuring NuttX requires only copying:
|
||||
The <code>configs/</code> subdirectory contains configuration data for each board.
|
||||
These board-specific configurations plus the architecture-specific configurations in
|
||||
the <code>arch/</code> subdirectory complete define a customized port of NuttX.
|
||||
</p>
|
||||
<ul>
|
||||
<code>arch/<<i>arch-name</i>>/Make.def</code> to <code>${TOPDIR}/Make.defs</code>,
|
||||
<code>arch/<<i>arch-name</i>>/setenv.sh</code> to <code>${TOPDIR}/setenv.sh</code>, and
|
||||
<code.arch/<<i>arch-name</i>>/defconfig</code> to ${TOPDIR}/.config</code>
|
||||
</ul>
|
||||
|
||||
<h3><a name="configsdirectorystructure">2.3.1 Subdirectory Structure</a></h3>
|
||||
<p>
|
||||
There is a script that automates these steps. The following steps will
|
||||
accomplish the same configuration:
|
||||
The configs directory contains board specific configuration files. Each board must
|
||||
provide a subdirectory <board-name> under <code>configs/</code> with the following characteristics:
|
||||
</p>
|
||||
<ul><pre>
|
||||
cd tools
|
||||
./configure.sh <<i>arch-name</i>>
|
||||
<i><board-name></i>
|
||||
|-- include/
|
||||
| `-- <i>(board-specific header files)</i>
|
||||
|-- src/
|
||||
| |-- Makefile
|
||||
| `-- <i>(board-specific source files)</i>
|
||||
|-- Make.defs
|
||||
|-- defconfig
|
||||
`-- setenv.sh
|
||||
</pre></ul>
|
||||
|
||||
<h2>2.3 <a name="DirStructDrivers">drivers</a></h2>
|
||||
<h3><a name="summaryofconfigfiles">2.3.2 Summary of Files</a></h3>
|
||||
<h4><a name="boardlogic">2.3.2.1 Board Specific Logic</a></h4>
|
||||
<ul>
|
||||
<li>
|
||||
<code>include/</code>:
|
||||
This directory contains board specific header files.
|
||||
This directory will be linked as <code>include/arch/board</code> at configuration time
|
||||
and can be included via <code>#include <arch/board/header.h></code>.
|
||||
These header file can only be included by files in <code>arch/</code><i><arch-name></i><code>/include/</code>
|
||||
and <code>arch/</code><i><arch-name></i><code>/src/</code>.
|
||||
</li>
|
||||
<li>
|
||||
<code>src/</code>:
|
||||
This directory contains board specific drivers.
|
||||
This directory will be linked as <config>arch/</code><i><arch-name></i><code>/src/board</config> at configuration
|
||||
time and will be integrated into the build system.
|
||||
</li>
|
||||
<li>
|
||||
<code>src/Makefile</code>:
|
||||
This makefile will be invoked to build the board specific drivers.
|
||||
It must support the following targets: <code>libext$(LIBEXT)</code>, <code>clean</code>, and <code>distclean</code>.
|
||||
</li>
|
||||
</ul>
|
||||
<h4><a name="boardconfigfiles">2.3.2.2 Board Specific Configuration Files</a></h4>
|
||||
<p>
|
||||
The <code>configs/</code><i><board-name></i><code>/</code> sub-directory holds all of the
|
||||
files that are necessary to configure Nuttx for the particular board.
|
||||
The procedure for configuring NuttX is described <a href="#configuringnuttx">below</a>,
|
||||
This paragraph will describe the contents of these configuration files.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<code>Make.defs</code>: This makefile fragment provides architecture and
|
||||
tool-specific build options. It will be included by all other
|
||||
makefiles in the build (once it is installed). This make fragment
|
||||
should define:
|
||||
<ul>
|
||||
<li>Tools: CC, LD, AR, NM, OBJCOPY, OBJDUMP</li>
|
||||
<li>Tool options: CFLAGS, LDFLAGS</li>
|
||||
</ul>
|
||||
<p>
|
||||
When this makefile fragment runs, it will be passed TOPDIR which
|
||||
is the path to the root directory of the build. This makefile
|
||||
fragment may include ${TOPDIR}/.config to perform configuration
|
||||
specific settings. For example, the CFLAGS will most likely be
|
||||
different if CONFIG_DEBUG=y.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<code>defconfig</code>: This is a configuration file similar to the Linux
|
||||
configuration file. In contains varialble/value pairs like:
|
||||
<ul>
|
||||
<li><code>CONFIG_VARIABLE</code>=value</li>
|
||||
</ul>
|
||||
<p>
|
||||
This configuration file will be used at build time:
|
||||
</p>
|
||||
<ol>
|
||||
<li>As a makefile fragment included in other makefiles, and</li>
|
||||
<li>to generate <code>include/nuttx/config.h</code> which is included by
|
||||
most C files in the system.</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>
|
||||
<code>setenv.sh</code>: This is a script that you can include that will be installed at
|
||||
the toplevel of the directory structure and can be sourced to set any
|
||||
necessary environment variables.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3><a name="supportedboards">2.3.3 Supported Boards</a></h3>
|
||||
<p>
|
||||
All of the specific boards supported by NuttX are identified below.
|
||||
These the the specific <i><board-name></i>'s that may be used to configure NuttX
|
||||
as described <a href="#configuringnuttx">below</a>.
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>configs/sim</code>:
|
||||
A user-mode port of NuttX to the x86 Linux platform is available.
|
||||
The purpose of this port is primarily to support OS feature developement.
|
||||
This port does not support interrupts or a real timer (and hence no
|
||||
round robin scheduler) Otherwise, it is complete.</li>
|
||||
|
||||
<li><code>configs/c5471evm</code>:
|
||||
This is a port to the Spectrum Digital C5471 evaluation board. The
|
||||
C5471 is a dual core processor from TI with an ARM7TDMI general purpose
|
||||
processor and a c54 SDP. NuttX runs on the ARM core and is built with
|
||||
with a GNU arm-elf toolchain*. This port is complete, verified, and
|
||||
included in the NuttX release.</li>
|
||||
|
||||
<li><code>configs/ntosd-dm320</code>:
|
||||
This port uses the Neuros OSD with a GNU arm-elf toolchain*.
|
||||
See <a href="http://wiki.neurostechnology.com/index.php/Developer_Welcome">Neuros Wiki</a>
|
||||
for futher information.
|
||||
NuttX operates on the ARM9EJS of this dual core processor.
|
||||
STATUS: This port is code complete, verified, and included in the
|
||||
NuttX 0.2.1 release.</li>
|
||||
|
||||
<li><code>configs/m68322evb</code>:
|
||||
This is a work in progress for the venerable m68322evb board from
|
||||
Motorola.</li>
|
||||
|
||||
<li><code>configs/pjrc-8051</code>:
|
||||
8051 Microcontroller. This port uses the PJRC 87C52 development system
|
||||
and the SDCC toolchain. This port is not quite ready for prime time.</li>
|
||||
</ul>
|
||||
|
||||
<p><small><blockquote>
|
||||
* A customized version of the <a href="http://www.buildroot.org">buildroot</a>
|
||||
is available to build these toolchains.
|
||||
</blockquote></small></p>
|
||||
|
||||
<h2>2.4 <a name="DirStructDrivers">drivers</a></h2>
|
||||
|
||||
<p>
|
||||
This directory holds architecture-independent device drivers.
|
||||
</p>
|
||||
|
||||
<h2>2.4 <a name="DirStructExamples">examples</a></h2>
|
||||
<h2>2.5 <a name="DirStructExamples">examples</a></h2>
|
||||
|
||||
<p>
|
||||
Example and test programs to build against.
|
||||
</p>
|
||||
|
||||
<h2>2.5 <a name="DirStructFs">fs</a></h2>
|
||||
<h2>2.6 <a name="DirStructFs">fs</a></h2>
|
||||
|
||||
<p>
|
||||
This directory contains the NuttX filesystem.
|
||||
@@ -345,7 +509,7 @@ below and discussed in the following paragraphs:</p>
|
||||
in a file-system-like name space.
|
||||
</p>
|
||||
|
||||
<h2>2.6 <a name="DirStructInclude">include</a></h2>
|
||||
<h2>2.7 <a name="DirStructInclude">include</a></h2>
|
||||
<p>
|
||||
This directory holds NuttX header files.
|
||||
Standard header files file retained in can be included in the <i>normal</i> fashion:
|
||||
@@ -356,34 +520,113 @@ below and discussed in the following paragraphs:</p>
|
||||
etc.
|
||||
</ul>
|
||||
|
||||
<h2>2.7 <a name="DirStructLib">lib</a></h2>
|
||||
|
||||
<h2>2.8 <a name="DirStructLib">lib</a></h2>
|
||||
<p>
|
||||
This directory holds a collection of standard libc-like functions with custom
|
||||
interfaces into Nuttx.
|
||||
</p>
|
||||
|
||||
<h2>2.8 <a name="DirStructMm">mm</a></h2>
|
||||
|
||||
<h2>2.9 <a name="DirStructMm">mm</a></h2>
|
||||
<p>
|
||||
This is the NuttX memory manager.
|
||||
</p>
|
||||
|
||||
<h2>2.9 <a name="DirStructSched">sched</a></h2>
|
||||
|
||||
<h2>2.10 <a name="DirStructSched">sched</a></h2>
|
||||
<p>
|
||||
The files forming core of the NuttX RTOS reside here.
|
||||
</p>
|
||||
|
||||
<h2>2.10 <a name="DirStructDrivers">tools</a></h2>
|
||||
|
||||
<h2>2.11 <a name="DirStructTools">tools</a></h2>
|
||||
<p>
|
||||
This directory holds a collection of tools and scripts to simplify
|
||||
configuring and building NuttX.
|
||||
</p>
|
||||
|
||||
<h2>2.12 <a name="topmakefile">Makefile</a></h2>
|
||||
<p>
|
||||
The top-level <code>Makefile</code> in the <code>${TOPDIR}</code> directory contains all of the top-level control
|
||||
logic to build NuttX.
|
||||
Use of this <code>Makefile</code> to build NuttX is described <a href="#buildingnuttx">below</a>.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<h1>3.0 <a name="DirectoryConfiAndBuild">Configuring and Building</a></h1>
|
||||
<h1>3.0 <a name="configandbuild">Configuring and Building</a></h1>
|
||||
<h2><a name="configuringnuttx">3.1 Configuring NuttX</a></h2>
|
||||
<p>
|
||||
<b>Manual Configuration</b>.
|
||||
Configuring NuttX requires only copying the
|
||||
<a href="#boardconfigfiles">board-specific configuration files</a> into the top level directory which appears in the make files as the make variable, <code>${TOPDIR}</code>.
|
||||
This could be done manually as follows:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Copy <code>configs/</code><i><board-name></i></code>/Make.def</code> to <code>${TOPDIR}/Make.defs</code>,<li>
|
||||
<li>Copy <code>configs/</code><i><board-name></i></code>/setenv.sh</code> to <code>${TOPDIR}/setenv.sh</code>, and</li>
|
||||
<li>Copy <code>configs/</code><i><board-name></i></code>/defconfig</code> to <code>${TOPDIR}/.config</code></li>
|
||||
</ul>
|
||||
<p>
|
||||
Where <i><board-name></i> is the name of one of the sub-directories of the
|
||||
NuttX <a href="#DirStructConfigs"><code>configs/</code></a> directory.
|
||||
This sub-directory name corresponds to one of the supported boards
|
||||
identified <a href="#supportedboards">above</a>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Automated Configuration</b>.
|
||||
There is a script that automates these steps. The following steps will
|
||||
accomplish the same configuration:
|
||||
</p>
|
||||
<ul><pre>
|
||||
cd tools
|
||||
./configure.sh <i><board-name></i>
|
||||
</pre></ul>
|
||||
|
||||
<p>
|
||||
<b>Additional Configuration Steps</b>.
|
||||
The remainder of configuration steps will be performed by <a href="#topmakefile"><code>${TOPDIR}/Makefile</code></a>
|
||||
the first time the system is built as described below.
|
||||
</p>
|
||||
|
||||
<h2><a name="buildingnuttx">3.2 Building NuttX</a></h2>
|
||||
<p>
|
||||
<b>Building NuttX</b>.
|
||||
Once NuttX has been configured as described <a href="#configuringnuttx">above</a>, it may be built as follows:
|
||||
</p>
|
||||
<ul><pre>
|
||||
cd ${TOPDIR}
|
||||
source ./setenv.sh
|
||||
make
|
||||
</pre></ul>
|
||||
<p>
|
||||
The <code>${TOPDIR}</code> directory holds:
|
||||
</p>
|
||||
<ul>
|
||||
<li>The top level <a href="#topmakefile"><code>Makefile</code></a> that controls the NuttX build.
|
||||
</ul>
|
||||
<p>
|
||||
That directory also holds:
|
||||
</p>
|
||||
<ul>
|
||||
<li>The makefile fragment <a href="#boardconfigfiles"><code>.config</code></a> that describes the current configuration.</li>
|
||||
<li>The makefile fragment <a href="#boardconfigfiles"><code>Make.defs</code></a> that provides customized build targers, and</li>
|
||||
<li>The shell script <a href="#boardconfigfiles"><code>setenv.sh</code></a> that sets up the configuration environment for the build.</li>
|
||||
</ul>
|
||||
<p>
|
||||
The <a href="#boardconfigfiles"><code>setenv.sh</code></a> contains Linux environmental settings that are needed for the build.
|
||||
The specific environmental definitions are unique for each board but should include, as a minimum, updates to the <code>PATH</code> variable to include the full path to the architecture-specific toolchain identified in <a href="#boardconfigfiles"><code>Make.defs</code></a>.
|
||||
The <a href="#boardconfigfiles"><code>setenv.sh</code></a> only needs to be source'ed at the beginning of a session.
|
||||
The system can be re-made subsequently by just typing <code>make</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>First Time Make.</b>
|
||||
Additional configuration actions will be taken the first time that system is built.
|
||||
These additional steps include:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Auto-generating the file <code>include/nuttx/config.</code> using the <code>${TOPDIR}/.config</code> file.
|
||||
<li>Creating a link to <code>${TOPDIR}/arch/</code><i><arch-name></i><code>/include</code> at <code>${TOPDIR}/include/arch</code>.
|
||||
<li>Creating a link to <code>${TOPDIR}/configs/</code><i><board-name></i><code>/include</code> at <code>${TOPDIR}/include/arch/board</code>.
|
||||
<li>Creating a link to <code>${TOPDIR}/configs/</code><i><board-name></i><code>/src</code> at <code>${TOPDIR}/arch/</code><i><arch-name></i><code>/src/board</code>
|
||||
<li>Creating make dependencies.
|
||||
</ul>
|
||||
|
||||
<h1>4.0 <a name="ArchAPIs">Architecture APIs</a></h1>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
62
Makefile
62
Makefile
@@ -39,6 +39,8 @@ TOPDIR = ${shell pwd}
|
||||
|
||||
ARCH_DIR = arch/$(CONFIG_ARCH)
|
||||
ARCH_SRC = $(ARCH_DIR)/src
|
||||
ARCH_INC = $(ARCH_DIR)/include
|
||||
BOARD_DIR = configs/$(CONFIG_BOARD)
|
||||
|
||||
SUBDIRS = sched lib $(ARCH_SRC) mm fs drivers examples/$(CONFIG_EXAMPLE)
|
||||
|
||||
@@ -54,17 +56,46 @@ all: $(BIN)
|
||||
tools/mkconfig:
|
||||
$(MAKE) -C tools -f Makefile.mkconfig TOPDIR=$(TOPDIR) mkconfig
|
||||
|
||||
include/nuttx/config.h: $(ARCH_DIR)/defconfig tools/mkconfig
|
||||
tools/mkconfig $(ARCH_DIR) > include/nuttx/config.h
|
||||
include/nuttx/config.h: $(TOPDIR)/.config tools/mkconfig
|
||||
tools/mkconfig $(TOPDIR) > include/nuttx/config.h
|
||||
|
||||
include/arch: include/nuttx/config.h
|
||||
ln -sf $(TOPDIR)/$(ARCH_DIR)/include include/arch
|
||||
include/arch: Make.defs
|
||||
@if [ -e include/arch ]; then \
|
||||
if [ -h include/arch ]; then \
|
||||
rm -f include/arch ; \
|
||||
else \
|
||||
echo "include/arch exists but is not a symbolic link" ; \
|
||||
exit 1 ; \
|
||||
fi ; \
|
||||
fi
|
||||
@ln -s $(TOPDIR)/$(ARCH_DIR)/include include/arch
|
||||
|
||||
context: check_context include/nuttx/config.h include/arch
|
||||
include/arch/board: Make.defs include/arch
|
||||
@if [ -e include/arch/board ]; then \
|
||||
if [ -h include/arch/board ]; then \
|
||||
rm -f include/arch/board ; \
|
||||
else \
|
||||
echo "include/arch/board exists but is not a symbolic link" ; \
|
||||
exit 1 ; \
|
||||
fi ; \
|
||||
fi
|
||||
@ln -s $(TOPDIR)/$(BOARD_DIR)/include include/arch/board
|
||||
|
||||
$(ARCH_SRC)/board: Make.defs
|
||||
@if [ -e $(ARCH_SRC)/board ]; then \
|
||||
if [ -h $(ARCH_SRC)/board ]; then \
|
||||
rm -f $(ARCH_SRC)/board ; \
|
||||
else \
|
||||
echo "$(ARCH_SRC)/board exists but is not a symbolic link" ; \
|
||||
exit 1 ; \
|
||||
fi ; \
|
||||
fi
|
||||
@ln -s $(TOPDIR)/$(BOARD_DIR)/src $(ARCH_SRC)/board
|
||||
|
||||
context: check_context include/nuttx/config.h include/arch include/arch/board $(ARCH_SRC)/board
|
||||
|
||||
clean_context:
|
||||
rm -f include/nuttx/config.h
|
||||
rm -f include/arch
|
||||
rm -f include/nuttx/config.h include/arch $(ARCH_INC)/board $(ARCH_SRC)/board
|
||||
|
||||
check_context:
|
||||
@if [ ! -e ${TOPDIR}/.config -o ! -e ${TOPDIR}/Make.defs ]; then \
|
||||
@@ -102,19 +133,26 @@ depend:
|
||||
$(MAKE) -C $$dir TOPDIR=$(TOPDIR) depend ; \
|
||||
done
|
||||
|
||||
clean:
|
||||
subdir_clean:
|
||||
@for dir in $(SUBDIRS) ; do \
|
||||
$(MAKE) -C $$dir TOPDIR=$(TOPDIR) clean ; \
|
||||
if [ -e $$dir/Makefile ]; then \
|
||||
$(MAKE) -C $$dir TOPDIR=$(TOPDIR) clean ; \
|
||||
fi \
|
||||
done
|
||||
$(MAKE) -C tools -f Makefile.mkconfig TOPDIR=$(TOPDIR) clean
|
||||
$(MAKE) -C mm -f Makefile.test TOPDIR=$(TOPDIR) clean
|
||||
|
||||
clean: subdir_clean
|
||||
rm -f $(BIN) $(BIN).* mm_test *.map *~
|
||||
|
||||
distclean: clean clean_context
|
||||
subdir_distclean:
|
||||
@for dir in $(SUBDIRS) ; do \
|
||||
$(MAKE) -C $$dir TOPDIR=$(TOPDIR) distclean ; \
|
||||
if [ -e $$dir/Makefile ]; then \
|
||||
$(MAKE) -C $$dir TOPDIR=$(TOPDIR) distclean ; \
|
||||
fi \
|
||||
done
|
||||
$(MAKE) -C examples/$(CONFIG_EXAMPLE) TOPDIR=$(TOPDIR) distclean
|
||||
|
||||
distclean: clean subdir_distclean clean_context
|
||||
rm -f Make.defs setenv.sh .config
|
||||
|
||||
|
||||
|
||||
29
ReleaseNotes
29
ReleaseNotes
@@ -1,19 +1,18 @@
|
||||
Nuttx-0.2.1
|
||||
^^^^^^^^^^^
|
||||
nuttx-0.2.3
|
||||
^^^^^^^^^^^^
|
||||
|
||||
This is the fourth relese of NuttX. This release adds adds
|
||||
support for a new platform, restructures many header files,
|
||||
and adds a few new features:
|
||||
This is the sixth release of NuttX. This release is primarily
|
||||
a bugfix release. Numerous problems were fixed as detailed
|
||||
in the change log. New functionaliy includes support for
|
||||
timed messsage queues.
|
||||
|
||||
(1) Support for Neuros OSD / DM320
|
||||
(2) Restructuring of header files for better POSIX compliance
|
||||
(3) Added kill()
|
||||
(4) Added POSIX timers
|
||||
(5) bugfixes and documentation updates
|
||||
See the ChangeLog for a complete list of changes.
|
||||
|
||||
This release has been verified on the Linux user-mode platform,
|
||||
the Spectrum Digital TMS320C5471 EVM, and the Neuros OSD using
|
||||
the test program under examples/ostest. Because of the stability
|
||||
of these tests, the project status has been upgraded to 'beta.'
|
||||
This release has been verified on the Linux user-mode platform
|
||||
and the Neuros OSD using the test program under examples/ostest.
|
||||
The results of the testing is available in the source tree under
|
||||
configs/ntosd-dm320/doc/test-results. There are no known,
|
||||
critical defects but the project development status remains at
|
||||
'beta' status pending further test and evaluation.
|
||||
|
||||
This tarball contains a complete CVS snapshot from March 22, 2007.
|
||||
This tarball contains a complete CVS snapshot from March 29, 2007.
|
||||
|
||||
41
TODO
41
TODO
@@ -1,27 +1,25 @@
|
||||
NuttX TODO List
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Task/Scheduler
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
o Task/Scheduler
|
||||
- When a tasks exits, shouldn't all of its child pthreads also be terminated?
|
||||
- Should task_delete() cause atexit() function to be called?
|
||||
- Implement sys/mman.h and functions
|
||||
- Implement sys/wait.h and functions
|
||||
- Implement priority inheritance
|
||||
- Implement vfork(). Could be tricky because of stack references.
|
||||
- Make the system timer frequency configurable via defconfig. See:
|
||||
_POSIX_CLOCKRES_MIN in limits.h
|
||||
CLK_TCK in time.h
|
||||
Definitions in sched/clock_internal.h
|
||||
MSEC_PER_TICK in sched/clock_internal.h
|
||||
- Consider implementing wait, waitpid, waitid. At present, a parent has
|
||||
no information about child tasks.
|
||||
|
||||
o Memory Managment
|
||||
- Add an option to free all memory allocated by a task when the task exits.
|
||||
This may not be worth the overhead for a deeply embedded system.
|
||||
This is probably not be worth the overhead for a deeply embedded system.
|
||||
|
||||
o Signals
|
||||
- 'Standard' signals and signal actions are not supported. Does this
|
||||
make since in a deeply embedded system?
|
||||
- 'Standard' signals and signal actions are not supported.
|
||||
|
||||
o pthreads
|
||||
- pthread_cancel(): Should implemenent cancellation points and pthread_testcancel()
|
||||
@@ -29,31 +27,31 @@ o pthreads
|
||||
o Libraries
|
||||
|
||||
o File system
|
||||
- This probabaly needs some rethinking.
|
||||
- Add some concept like mount points to handle mounted "real" filesystems.
|
||||
|
||||
o Console Output
|
||||
|
||||
o Documentation
|
||||
- Document fs & driver logic
|
||||
- Document filesystem, library
|
||||
- Document fs/ & driver/ logic
|
||||
- Document C-library APIs
|
||||
|
||||
o Build system
|
||||
- Something leaves garbage link 'include' in arch/*/include
|
||||
- Separate configurations from architectures. arch/* contains
|
||||
generic logic. Like arch/armnommu, arch/arm, arch/805x, etc.
|
||||
config/* has like config/pjrc-8052, config/c5471, etc.
|
||||
- Names under arch are incorrect. These should hold processor architectures.
|
||||
c5471 should be arm7
|
||||
dm320 should be arm9
|
||||
pjrc-8051 should be 805x
|
||||
- SoC-specific logic should be in subdirectories under arch/<processor-name>.
|
||||
Eg. arm7/include/c5471 should hold c5471 specific header files
|
||||
- configs/pjrc-8051 should be configs/pjrc-87c52
|
||||
|
||||
o Applications & Tests
|
||||
|
||||
o C5471
|
||||
- At present, there is a failure in the examples/ostest POSIX timer
|
||||
test when CONFIG_DEBUG is enabled. This is almost certainly yet
|
||||
another case where printf (or its kin) are being called from a
|
||||
sensitive area in the OS.
|
||||
|
||||
o DM320
|
||||
|
||||
o pjrc-8052 / MCS51
|
||||
* Current status:
|
||||
- Current status:
|
||||
- Basic OS task management seems OK
|
||||
- Fails when interrupts enabled. The stack pointer is around 0x6e
|
||||
before the failure occurs. It looks like some issue when the
|
||||
@@ -69,6 +67,3 @@ o pjrc-8052 / MCS51
|
||||
clock_initialize.c at line 107
|
||||
pthread_create.c at 330
|
||||
sighand.c at 225 and 244
|
||||
|
||||
o DM320
|
||||
- In progress
|
||||
|
||||
216
arch/README.txt
216
arch/README.txt
@@ -11,161 +11,65 @@ Table of Contents
|
||||
Architecture-Specific Code
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The file include/nuttx/arch.h identifies all of the APIs that must
|
||||
be provided by the architecture specific logic. (It also includes
|
||||
The NuttX configuration consists of:
|
||||
|
||||
o Processor architecture specific files. These are the files contained
|
||||
in the arch/<arch-name>/ directory discussed in this README.
|
||||
|
||||
o Chip/SoC specific files. Each processor processor architecture
|
||||
is embedded in chip or System-on-a-Chip (SoC) architecture. The
|
||||
full chip architecture includes the processor architecture plus
|
||||
chip-specific interrupt logic, general purpose I/O (GIO) logic, and
|
||||
specialized, internal peripherals (such as UARTs, USB, etc.).
|
||||
|
||||
These chip-specific files are contained within chip-specific
|
||||
sub-directories in the arch/<arch-name>/ directory and are selected
|
||||
via the CONFIG_ARCH_name selection
|
||||
|
||||
o Board specific files. In order to be usable, the chip must be
|
||||
contained in a board environment. The board configuration defines
|
||||
additional properties of the board including such things as
|
||||
peripheral LEDs, external peripherals (such as network, USB, etc.).
|
||||
|
||||
These board-specific configuration files can be found in the
|
||||
configs/<board-name>/ sub-directories.
|
||||
|
||||
This README will address the processor architecture specific files
|
||||
that are contained in the arch/<arch-name>/ directory. The file
|
||||
include/nuttx/arch.h identifies all of the APIs that must
|
||||
be provided by this architecture specific logic. (It also includes
|
||||
arch/<arch-name>/arch.h as described below).
|
||||
|
||||
Directory Structure
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The arch directory contains architecture specific logic. Each architecture must
|
||||
provide a subdirectory <arch-name> under arch/ with the folling characteristics:
|
||||
The arch directory contains architecture specific logic. The complete
|
||||
board port in is defined by the architecture-specific code in this
|
||||
directory (plus the board-specific configurations in the config/
|
||||
subdirectory). Each architecture must provide a subdirectory <arch-name>
|
||||
under arch/ with the following characteristics:
|
||||
|
||||
|
||||
<arch-name>
|
||||
|-- Make.defs
|
||||
|-- defconfig
|
||||
|-- setenv.sh
|
||||
|-- include
|
||||
<arch-name>/
|
||||
|-- include/
|
||||
| |--<chip-name>/
|
||||
| | `-- (chip-specific header files)
|
||||
| |--<other-chips>/
|
||||
| |-- arch.h
|
||||
| |-- irq.h
|
||||
| `-- types.h
|
||||
`-- src
|
||||
`-- src/
|
||||
|--<chip-name>/
|
||||
| `-- (chip-specific source files)
|
||||
|--<other-chips>/
|
||||
|-- Makefile
|
||||
`-- (architecture-specific source files)
|
||||
|
||||
Summary of Files
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Make.defs -- This makefile fragment provides architecture and
|
||||
tool-specific build options. It will be included by all other
|
||||
makefiles in the build (once it is installed). This make fragment
|
||||
should define:
|
||||
|
||||
Tools: CC, LD, AR, NM, OBJCOPY, OBJDUMP
|
||||
Tool options: CFLAGS, LDFLAGS
|
||||
|
||||
When this makefile fragment runs, it will be passed TOPDIR which
|
||||
is the path to the root directory of the build. This makefile
|
||||
fragment may include ${TOPDIR}/.config to perform configuration
|
||||
specific settings. For example, the CFLAGS will most likely be
|
||||
different if CONFIG_DEBUG=y.
|
||||
|
||||
defconfig -- This is a configuration file similar to the Linux
|
||||
configuration file. In contains varialble/value pairs like:
|
||||
|
||||
CONFIG_VARIABLE=value
|
||||
|
||||
This configuration file will be used at build time:
|
||||
|
||||
(1) as a makefile fragment included in other makefiles, and
|
||||
(2) to generate include/nuttx/config.h which is included by
|
||||
most C files in the system.
|
||||
|
||||
The following variables are recognized by the build (you may
|
||||
also include architecture-specific settings).
|
||||
|
||||
Architecture selection:
|
||||
|
||||
CONFIG_ARCH - identifies the arch subdirectory
|
||||
CONFIG_ARCH_name - for use in C code
|
||||
|
||||
General OS setup
|
||||
|
||||
CONFIG_EXAMPLE - identifies the subdirectory in examples
|
||||
that will be used in the build
|
||||
CONFIG_DEBUG - enables built-in debug options
|
||||
CONFIG_DEBUG_VERBOSE - enables verbose debug output
|
||||
CONFIG_HAVE_LOWPUTC - architecture supports low-level, boot
|
||||
time console output
|
||||
CONFIG_MM_REGIONS - If the architecture includes multiple
|
||||
regions of memory to allocate from, this specifies the
|
||||
number of memory regions that the memory manager must
|
||||
handle and enables the API mm_addregion(start, end);
|
||||
CONFIG_RR_INTERVAL - The round robin timeslice will be set
|
||||
this number of milliseconds; Round robin scheduling can
|
||||
be disabled by setting this value to zero.
|
||||
CONFIG_SCHED_INSTRUMENTATION - enables instrumentation in
|
||||
scheduler to monitor system performance
|
||||
CONFIG_TASK_NAME_SIZE - Spcifies that maximum size of a
|
||||
task name to save in the TCB. Useful if scheduler
|
||||
instrumentation is selected. Set to zero to disable.
|
||||
CONFIG_START_YEAR, CONFIG_START_MONTH, CONFIG_START_DAY -
|
||||
Used to initialize the internal time logic.
|
||||
CONFIG_JULIAN_TIME - Enables Julian time conversions
|
||||
CONFIG_DEV_CONSOLE - Set if architecture-specific logic
|
||||
provides /dev/console. Enables stdout, stderr, stdin.
|
||||
|
||||
The following can be used to disable categories of APIs supported
|
||||
by the OS. If the compiler supports weak functions, then it
|
||||
should not be necessary to disable functions unless you want to
|
||||
restrict usage of those APIs.
|
||||
|
||||
There are certain dependency relationships in these features.
|
||||
|
||||
o mq_notify logic depends on signals to awaken tasks
|
||||
waiting for queues to become full or empty.
|
||||
o pthread_condtimedwait() depends on signals to wake
|
||||
up waiting tasks.
|
||||
|
||||
CONFIG_DISABLE_CLOCK, CONFIG_DISABLE_POSIX_TIMERS, CONFIG_DISABLE_PTHREAD.
|
||||
CONFIG_DISABLE_SIGNALS, CONFIG_DISABLE_MQUEUE
|
||||
|
||||
|
||||
Misc libc settings
|
||||
|
||||
CONFIG_NOPRINTF_FIELDWIDTH - sprintf-related logic is a
|
||||
little smaller if we do not support fieldwidthes
|
||||
|
||||
Allow for architecture optimized implementations
|
||||
|
||||
The architecture can provide optimized versions of the
|
||||
following to improve sysem performance
|
||||
|
||||
CONFIG_ARCH_MEMCPY, CONFIG_ARCH_MEMCMP, CONFIG_ARCH_MEMMOVE
|
||||
CONFIG_ARCH_MEMSET, CONFIG_ARCH_STRCMP, CONFIG_ARCH_STRCPY
|
||||
CONFIG_ARCH_STRNCPY, CONFIG_ARCH_STRLEN, CONFIG_ARCH_BZERO
|
||||
CONFIG_ARCH_KMALLOC, CONFIG_ARCH_KZMALLOC, CONFIG_ARCH_KFREE
|
||||
|
||||
Sizes of configurable things (0 disables)
|
||||
|
||||
CONFIG_MAX_TASKS - The maximum number of simultaneously
|
||||
active tasks. This value must be a power of two.
|
||||
CONFIG_NPTHREAD_KEYS - The number of items of thread-
|
||||
specific data that can be retained
|
||||
CONFIG_NFILE_DESCRIPTORS - The maximum number of file
|
||||
descriptors (one for each open)
|
||||
CONFIG_NFILE_STREAMS - The maximum number of streams that
|
||||
can be fopen'ed
|
||||
CONFIG_NAME_MAX - The maximum size of a file name.
|
||||
CONFIG_STDIO_BUFFER_SIZE - Size of the buffer to allocate
|
||||
on fopen. (Only if CONFIG_NFILE_STREAMS > 0)
|
||||
CONFIG_NUNGET_CHARS - Number of characters that can be
|
||||
buffered by ungetc() (Only if CONFIG_NFILE_STREAMS > 0)
|
||||
CONFIG_PREALLOC_MQ_MSGS - The number of pre-allocated message
|
||||
structures. The system manages a pool of preallocated
|
||||
message structures to minimize dynamic allocations
|
||||
CONFIG_MQ_MAXMSGSIZE - Message structures are allocated with
|
||||
a fixed payload size given by this settin (does not include
|
||||
other message structure overhead.
|
||||
CONFIG_PREALLOC_WDOGS - The number of pre-allocated watchdog
|
||||
structures. The system manages a pool of preallocated
|
||||
watchdog structures to minimize dynamic allocations
|
||||
|
||||
Stack and heap information
|
||||
|
||||
CONFIG_BOOT_FROM_FLASH - Some configurations support XIP
|
||||
operation from FLASH.
|
||||
CONFIG_STACK_POINTER - The initial stack pointer
|
||||
CONFIG_PROC_STACK_SIZE - The size of the initial stack
|
||||
CONFIG_PTHREAD_STACK_MIN - Minimum pthread stack size
|
||||
CONFIG_PTHREAD_STACK_DEFAULT - Default pthread stack size
|
||||
CONFIG_HEAP_BASE - The beginning of the heap
|
||||
CONFIG_HEAP_SIZE - The size of the heap
|
||||
|
||||
setenv.sh -- This is a script that you can include that will be installed at
|
||||
the toplevel of the directory structure and can be sourced to set any
|
||||
necessary environment variables.
|
||||
include/<chip-name>/
|
||||
This sub-directory contains chip-specific header files.
|
||||
|
||||
include/arch.h
|
||||
This is a hook for any architecture specific definitions that may
|
||||
@@ -206,6 +110,9 @@ include/irq.h
|
||||
This file must also define NR_IRQS, the total number of IRQs supported
|
||||
by the board.
|
||||
|
||||
src/<chip-name>/
|
||||
This sub-directory contains chip-specific source files.
|
||||
|
||||
src/Makefile
|
||||
This makefile will be executed to build the targets src/libup.a and
|
||||
src/up_head.o. The up_head.o file holds the entry point into the system
|
||||
@@ -225,37 +132,20 @@ arch/sim
|
||||
arch/c5471
|
||||
TI TMS320C5471 (also called TMS320DM180 or just C5471).
|
||||
NuttX operates on the ARM7 of this dual core processor. This port
|
||||
uses the Spectrum Digital evaluation board with a GNU arm-elf toolchain*.
|
||||
This port is complete, verified, and included in the NuttX release.
|
||||
complete, verified, and included in the NuttX release 0.1.1.
|
||||
|
||||
arch/dm320
|
||||
TI TMS320DM320 (also called just DM320).
|
||||
NuttX operates on the ARM9EJS of this dual core processor.
|
||||
This port uses the Neuros OSD with a GNU arm-elf toolchain*:
|
||||
see http://wiki.neurostechnology.com/index.php/Developer_Welcome .
|
||||
STATUS: This port is code complete but totally untested due to
|
||||
hardware issues with my OSD.
|
||||
NuttX operates on the ARM9EJS of this dual core processor. This port
|
||||
complete, verified, and included in the NuttX release 0.2.1.
|
||||
|
||||
arch/m68322
|
||||
A work in progress.
|
||||
|
||||
arch/pjrc-8051
|
||||
8051 Microcontroller. This port uses the PJRC 87C52 development system
|
||||
and the SDCC toolchain. This port is not quite ready for prime time.
|
||||
8051 Microcontroller. This port is not quite ready for prime time.
|
||||
|
||||
Other ports for the for the TI TMS320DM270 and for MIPS are in various states
|
||||
of progress
|
||||
|
||||
Configuring NuttX
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Configuring NuttX requires only copying
|
||||
|
||||
arch/<arch-name>/Make.def to ${TOPDIR}/Make.defs
|
||||
arch/<arch-name>/setenv.sh to ${TOPDIR}/setenv.sh
|
||||
arch/<arch-name>/defconfig to ${TOPDIR}/.config
|
||||
|
||||
There is a script that automates these steps. The following steps will
|
||||
accomplish the same configuration:
|
||||
|
||||
cd tools
|
||||
./configure.sh <arch-name>
|
||||
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ CSRCS = up_initialize.c up_initialstate.c up_idle.c up_doirq.c \
|
||||
up_exit.c up_assert.c up_blocktask.c up_unblocktask.c \
|
||||
up_releasepending.c up_reprioritizertr.c up_copystate.c \
|
||||
up_schedulesigaction.c up_sigdeliver.c up_serial.c \
|
||||
up_delay.c up_allocateheap.c up_leds.c up_watchdog.c
|
||||
up_delay.c up_allocateheap.c up_watchdog.c
|
||||
COBJS = $(CSRCS:.c=.o)
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
@@ -65,6 +65,8 @@ LINKLIBS =
|
||||
LDPATHES = $(addprefix -L$(TOPDIR)/,$(dir $(LINKLIBS)))
|
||||
LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(LINKLIBS))))
|
||||
|
||||
BOARDDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src/board
|
||||
|
||||
LIBGCC = ${shell $(CC) -print-libgcc-file-name}
|
||||
|
||||
all: up_head.o libarch$(LIBEXT)
|
||||
@@ -81,9 +83,12 @@ libarch$(LIBEXT): $(OBJS)
|
||||
{ echo "$(AR) $@ $obj FAILED!" ; exit 1 ; } ; \
|
||||
done ; )
|
||||
|
||||
nuttx: $(LINKOBJS)
|
||||
$(LD) --entry=__start $(LDFLAGS) $(LDPATHES) -o $(TOPDIR)/$@ $(LINKOBJS) \
|
||||
--start-group $(LDLIBS) --end-group $(EXTRA_LIBS) $(LIBGCC)
|
||||
board/libboard$(LIBEXT):
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) libboard$(LIBEXT)
|
||||
|
||||
nuttx: $(LINKOBJS) board/libboard$(LIBEXT)
|
||||
$(LD) --entry=__start $(LDFLAGS) $(LDPATHES) -L$(BOARDDIR) -o $(TOPDIR)/$@ $(LINKOBJS) \
|
||||
--start-group $(LDLIBS) -lboard --end-group $(EXTRA_LIBS) $(LIBGCC)
|
||||
@$(NM) $(TOPDIR)/$@ | \
|
||||
grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
|
||||
sort > $(TOPDIR)/System.map
|
||||
@@ -101,14 +106,21 @@ endif
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
$(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) depend
|
||||
touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
@if [ -e board/Makefile ]; then \
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) clean ; \
|
||||
fi
|
||||
rm -f libarch$(LIBEXT) *.o *~
|
||||
|
||||
distclean: clean
|
||||
@if [ -e board/Makefile ]; then \
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) distclean ; \
|
||||
fi
|
||||
rm -f Make.dep .depend
|
||||
|
||||
-include Make.dep
|
||||
|
||||
@@ -40,10 +40,18 @@
|
||||
* Included Files
|
||||
************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BOARD_C5471EVM)
|
||||
# include <arch/board/c5471evm.h>
|
||||
#else
|
||||
# warning "Undefined C5471 Board"
|
||||
#endif
|
||||
|
||||
/************************************************************
|
||||
* Definitions
|
||||
************************************************************/
|
||||
@@ -72,10 +80,6 @@
|
||||
#define CC_Z_BIT (1 << 30)
|
||||
#define CC_N_BIT (1 << 31)
|
||||
|
||||
/* Clocking *************************************************/
|
||||
|
||||
#define C5471_CLOCK 47500000 /* 47.5 MHz */
|
||||
|
||||
/* UARTs ****************************************************/
|
||||
|
||||
#define UART_IRDA_BASE 0xffff0800
|
||||
@@ -370,11 +374,6 @@ static inline void putreg16(uint16 val, unsigned int addr)
|
||||
__asm__ __volatile__("\tstrh %0, [%1]\n\t": : "r"(val), "r"(addr));
|
||||
}
|
||||
|
||||
/* Most C5471 registers are 16-bits wide */
|
||||
|
||||
#define getreg(a) getreg16(1)
|
||||
#define putreg(v,a) putreg16(v,a)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __C5471_H */
|
||||
|
||||
@@ -79,7 +79,7 @@ static inline uint32 up_getsp(void)
|
||||
* Name: up_stackdump
|
||||
************************************************************/
|
||||
|
||||
#ifdef CONFIG_C5471_STACKDUMP
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
static void up_stackdump(void)
|
||||
{
|
||||
_TCB *rtcb = (_TCB*)g_readytorun.head;
|
||||
@@ -137,7 +137,7 @@ static void _up_assert(int errorcode) /* __attribute__ ((noreturn)) */
|
||||
(void)irqsave();
|
||||
for(;;)
|
||||
{
|
||||
#ifdef CONFIG_C5471_LEDS
|
||||
#ifdef CONFIG_ARCH_LEDS
|
||||
up_ledon(LED_PANIC);
|
||||
up_delay(250);
|
||||
up_ledoff(LED_PANIC);
|
||||
|
||||
@@ -145,6 +145,13 @@ void _exit(int status)
|
||||
|
||||
(void)sched_removereadytorun(tcb);
|
||||
|
||||
/* We are not in a bad stack-- the head of the ready to run task list
|
||||
* does not correspond to the thread that is running. Disabling pre-
|
||||
* emption on this TCB should be enough to keep things stable.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Move the TCB to the specified blocked task list and delete it */
|
||||
|
||||
sched_addblocked(tcb, TSTATE_TASK_INACTIVE);
|
||||
@@ -159,6 +166,10 @@ void _exit(int status)
|
||||
(void)sched_mergepending();
|
||||
}
|
||||
|
||||
/* Now calling sched_unlock() should have no effect */
|
||||
|
||||
sched_unlock();
|
||||
|
||||
/* Now, perform the context switch to the new ready-to-run task at the
|
||||
* head of the list.
|
||||
*/
|
||||
|
||||
@@ -117,7 +117,7 @@ __start:
|
||||
#endif
|
||||
/* Initialize onboard LEDs */
|
||||
|
||||
#ifdef CONFIG_C5471_LEDS
|
||||
#ifdef CONFIG_ARCH_LEDS
|
||||
bl up_ledinit
|
||||
#endif
|
||||
|
||||
|
||||
@@ -40,6 +40,14 @@
|
||||
* Included Files
|
||||
************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#if defined(CONFIG_BOARD_C5471EVM)
|
||||
# include <arch/board/c5471evm.h>
|
||||
#else
|
||||
# warning "Undefined C5471 Board"
|
||||
#endif
|
||||
|
||||
/************************************************************
|
||||
* Definitions
|
||||
************************************************************/
|
||||
@@ -55,17 +63,6 @@
|
||||
#undef CONFIG_SUPPRESS_UART_CONFIG /* Do not reconfig UART */
|
||||
#undef CONFIG_DUMP_ON_EXIT /* Dump task state on exit */
|
||||
|
||||
/* LED definitions */
|
||||
|
||||
#define LED_STARTED 0
|
||||
#define LED_HEAPALLOCATE 1
|
||||
#define LED_IRQSENABLED 2
|
||||
#define LED_STACKCREATED 3
|
||||
#define LED_INIRQ 4
|
||||
#define LED_SIGNAL 5
|
||||
#define LED_ASSERTION 6
|
||||
#define LED_PANIC 7
|
||||
|
||||
/************************************************************
|
||||
* Public Types
|
||||
************************************************************/
|
||||
@@ -156,7 +153,7 @@ extern void up_maskack_irq(int irq);
|
||||
|
||||
/* Defined in up_leds.c */
|
||||
|
||||
#ifdef CONFIG_C5471_LEDS
|
||||
#ifdef CONFIG_ARCH_LEDS
|
||||
extern void up_ledinit(void);
|
||||
extern void up_ledon(int led);
|
||||
extern void up_ledoff(int led);
|
||||
|
||||
@@ -63,6 +63,8 @@ LINKLIBS =
|
||||
LDPATHES = $(addprefix -L$(TOPDIR)/,$(dir $(LINKLIBS)))
|
||||
LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(LINKLIBS))))
|
||||
|
||||
BOARDDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src/board
|
||||
|
||||
LIBGCC = ${shell $(CC) -print-libgcc-file-name}
|
||||
|
||||
all: up_head.o libarch$(LIBEXT)
|
||||
@@ -79,9 +81,12 @@ libarch$(LIBEXT): $(OBJS)
|
||||
{ echo "$(AR) $@ $obj FAILED!" ; exit 1 ; } ; \
|
||||
done ; )
|
||||
|
||||
nuttx: $(LINKOBJS)
|
||||
$(LD) --entry=__start $(LDFLAGS) $(LDPATHES) -o $(TOPDIR)/$@ $(LINKOBJS) \
|
||||
--start-group $(LDLIBS) --end-group $(EXTRA_LIBS) $(LIBGCC)
|
||||
board/libboard$(LIBEXT):
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) libboard$(LIBEXT)
|
||||
|
||||
nuttx: $(LINKOBJS) board/libboard$(LIBEXT)
|
||||
$(LD) --entry=__start $(LDFLAGS) $(LDPATHES) -L$(BOARDDIR) -o $(TOPDIR)/$@ $(LINKOBJS) \
|
||||
--start-group $(LDLIBS) -lboard --end-group $(EXTRA_LIBS) $(LIBGCC)
|
||||
@$(NM) $(TOPDIR)/$@ | \
|
||||
grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
|
||||
sort > $(TOPDIR)/System.map
|
||||
@@ -98,15 +103,24 @@ ifeq ($(CONFIG_RRLOAD_BINARY),y)
|
||||
endif
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
@if [ -e board/Makefile ]; then \
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) depend ; \
|
||||
if
|
||||
$(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
@if [ -e board/Makefile ]; then \
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) clean ; \
|
||||
fi
|
||||
rm -f libarch$(LIBEXT) *.o *~
|
||||
|
||||
distclean: clean
|
||||
@if [ -e board/Makefile ]; then \
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) distclean ; \
|
||||
fi
|
||||
rm -f Make.dep .depend
|
||||
|
||||
-include Make.dep
|
||||
|
||||
@@ -40,12 +40,19 @@
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#ifndef __ASSEMBLY__
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include "arm9.h"
|
||||
#include "ntosd.h"
|
||||
|
||||
#if defined(CONFIG_BOARD_NTOSD_DM320)
|
||||
# include <arch/board/ntosd.h>
|
||||
#else
|
||||
# warning "Unknown DM320 board"
|
||||
#endif
|
||||
|
||||
#include "dm320-memorymap.h"
|
||||
#include "dm320-uart.h"
|
||||
#include "dm320-timer.h"
|
||||
|
||||
@@ -128,7 +128,12 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
|
||||
void _exit(int status)
|
||||
{
|
||||
_TCB* tcb = (_TCB*)g_readytorun.head;
|
||||
irqstate_t flags = irqsave();
|
||||
|
||||
/* Disable interrupts. They will be restored when the next
|
||||
* task is started.
|
||||
*/
|
||||
|
||||
(void)irqsave();
|
||||
|
||||
lldbg("TCB=%p exitting\n", tcb);
|
||||
|
||||
@@ -144,6 +149,13 @@ void _exit(int status)
|
||||
|
||||
(void)sched_removereadytorun(tcb);
|
||||
|
||||
/* We are not in a bad stack-- the head of the ready to run task list
|
||||
* does not correspond to the thread that is running. Disabling pre-
|
||||
* emption on this TCB should be enough to keep things stable.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Move the TCB to the specified blocked task list and delete it */
|
||||
|
||||
sched_addblocked(tcb, TSTATE_TASK_INACTIVE);
|
||||
@@ -158,6 +170,10 @@ void _exit(int status)
|
||||
(void)sched_mergepending();
|
||||
}
|
||||
|
||||
/* Now calling sched_unlock() should have no effect */
|
||||
|
||||
sched_unlock();
|
||||
|
||||
/* Now, perform the context switch to the new ready-to-run task at the
|
||||
* head of the list.
|
||||
*/
|
||||
|
||||
@@ -277,10 +277,14 @@ __start:
|
||||
|
||||
bl up_boot
|
||||
|
||||
/* Set up the LEDs */
|
||||
|
||||
#ifdef CONFIG_ARCH_LEDS
|
||||
bl up_ledinit
|
||||
#endif
|
||||
/* Perform early serial initialization */
|
||||
|
||||
#ifdef CONFIG_DEV_CONSOLE
|
||||
mov fp, #0
|
||||
bl up_earlyserialinit
|
||||
#endif
|
||||
|
||||
|
||||
@@ -144,6 +144,18 @@ extern void up_timerinit(void);
|
||||
|
||||
extern void up_maskack_irq(int irq);
|
||||
|
||||
/* Defined in board/up_leds.c */
|
||||
|
||||
#ifdef CONFIG_ARCH_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 /* __UP_INTERNAL_H */
|
||||
|
||||
@@ -132,8 +132,6 @@ int up_timerisr(int irq, uint32 *regs)
|
||||
|
||||
void up_timerinit(void)
|
||||
{
|
||||
uint32 val;
|
||||
|
||||
up_disable_irq(DM320_IRQ_SYSTIMER);
|
||||
|
||||
/* Start timer0 running so that an interrupt is generated at
|
||||
|
||||
@@ -48,8 +48,7 @@ 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_leds.c \
|
||||
up_delay.c
|
||||
up_timerisr.c up_putc.c up_debug.c up_delay.c
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
SRCS = $(SSRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
@@ -70,6 +69,8 @@ TESTOBJS = $(TESTSRCS:.c=$(OBJEXT))
|
||||
TESTLINKOBJS = up_head$(OBJEXT)
|
||||
TESTEXTRAOBJS = up_savecontext$(OBJEXT) up_restorecontext$(OBJEXT)
|
||||
|
||||
BOARDDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src/board
|
||||
|
||||
IRAM_SIZE = 0x100
|
||||
DEF_STACK_BASE = 0x24
|
||||
LDFLAGS = --model-large --nostdlib \
|
||||
@@ -163,16 +164,23 @@ $(SDCCLIBDIR)/libmysdcc.lib: $(SDCCLIBDIR)/libsdcc.lib
|
||||
> libmysdcc.lib
|
||||
@sudo mv -f libmysdcc.lib $(SDCCLIBDIR)/libmysdcc.lib
|
||||
|
||||
# This builds the libboard library in the board/ subdirectory
|
||||
|
||||
board/libboard$(LIBEXT):
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) libboard$(LIBEXT)
|
||||
|
||||
# This target builds the final executable
|
||||
|
||||
pass1.ihx: up_mem.h $(SDCCLIBDIR)/libmysdcc.lib $(LINKOBJS)
|
||||
$(CC) $(LDFLAGS) $(LDPATHES) $(SDCCPATH) $(LINKOBJS) $(LDLIBS) $(SDCCLIBS) -o $@
|
||||
pass1.ihx: up_mem.h $(SDCCLIBDIR)/libmysdcc.lib $(LINKOBJS) board/libboard$(LIBEXT)
|
||||
$(CC) $(LDFLAGS) $(LDPATHES) -L$(BOARDDIR) $(SDCCPATH) $(LINKOBJS) \
|
||||
$(LDLIBS) -llibboard$(LIBEXT) $(SDCCLIBS) -o $@
|
||||
@rm -f up_mem.h
|
||||
@rm -f up_allocateheap$(OBJEXT) libarch$(LIBEXT)
|
||||
@$(MAKE) TOPDIR=$(TOPDIR) libarch$(LIBEXT)
|
||||
|
||||
nuttx.ihx: up_mem.h $(SDCCLIBDIR)/libmysdcc.lib $(LINKOBJS)
|
||||
$(CC) $(LDFLAGS) $(LDPATHES) $(SDCCPATH) $(LINKOBJS) $(LDLIBS) $(SDCCLIBS) -o $@
|
||||
$(CC) $(LDFLAGS) $(LDPATHES) -L$(BOARDDIR) $(SDCCPATH) $(LINKOBJS) \
|
||||
$(LDLIBS) -llibboard$(LIBEXT) $(SDCCLIBS) -o $@
|
||||
|
||||
nuttx$(EXEEXT): pass1.ihx nuttx.ihx
|
||||
@rm -f pass1.*
|
||||
@@ -191,17 +199,26 @@ irqtest:
|
||||
# Build dependencies
|
||||
|
||||
.depend: Makefile up_mem.h $(DEPSRCS)
|
||||
@if [ -e board/Makefile ]; then \
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) depend ; \
|
||||
if
|
||||
$(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
@if [ -e board/Makefile ]; then \
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) clean ; \
|
||||
fi
|
||||
rm -f libarch$(LIBEXT) up_mem.h
|
||||
rm -f *.asm *.rel *.lst *.rst *.sym *.adb *.lnk *.map *.mem *.ihx *.hex *~
|
||||
if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi
|
||||
|
||||
distclean: clean
|
||||
@if [ -e board/Makefile ]; then \
|
||||
$(MAKE) -C board TOPDIR=$(TOPDIR) distclean ; \
|
||||
fi
|
||||
rm -f Make.dep .depend
|
||||
|
||||
-include Make.dep
|
||||
|
||||
@@ -90,6 +90,13 @@ void _exit(int status)
|
||||
|
||||
(void)sched_removereadytorun(tcb);
|
||||
|
||||
/* We are not in a bad stack-- the head of the ready to run task list
|
||||
* does not correspond to the thread that is running. Disabling pre-
|
||||
* emption on this TCB should be enough to keep things stable.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Move the TCB to the specified blocked task list and delete it */
|
||||
|
||||
sched_addblocked(tcb, TSTATE_TASK_INACTIVE);
|
||||
@@ -104,6 +111,10 @@ void _exit(int status)
|
||||
(void)sched_mergepending();
|
||||
}
|
||||
|
||||
/* Now calling sched_unlock() should have no effect */
|
||||
|
||||
sched_unlock();
|
||||
|
||||
/* Now, perform the context switch to the new ready-to-run task at the
|
||||
* head of the list.
|
||||
*/
|
||||
|
||||
@@ -42,8 +42,11 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/irq.h>
|
||||
#ifdef CONFIG_ARCH_PJRC
|
||||
# include "pjrc.h"
|
||||
|
||||
#if defined(CONFIG_BOARD_PJRC_87C52)
|
||||
# include <arch/board/pjrc.h>
|
||||
#else
|
||||
# warning "805x board not recognized"
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
@@ -131,7 +134,7 @@ extern void up_dumpframe(FAR struct xcptcontext *context);
|
||||
# define up_dumpframe(x)
|
||||
#endif
|
||||
|
||||
/* Defined in up_leds.c */
|
||||
/* Defined in board/up_leds.c */
|
||||
|
||||
#ifdef CONFIG_ARCH_LEDS
|
||||
extern void up_ledinit(void);
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
void _exit(int status)
|
||||
{
|
||||
_TCB* tcb = (_TCB*)g_readytorun.head;
|
||||
irqstate_t flags;
|
||||
|
||||
dbg("TCB=%p exitting\n", tcb);
|
||||
|
||||
@@ -83,13 +84,20 @@ void _exit(int status)
|
||||
|
||||
(void)sched_removereadytorun(tcb);
|
||||
|
||||
/* We are not in a bad stack-- the head of the ready to run task list
|
||||
* does not correspond to the thread that is running. Disabling pre-
|
||||
* emption on this TCB should be enough to keep things stable.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Move the TCB to the specified blocked task list and delete it */
|
||||
|
||||
sched_addblocked(tcb, TSTATE_TASK_INACTIVE);
|
||||
task_delete(tcb->pid);
|
||||
|
||||
/* If there are any pending tasks, then add them to the g_readytorun
|
||||
* task list now
|
||||
* task list now.
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
@@ -97,6 +105,10 @@ void _exit(int status)
|
||||
(void)sched_mergepending();
|
||||
}
|
||||
|
||||
/* Now calling sched_unlock() should have no effect */
|
||||
|
||||
sched_unlock();
|
||||
|
||||
/* Now, perform the context switch to the new ready-to-run task at the
|
||||
* head of the list.
|
||||
*/
|
||||
|
||||
256
configs/README.txt
Normal file
256
configs/README.txt
Normal file
@@ -0,0 +1,256 @@
|
||||
Board-Specific Configurations
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Table of Contents
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
o Board-Specific Configurations
|
||||
o Summary of Files
|
||||
o Supported Architectures
|
||||
o Configuring NuttX
|
||||
|
||||
Board-Specific Configurations
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The NuttX configuration consists of:
|
||||
|
||||
o Processor architecture specific files. These are the files contained
|
||||
in the arch/<arch-name>/ directory.
|
||||
|
||||
o Chip/SoC specific files. Each processor processor architecture
|
||||
is embedded in chip or System-on-a-Chip (SoC) architecture. The
|
||||
full chip architecture includes the processor architecture plus
|
||||
chip-specific interrupt logic, general purpose I/O (GIO) logic, and
|
||||
specialized, internal peripherals (such as UARTs, USB, etc.).
|
||||
|
||||
These chip-specific files are contained within chip-specific
|
||||
sub-directories in the arch/<arch-name>/ directory and are selected
|
||||
via the CONFIG_ARCH_name selection
|
||||
|
||||
o Board specific files. In order to be usable, the chip must be
|
||||
contained in a board environment. The board configuration defines
|
||||
additional properties of the board including such things as
|
||||
peripheral LEDs, external peripherals (such as network, USB, etc.).
|
||||
|
||||
These board-specific configuration files can be found in the
|
||||
configs/<board-name>/ sub-directories and are discussed in this
|
||||
README.
|
||||
|
||||
The configs/ subdirectory contains configuration data for each board. These
|
||||
board-specific configurations plus the architecture-specific configurations in
|
||||
the arch/ subdirectory completely define a customized port of NuttX.
|
||||
|
||||
Directory Structure
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The configs directory contains board specific configurationlogic. Each
|
||||
board must provide a subdirectory <board-name> under configs/ with the
|
||||
following characteristics:
|
||||
|
||||
|
||||
<board-name>
|
||||
|-- include/
|
||||
| `-- (board-specific header files)
|
||||
|-- src/
|
||||
| |-- Makefile
|
||||
| `-- (board-specific source files)
|
||||
|-- Make.defs
|
||||
|-- defconfig
|
||||
`-- setenv.sh
|
||||
|
||||
Summary of Files
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
include/ -- This directory contains board specific header files. This
|
||||
directory will be linked as include/arch/board at configuration time and
|
||||
can be included via '#include <arch/board/header.h>'. These header file
|
||||
can only be included by files in arch/<arch-name>include/ and
|
||||
arch/<arch-name>/src
|
||||
|
||||
src/ -- This directory contains board specific drivers. This
|
||||
directory will be linked as arch/<arch-name>/src/board at configuration
|
||||
time and will be integrated into the build system.
|
||||
|
||||
src/Makefile -- This makefile will be invoked to build the board specific
|
||||
drivers. It must support the following targets: libext$(LIBEXT), clean,
|
||||
and distclean.
|
||||
|
||||
Make.defs -- This makefile fragment provides architecture and
|
||||
tool-specific build options. It will be included by all other
|
||||
makefiles in the build (once it is installed). This make fragment
|
||||
should define:
|
||||
|
||||
Tools: CC, LD, AR, NM, OBJCOPY, OBJDUMP
|
||||
Tool options: CFLAGS, LDFLAGS
|
||||
|
||||
When this makefile fragment runs, it will be passed TOPDIR which
|
||||
is the path to the root directory of the build. This makefile
|
||||
fragment may include ${TOPDIR}/.config to perform configuration
|
||||
specific settings. For example, the CFLAGS will most likely be
|
||||
different if CONFIG_DEBUG=y.
|
||||
|
||||
defconfig -- This is a configuration file similar to the Linux
|
||||
configuration file. In contains varialble/value pairs like:
|
||||
|
||||
CONFIG_VARIABLE=value
|
||||
|
||||
This configuration file will be used at build time:
|
||||
|
||||
(1) as a makefile fragment included in other makefiles, and
|
||||
(2) to generate include/nuttx/config.h which is included by
|
||||
most C files in the system.
|
||||
|
||||
The following variables are recognized by the build (you may
|
||||
also include architecture/board-specific settings).
|
||||
|
||||
Architecture selection:
|
||||
|
||||
CONFIG_ARCH - identifies the arch/ subdirectory
|
||||
CONFIG_ARCH_name - for use in C code
|
||||
|
||||
General OS setup
|
||||
|
||||
CONFIG_EXAMPLE - identifies the subdirectory in examples
|
||||
that will be used in the build
|
||||
CONFIG_DEBUG - enables built-in debug options
|
||||
CONFIG_DEBUG_VERBOSE - enables verbose debug output
|
||||
CONFIG_HAVE_LOWPUTC - architecture supports low-level, boot
|
||||
time console output
|
||||
CONFIG_MM_REGIONS - If the architecture includes multiple
|
||||
regions of memory to allocate from, this specifies the
|
||||
number of memory regions that the memory manager must
|
||||
handle and enables the API mm_addregion(start, end);
|
||||
CONFIG_RR_INTERVAL - The round robin timeslice will be set
|
||||
this number of milliseconds; Round robin scheduling can
|
||||
be disabled by setting this value to zero.
|
||||
CONFIG_SCHED_INSTRUMENTATION - enables instrumentation in
|
||||
scheduler to monitor system performance
|
||||
CONFIG_TASK_NAME_SIZE - Spcifies that maximum size of a
|
||||
task name to save in the TCB. Useful if scheduler
|
||||
instrumentation is selected. Set to zero to disable.
|
||||
CONFIG_START_YEAR, CONFIG_START_MONTH, CONFIG_START_DAY -
|
||||
Used to initialize the internal time logic.
|
||||
CONFIG_JULIAN_TIME - Enables Julian time conversions
|
||||
CONFIG_DEV_CONSOLE - Set if architecture-specific logic
|
||||
provides /dev/console. Enables stdout, stderr, stdin.
|
||||
|
||||
The following can be used to disable categories of APIs supported
|
||||
by the OS. If the compiler supports weak functions, then it
|
||||
should not be necessary to disable functions unless you want to
|
||||
restrict usage of those APIs.
|
||||
|
||||
There are certain dependency relationships in these features.
|
||||
|
||||
o mq_notify logic depends on signals to awaken tasks
|
||||
waiting for queues to become full or empty.
|
||||
o pthread_condtimedwait() depends on signals to wake
|
||||
up waiting tasks.
|
||||
|
||||
CONFIG_DISABLE_CLOCK, CONFIG_DISABLE_POSIX_TIMERS, CONFIG_DISABLE_PTHREAD.
|
||||
CONFIG_DISABLE_SIGNALS, CONFIG_DISABLE_MQUEUE
|
||||
|
||||
|
||||
Misc libc settings
|
||||
|
||||
CONFIG_NOPRINTF_FIELDWIDTH - sprintf-related logic is a
|
||||
little smaller if we do not support fieldwidthes
|
||||
|
||||
Allow for architecture optimized implementations
|
||||
|
||||
The architecture can provide optimized versions of the
|
||||
following to improve sysem performance
|
||||
|
||||
CONFIG_ARCH_MEMCPY, CONFIG_ARCH_MEMCMP, CONFIG_ARCH_MEMMOVE
|
||||
CONFIG_ARCH_MEMSET, CONFIG_ARCH_STRCMP, CONFIG_ARCH_STRCPY
|
||||
CONFIG_ARCH_STRNCPY, CONFIG_ARCH_STRLEN, CONFIG_ARCH_BZERO
|
||||
CONFIG_ARCH_KMALLOC, CONFIG_ARCH_KZMALLOC, CONFIG_ARCH_KFREE
|
||||
|
||||
Sizes of configurable things (0 disables)
|
||||
|
||||
CONFIG_MAX_TASKS - The maximum number of simultaneously
|
||||
active tasks. This value must be a power of two.
|
||||
CONFIG_NPTHREAD_KEYS - The number of items of thread-
|
||||
specific data that can be retained
|
||||
CONFIG_NFILE_DESCRIPTORS - The maximum number of file
|
||||
descriptors (one for each open)
|
||||
CONFIG_NFILE_STREAMS - The maximum number of streams that
|
||||
can be fopen'ed
|
||||
CONFIG_NAME_MAX - The maximum size of a file name.
|
||||
CONFIG_STDIO_BUFFER_SIZE - Size of the buffer to allocate
|
||||
on fopen. (Only if CONFIG_NFILE_STREAMS > 0)
|
||||
CONFIG_NUNGET_CHARS - Number of characters that can be
|
||||
buffered by ungetc() (Only if CONFIG_NFILE_STREAMS > 0)
|
||||
CONFIG_PREALLOC_MQ_MSGS - The number of pre-allocated message
|
||||
structures. The system manages a pool of preallocated
|
||||
message structures to minimize dynamic allocations
|
||||
CONFIG_MQ_MAXMSGSIZE - Message structures are allocated with
|
||||
a fixed payload size given by this settin (does not include
|
||||
other message structure overhead.
|
||||
CONFIG_PREALLOC_WDOGS - The number of pre-allocated watchdog
|
||||
structures. The system manages a pool of preallocated
|
||||
watchdog structures to minimize dynamic allocations
|
||||
|
||||
Stack and heap information
|
||||
|
||||
CONFIG_BOOT_FROM_FLASH - Some configurations support XIP
|
||||
operation from FLASH.
|
||||
CONFIG_STACK_POINTER - The initial stack pointer
|
||||
CONFIG_PROC_STACK_SIZE - The size of the initial stack
|
||||
CONFIG_PTHREAD_STACK_MIN - Minimum pthread stack size
|
||||
CONFIG_PTHREAD_STACK_DEFAULT - Default pthread stack size
|
||||
CONFIG_HEAP_BASE - The beginning of the heap
|
||||
CONFIG_HEAP_SIZE - The size of the heap
|
||||
|
||||
setenv.sh -- This is a script that you can include that will be installed at
|
||||
the toplevel of the directory structure and can be sourced to set any
|
||||
necessary environment variables.
|
||||
|
||||
Supported Boards
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
configs/sim
|
||||
A user-mode port of NuttX to the x86 Linux platform is available.
|
||||
The purpose of this port is primarily to support OS feature developement.
|
||||
This port does not support interrupts or a real timer (and hence no
|
||||
round robin scheduler) Otherwise, it is complete.
|
||||
|
||||
configs/c5471evm
|
||||
This is a port to the Spectrum Digital C5471 evaluation board. The
|
||||
C5471 is a dual core processor from TI with an ARM7TDMI general purpose
|
||||
processor and a c54 SDP. NuttX runs on the ARM core and is built with
|
||||
with a GNU arm-elf toolchain*. This port is complete, verified, and
|
||||
included in the NuttX release.
|
||||
|
||||
configs/ntosd-dm320
|
||||
This port uses the Neuros OSD with a GNU arm-elf toolchain*:
|
||||
see http://wiki.neurostechnology.com/index.php/Developer_Welcome .
|
||||
NuttX operates on the ARM9EJS of this dual core processor.
|
||||
STATUS: This port is code complete, verified, and included in the
|
||||
NuttX 0.2.1 release.
|
||||
|
||||
configs/m68322evb
|
||||
This is a work in progress for the venerable m68322evb board from
|
||||
Motorola.
|
||||
|
||||
configs/pjrc-8051
|
||||
8051 Microcontroller. This port uses the PJRC 87C52 development system
|
||||
and the SDCC toolchain. This port is not quite ready for prime time.
|
||||
|
||||
Other ports for the for the TI TMS320DM270, M683222 and for MIPS are in various
|
||||
states of progress
|
||||
|
||||
Configuring NuttX
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Configuring NuttX requires only copying
|
||||
|
||||
configs/<board-name>/Make.def to ${TOPDIR}/Make.defs
|
||||
configs/<board-name>/setenv.sh to ${TOPDIR}/setenv.sh
|
||||
configs/<board-name>/defconfig to ${TOPDIR}/.config
|
||||
|
||||
There is a script that automates these steps. The following steps will
|
||||
accomplish the same configuration:
|
||||
|
||||
cd tools
|
||||
./configure.sh <board-name>
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ ARCHPICFLAGS = -fpic
|
||||
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow
|
||||
ARCHDEFINES =
|
||||
ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
|
||||
ARCHSCRIPT = -T$(TOPDIR)/arch/$(CONFIG_ARCH)/ld.script
|
||||
ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_BOARD)/ld.script
|
||||
|
||||
CROSSDEV = arm-elf-
|
||||
CC = $(CROSSDEV)gcc
|
||||
@@ -35,20 +35,28 @@
|
||||
#
|
||||
# architecture selection
|
||||
#
|
||||
# CONFIG_ARCH - identifies the arch subdirectory
|
||||
# CONFIG_ARCH_name - for use in C code
|
||||
# CONFIG_ARCH - identifies the arch subdirectory and, hence, the
|
||||
# processor architecture.
|
||||
# CONFIG_ARCH_name - for use in C code. This identifies the
|
||||
# particular chip or SoC that the architecture is implemented
|
||||
# in.
|
||||
# CONFIG_BOARD - identifies the configs subdirectory and, hence,
|
||||
# the board that supports the particular chip or SoC.
|
||||
# CONFIG_BOARD_name - for use in C code
|
||||
# CONFIG_ROM_VECTORS - unique to c5471
|
||||
# CONFIG_DRAM_END - the size of installed DRAM.
|
||||
# Unique to c5471
|
||||
# CONFIG_C5471_LEDS - Use LEDs to show state. Unique to c5471.
|
||||
# CONFIG_C5471_STACKDUMP - Do stack dumps after assertions
|
||||
# CONFIG_ARCH_LEDS - Use LEDs to show state. Unique to c5471.
|
||||
# CONFIG_ARCH_STACKDUMP - Do stack dumps after assertions
|
||||
#
|
||||
CONFIG_ARCH=c5471
|
||||
CONFIG_ARCH_C5471=y
|
||||
CONFIG_BOARD=c5471evm
|
||||
CONFIG_BOARD_C5471EVM=y
|
||||
CONFIG_ROM_VECTORS=n
|
||||
CONFIG_DRAM_END=0x11000000
|
||||
CONFIG_C5471_LEDS=y
|
||||
CONFIG_C5471_STACKDUMP=y
|
||||
CONFIG_ARCH_LEDS=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
|
||||
#
|
||||
# C5471 specific device driver settings
|
||||
1
configs/c5471evm/include/README.txt
Normal file
1
configs/c5471evm/include/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
This directory contains header files unique to the Spectrum Digital C5471 EVM.
|
||||
70
configs/c5471evm/include/c5471evm.h
Normal file
70
configs/c5471evm/include/c5471evm.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/************************************************************
|
||||
* c5471.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 __C5471EVM_H
|
||||
#define __C5471EVM_H
|
||||
|
||||
/************************************************************
|
||||
* Included Files
|
||||
************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/************************************************************
|
||||
* Definitions
|
||||
************************************************************/
|
||||
|
||||
/* Clocking *************************************************/
|
||||
|
||||
#define C5471_CLOCK 47500000 /* 47.5 MHz */
|
||||
|
||||
/* LED definitions ******************************************/
|
||||
|
||||
#define LED_STARTED 0
|
||||
#define LED_HEAPALLOCATE 1
|
||||
#define LED_IRQSENABLED 2
|
||||
#define LED_STACKCREATED 3
|
||||
#define LED_INIRQ 4
|
||||
#define LED_SIGNAL 5
|
||||
#define LED_ASSERTION 6
|
||||
#define LED_PANIC 7
|
||||
|
||||
/************************************************************
|
||||
* Inline Functions
|
||||
************************************************************/
|
||||
|
||||
#endif /* __C5471EVM_H */
|
||||
78
configs/c5471evm/src/Makefile
Normal file
78
configs/c5471evm/src/Makefile
Normal file
@@ -0,0 +1,78 @@
|
||||
############################################################
|
||||
# Makefile
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################
|
||||
|
||||
-include $(TOPDIR)/Make.defs
|
||||
|
||||
MKDEP = $(TOPDIR)/tools/mkdeps.sh
|
||||
CFLAGS += -I$(TOPDIR)/sched
|
||||
|
||||
ASRCS =
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
CSRCS = up_leds.c
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
CFLAGS += -I $(TOPDIR)/arch/$(CONFIG_ARCH)/src
|
||||
|
||||
all: libboard$(LIBEXT)
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(CC) -c $(CFLAGS) -D__ASSEMBLY__ $< -o $@
|
||||
|
||||
$(COBJS) $(LINKOBJS): %$(OBJEXT): %.c
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
libboard$(LIBEXT): $(OBJS)
|
||||
( for obj in $(OBJS) ; do \
|
||||
$(AR) $@ $${obj} || \
|
||||
{ echo "$(AR) $@ $obj FAILED!" ; exit 1 ; } ; \
|
||||
done ; )
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
$(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
rm -f libboard$(LIBEXT) *~
|
||||
if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi
|
||||
|
||||
distclean: clean
|
||||
rm -f Make.dep .depend
|
||||
|
||||
-include Make.dep
|
||||
2
configs/c5471evm/src/README.txt
Normal file
2
configs/c5471evm/src/README.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
This directory contains drivers unique to the Spectrum Digital C5471 EVM.
|
||||
|
||||
@@ -66,10 +66,10 @@ static uint32 g_ledstate;
|
||||
* Name: up_ledinit
|
||||
************************************************************/
|
||||
|
||||
#ifdef CONFIG_C5471_LEDS
|
||||
#ifdef CONFIG_ARCH_LEDS
|
||||
void up_ledinit(void)
|
||||
{
|
||||
/* Enable acces to LEDs */
|
||||
/* Enable access to LEDs */
|
||||
|
||||
CS2 = 0x000013db;
|
||||
|
||||
@@ -104,4 +104,4 @@ void up_ledoff(int led)
|
||||
LEDS = g_ledstate;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_C5471_LEDS */
|
||||
#endif /* CONFIG_ARCH_LEDS */
|
||||
71
configs/m68332evb/Make.defs
Normal file
71
configs/m68332evb/Make.defs
Normal file
@@ -0,0 +1,71 @@
|
||||
############################################################
|
||||
# Make.defs
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################
|
||||
|
||||
include ${TOPDIR}/.config
|
||||
|
||||
ifeq ("${CONFIG_DEBUG}","y")
|
||||
ARCHOPTIMIZATION = -g
|
||||
else
|
||||
ARCHOPTIMIZATION = -Os -fno-strict-aliasing -fno-strength-reduce \
|
||||
-fomit-frame-pointer
|
||||
endif
|
||||
|
||||
ARCHCPUFLAGS = -m68332 -mcpu32
|
||||
ARCHPICFLAGS = -pic
|
||||
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow
|
||||
ARCHDEFINES =
|
||||
ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
|
||||
ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_BOARD)/ld.script
|
||||
|
||||
CROSSDEV = m68k-elf-
|
||||
CC = $(CROSSDEV)gcc
|
||||
LD = $(CROSSDEV)ld
|
||||
AR = $(CROSSDEV)ar rcs
|
||||
NM = $(CROSSDEV)nm
|
||||
OBJCOPY = $(CROSSDEV)objcopy
|
||||
OBJDUMP = $(CROSSDEV)objdump
|
||||
|
||||
CFLAGS = $(ARCHWARNINGS) $(ARCHOPTIMIZATION) \
|
||||
$(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) -pipe
|
||||
|
||||
OBJEXT = .o
|
||||
LIBEXT = .a
|
||||
EXEEXT =
|
||||
|
||||
ifeq ("${CONFIG_DEBUG}","y")
|
||||
LDFLAGS += -g
|
||||
endif
|
||||
|
||||
|
||||
252
configs/m68332evb/defconfig
Normal file
252
configs/m68332evb/defconfig
Normal file
@@ -0,0 +1,252 @@
|
||||
############################################################
|
||||
# defconfig
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################
|
||||
#
|
||||
# architecture selection
|
||||
#
|
||||
# CONFIG_ARCH - identifies the arch subdirectory and, hence, the
|
||||
# processor architecture.
|
||||
# CONFIG_ARCH_name - for use in C code. This identifies the
|
||||
# particular chip or SoC that the architecture is implemented
|
||||
# in.
|
||||
# CONFIG_BOARD - identifies the configs subdirectory and, hence,
|
||||
# the board that supports the particular chip or SoC.
|
||||
# CONFIG_BOARD_name - for use in C code
|
||||
# CONFIG_DRAM_SIZE - Describes the installed DRAM.
|
||||
# CONFIG_ARCH_STACKDUMP - Do stack dumps after assertions
|
||||
#
|
||||
CONFIG_ARCH=m68332evb
|
||||
CONFIG_ARCH_M68332=y
|
||||
CONFIG_ARCH_M68332EVB=y
|
||||
CONFIG_BOARD=m68332evb
|
||||
CONFIG_BOARD_M68332EVB=y
|
||||
CONFIG_DRAM_SIZE=0x003000
|
||||
CONFIG_DRAM_NUTTXENTRY=0x003000
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
|
||||
#
|
||||
# DM320 specific device driver settings
|
||||
#
|
||||
# CONFIG_UARTn_SERIAL_CONSOLE - selects the UARTn for the
|
||||
# console and ttys0 (default is the UART0).
|
||||
# CONFIG_UARTn_RXBUFSIZE - Characters are buffered as received.
|
||||
# This specific the size of the receive buffer
|
||||
# CONFIG_UARTn_TXBUFSIZE - Characters are buffered before
|
||||
# being sent. This specific the size of the transmit buffer
|
||||
# CONFIG_UARTn_BAUD - The configure BAUD of the UART. Must be
|
||||
# CONFIG_UARTn_BITS - The number of bits. Must be either 7 or 8.
|
||||
# CONFIG_UARTn_PARTIY - 0=no parity, 1=odd parity, 2=even parity
|
||||
# CONFIG_UARTn_2STOP - Two stop bits
|
||||
#
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_UART1_SERIAL_CONSOLE=n
|
||||
CONFIG_UART0_TXBUFSIZE=256
|
||||
CONFIG_UART1_TXBUFSIZE=256
|
||||
CONFIG_UART0_RXBUFSIZE=256
|
||||
CONFIG_UART1_RXBUFSIZE=256
|
||||
CONFIG_UART0_BAUD=115200
|
||||
CONFIG_UART1_BAUD=115200
|
||||
CONFIG_UART0_BITS=8
|
||||
CONFIG_UART1_BITS=8
|
||||
CONFIG_UART0_PARITY=0
|
||||
CONFIG_UART1_PARITY=0
|
||||
CONFIG_UART0_2STOP=0
|
||||
CONFIG_UART1_2STOP=0
|
||||
|
||||
#
|
||||
# General OS setup
|
||||
#
|
||||
# CONFIG_EXAMPLE - identifies the subdirectory in examples
|
||||
# that will be used in the build
|
||||
# CONFIG_DEBUG - enables built-in debug options
|
||||
# CONFIG_DEBUG_VERBOSE - enables verbose debug output
|
||||
# CONFIG_MM_REGIONS - If the architecture includes multiple
|
||||
# regions of memory to allocate from, this specifies the
|
||||
# number of memory regions that the memory manager must
|
||||
# handle and enables the API mm_addregion(start, end);
|
||||
# CONFIG_HAVE_LOWPUTC - architecture supports low-level, boot
|
||||
# time console output
|
||||
# CONFIG_RR_INTERVAL - The round robin timeslice will be set
|
||||
# this number of milliseconds; Round robin scheduling can
|
||||
# be disabled by setting this value to zero.
|
||||
# CONFIG_SCHED_INSTRUMENTATION - enables instrumentation in
|
||||
# scheduler to monitor system performance
|
||||
# CONFIG_TASK_NAME_SIZE - Spcifies that maximum size of a
|
||||
# task name to save in the TCB. Useful if scheduler
|
||||
# instrumentation is selected. Set to zero to disable.
|
||||
# CONFIG_START_YEAR, CONFIG_START_MONTH, CONFIG_START_DAY -
|
||||
# Used to initialize the internal time logic.
|
||||
# CONFIG_JULIAN_TIME - Enables Julian time conversions
|
||||
# CONFIG_DEV_CONSOLE - Set if architecture-specific logic
|
||||
# provides /dev/console. Enables stdout, stderr, stdin.
|
||||
#
|
||||
CONFIG_EXAMPLE=ostest
|
||||
CONFIG_DEBUG=n
|
||||
CONFIG_DEBUG_VERBOSE=n
|
||||
CONFIG_MM_REGIONS=1
|
||||
CONFIG_ARCH_LOWPUTC=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_INSTRUMENTATION=n
|
||||
CONFIG_TASK_NAME_SIZE=0
|
||||
CONFIG_START_YEAR=2007
|
||||
CONFIG_START_MONTH=2
|
||||
CONFIG_START_DAY=13
|
||||
CONFIG_JULIAN_TIME=n
|
||||
CONFIG_DEV_CONSOLE=y
|
||||
|
||||
#
|
||||
# The following can be used to disable categories of
|
||||
# APIs supported by the OS. If the compiler supports
|
||||
# weak functions, then it should not be necessary to
|
||||
# disable functions unless you want to restrict usage
|
||||
# of those APIs.
|
||||
#
|
||||
# There are certain dependency relationships in these
|
||||
# features.
|
||||
#
|
||||
# o mq_notify logic depends on signals to awaken tasks
|
||||
# waiting for queues to become full or empty.
|
||||
# o pthread_condtimedwait() depends on signals to wake
|
||||
# up waiting tasks.
|
||||
#
|
||||
CONFIG_DISABLE_CLOCK=n
|
||||
CONFIG_DISABLE_POSIX_TIMERS=n
|
||||
CONFIG_DISABLE_PTHREAD=n
|
||||
CONFIG_DISABLE_SIGNALS=n
|
||||
CONFIG_DISABLE_MQUEUE=n
|
||||
|
||||
#
|
||||
# Misc libc settings
|
||||
#
|
||||
# CONFIG_NOPRINTF_FIELDWIDTH - sprintf-related logic is a
|
||||
# little smaller if we do not support fieldwidthes
|
||||
#
|
||||
CONFIG_NOPRINTF_FIELDWIDTH=n
|
||||
|
||||
#
|
||||
# Allow for architecture optimized implementations
|
||||
#
|
||||
# The architecture can provide optimized versions of the
|
||||
# following to improve sysem performance
|
||||
#
|
||||
CONFIG_ARCH_MEMCPY=n
|
||||
CONFIG_ARCH_MEMCMP=n
|
||||
CONFIG_ARCH_MEMMOVE=n
|
||||
CONFIG_ARCH_MEMSET=n
|
||||
CONFIG_ARCH_STRCMP=n
|
||||
CONFIG_ARCH_STRCPY=n
|
||||
CONFIG_ARCH_STRNCPY=n
|
||||
CONFIG_ARCH_STRLEN=n
|
||||
CONFIG_ARCH_BZERO=n
|
||||
CONFIG_ARCH_KMALLOC=n
|
||||
CONFIG_ARCH_KZMALLOC=n
|
||||
CONFIG_ARCH_KFREE=n
|
||||
|
||||
#
|
||||
# General build options
|
||||
#
|
||||
# CONFIG_RRLOAD_BINARY - make the rrload binary format used with
|
||||
# BSPs from www.ridgerun.com
|
||||
#
|
||||
CONFIG_RRLOAD_BINARY=n
|
||||
|
||||
#
|
||||
# Sizes of configurable things (0 disables)
|
||||
#
|
||||
# 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
|
||||
# descriptors (one for each open)
|
||||
# CONFIG_NFILE_STREAMS - The maximum number of streams that
|
||||
# can be fopen'ed
|
||||
# CONFIG_NAME_MAX - The maximum size of a file name.
|
||||
# CONFIG_STDIO_BUFFER_SIZE - Size of the buffer to allocate
|
||||
# on fopen. (Only if CONFIG_NFILE_STREAMS > 0)
|
||||
# CONFIG_NUNGET_CHARS - Number of characters that can be
|
||||
# buffered by ungetc() (Only if CONFIG_NFILE_STREAMS > 0)
|
||||
# CONFIG_PREALLOC_MQ_MSGS - The number of pre-allocated message
|
||||
# structures. The system manages a pool of preallocated
|
||||
# message structures to minimize dynamic allocations
|
||||
# CONFIG_MQ_MAXMSGSIZE - Message structures are allocated with
|
||||
# a fixed payload size given by this settin (does not include
|
||||
# other message structure overhead.
|
||||
# CONFIG_MAX_WDOGPARMS - Maximum number of parameters that
|
||||
# can be passed to a watchdog handler
|
||||
# CONFIG_PREALLOC_WDOGS - The number of pre-allocated watchdog
|
||||
# structures. The system manages a pool of preallocated
|
||||
# watchdog structures to minimize dynamic allocations
|
||||
# CONFIG_PREALLOC_TIMERS - The number of pre-allocated POSIX
|
||||
# timer structures. The system manages a pool of preallocated
|
||||
# timer structures to minimize dynamic allocations. Set to
|
||||
# zero for all dynamic allocations.
|
||||
#
|
||||
CONFIG_MAX_TASKS=64
|
||||
CONFIG_MAX_TASK_ARGS=4
|
||||
CONFIG_NPTHREAD_KEYS=4
|
||||
CONFIG_NFILE_DESCRIPTORS=32
|
||||
CONFIG_NFILE_STREAMS=16
|
||||
CONFIG_NAME_MAX=32
|
||||
CONFIG_STDIO_BUFFER_SIZE=1024
|
||||
CONFIG_NUNGET_CHARS=2
|
||||
CONFIG_PREALLOC_MQ_MSGS=32
|
||||
CONFIG_MQ_MAXMSGSIZE=32
|
||||
CONFIG_MAX_WDOGPARMS=4
|
||||
CONFIG_PREALLOC_WDOGS=32
|
||||
CONFIG_PREALLOC_TIMERS=8
|
||||
|
||||
#
|
||||
# Stack and heap information
|
||||
#
|
||||
# CONFIG_BOOT_FROM_FLASH - Some configurations support XIP
|
||||
# operation from FLASH.
|
||||
# CONFIG_CUSTOM_STACK - The up_ implementation will handle
|
||||
# all stack operations outside of the nuttx model.
|
||||
# CONFIG_PROC_STACK_SIZE - The size of the initial stack
|
||||
# CONFIG_PTHREAD_STACK_MIN - Minimum pthread stack size
|
||||
# CONFIG_PTHREAD_STACK_DEFAULT - Default pthread stack size
|
||||
# CONFIG_HEAP_BASE - The beginning of the heap
|
||||
# CONFIG_HEAP_SIZE - The size of the heap
|
||||
#
|
||||
CONFIG_BOOT_FROM_FLASH=n
|
||||
CONFIG_CUSTOM_STACK=n
|
||||
CONFIG_PROC_STACK_SIZE=4096
|
||||
CONFIG_PTHREAD_STACK_MIN=256
|
||||
CONFIG_PTHREAD_STACK_DEFAULT=4096
|
||||
CONFIG_HEAP_BASE=
|
||||
CONFIG_HEAP_SIZE=
|
||||
111
configs/m68332evb/doc/m68k-defconfig
Normal file
111
configs/m68332evb/doc/m68k-defconfig
Normal file
@@ -0,0 +1,111 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
#
|
||||
BR2_HAVE_DOT_CONFIG=y
|
||||
# BR2_alpha is not set
|
||||
# BR2_arm is not set
|
||||
# BR2_armeb is not set
|
||||
# BR2_avr32 is not set
|
||||
# BR2_cris is not set
|
||||
# BR2_i386 is not set
|
||||
BR2_m68k=y
|
||||
# BR2_mips is not set
|
||||
# BR2_mipsel is not set
|
||||
# BR2_nios2 is not set
|
||||
# BR2_powerpc is not set
|
||||
# BR2_sh is not set
|
||||
# BR2_sh64 is not set
|
||||
# BR2_sparc is not set
|
||||
# BR2_x86_64 is not set
|
||||
BR2_ARCH="m68k"
|
||||
BR2_ENDIAN="BIG"
|
||||
|
||||
#
|
||||
# Build options
|
||||
#
|
||||
BR2_WGET="wget --passive-ftp"
|
||||
BR2_SVN="svn co"
|
||||
BR2_ZCAT="zcat"
|
||||
BR2_BZCAT="bzcat"
|
||||
BR2_TAR_OPTIONS=""
|
||||
BR2_DL_DIR="$(BASE_DIR)/../archives"
|
||||
BR2_SOURCEFORGE_MIRROR="easynews"
|
||||
BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
|
||||
BR2_NUTTX_DIR="$(TOPDIR)/../nuttx"
|
||||
BR2_TOPDIR_PREFIX=""
|
||||
BR2_TOPDIR_SUFFIX=""
|
||||
BR2_GNU_BUILD_SUFFIX="m68k-elf"
|
||||
BR2_GNU_TARGET_SUFFIX="elf"
|
||||
# BR2_PREFER_IMA is not set
|
||||
# BR2_DEPRECATED is not set
|
||||
|
||||
#
|
||||
# Toolchain Options
|
||||
#
|
||||
|
||||
#
|
||||
# Binutils Options
|
||||
#
|
||||
# BR2_BINUTILS_VERSION_2_14_90_0_8 is not set
|
||||
# BR2_BINUTILS_VERSION_2_15 is not set
|
||||
# BR2_BINUTILS_VERSION_2_15_94_0_2_2 is not set
|
||||
# BR2_BINUTILS_VERSION_2_16_1 is not set
|
||||
# BR2_BINUTILS_VERSION_2_16_90_0_3 is not set
|
||||
# BR2_BINUTILS_VERSION_2_16_91_0_5 is not set
|
||||
# BR2_BINUTILS_VERSION_2_16_91_0_6 is not set
|
||||
# BR2_BINUTILS_VERSION_2_16_91_0_7 is not set
|
||||
BR2_BINUTILS_VERSION_2_17=y
|
||||
# BR2_BINUTILS_VERSION_2_17_50_0_2 is not set
|
||||
# BR2_BINUTILS_VERSION_2_17_50_0_3 is not set
|
||||
# BR2_BINUTILS_VERSION_2_17_50_0_4 is not set
|
||||
# BR2_BINUTILS_VERSION_2_17_50_0_5 is not set
|
||||
# BR2_BINUTILS_VERSION_2_17_50_0_6 is not set
|
||||
# BR2_BINUTILS_VERSION_2_17_50_0_7 is not set
|
||||
# BR2_BINUTILS_VERSION_2_17_50_0_8 is not set
|
||||
# BR2_BINUTILS_VERSION_2_17_50_0_9 is not set
|
||||
# BR2_BINUTILS_VERSION_2_17_50_0_10 is not set
|
||||
BR2_BINUTILS_VERSION="2.17"
|
||||
BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
|
||||
|
||||
#
|
||||
# Gcc Options
|
||||
#
|
||||
# BR2_GCC_VERSION_3_3_5 is not set
|
||||
# BR2_GCC_VERSION_3_3_6 is not set
|
||||
# BR2_GCC_VERSION_3_4_2 is not set
|
||||
# BR2_GCC_VERSION_3_4_3 is not set
|
||||
# BR2_GCC_VERSION_3_4_4 is not set
|
||||
# BR2_GCC_VERSION_3_4_5 is not set
|
||||
BR2_GCC_VERSION_3_4_6=y
|
||||
# BR2_GCC_VERSION_4_0_0 is not set
|
||||
# BR2_GCC_VERSION_4_0_1 is not set
|
||||
# BR2_GCC_VERSION_4_0_2 is not set
|
||||
# BR2_GCC_VERSION_4_0_3 is not set
|
||||
# BR2_GCC_VERSION_4_0_4 is not set
|
||||
# BR2_GCC_VERSION_4_1_0 is not set
|
||||
# BR2_GCC_VERSION_4_1_1 is not set
|
||||
# BR2_GCC_VERSION_4_1_2 is not set
|
||||
# BR2_GCC_VERSION_4_2 is not set
|
||||
# BR2_GCC_IS_SNAP is not set
|
||||
BR2_GCC_VERSION="3.4.6"
|
||||
# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
|
||||
BR2_EXTRA_GCC_CONFIG_OPTIONS=""
|
||||
# BR2_INSTALL_LIBSTDCPP is not set
|
||||
# BR2_INSTALL_OBJC is not set
|
||||
# BR2_INSTALL_FORTRAN is not set
|
||||
|
||||
#
|
||||
# Gdb Options
|
||||
#
|
||||
# BR2_PACKAGE_GDB is not set
|
||||
# BR2_PACKAGE_GDB_SERVER is not set
|
||||
# BR2_PACKAGE_GDB_HOST is not set
|
||||
|
||||
#
|
||||
# Common Toolchain Options
|
||||
#
|
||||
# BR2_PACKAGE_SSTRIP_TARGET is not set
|
||||
# BR2_PACKAGE_SSTRIP_HOST is not set
|
||||
# BR2_ENABLE_MULTILIB is not set
|
||||
BR2_LARGEFILE=y
|
||||
BR2_TARGET_OPTIMIZATION="-Os -pipe"
|
||||
1
configs/m68332evb/include/README.txt
Normal file
1
configs/m68332evb/include/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
This directory contains header files unique to the M68322EVB.
|
||||
84
configs/m68332evb/ld.script
Normal file
84
configs/m68332evb/ld.script
Normal file
@@ -0,0 +1,84 @@
|
||||
/************************************************************
|
||||
* ld.script
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_stext)
|
||||
SECTIONS
|
||||
{
|
||||
/* The OS entry point is here */
|
||||
|
||||
. = 0x003000;
|
||||
.text : {
|
||||
_stext = ABSOLUTE(.);
|
||||
*(.text)
|
||||
*(.fixup)
|
||||
*(.gnu.warning)
|
||||
*(.rodata)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.got) /* Global offset table */
|
||||
_etext = ABSOLUTE(.);
|
||||
}
|
||||
|
||||
_eronly = ABSOLUTE(.); /* See below */
|
||||
. = ALIGN(4096);
|
||||
|
||||
.data : {
|
||||
_sdata = ABSOLUTE(.);
|
||||
*(.data)
|
||||
CONSTRUCTORS
|
||||
_edata = ABSOLUTE(.);
|
||||
}
|
||||
|
||||
.bss : { /* BSS */
|
||||
_sbss = ABSOLUTE(.);
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_ebss = ABSOLUTE(.);
|
||||
}
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
}
|
||||
46
configs/m68332evb/setenv.sh
Executable file
46
configs/m68332evb/setenv.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
# setenv.sh
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
if [ "$(basename $0)" = "setenv" ] ; then
|
||||
echo "You must source this script, not run it!" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z ${PATH_ORIG} ]; then export PATH_ORIG=${PATH}; fi
|
||||
|
||||
WD=`pwd`
|
||||
export BUILDROOT_BIN=${WD}/../buildroot/build_m68k/staging_dir/bin
|
||||
export PATH=${BUILDROOT_BIN}:/sbin:/usr/sbin:${PATH_ORIG}
|
||||
|
||||
echo "PATH : ${PATH}"
|
||||
76
configs/m68332evb/src/Makefile
Normal file
76
configs/m68332evb/src/Makefile
Normal file
@@ -0,0 +1,76 @@
|
||||
############################################################
|
||||
# Makefile
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################
|
||||
|
||||
-include $(TOPDIR)/Make.defs
|
||||
|
||||
MKDEP = $(TOPDIR)/tools/mkdeps.sh
|
||||
CFLAGS += -I$(TOPDIR)/sched
|
||||
|
||||
ASRCS =
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
CSRCS =
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
all: libboard$(LIBEXT)
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(CC) -c $(CFLAGS) -D__ASSEMBLY__ $< -o $@
|
||||
|
||||
$(COBJS) $(LINKOBJS): %$(OBJEXT): %.c
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
libboard$(LIBEXT): $(OBJS)
|
||||
( for obj in $(OBJS) ; do \
|
||||
$(AR) $@ $${obj} || \
|
||||
{ echo "$(AR) $@ $obj FAILED!" ; exit 1 ; } ; \
|
||||
done ; )
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
$(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
rm -f libboard$(LIBEXT) *~
|
||||
if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi
|
||||
|
||||
distclean: clean
|
||||
rm -f Make.dep .depend
|
||||
|
||||
-include Make.dep
|
||||
1
configs/m68332evb/src/README.txt
Normal file
1
configs/m68332evb/src/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
This directory contains drivers unique to the m68332evb.
|
||||
@@ -42,12 +42,12 @@ else
|
||||
-fomit-frame-pointer
|
||||
endif
|
||||
|
||||
ARCHCPUFLAGS = -mapcs-32 -mcpu=arm7tdmi -msoft-float -fno-builtin
|
||||
ARCHCPUFLAGS = -mapcs-32 -mtune=arm9tdmi -march=armv5te -msoft-float -fno-builtin
|
||||
ARCHPICFLAGS = -fpic
|
||||
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow
|
||||
ARCHDEFINES =
|
||||
ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
|
||||
ARCHSCRIPT = -T$(TOPDIR)/arch/$(CONFIG_ARCH)/ld.script
|
||||
ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_BOARD)/ld.script
|
||||
|
||||
CROSSDEV = arm-elf-
|
||||
CC = $(CROSSDEV)gcc
|
||||
@@ -35,14 +35,22 @@
|
||||
#
|
||||
# architecture selection
|
||||
#
|
||||
# CONFIG_ARCH - identifies the arch subdirectory
|
||||
# CONFIG_ARCH_name - for use in C code
|
||||
# CONFIG_ARCH - identifies the arch subdirectory and, hence, the
|
||||
# processor architecture.
|
||||
# CONFIG_ARCH_name - for use in C code. This identifies the
|
||||
# particular chip or SoC that the architecture is implemented
|
||||
# in.
|
||||
# CONFIG_BOARD - identifies the configs subdirectory and, hence,
|
||||
# the board that supports the particular chip or SoC.
|
||||
# CONFIG_BOARD_name - for use in C code
|
||||
# CONFIG_ROM_VECTORS - unique to dm320
|
||||
# CONFIG_DRAM_SIZE - Describes the installed DRAM.
|
||||
# CONFIG_ARCH_STACKDUMP - Do stack dumps after assertions
|
||||
#
|
||||
CONFIG_ARCH=dm320
|
||||
CONFIG_ARCH_DM320=y
|
||||
CONFIG_BOARD=ntosd-dm320
|
||||
CONFIG_BOARD_NTOSD_DM320=y
|
||||
CONFIG_ROM_VECTORS=n
|
||||
CONFIG_DRAM_SIZE=0x01000000
|
||||
CONFIG_DRAM_NUTTXENTRY=0x01008000
|
||||
@@ -172,7 +180,7 @@ CONFIG_ARCH_KFREE=n
|
||||
# CONFIG_RRLOAD_BINARY - make the rrload binary format used with
|
||||
# BSPs from www.ridgerun.com
|
||||
#
|
||||
CONFIG_RRLOAD_BINARY=y
|
||||
CONFIG_RRLOAD_BINARY=n
|
||||
|
||||
#
|
||||
# Sizes of configurable things (0 disables)
|
||||
468
configs/ntosd-dm320/doc/test-result.txt
Normal file
468
configs/ntosd-dm320/doc/test-result.txt
Normal file
@@ -0,0 +1,468 @@
|
||||
This is the output from running examples/ostest on March 28, 2007
|
||||
=================================================================
|
||||
|
||||
Neuros Devboard > tftpboot 10.0.0.1 nuttx.dm320
|
||||
Found DM9000 ID:90000a46 at address 60000300 !
|
||||
DM9000 work in 16 bus width
|
||||
[eth_init]MAC:0:18:11:80:10:6:
|
||||
TFTP from server 10.0.0.1; our IP address is 10.0.0.2
|
||||
Filename 'nuttx.dm320'.
|
||||
Load address: 0x10
|
||||
Loading: #############################
|
||||
done
|
||||
Bytes transferred = 146570 (23c8a hex)
|
||||
Neuros Devboard > go 1008000
|
||||
## Starting application at 0x01008000 ...
|
||||
stdio_test: write fd=1
|
||||
stdio_test: write fd=2
|
||||
stdio_test: Standard I/O Check: printf
|
||||
user_start: Started user_main at PID=2
|
||||
stdio_test: Standard I/O Check: fprintf to stderr
|
||||
|
||||
user_main: Begin argument test
|
||||
user_main: Started with argc=5
|
||||
user_main: argv[0]="<noname>"
|
||||
user_main: argv[1]="Arg1"
|
||||
user_main: argv[2]="Arg2"
|
||||
user_main: argv[3]="Arg3"
|
||||
user_main: argv[4]="Arg4"
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: /dev/null test
|
||||
dev_null: Read 0 bytes from /dev/null
|
||||
dev_null: Wrote 1024 bytes to /dev/null
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: mutex test
|
||||
Initializing mutex
|
||||
Starting thread 1
|
||||
Starting thread 2
|
||||
Thread1 Thread2
|
||||
Loops 32 32
|
||||
Errors 0 0
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: cancel test
|
||||
cancel_test: Test 1: Normal Cancelation
|
||||
cancel_test: Starting thread
|
||||
start_thread: Initializing mutex
|
||||
start_thread: Initializing cond
|
||||
start_thread: Starting thread
|
||||
thread_waiter: Taking mutex
|
||||
thread_waiter: Starting wait for condition
|
||||
start_thread: Yielding
|
||||
cancel_test: Canceling thread
|
||||
cancel_test: Joining
|
||||
cancel_test: waiter exited with result=ffffffff
|
||||
cancel_test: PASS thread terminated with PTHREAD_CANCELED
|
||||
cancel_test: Test 2: Cancelation of detached thread
|
||||
cancel_test: Re-starting thread
|
||||
restart_thread: Destroying cond
|
||||
restart_thread: Destroying mutex
|
||||
restart_thread: Re-starting thread
|
||||
start_thread: Initializing mutex
|
||||
start_thread: Initializing cond
|
||||
start_thread: Starting thread
|
||||
thread_waiter: Taking mutex
|
||||
thread_waiter: Starting wait for condition
|
||||
start_thread: Yielding
|
||||
cancel_test: Canceling thread
|
||||
cancel_test: Joining
|
||||
cancel_test: PASS pthread_join failed with status=ESRCH
|
||||
cancel_test: Test 3: Non-cancelable threads
|
||||
cancel_test: Re-starting thread (non-cancelable)
|
||||
restart_thread: Destroying cond
|
||||
restart_thread: Destroying mutex
|
||||
restart_thread: Re-starting thread
|
||||
start_thread: Initializing mutex
|
||||
start_thread: Initializing cond
|
||||
start_thread: Starting thread
|
||||
thread_waiter: Taking mutex
|
||||
thread_waiter: Starting wait for condition
|
||||
thread_waiter: Setting non-cancelable
|
||||
start_thread: Yielding
|
||||
cancel_test: Canceling thread
|
||||
cancel_test: Joining
|
||||
thread_waiter: Releasing mutex
|
||||
thread_waiter: Setting cancelable
|
||||
cancel_test: waiter exited with result=ffffffff
|
||||
cancel_test: PASS thread terminated with PTHREAD_CANCELED
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: semaphore test
|
||||
sem_test: Initializing semaphore to 0
|
||||
sem_test: Starting waiter thread 1
|
||||
sem_test: Set thread 1 priority to 191
|
||||
waiter_func: Thread 1 Started
|
||||
waiter_func: Thread 1 initial semaphore value = 0
|
||||
waiter_func: Thread 1 aiting on semaphore
|
||||
sem_test: Starting waiter thread 2
|
||||
sem_test: Set thread 2 priority to 128
|
||||
waiter_func: Thread 2 Started
|
||||
waiter_func: Thread 2 initial semaphore value = -1
|
||||
waiter_func: Thread 2 aiting on semaphore
|
||||
sem_test: Starting poster thread 3
|
||||
sem_test: Set thread 3 priority to 64
|
||||
poster_func: Thread 3 started
|
||||
poster_func: Thread 3 semaphore value = -2
|
||||
poster_func: Thread 3 posting semaphore
|
||||
waiter_func: Thread 1 awakened
|
||||
waiter_func: Thread 1 new semaphore value = -1
|
||||
waiter_func: Thread 1 done
|
||||
poster_func: Thread 3 new semaphore value = -1
|
||||
poster_func: Thread 3 semaphore value = -1
|
||||
poster_func: Thread 3 posting semaphore
|
||||
waiter_func: Thread 2 awakened
|
||||
waiter_func: Thread 2 new semaphore value = 0
|
||||
waiter_func: Thread 2 done
|
||||
poster_func: Thread 3 new semaphore value = 0
|
||||
poster_func: Thread 3 done
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: condition variable test
|
||||
cond_test: Initializing mutex
|
||||
cond_test: Initializing cond
|
||||
cond_test: Starting waiter
|
||||
cond_test: Set thread 1 priority to 128
|
||||
waiter_thread: Started
|
||||
cond_test: Starting signaler
|
||||
cond_test: Set thread 2 priority to 64
|
||||
thread_signaler: Started
|
||||
thread_signaler: Terminating
|
||||
cond_test: signaler terminated, now cancel the waiter
|
||||
cond_test: Waiter Signaler
|
||||
cond_test: Loops 32 32
|
||||
cond_test: Errors 0 0
|
||||
cond_test:
|
||||
0 times, waiter did not have to wait for data
|
||||
cond_test: 0 times, data was already available when the signaler run
|
||||
cond_test: 0 times, the waiter was in an unexpected state when the signaler ran
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: timed wait test
|
||||
thread_waiter: Initializing mutex
|
||||
timedwait_test: Initializing cond
|
||||
timedwait_test: Starting waiter
|
||||
timedwait_test: Set thread 2 priority to 177
|
||||
thread_waiter: Taking mutex
|
||||
thread_waiter: Starting 5 second wait for condition
|
||||
timedwait_test: Joining
|
||||
thread_waiter: pthread_cond_timedwait timed out
|
||||
thread_waiter: Releasing mutex
|
||||
thread_waiter: Exit with status 0x12345678
|
||||
timedwait_test: waiter exited with result=12345678
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: message queue test
|
||||
mqueue_test: Starting receiver
|
||||
mqueue_test: Set receiver priority to 128
|
||||
receiver_thread: Starting
|
||||
mqueue_test: Starting sender
|
||||
mqueue_test: Set sender thread priority to 64
|
||||
mqueue_test: Waiting for sender to complete
|
||||
sender_thread: Starting
|
||||
receiver_thread: mq_receive succeeded on msg 0
|
||||
sender_thread: mq_send succeeded on msg 0
|
||||
receiver_thread: mq_receive succeeded on msg 1
|
||||
sender_thread: mq_send succeeded on msg 1
|
||||
receiver_thread: mq_receive succeeded on msg 2
|
||||
sender_thread: mq_send succeeded on msg 2
|
||||
receiver_thread: mq_receive succeeded on msg 3
|
||||
sender_thread: mq_send succeeded on msg 3
|
||||
receiver_thread: mq_receive succeeded on msg 4
|
||||
sender_thread: mq_send succeeded on msg 4
|
||||
receiver_thread: mq_receive succeeded on msg 5
|
||||
sender_thread: mq_send succeeded on msg 5
|
||||
receiver_thread: mq_receive succeeded on msg 6
|
||||
sender_thread: mq_send succeeded on msg 6
|
||||
receiver_thread: mq_receive succeeded on msg 7
|
||||
sender_thread: mq_send succeeded on msg 7
|
||||
receiver_thread: mq_receive succeeded on msg 8
|
||||
sender_thread: mq_send succeeded on msg 8
|
||||
receiver_thread: mq_receive succeeded on msg 9
|
||||
sender_thread: mq_send succeeded on msg 9
|
||||
sender_thread: returning nerrors=0
|
||||
mqueue_test: Killing receiver
|
||||
receiver_thread: mq_receive interrupted!
|
||||
receiver_thread: returning nerrors=0
|
||||
mqueue_test: Canceling receiver
|
||||
mqueue_test: receiver has already terminated
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: timed message queue test
|
||||
timedmqueue_test: Starting sender
|
||||
sender_thread: Starting
|
||||
sender_thread: mq_timedsend succeeded on msg 0
|
||||
sender_thread: mq_timedsend succeeded on msg 1
|
||||
sender_thread: mq_timedsend succeeded on msg 2
|
||||
sender_thread: mq_timedsend succeeded on msg 3
|
||||
sender_thread: mq_timedsend succeeded on msg 4
|
||||
sender_thread: mq_timedsend succeeded on msg 5
|
||||
sender_thread: mq_timedsend succeeded on msg 6
|
||||
sender_thread: mq_timedsend succeeded on msg 7
|
||||
sender_thread: mq_timedsend succeeded on msg 8
|
||||
timedmqueue_test: Waiting for sender to complete
|
||||
sender_thread: mq_timedsend 9 timed out as expected
|
||||
sender_thread: returning nerrors=0
|
||||
timedmqueue_test: Starting receiver
|
||||
receiver_thread: Starting
|
||||
receiver_thread: mq_timedreceive succeeded on msg 0
|
||||
receiver_thread: mq_timedreceive succeeded on msg 1
|
||||
receiver_thread: mq_timedreceive succeeded on msg 2
|
||||
receiver_thread: mq_timedreceive succeeded on msg 3
|
||||
receiver_thread: mq_timedreceive succeeded on msg 4
|
||||
receiver_thread: mq_timedreceive succeeded on msg 5
|
||||
receiver_thread: mq_timedreceive succeeded on msg 6
|
||||
receiver_thread: mq_timedreceive succeeded on msg 7
|
||||
receiver_thread: mq_timedreceive succeeded on msg 8
|
||||
timedmqueue_test: Waiting for sender to complete
|
||||
receiver_thread: Receive 9 timed out as expected
|
||||
receiver_thread: returning nerrors=0
|
||||
timedmqueue_test: Test complete
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: signal handler test
|
||||
sighand_test: Initializing semaphore to 0
|
||||
sighand_test: Starting waiter task
|
||||
sighand_test: Started waiter_main pid=18
|
||||
waiter_main: Waiter started
|
||||
waiter_main: Unmasking signal 17
|
||||
waiter_main: Registering signal handler
|
||||
waiter_main: oact.sigaction=0 oact.sa_flags=0 oact.sa_mask=0
|
||||
waiter_main: Waiting on semaphore
|
||||
sighand_test: Signaling pid=18 with signo=17 sigvalue=42
|
||||
wakeup_action: Received signal 17
|
||||
wakeup_action: sival_int=42
|
||||
wakeup_action: si_code=1
|
||||
wakeup_action: ucontext=0
|
||||
waiter_main: sem_wait() successfully interrupted by signal
|
||||
waiter_main: done
|
||||
sighand_test: done
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: POSIX timer test
|
||||
timer_test: Initializing semaphore to 0
|
||||
timer_test: Unmasking signal 17
|
||||
timer_test: Registering signal handler
|
||||
timer_test: oact.sigaction=0 oact.sa_flags=0 oact.sa_mask=0
|
||||
timer_test: Creating timer
|
||||
timer_test: Starting timer
|
||||
timer_test: Waiting on semaphore
|
||||
timer_expiration: Received signal 17
|
||||
timer_expiration: sival_int=42
|
||||
timer_expiration: si_code=2 (SI_TIMER)
|
||||
timer_expiration: ucontext=0
|
||||
timer_test: sem_wait() successfully interrupted by signal
|
||||
timer_test: g_nsigreceived=1
|
||||
timer_test: Waiting on semaphore
|
||||
timer_expiration: Received signal 17
|
||||
timer_expiration: sival_int=42
|
||||
timer_expiration: si_code=2 (SI_TIMER)
|
||||
timer_expiration: ucontext=0
|
||||
timer_test: sem_wait() successfully interrupted by signal
|
||||
timer_test: g_nsigreceived=2
|
||||
timer_test: Waiting on semaphore
|
||||
timer_expiration: Received signal 17
|
||||
timer_expiration: sival_int=42
|
||||
timer_expiration: si_code=2 (SI_TIMER)
|
||||
timer_expiration: ucontext=0
|
||||
timer_test: sem_wait() successfully interrupted by signal
|
||||
timer_test: g_nsigreceived=3
|
||||
timer_test: Waiting on semaphore
|
||||
timer_expiration: Received signal 17
|
||||
timer_expiration: sival_int=42
|
||||
timer_expiration: si_code=2 (SI_TIMER)
|
||||
timer_expiration: ucontext=0
|
||||
timer_test: sem_wait() successfully interrupted by signal
|
||||
timer_test: g_nsigreceived=4
|
||||
timer_test: Waiting on semaphore
|
||||
timer_expiration: Received signal 17
|
||||
timer_expiration: sival_int=42
|
||||
timer_expiration: si_code=2 (SI_TIMER)
|
||||
timer_expiration: ucontext=0
|
||||
timer_test: sem_wait() successfully interrupted by signal
|
||||
timer_test: g_nsigreceived=5
|
||||
timer_test: Deleting timer
|
||||
timer_test: done
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: round-robin scheduler test
|
||||
rr_test: Starting sieve1 thread
|
||||
rr_test: Set thread priority to 1
|
||||
rr_test: Set thread policty to SCHED_RR
|
||||
rr_test: Starting sieve1 thread
|
||||
sieve1 started
|
||||
sieve1 finished
|
||||
rr_test: Waiting for sieves to complete -- this should take awhile
|
||||
rr_test: If RR scheduling is working, they should start and complete at
|
||||
rr_test: about the same time
|
||||
sieve2 started
|
||||
sieve2 finished
|
||||
rr_test: Done
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
user_main: barrier test
|
||||
barrier_test: Initializing barrier
|
||||
barrier_func: Thread 0 started
|
||||
barrier_test: Thread 0 created
|
||||
barrier_func: Thread 1 started
|
||||
barrier_test: Thread 1 created
|
||||
barrier_func: Thread 0 calling pthread_barrier_wait()
|
||||
barrier_func: Thread 1 calling pthread_barrier_wait()
|
||||
barrier_func: Thread 2 started
|
||||
barrier_test: Thread 2 created
|
||||
barrier_func: Thread 3 started
|
||||
barrier_test: Thread 3 created
|
||||
barrier_func: Thread 4 started
|
||||
barrier_test: Thread 4 created
|
||||
barrier_func: Thread 5 started
|
||||
barrier_func: Thread 2 calling pthread_barrier_wait()
|
||||
barrier_func: Thread 3 calling pthread_barrier_wait()
|
||||
barrier_func: Thread 4 calling pthread_barrier_wait()
|
||||
barrier_test: Thread 5 created
|
||||
barrier_func: Thread 6 started
|
||||
barrier_test: Thread 6 created
|
||||
barrier_func: Thread 7 started
|
||||
barrier_test: Thread 7 created
|
||||
barrier_func: Thread 5 calling pthread_barrier_wait()
|
||||
barrier_func: Thread 6 calling pthread_barrier_wait()
|
||||
barrier_func: Thread 7 calling pthread_barrier_wait()
|
||||
barrier_func: Thread 7, back with status=PTHREAD_BARRIER_SERIAL_THREAD (I AM SPECIAL)
|
||||
barrier_func: Thread 0, back with status=0 (I am not special)
|
||||
barrier_func: Thread 1, back with status=0 (I am not special)
|
||||
barrier_func: Thread 2, back with status=0 (I am not special)
|
||||
barrier_func: Thread 3, back with status=0 (I am not special)
|
||||
barrier_func: Thread 4, back with status=0 (I am not special)
|
||||
barrier_func: Thread 5, back with status=0 (I am not special)
|
||||
barrier_func: Thread 6, back with status=0 (I am not special)
|
||||
barrier_func: Thread 7 done
|
||||
barrier_func: Thread 0 done
|
||||
barrier_test: Thread 0 completed with result=0
|
||||
barrier_func: Thread 1 done
|
||||
barrier_func: Thread 2 done
|
||||
barrier_func: Thread 3 done
|
||||
barrier_func: Thread 4 done
|
||||
barrier_func: Thread 5 done
|
||||
barrier_func: Thread 6 done
|
||||
barrier_test: Thread 1 completed with result=0
|
||||
barrier_test: Thread 2 completed with result=0
|
||||
barrier_test: Thread 3 completed with result=0
|
||||
barrier_test: Thread 4 completed with result=0
|
||||
barrier_test: Thread 5 completed with result=0
|
||||
barrier_test: Thread 6 completed with result=0
|
||||
barrier_test: Thread 7 completed with result=0
|
||||
|
||||
End of test memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
|
||||
Final memory usage:
|
||||
VARIABLE BEFORE AFTER
|
||||
======== ======== ========
|
||||
arena fe0f10 fe0f10
|
||||
ordblks 2 2
|
||||
mxordblk fd99b0 fd99b0
|
||||
uordblks 53f0 53f0
|
||||
fordblks fdbb20 fdbb20
|
||||
user_main: Exitting
|
||||
1
configs/ntosd-dm320/include/README.txt
Normal file
1
configs/ntosd-dm320/include/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
This directory contains header files unique to the Neuros dm320-based OSD.
|
||||
78
configs/ntosd-dm320/src/Makefile
Normal file
78
configs/ntosd-dm320/src/Makefile
Normal file
@@ -0,0 +1,78 @@
|
||||
############################################################
|
||||
# Makefile
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################
|
||||
|
||||
-include $(TOPDIR)/Make.defs
|
||||
|
||||
MKDEP = $(TOPDIR)/tools/mkdeps.sh
|
||||
CFLAGS += -I$(TOPDIR)/sched
|
||||
|
||||
ASRCS =
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
CSRCS = up_leds.c
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
CFLAGS += -I $(TOPDIR)/arch/$(CONFIG_ARCH)/src
|
||||
|
||||
all: libboard$(LIBEXT)
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(CC) -c $(CFLAGS) -D__ASSEMBLY__ $< -o $@
|
||||
|
||||
$(COBJS) $(LINKOBJS): %$(OBJEXT): %.c
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
libboard$(LIBEXT): $(OBJS)
|
||||
( for obj in $(OBJS) ; do \
|
||||
$(AR) $@ $${obj} || \
|
||||
{ echo "$(AR) $@ $obj FAILED!" ; exit 1 ; } ; \
|
||||
done ; )
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
$(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
rm -f libboard$(LIBEXT) *~
|
||||
if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi
|
||||
|
||||
distclean: clean
|
||||
rm -f Make.dep .depend
|
||||
|
||||
-include Make.dep
|
||||
1
configs/ntosd-dm320/src/README.txt
Normal file
1
configs/ntosd-dm320/src/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
This directory contains drivers unique to the Neuros OSD.
|
||||
104
configs/ntosd-dm320/src/up_leds.c
Normal file
104
configs/ntosd-dm320/src/up_leds.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/************************************************************
|
||||
* 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
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Private Functions
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Public Funtions
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Name: up_ledinit
|
||||
************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_LEDS
|
||||
void up_ledinit(void)
|
||||
{
|
||||
GIO_OUTPUT(GIO_LED_GREEN);
|
||||
GIO_OUTPUT(GIO_LED_RED);
|
||||
GIO_SET_OUTPUT(GIO_LED_GREEN);
|
||||
GIO_CLEAR_OUTPUT(GIO_LED_RED);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* Name: up_ledon
|
||||
************************************************************/
|
||||
|
||||
void up_ledon(int led)
|
||||
{
|
||||
if (led == GIO_LED_GREEN)
|
||||
{
|
||||
GIO_SET_OUTPUT(GIO_LED_GREEN);
|
||||
}
|
||||
else if (led == GIO_LED_RED)
|
||||
{
|
||||
GIO_SET_OUTPUT(GIO_LED_RED);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* Name: up_ledoff
|
||||
************************************************************/
|
||||
|
||||
void up_ledoff(int led)
|
||||
{
|
||||
if (led == GIO_LED_GREEN)
|
||||
{
|
||||
GIO_CLEAR_OUTPUT(GIO_LED_GREEN);
|
||||
}
|
||||
else if (led == GIO_LED_RED)
|
||||
{
|
||||
GIO_CLEAR_OUTPUT(GIO_LED_RED);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_ARCH_LEDS */
|
||||
@@ -35,13 +35,21 @@
|
||||
#
|
||||
# Architecture selection
|
||||
#
|
||||
# CONFIG_ARCH - identifies the arch subdirectory
|
||||
# CONFIG_ARCH - identifies the arch subdirectory and, hence, the
|
||||
# processor architecture.
|
||||
# CONFIG_ARCH_8051 - Set if processor is 8051 family
|
||||
# CONFIG_ARCH_8052 = Set if processor is 8052 family
|
||||
# CONFIG_BOARD - identifies the configs subdirectory and, hence,
|
||||
# the board that supports the particular chip or SoC.
|
||||
# CONFIG_BOARD_name - for use in C code
|
||||
# CONFIG_BOARD - identifies the configs subdirectory
|
||||
# CONFIG_BARD_name - for use in C code
|
||||
#
|
||||
CONFIG_ARCH=pjrc-8051
|
||||
CONFIG_ARCH_8051=n
|
||||
CONFIG_ARCH_8052=y
|
||||
CONFIG_BOARD=pjrc-8051
|
||||
CONFIG_BOARD_PJRC_87C52=y
|
||||
|
||||
#
|
||||
# Architecture-specific settings. These may mean nothing to
|
||||
1
configs/pjrc-8051/include/README.txt
Normal file
1
configs/pjrc-8051/include/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
This directory contains header files unique to the PJRC 87C52 development board.
|
||||
79
configs/pjrc-8051/src/Makefile
Normal file
79
configs/pjrc-8051/src/Makefile
Normal file
@@ -0,0 +1,79 @@
|
||||
############################################################
|
||||
# Makefile
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################
|
||||
|
||||
-include $(TOPDIR)/Make.defs
|
||||
|
||||
MKDEP = $(TOPDIR)/tools/mkdeps.sh
|
||||
CFLAGS += -I$(TOPDIR)/sched
|
||||
|
||||
ASRCS =
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
CSRCS = up_leds.c
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
CFLAGS += -I $(TOPDIR)/arch/$(CONFIG_ARCH)/src
|
||||
|
||||
all: libboard$(LIBEXT)
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(CC) -c $(CFLAGS) -D__ASSEMBLY__ $< -o $@
|
||||
|
||||
$(COBJS) $(LINKOBJS): %$(OBJEXT): %.c
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
libboard$(LIBEXT): $(OBJS)
|
||||
( for obj in $(OBJS) ; do \
|
||||
$(AR) $@ $${obj} || \
|
||||
{ echo "$(AR) $@ $obj FAILED!" ; exit 1 ; } ; \
|
||||
done ; )
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
$(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
rm -f libboard$(LIBEXT)
|
||||
rm -f *.asm *.rel *.lst *.rst *.sym *.adb *.lnk *.map *.mem *.ihx *.hex *~
|
||||
if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi
|
||||
|
||||
distclean: clean
|
||||
rm -f Make.dep .depend
|
||||
|
||||
-include Make.dep
|
||||
1
configs/pjrc-8051/src/README.txt
Normal file
1
configs/pjrc-8051/src/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
This directory contains drivers unique to the PJRC 87C52 board.
|
||||
@@ -35,11 +35,19 @@
|
||||
#
|
||||
# architecture selection
|
||||
#
|
||||
# CONFIG_ARCH - identifies the arch subdirectory
|
||||
# CONFIG_ARCH_name - for use in C code
|
||||
# CONFIG_ARCH - identifies the arch subdirectory and, hence, the
|
||||
# processor architecture.
|
||||
# CONFIG_ARCH_name - for use in C code. This identifies the
|
||||
# particular chip or SoC that the architecture is implemented
|
||||
# in.
|
||||
# CONFIG_BOARD - identifies the configs subdirectory and, hence,
|
||||
# the board that supports the particular chip or SoC.
|
||||
# CONFIG_BOARD_name - for use in C code
|
||||
#
|
||||
CONFIG_ARCH=sim
|
||||
CONFIG_ARCH_SIM=y
|
||||
CONFIG_BOARD=sim
|
||||
CONFIG_BOARD_SIM=y
|
||||
|
||||
#
|
||||
# General OS setup
|
||||
1
configs/sim/include/README.txt
Normal file
1
configs/sim/include/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
This directory contains header files unique to the Linux user-mode platform.
|
||||
76
configs/sim/src/Makefile
Normal file
76
configs/sim/src/Makefile
Normal file
@@ -0,0 +1,76 @@
|
||||
############################################################
|
||||
# Makefile
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################
|
||||
|
||||
-include $(TOPDIR)/Make.defs
|
||||
|
||||
MKDEP = $(TOPDIR)/tools/mkdeps.sh
|
||||
CFLAGS += -I$(TOPDIR)/sched
|
||||
|
||||
ASRCS =
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
CSRCS =
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
all: libboard$(LIBEXT)
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(CC) -c $(CFLAGS) -D__ASSEMBLY__ $< -o $@
|
||||
|
||||
$(COBJS) $(LINKOBJS): %$(OBJEXT): %.c
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
libboard$(LIBEXT): $(OBJS)
|
||||
( for obj in $(OBJS) ; do \
|
||||
$(AR) $@ $${obj} || \
|
||||
{ echo "$(AR) $@ $obj FAILED!" ; exit 1 ; } ; \
|
||||
done ; )
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
$(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
rm -f libboard$(LIBEXT) *~
|
||||
if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi
|
||||
|
||||
distclean: clean
|
||||
rm -f Make.dep .depend
|
||||
|
||||
-include Make.dep
|
||||
1
configs/sim/src/README.txt
Normal file
1
configs/sim/src/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
This directory contains drivers unique to the Linux user-mode platform.
|
||||
@@ -42,17 +42,22 @@ ASRCS =
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
CSRCS = main.c dev_null.c
|
||||
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
|
||||
CSRCS += cancel.c cond.c mutex.c sem.c roundrobin.c
|
||||
CSRCS += cancel.c cond.c mutex.c sem.c roundrobin.c barrier.c
|
||||
endif
|
||||
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
||||
CSRCS += sighand.c
|
||||
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
|
||||
ifneq ($(CONFIG_DISABLE_CLOCK),y)
|
||||
CSRCS += timedwait.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifneq ($(CONFIG_DISABLE_MQUEUE),y)
|
||||
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
|
||||
CSRCS += mqueue.c
|
||||
ifneq ($(CONFIG_DISABLE_CLOCK),y)
|
||||
CSRCS += timedmqueue.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifneq ($(CONFIG_DISABLE_POSIX_TIMERS),y)
|
||||
|
||||
151
examples/ostest/barrier.c
Normal file
151
examples/ostest/barrier.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/***********************************************************************
|
||||
* barrier.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.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include "ostest.h"
|
||||
|
||||
#define NBARRIER_THREADS 8
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
|
||||
static void *barrier_func(void *parameter)
|
||||
{
|
||||
int id = (int)parameter;
|
||||
int status;
|
||||
|
||||
printf("barrier_func: Thread %d started\n", id);
|
||||
usleep(500*1000);
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
printf("barrier_func: Thread %d calling pthread_barrier_wait()\n", id);
|
||||
status = pthread_barrier_wait(&barrier);
|
||||
if (status == 0)
|
||||
{
|
||||
printf("barrier_func: Thread %d, back with status=0 (I am not special)\n", id, status);
|
||||
}
|
||||
else if (status == PTHREAD_BARRIER_SERIAL_THREAD)
|
||||
{
|
||||
printf("barrier_func: Thread %d, back with status=PTHREAD_BARRIER_SERIAL_THREAD (I AM SPECIAL)\n", id, status);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("barrier_func: ERROR thread %d could not get semaphore value\n", id);
|
||||
}
|
||||
|
||||
usleep(500*1000);
|
||||
printf("barrier_func: Thread %d done\n", id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void barrier_test(void)
|
||||
{
|
||||
pthread_t barrier_thread[NBARRIER_THREADS];
|
||||
pthread_addr_t result;
|
||||
pthread_attr_t attr;
|
||||
pthread_barrierattr_t barrierattr;
|
||||
int status;
|
||||
int i;
|
||||
|
||||
printf("barrier_test: Initializing barrier\n");
|
||||
|
||||
status = pthread_barrierattr_init(&barrierattr);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("barrier_test: pthread_barrierattr_init failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
status = pthread_barrier_init(&barrier, &barrierattr, NBARRIER_THREADS);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("barrier_test: pthread_barrierattr_init failed, status=%d\n", status);
|
||||
}
|
||||
/* Create the barrier */
|
||||
|
||||
status = pthread_barrierattr_init(&barrierattr);
|
||||
|
||||
/* Start NBARRIER_THREADS thread instances */
|
||||
|
||||
status = pthread_attr_init(&attr);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("barrier_test: pthread_attr_init failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
for (i = 0; i < NBARRIER_THREADS; i++)
|
||||
{
|
||||
status = pthread_create(&barrier_thread[i], &attr, barrier_func, (pthread_addr_t)i);
|
||||
if (status != 0)
|
||||
{
|
||||
printf("barrier_test: Error in thread %d create, status=%d\n", i, status);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("barrier_test: Thread %d created\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for all thread instances to complete */
|
||||
|
||||
for (i = 0; i < NBARRIER_THREADS; i++)
|
||||
{
|
||||
status = pthread_join(barrier_thread[i], &result);
|
||||
if (status != 0)
|
||||
{
|
||||
printf("barrier_test: Error in thread %d join, status=%d\n", i, status);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("barrier_test: Thread %d completed with result=%p\n", i, result);
|
||||
}
|
||||
}
|
||||
|
||||
/* Destroy the barrier */
|
||||
|
||||
status = pthread_barrier_destroy(&barrier);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("barrier_test: pthread_barrier_destroy failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
status = pthread_barrierattr_destroy(&barrierattr);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("barrier_test: pthread_barrierattr_destroy failed, status=%d\n", status);
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,9 @@ void cancel_test(void)
|
||||
printf("cancel_test: ERROR pthread_cancel failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
/* Then join to the thread to pick up the result */
|
||||
/* Then join to the thread to pick up the result (if we don't do
|
||||
* we will have a memory leak!)
|
||||
*/
|
||||
|
||||
printf("cancel_test: Joining\n");
|
||||
status = pthread_join(waiter, &result);
|
||||
@@ -283,7 +285,7 @@ void cancel_test(void)
|
||||
printf("cancel_test: ERROR pthread_cancel failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
/* Signal the thread. It should wake up an restore the cancelable state.
|
||||
/* Signal the thread. It should wake up and restore the cancelable state.
|
||||
* When the cancelable state is re-enabled, the thread should be canceled.
|
||||
*/
|
||||
|
||||
@@ -304,4 +306,28 @@ void cancel_test(void)
|
||||
{
|
||||
printf("cancel_test: ERROR pthread_mutex_unlock failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
/* Then join to the thread to pick up the result (if we don't do
|
||||
* we will have a memory leak!)
|
||||
*/
|
||||
|
||||
printf("cancel_test: Joining\n");
|
||||
status = pthread_join(waiter, &result);
|
||||
if (status != 0)
|
||||
{
|
||||
printf("cancel_test: ERROR pthread_join failed, status=%d\n", status);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("cancel_test: waiter exited with result=%p\n", result);
|
||||
if (result != PTHREAD_CANCELED)
|
||||
{
|
||||
printf("cancel_test: ERROR expected result=%p\n", PTHREAD_CANCELED);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("cancel_test: PASS thread terminated with PTHREAD_CANCELED\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,11 +41,13 @@
|
||||
* Included Files
|
||||
************************************************************/
|
||||
|
||||
#include <nuttx/os_external.h>
|
||||
#include <nuttx/config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sched.h>
|
||||
#include <nuttx/os_external.h>
|
||||
#include "ostest.h"
|
||||
|
||||
/************************************************************
|
||||
@@ -81,10 +83,72 @@ static const char *g_argv[NARGS+1];
|
||||
static const char *g_argv[NARGS+1] = { arg1, arg2, arg3, arg4, NULL };
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
static struct mallinfo g_mmbefore;
|
||||
static struct mallinfo g_mmprevious;
|
||||
static struct mallinfo g_mmafter;
|
||||
#endif
|
||||
|
||||
/************************************************************
|
||||
* Private Functions
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Name: show_memory_usage
|
||||
************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
static void show_memory_usage(struct mallinfo *mmbefore,
|
||||
struct mallinfo *mmafter)
|
||||
{
|
||||
printf("VARIABLE BEFORE AFTER\n");
|
||||
printf("======== ======== ========\n");
|
||||
printf("arena %8x %8x\n", mmbefore->arena, mmafter->arena);
|
||||
printf("ordblks %8d %8d\n", mmbefore->ordblks, mmafter->ordblks);
|
||||
printf("mxordblk %8x %8x\n", mmbefore->mxordblk, mmafter->mxordblk);
|
||||
printf("uordblks %8x %8x\n", mmbefore->uordblks, mmafter->uordblks);
|
||||
printf("fordblks %8x %8x\n", mmbefore->fordblks, mmafter->fordblks);
|
||||
}
|
||||
#else
|
||||
# define show_memory_usage(mm1, mm2)
|
||||
#endif
|
||||
|
||||
/************************************************************
|
||||
* Name: check_test_memory_usage
|
||||
************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
static void check_test_memory_usage(void)
|
||||
{
|
||||
/* Wait a little bit to let any threads terminate */
|
||||
|
||||
usleep(500*1000);
|
||||
|
||||
/* Get the current memory usage */
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
g_mmafter = mallinfo();
|
||||
#else
|
||||
(void)mallinfo(&g_mmafter);
|
||||
#endif
|
||||
|
||||
/* Show the change from the previous time */
|
||||
|
||||
printf("\nEnd of test memory usage:\n");
|
||||
show_memory_usage(&g_mmprevious, &g_mmafter);
|
||||
|
||||
/* Set up for the next test */
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
g_mmprevious = g_mmafter;
|
||||
#else
|
||||
memcpy(&g_mmprevious, &g_mmafter, sizeof(struct mallinfo));
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
# define check_test_memory_usage()
|
||||
#endif
|
||||
|
||||
/************************************************************
|
||||
* Name: user_main
|
||||
************************************************************/
|
||||
@@ -93,6 +157,21 @@ static int user_main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Sample the memory usage now */
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
usleep(500*1000);
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
g_mmbefore = mallinfo();
|
||||
g_mmprevious = g_mmbefore;
|
||||
#else
|
||||
(void)mallinfo(&g_mmbefore);
|
||||
memcpy(g_mmprevious, g_mmbefore, sizeof(struct mallinfo));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
printf("\nuser_main: Begin argument test\n");
|
||||
printf("user_main: Started with argc=%d\n", argc);
|
||||
|
||||
/* Verify passed arguments */
|
||||
@@ -116,65 +195,121 @@ static int user_main(int argc, char *argv[])
|
||||
i, g_argv[i-1], argv[i]);
|
||||
}
|
||||
}
|
||||
check_test_memory_usage();
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
/* Checkout /dev/null */
|
||||
|
||||
printf("\nuser_main: /dev/null test\n");
|
||||
dev_null();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_PTHREAD
|
||||
/* Verify pthreads and pthread mutex */
|
||||
|
||||
printf("\nuser_main: mutex test\n");
|
||||
mutex_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_PTHREAD
|
||||
/* Verify pthread cancellation */
|
||||
|
||||
printf("\nuser_main: cancel test\n");
|
||||
cancel_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_PTHREAD
|
||||
/* Verify pthreads and semaphores */
|
||||
|
||||
printf("\nuser_main: semaphore test\n");
|
||||
sem_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_PTHREAD
|
||||
/* Verify pthreads and condition variables */
|
||||
|
||||
printf("\nuser_main: condition variable test\n");
|
||||
cond_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DISABLE_SIGNALS) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
#if !defined(CONFIG_DISABLE_SIGNALS) && !defined(CONFIG_DISABLE_PTHREAD) && !defined(CONFIG_DISABLE_CLOCK)
|
||||
/* Verify pthreads and condition variable timed waits */
|
||||
|
||||
printf("\nuser_main: timed wait test\n");
|
||||
timedwait_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DISABLE_MQUEUE) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
/* Verify pthreads and message queues */
|
||||
|
||||
printf("\nuser_main: message queue test\n");
|
||||
mqueue_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DISABLE_MQUEUE) && !defined(CONFIG_DISABLE_PTHREAD) && !defined(CONFIG_DISABLE_CLOCK)
|
||||
/* Verify pthreads and message queues */
|
||||
|
||||
printf("\nuser_main: timed message queue test\n");
|
||||
timedmqueue_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
/* Verify signal handlers */
|
||||
|
||||
printf("\nuser_main: signal handler test\n");
|
||||
sighand_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DISABLE_POSIX_TIMERS) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||
/* Verify posix timers */
|
||||
|
||||
printf("\nuser_main: POSIX timer test\n");
|
||||
timer_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DISABLE_PTHREAD) && CONFIG_RR_INTERVAL > 0
|
||||
/* Verify round robin scheduling */
|
||||
|
||||
printf("\nuser_main: round-robin scheduler test\n");
|
||||
rr_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_PTHREAD
|
||||
/* Verify pthread barriers */
|
||||
|
||||
printf("\nuser_main: barrier test\n");
|
||||
barrier_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
/* Compare memory usage at time user_start started until
|
||||
* user_main exits. These should not be identical, but should
|
||||
* be similar enough that we can detect any serious OS memory
|
||||
* leaks.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
usleep(500*1000);
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
g_mmafter = mallinfo();
|
||||
#else
|
||||
(void)mallinfo(&g_mmafter);
|
||||
#endif
|
||||
|
||||
printf("\nFinal memory usage:\n");
|
||||
show_memory_usage(&g_mmbefore, &g_mmafter);
|
||||
#endif
|
||||
|
||||
printf("user_main: Exitting\n");
|
||||
|
||||
@@ -37,13 +37,17 @@
|
||||
* Included Files
|
||||
**************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <mqueue.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "ostest.h"
|
||||
|
||||
@@ -51,11 +55,18 @@
|
||||
* Private Definitions
|
||||
**************************************************************************/
|
||||
|
||||
#define TEST_MESSAGE "This is a test and only a test"
|
||||
#define TEST_MESSAGE "This is a test and only a test"
|
||||
#ifdef SDCC
|
||||
#define TEST_MSGLEN (31)
|
||||
#define TEST_MSGLEN (31)
|
||||
#else
|
||||
#define TEST_MSGLEN (strlen(TEST_MESSAGE)+1)
|
||||
#define TEST_MSGLEN (strlen(TEST_MESSAGE)+1)
|
||||
#endif
|
||||
|
||||
#define TEST_SEND_NMSGS (10)
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
# define TEST_RECEIVE_NMSGS (11)
|
||||
#else
|
||||
# define TEST_RECEIVE_NMSGS (10)
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
@@ -121,9 +132,9 @@ static void *sender_thread(void *arg)
|
||||
|
||||
memcpy(msg_buffer, TEST_MESSAGE, TEST_MSGLEN);
|
||||
|
||||
/* Perform the send 10 times */
|
||||
/* Perform the send TEST_SEND_NMSGS times */
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
for (i = 0; i < TEST_SEND_NMSGS; i++)
|
||||
{
|
||||
status = mq_send(mqfd, msg_buffer, TEST_MSGLEN, 42);
|
||||
if (status < 0)
|
||||
@@ -183,16 +194,27 @@ static void *receiver_thread(void *arg)
|
||||
pthread_exit((pthread_addr_t)1);
|
||||
}
|
||||
|
||||
/* Perform the receive 10 times */
|
||||
/* Perform the receive TEST_RECEIVE_NMSGS times */
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
for (i = 0; i < TEST_RECEIVE_NMSGS; i++)
|
||||
{
|
||||
memset(msg_buffer, 0xaa, TEST_MSGLEN);
|
||||
nbytes = mq_receive(mqfd, msg_buffer, TEST_MSGLEN, 0);
|
||||
if (nbytes < 0)
|
||||
{
|
||||
printf("receiver_thread: ERROR mq_receive failure on msg %d\n", i);
|
||||
nerrors++;
|
||||
/* mq_receive failed. If the error is because of EINTR then
|
||||
* it is not a failure.
|
||||
*/
|
||||
|
||||
if (*get_errno_ptr() != EINTR)
|
||||
{
|
||||
printf("receiver_thread: ERROR mq_receive failure on msg %d, errno=%d\n", i, *get_errno_ptr());
|
||||
nerrors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("receiver_thread: mq_receive interrupted!\n", i);
|
||||
}
|
||||
}
|
||||
else if (nbytes != TEST_MSGLEN)
|
||||
{
|
||||
@@ -236,8 +258,6 @@ static void *receiver_thread(void *arg)
|
||||
nerrors++;
|
||||
}
|
||||
|
||||
pthread_exit((pthread_addr_t)nerrors);
|
||||
|
||||
/* Destroy the queue */
|
||||
|
||||
if (mq_unlink("testmq") < 0)
|
||||
@@ -247,6 +267,7 @@ static void *receiver_thread(void *arg)
|
||||
}
|
||||
|
||||
printf("receiver_thread: returning nerrors=%d\n", nerrors);
|
||||
pthread_exit((pthread_addr_t)nerrors);
|
||||
return (pthread_addr_t)nerrors;
|
||||
}
|
||||
|
||||
@@ -330,13 +351,33 @@ void mqueue_test(void)
|
||||
printf("mqueue_test: pthread_create failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
printf("mqueue_test: Waiting for sender to complete\n");
|
||||
pthread_join(sender, &result);
|
||||
if (result != (void*)0)
|
||||
{
|
||||
printf("mqueue_test: ERROR sender thread exited with %d errors\n", (int)result);
|
||||
}
|
||||
|
||||
pthread_cancel(receiver);
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
/* Wake up the receiver thread with a signal */
|
||||
|
||||
printf("mqueue_test: Killing receiver\n");
|
||||
pthread_kill(receiver, 9);
|
||||
#endif
|
||||
|
||||
/* Wait a bit to see if the thread exits on its own */
|
||||
|
||||
usleep(500*1000);
|
||||
|
||||
/* Then cancel the thread and see if it did */
|
||||
|
||||
printf("mqueue_test: Canceling receiver\n");
|
||||
status = pthread_cancel(receiver);
|
||||
if (status == ESRCH)
|
||||
{
|
||||
printf("mqueue_test: receiver has already terminated\n");
|
||||
}
|
||||
|
||||
pthread_join(receiver, &result);
|
||||
if (result != (void*)0)
|
||||
{
|
||||
|
||||
@@ -76,10 +76,14 @@ extern void sem_test(void);
|
||||
|
||||
extern void cond_test(void);
|
||||
|
||||
/* queue.c **************************************************/
|
||||
/* mqueue.c *************************************************/
|
||||
|
||||
extern void mqueue_test(void);
|
||||
|
||||
/* timedmqueue.c ********************************************/
|
||||
|
||||
extern void timedmqueue_test(void);
|
||||
|
||||
/* cancel.c *************************************************/
|
||||
|
||||
extern void cancel_test(void);
|
||||
@@ -92,8 +96,16 @@ extern void timedwait_test(void);
|
||||
|
||||
extern void sighand_test(void);
|
||||
|
||||
/* posixtimers.c ********************************************/
|
||||
|
||||
extern void timer_test(void);
|
||||
|
||||
/* roundrobin.c *********************************************/
|
||||
|
||||
extern void rr_test(void);
|
||||
|
||||
/* barrier.c ************************************************/
|
||||
|
||||
extern void barrier_test(void);
|
||||
|
||||
#endif /* __OSTEST_H */
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
@@ -122,7 +121,6 @@ static void timer_expiration(int signo, siginfo_t *info, void *ucontext)
|
||||
|
||||
void timer_test(void)
|
||||
{
|
||||
struct sched_param param;
|
||||
sigset_t sigset;
|
||||
struct sigaction act;
|
||||
struct sigaction oact;
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
|
||||
384
examples/ostest/timedmqueue.c
Normal file
384
examples/ostest/timedmqueue.c
Normal file
@@ -0,0 +1,384 @@
|
||||
/**************************************************************************
|
||||
* mqueue.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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <mqueue.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "ostest.h"
|
||||
|
||||
/**************************************************************************
|
||||
* Private Definitions
|
||||
**************************************************************************/
|
||||
|
||||
#define TEST_MESSAGE "This is a test and only a test"
|
||||
|
||||
#ifdef SDCC
|
||||
#define TEST_MSGLEN (31)
|
||||
#else
|
||||
#define TEST_MSGLEN (strlen(TEST_MESSAGE)+1)
|
||||
#endif
|
||||
|
||||
#define TEST_SEND_NMSGS (10)
|
||||
#define TEST_RECEIVE_NMSGS (10)
|
||||
|
||||
/**************************************************************************
|
||||
* Private Types
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Function Prototypes
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Global Variables
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Variables
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Functions
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Public Functions
|
||||
**************************************************************************/
|
||||
|
||||
static void *sender_thread(void *arg)
|
||||
{
|
||||
mqd_t mqfd;
|
||||
char msg_buffer[TEST_MSGLEN];
|
||||
struct mq_attr attr;
|
||||
int status = 0;
|
||||
int nerrors = 0;
|
||||
int i;
|
||||
|
||||
printf("sender_thread: Starting\n");
|
||||
|
||||
/* Fill in attributes for message queue */
|
||||
|
||||
attr.mq_maxmsg = TEST_SEND_NMSGS-1;
|
||||
attr.mq_msgsize = TEST_MSGLEN;
|
||||
attr.mq_flags = 0;
|
||||
|
||||
/* Set the flags for the open of the queue.
|
||||
* Make it a blocking open on the queue, meaning it will block if
|
||||
* this process tries to send to the queue and the queue is full.
|
||||
*
|
||||
* O_CREAT - the queue will get created if it does not already exist.
|
||||
* O_WRONLY - we are only planning to write to the queue.
|
||||
*
|
||||
* Open the queue, and create it if the receiving process hasn't
|
||||
* already created it.
|
||||
*/
|
||||
|
||||
mqfd = mq_open("testmq", O_WRONLY|O_CREAT, 0666, &attr);
|
||||
if (mqfd < 0)
|
||||
{
|
||||
printf("sender_thread: ERROR mq_open failed\n");
|
||||
pthread_exit((pthread_addr_t)1);
|
||||
}
|
||||
|
||||
/* Fill in a test message buffer to send */
|
||||
|
||||
memcpy(msg_buffer, TEST_MESSAGE, TEST_MSGLEN);
|
||||
|
||||
/* Perform the send TEST_SEND_NMSGS times */
|
||||
|
||||
for (i = 0; i < TEST_SEND_NMSGS; i++)
|
||||
{
|
||||
struct timespec time;
|
||||
status = clock_gettime(CLOCK_REALTIME, &time);
|
||||
if (status != 0)
|
||||
{
|
||||
printf("sender_thread: ERROR clock_gettime failed\n");
|
||||
}
|
||||
time.tv_sec += 5;
|
||||
|
||||
/* The first TEST_SEND_NMSGS-1 send should succeed. The last
|
||||
* one should fail with errno == ETIMEDOUT
|
||||
*/
|
||||
|
||||
status = mq_timedsend(mqfd, msg_buffer, TEST_MSGLEN, 42, &time);
|
||||
if (status < 0)
|
||||
{
|
||||
if (i == TEST_SEND_NMSGS-1 && *get_errno_ptr() == ETIMEDOUT)
|
||||
{
|
||||
printf("sender_thread: mq_timedsend %d timed out as expected\n", i);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("sender_thread: ERROR mq_timedsend failure=%d on msg %d\n", *get_errno_ptr(), i);
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == TEST_SEND_NMSGS-1)
|
||||
{
|
||||
printf("sender_thread: ERROR mq_timedsend of msg %d succeeded\n", i);
|
||||
nerrors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("sender_thread: mq_timedsend succeeded on msg %d\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the queue and return success */
|
||||
|
||||
if (mq_close(mqfd) < 0)
|
||||
{
|
||||
printf("sender_thread: ERROR mq_close failed\n");
|
||||
}
|
||||
|
||||
printf("sender_thread: returning nerrors=%d\n", nerrors);
|
||||
fflush(stdout);
|
||||
return (pthread_addr_t)nerrors;
|
||||
}
|
||||
|
||||
static void *receiver_thread(void *arg)
|
||||
{
|
||||
mqd_t mqfd;
|
||||
char msg_buffer[TEST_MSGLEN];
|
||||
struct mq_attr attr;
|
||||
int nbytes;
|
||||
int nerrors = 0;
|
||||
int i;
|
||||
|
||||
printf("receiver_thread: Starting\n");
|
||||
|
||||
/* Fill in attributes for message queue */
|
||||
|
||||
attr.mq_maxmsg = TEST_SEND_NMSGS-1;
|
||||
attr.mq_msgsize = TEST_MSGLEN;
|
||||
attr.mq_flags = 0;
|
||||
|
||||
/* Set the flags for the open of the queue.
|
||||
* Make it a blocking open on the queue, meaning it will block if
|
||||
* this process tries to* send to the queue and the queue is full.
|
||||
*
|
||||
* O_CREAT - the queue will get created if it does not already exist.
|
||||
* O_RDONLY - we are only planning to write to the queue.
|
||||
*
|
||||
* Open the queue, and create it if the sending process hasn't
|
||||
* already created it.
|
||||
*/
|
||||
|
||||
mqfd = mq_open("testmq", O_RDONLY|O_CREAT, 0666, &attr);
|
||||
if (mqfd < 0)
|
||||
{
|
||||
printf("receiver_thread: ERROR mq_open failed\n");
|
||||
pthread_exit((pthread_addr_t)1);
|
||||
}
|
||||
|
||||
/* Perform the receive TEST_RECEIVE_NMSGS times */
|
||||
|
||||
for (i = 0; i < TEST_RECEIVE_NMSGS; i++)
|
||||
{
|
||||
struct timespec time;
|
||||
int status = clock_gettime(CLOCK_REALTIME, &time);
|
||||
if (status != 0)
|
||||
{
|
||||
printf("sender_thread: ERROR clock_gettime failed\n");
|
||||
}
|
||||
time.tv_sec += 5;
|
||||
|
||||
/* The first TEST_SEND_NMSGS-1 send should succeed. The last
|
||||
* one should fail with errno == ETIMEDOUT
|
||||
*/
|
||||
|
||||
memset(msg_buffer, 0xaa, TEST_MSGLEN);
|
||||
nbytes = mq_timedreceive(mqfd, msg_buffer, TEST_MSGLEN, 0, &time);
|
||||
if (nbytes < 0)
|
||||
{
|
||||
if (i == TEST_SEND_NMSGS-1 && *get_errno_ptr() == ETIMEDOUT)
|
||||
{
|
||||
printf("receiver_thread: Receive %d timed out as expected\n", i);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("receiver_thread: ERROR mq_timedreceive failure=%d on msg %d\n", *get_errno_ptr(), i);
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
else if (nbytes != TEST_MSGLEN)
|
||||
{
|
||||
printf("receiver_thread: mq_timedreceive return bad size %d on msg %d\n", nbytes, i);
|
||||
nerrors++;
|
||||
}
|
||||
else if (memcmp(TEST_MESSAGE, msg_buffer, nbytes) != 0)
|
||||
{
|
||||
int j;
|
||||
|
||||
printf("receiver_thread: mq_timedreceive returned corrupt message on msg %d\n", i);
|
||||
printf("receiver_thread: i Expected Received\n");
|
||||
|
||||
for (j = 0; j < TEST_MSGLEN-1; j++)
|
||||
{
|
||||
if (isprint(msg_buffer[j]))
|
||||
{
|
||||
printf("receiver_thread: %2d %02x (%c) %02x (%c)\n",
|
||||
j, TEST_MESSAGE[j], TEST_MESSAGE[j], msg_buffer[j], msg_buffer[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("receiver_thread: %2d %02x (%c) %02x\n",
|
||||
j, TEST_MESSAGE[j], TEST_MESSAGE[j], msg_buffer[j]);
|
||||
}
|
||||
}
|
||||
printf("receiver_thread: %2d 00 %02x\n",
|
||||
j, msg_buffer[j]);
|
||||
}
|
||||
else if (i == TEST_SEND_NMSGS-1)
|
||||
{
|
||||
printf("receiver_thread: ERROR mq_timedreceive of msg %d succeeded\n", i);
|
||||
nerrors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("receiver_thread: mq_timedreceive succeeded on msg %d\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the queue and return success */
|
||||
|
||||
if (mq_close(mqfd) < 0)
|
||||
{
|
||||
printf("receiver_thread: ERROR mq_close failed\n");
|
||||
nerrors++;
|
||||
}
|
||||
|
||||
/* Destroy the queue */
|
||||
|
||||
if (mq_unlink("testmq") < 0)
|
||||
{
|
||||
printf("receiver_thread: ERROR mq_close failed\n");
|
||||
nerrors++;
|
||||
}
|
||||
|
||||
printf("receiver_thread: returning nerrors=%d\n", nerrors);
|
||||
fflush(stdout);
|
||||
pthread_exit((pthread_addr_t)nerrors);
|
||||
return (pthread_addr_t)nerrors;
|
||||
}
|
||||
|
||||
void timedmqueue_test(void)
|
||||
{
|
||||
pthread_t sender;
|
||||
pthread_t receiver;
|
||||
void *result;
|
||||
pthread_attr_t attr;
|
||||
int status;
|
||||
|
||||
/* Start the sending thread at the default priority */
|
||||
|
||||
printf("timedmqueue_test: Starting sender\n");
|
||||
status = pthread_attr_init(&attr);
|
||||
if (status != 0)
|
||||
{
|
||||
printf("timedmqueue_test: pthread_attr_init failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
status = pthread_attr_setstacksize(&attr, 16384);
|
||||
if (status != 0)
|
||||
{
|
||||
printf("timedmqueue_test: pthread_attr_setstacksize failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
status = pthread_create(&sender, &attr, sender_thread, NULL);
|
||||
if (status != 0)
|
||||
{
|
||||
printf("timedmqueue_test: pthread_create failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
/* Wait for the sending thread to complete */
|
||||
|
||||
printf("timedmqueue_test: Waiting for sender to complete\n");
|
||||
pthread_join(sender, &result);
|
||||
if (result != (void*)0)
|
||||
{
|
||||
printf("timedmqueue_test: ERROR sender thread exited with %d errors\n", (int)result);
|
||||
}
|
||||
|
||||
/* Start the receiving thread at the default priority */
|
||||
|
||||
printf("timedmqueue_test: Starting receiver\n");
|
||||
status = pthread_attr_init(&attr);
|
||||
if (status != 0)
|
||||
{
|
||||
printf("timedmqueue_test: pthread_attr_init failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
status = pthread_attr_setstacksize(&attr, 16384);
|
||||
if (status != 0)
|
||||
{
|
||||
printf("timedmqueue_test: pthread_attr_setstacksize failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
status = pthread_create(&receiver, &attr, receiver_thread, NULL);
|
||||
if (status != 0)
|
||||
{
|
||||
printf("timedmqueue_test: pthread_create failed, status=%d\n", status);
|
||||
}
|
||||
|
||||
/* Wait for the receiving thread to complete */
|
||||
|
||||
printf("timedmqueue_test: Waiting for sender to complete\n");
|
||||
pthread_join(receiver, &result);
|
||||
if (result != (void*)0)
|
||||
{
|
||||
printf("timedmqueue_test: ERROR receiver thread exited with %d errors\n", (int)result);
|
||||
}
|
||||
|
||||
printf("timedmqueue_test: Test complete\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "fs_internal.h"
|
||||
|
||||
@@ -87,12 +87,16 @@ extern "C" {
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
EXTERN mqd_t mq_open(const char *mq_name, int oflags, ... );
|
||||
EXTERN mqd_t mq_open(const char *mq_name, int oflags, ...);
|
||||
EXTERN int mq_close(mqd_t mqdes );
|
||||
EXTERN int mq_unlink(const char *mq_name );
|
||||
EXTERN int mq_send(mqd_t mqdes, const void *msg, size_t msglen, int prio );
|
||||
EXTERN int mq_receive(mqd_t mqdes, void *msg, size_t msglen, int *prio );
|
||||
EXTERN int mq_notify(mqd_t mqdes, const struct sigevent *notification );
|
||||
EXTERN int mq_unlink(const char *mq_name);
|
||||
EXTERN int mq_send(mqd_t mqdes, const void *msg, size_t msglen, int prio);
|
||||
EXTERN int mq_timedsend(mqd_t mqdes, const char *msg, size_t msglen, int prio,
|
||||
const struct timespec *abstime);
|
||||
EXTERN ssize_t mq_receive(mqd_t mqdes, void *msg, size_t msglen, int *prio);
|
||||
EXTERN ssize_t mq_timedreceive(mqd_t mqdes, void *msg, size_t msglen,
|
||||
int *prio, const struct timespec *abstime);
|
||||
EXTERN int mq_notify(mqd_t mqdes, const struct sigevent *notification);
|
||||
EXTERN int mq_setattr(mqd_t mqdes, const struct mq_attr *mq_stat,
|
||||
struct mq_attr *oldstat);
|
||||
EXTERN int mq_getattr(mqd_t mqdes, struct mq_attr *mq_stat);
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <nuttx/compiler.h> /* Compiler settings */
|
||||
#include <sys/types.h> /* Needed for general types */
|
||||
#include <semaphore.h> /* Needed for sem_t */
|
||||
#include <signal.h> /* Needed for sigset_t */
|
||||
#include <time.h> /* Needed for struct timespec */
|
||||
#include <nuttx/compiler.h> /* For noreturn_function */
|
||||
|
||||
@@ -64,29 +65,43 @@
|
||||
* Definitions
|
||||
********************************************************************************/
|
||||
|
||||
#define PTHREAD_PROCESS_PRIVATE 0
|
||||
#define PTHREAD_PROCESS_SHARED 1
|
||||
/* Values for the process shared (pshared) attribute */
|
||||
|
||||
#define PTHREAD_STACK_MIN CONFIG_PTHREAD_STACK_MIN
|
||||
#define PTHREAD_STACK_DEFAULT CONFIG_PTHREAD_STACK_DEFAULT
|
||||
#define PTHREAD_PROCESS_PRIVATE 0
|
||||
#define PTHREAD_PROCESS_SHARED 1
|
||||
|
||||
#define PTHREAD_INHERIT_SCHED 0
|
||||
#define PTHREAD_EXPLICIT_SCHED 1
|
||||
/* Valid ranges for the pthread stacksize attribute */
|
||||
|
||||
#define PTHREAD_PRIO_NONE 0
|
||||
#define PTHREAD_PRIO_INHERIT 1
|
||||
#define PTHREAD_PRIO_PROTECT 2
|
||||
#define PTHREAD_STACK_MIN CONFIG_PTHREAD_STACK_MIN
|
||||
#define PTHREAD_STACK_DEFAULT CONFIG_PTHREAD_STACK_DEFAULT
|
||||
|
||||
#define PTHREAD_DEFAULT_PRIORITY 100
|
||||
/* Values for the pthread inheritsched attribute */
|
||||
|
||||
#define PTHREAD_INHERIT_SCHED 0
|
||||
#define PTHREAD_EXPLICIT_SCHED 1
|
||||
|
||||
#define PTHREAD_PRIO_NONE 0
|
||||
#define PTHREAD_PRIO_INHERIT 1
|
||||
#define PTHREAD_PRIO_PROTECT 2
|
||||
|
||||
#define PTHREAD_DEFAULT_PRIORITY 100
|
||||
|
||||
/* Cancellation states returned by pthread_cancelstate() */
|
||||
|
||||
#define PTHREAD_CANCEL_ENABLE (0)
|
||||
#define PTHREAD_CANCEL_DISABLE (1)
|
||||
#define PTHREAD_CANCEL_ENABLE (0)
|
||||
#define PTHREAD_CANCEL_DISABLE (1)
|
||||
|
||||
/* Thread return value when a pthread is canceled */
|
||||
|
||||
# define PTHREAD_CANCELED ((FAR void*)ERROR)
|
||||
#define PTHREAD_CANCELED ((FAR void*)ERROR)
|
||||
|
||||
/* Used to initialize a pthread_once_t */
|
||||
|
||||
#define PTHREAD_ONCE_INIT (FALSE)
|
||||
|
||||
/* This is returned by pthread_wait. It must not match any errno in errno.h */
|
||||
|
||||
#define PTHREAD_BARRIER_SERIAL_THREAD 0x1000
|
||||
|
||||
/********************************************************************************
|
||||
* Global Type Declarations
|
||||
@@ -144,6 +159,21 @@ struct pthread_mutex_s
|
||||
typedef struct pthread_mutex_s pthread_mutex_t;
|
||||
#define PTHREAD_MUTEX_INITIALIZER {0, {1, 0xffff}}
|
||||
|
||||
struct pthread_barrierattr_s
|
||||
{
|
||||
int pshared;
|
||||
};
|
||||
typedef struct pthread_barrierattr_s pthread_barrierattr_t;
|
||||
|
||||
struct pthread_barrier_s
|
||||
{
|
||||
sem_t sem;
|
||||
unsigned int count;
|
||||
};
|
||||
typedef struct pthread_barrier_s pthread_barrier_t;
|
||||
|
||||
typedef boolean pthread_once_t;
|
||||
|
||||
/* Forware references */
|
||||
|
||||
struct sched_param; /* Defined in sched.h */
|
||||
@@ -155,6 +185,7 @@ struct sched_param; /* Defined in sched.h */
|
||||
/********************************************************************************
|
||||
* Global Function Prototypes
|
||||
********************************************************************************/
|
||||
|
||||
/* Initializes a thread attributes object (attr) with default values for all of
|
||||
* the individual attributes used by a given implementation.
|
||||
*/
|
||||
@@ -232,6 +263,7 @@ EXTERN int pthread_getschedparam(pthread_t thread, int *policy,
|
||||
struct sched_param *param);
|
||||
EXTERN int pthread_setschedparam(pthread_t thread, int policy,
|
||||
const struct sched_param *param);
|
||||
EXTERN int pthread_setschedprio(pthread_t thread, int prio);
|
||||
|
||||
/* Thread-specific Data Interfaces */
|
||||
|
||||
@@ -280,6 +312,33 @@ EXTERN int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
|
||||
EXTERN int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime);
|
||||
|
||||
/* Barrier attributes */
|
||||
|
||||
EXTERN int pthread_barrierattr_destroy(FAR pthread_barrierattr_t *attr);
|
||||
EXTERN int pthread_barrierattr_init(FAR pthread_barrierattr_t *attr);
|
||||
EXTERN int pthread_barrierattr_getpshared(FAR const pthread_barrierattr_t *attr,
|
||||
FAR int *pshared);
|
||||
EXTERN int pthread_barrierattr_setpshared(FAR pthread_barrierattr_t *attr,
|
||||
int pshared);
|
||||
|
||||
/* Barriers */
|
||||
|
||||
EXTERN int pthread_barrier_destroy(FAR pthread_barrier_t *barrier);
|
||||
EXTERN int pthread_barrier_init(FAR pthread_barrier_t *barrier,
|
||||
FAR const pthread_barrierattr_t *attr,
|
||||
unsigned int count);
|
||||
EXTERN int pthread_barrier_wait(FAR pthread_barrier_t *barrier);
|
||||
|
||||
/* Pthread initialization */
|
||||
|
||||
EXTERN int pthread_once(FAR pthread_once_t *once_control,
|
||||
CODE void (*init_routine)(void));
|
||||
|
||||
/* Pthread signal management APIs */
|
||||
|
||||
EXTERN int pthread_kill(pthread_t thread, int sig);
|
||||
EXTERN int pthread_sigmask(int how, FAR const sigset_t *set, FAR sigset_t *oset);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -51,9 +51,10 @@
|
||||
|
||||
/* POSIX-like scheduling policies */
|
||||
|
||||
#define SCHED_FIFO 1 /* FIFO per priority scheduling policy */
|
||||
#define SCHED_RR 2 /* Round robin scheduling policy */
|
||||
#define SCHED_OTHER 4 /* Not used */
|
||||
#define SCHED_FIFO 1 /* FIFO per priority scheduling policy */
|
||||
#define SCHED_RR 2 /* Round robin scheduling policy */
|
||||
#define SCHED_SPORADIC 3 /* Not supported */
|
||||
#define SCHED_OTHER 4 /* Not supported */
|
||||
|
||||
/* Pthread definitions **********************************************************/
|
||||
|
||||
@@ -88,18 +89,18 @@ 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, char *argv[]);
|
||||
main_t entry, const char *argv[]);
|
||||
#else
|
||||
EXTERN STATUS task_init(FAR _TCB *tcb, const char *name, int priority,
|
||||
main_t entry, char *argv[]);
|
||||
main_t entry, const 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 entry, char *argv[]);
|
||||
main_t entry, const char *argv[]);
|
||||
#else
|
||||
EXTERN int task_create(const char *name, int priority,
|
||||
main_t entry, char *argv[]);
|
||||
main_t entry, const char *argv[]);
|
||||
#endif
|
||||
EXTERN STATUS task_delete(pid_t pid);
|
||||
EXTERN STATUS task_restart(pid_t pid);
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
#include <time.h> /* Needed for struct timespec */
|
||||
#include <sys/types.h> /* Needed for, e.g., sigset_t */
|
||||
#include <sys/types.h>
|
||||
|
||||
/********************************************************************************
|
||||
* Compilations Switches
|
||||
|
||||
@@ -106,7 +106,7 @@ void lib_take_semaphore(FAR struct file_struct *stream)
|
||||
|
||||
/* We have it. Claim the stak and return */
|
||||
|
||||
stream->fs_holder = my_pid;
|
||||
stream->fs_holder = my_pid;
|
||||
stream->fs_counts = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,9 +173,9 @@ void lib_releaselist(FAR struct streamlist *list)
|
||||
/* Destroy the semaphore and release the filelist */
|
||||
|
||||
(void)sem_destroy(&list->sl_sem);
|
||||
sched_free(list);
|
||||
|
||||
/* Initialize each FILE structure */
|
||||
/* Release each stream in the list */
|
||||
|
||||
#if CONFIG_STDIO_BUFFER_SIZE > 0
|
||||
for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
|
||||
{
|
||||
@@ -190,6 +190,9 @@ void lib_releaselist(FAR struct streamlist *list)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Finally, release the list itself */
|
||||
|
||||
sched_free(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +104,9 @@ void lib_take_semaphore(FILE *stream)
|
||||
ASSERT(*get_errno_ptr() == EINTR);
|
||||
}
|
||||
|
||||
/* We have it. Claim the stak and return */
|
||||
/* We have it. Stake the claim and return */
|
||||
|
||||
stream->holder = my_pid;
|
||||
stream->holder = my_pid;
|
||||
stream->counts = 1;
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ void lib_give_semaphore(FILE *stream)
|
||||
{
|
||||
pid_t my_pid = getpid();
|
||||
|
||||
/* I better be holding at least one reference to the semaphore */
|
||||
/* I better be holding at least one count on the semaphore */
|
||||
|
||||
ASSERT(stream->holder == my_pid);
|
||||
|
||||
|
||||
@@ -87,7 +87,15 @@ int vfprintf(FILE *stream, const char *fmt, va_list ap)
|
||||
*/
|
||||
|
||||
lib_stdstream(&stdstream, stream);
|
||||
|
||||
/* Hold the stream semaphore throughout the lib_vsprintf
|
||||
* call so that this thread can get its entire message out
|
||||
* before being pre-empted by the next thread.
|
||||
*/
|
||||
|
||||
lib_take_semaphore(stream);
|
||||
n = lib_vsprintf(&stdstream.public, fmt, ap);
|
||||
lib_give_semaphore(stream);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -69,9 +69,11 @@ SIGNAL_SRCS = sig_initialize.c \
|
||||
sig_unmaskpendingsignal.c sig_removependingsignal.c \
|
||||
sig_releasependingsignal.c sig_lowest.c sig_mqnotempty.c \
|
||||
sig_cleanup.c sig_received.c sig_deliver.c
|
||||
MQUEUE_SRCS = mq_open.c mq_close.c mq_unlink.c mq_send.c mq_receive.c \
|
||||
MQUEUE_SRCS = mq_open.c mq_close.c mq_unlink.c \
|
||||
mq_send.c mq_timedsend.c mq_sndinternal.c \
|
||||
mq_receive.c mq_timedreceive.c mq_rcvinternal.c \
|
||||
mq_setattr.c mq_getattr.c mq_initialize.c mq_descreate.c \
|
||||
mq_findnamed.c mq_msgfree.c mq_msgqfree.c
|
||||
mq_findnamed.c mq_msgfree.c mq_msgqfree.c mq_waitirq.c
|
||||
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
||||
MQUEUE_SRCS += mq_notify.c
|
||||
endif
|
||||
@@ -89,12 +91,15 @@ PTHREAD_SRCS = pthread_attrinit.c pthread_attrdestroy.c \
|
||||
pthread_condinit.c pthread_conddestroy.c \
|
||||
pthread_condattrinit.c pthread_condattrdestroy.c \
|
||||
pthread_condwait.c pthread_condsignal.c pthread_condbroadcast.c \
|
||||
pthread_barrierattrinit.c pthread_barrierattrdestroy.c \
|
||||
pthread_barrierattrgetpshared.c pthread_barrierattrsetpshared.c \
|
||||
pthread_barrierinit.c pthread_barrierdestroy.c pthread_barrierwait.c \
|
||||
pthread_cancel.c pthread_setcancelstate.c \
|
||||
pthread_keycreate.c pthread_setspecific.c pthread_getspecific.c pthread_keydelete.c \
|
||||
pthread_initialize.c pthread_completejoin.c pthread_findjoininfo.c \
|
||||
pthread_removejoininfo.c
|
||||
pthread_removejoininfo.c pthread_once.c pthread_setschedprio.c
|
||||
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
||||
PTHREAD_SRCS += pthread_condtimedwait.c
|
||||
PTHREAD_SRCS += pthread_condtimedwait.c pthread_kill.c pthread_sigmask.c
|
||||
endif
|
||||
SEM_SRCS = sem_initialize.c sem_init.c sem_destroy.c\
|
||||
sem_open.c sem_close.c sem_unlink.c \
|
||||
|
||||
@@ -93,7 +93,6 @@ extern int clock_abstime2ticks(clockid_t clockid, const struct timespec *abstime
|
||||
{
|
||||
struct timespec currtime;
|
||||
struct timespec reltime;
|
||||
sint32 relusec;
|
||||
int ret;
|
||||
|
||||
/* Convert the timespec to clock ticks. NOTE: Here we use
|
||||
|
||||
@@ -37,14 +37,22 @@
|
||||
* Included Files
|
||||
************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include "os_internal.h"
|
||||
|
||||
#undef get_errno_ptr
|
||||
|
||||
/************************************************************
|
||||
* Global Functions
|
||||
* Private Data
|
||||
************************************************************/
|
||||
|
||||
static int g_irqerrno;
|
||||
|
||||
/************************************************************
|
||||
* Public Functions
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
@@ -65,8 +73,32 @@
|
||||
|
||||
FAR int *get_errno_ptr(void)
|
||||
{
|
||||
FAR _TCB *ptcb = (FAR _TCB*)g_readytorun.head;
|
||||
return &ptcb->errno;
|
||||
/* Check if this function was called from an interrupt
|
||||
* handler. In that case, we have to do things a little
|
||||
* differently.
|
||||
*/
|
||||
|
||||
if (up_interrupt_context())
|
||||
{
|
||||
/* Yes, we were called from an interrupt handler. Do
|
||||
* not permit access to the errno in the TCB of the
|
||||
* interrupt task. Instead, use a separate errno just
|
||||
* for interrupt handlers. Of course, this would have
|
||||
* to change if we ever wanted to support nested
|
||||
* interrupts.
|
||||
*/
|
||||
|
||||
return &g_irqerrno;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We were called from the normal tasking context. Return
|
||||
* a reference to the thread-private errno in the TCB.
|
||||
*/
|
||||
|
||||
FAR _TCB *ptcb = (FAR _TCB*)g_readytorun.head;
|
||||
return &ptcb->errno;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* mq_internal.h
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
@@ -31,14 +31,14 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __MQ_INTERNAL_H
|
||||
#define __MQ_INTERNAL_H
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
@@ -47,16 +47,15 @@
|
||||
#include <signal.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Compilations Switches
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#define MQ_MAX_BYTES CONFIG_MQ_MAXMSGSIZE
|
||||
#define MQ_MAX_HWORDS ((MQ_MAX_BYTES + sizeof(uint16) - 1) / sizeof(uint16))
|
||||
#define MQ_MAX_MSGS 16
|
||||
#define MQ_PRIO_MAX _POSIX_MQ_PRIO_MAX
|
||||
|
||||
@@ -72,9 +71,9 @@
|
||||
|
||||
#define NUM_INTERRUPT_MSGS 8
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Global Type Declarations
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
enum mqalloc_e
|
||||
{
|
||||
@@ -85,23 +84,18 @@ enum mqalloc_e
|
||||
typedef enum mqalloc_e mqalloc_t;
|
||||
|
||||
/* This structure describes one buffered POSIX message. */
|
||||
/* NOTE: This structure is allocated from the same pool as MQ_type.
|
||||
* Therefore, (1) it must have a fixed "mail" size, and (2) must
|
||||
* exactly match MQ_type in size.
|
||||
*/
|
||||
|
||||
struct mqmsg
|
||||
{
|
||||
/* The position of the following two field must exactly match
|
||||
* MQ_type.
|
||||
*/
|
||||
|
||||
FAR struct mqmsg *next; /* Forward link to next message */
|
||||
ubyte type; /* (Used to manage allocations) */
|
||||
|
||||
ubyte priority; /* priority of message */
|
||||
#if MQ_MAX_BYTES < 256
|
||||
ubyte msglen; /* Message data length */
|
||||
uint16 mail[MQ_MAX_HWORDS]; /* Message data */
|
||||
#else
|
||||
uint16 msglen; /* Message data length */
|
||||
#endif
|
||||
ubyte mail[MQ_MAX_BYTES]; /* Message data */
|
||||
};
|
||||
typedef struct mqmsg mqmsg_t;
|
||||
|
||||
@@ -142,9 +136,9 @@ struct mq_des
|
||||
int oflags; /* Flags set when message queue was opened */
|
||||
};
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* This is a list of all opened message queues */
|
||||
|
||||
@@ -170,9 +164,9 @@ extern sq_queue_t g_msgfreeirq;
|
||||
|
||||
extern sq_queue_t g_desfree;
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Global Function Prototypes
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
@@ -181,15 +175,35 @@ extern "C" {
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* Functions defined in mq_initialized.c *******************/
|
||||
/* Functions defined in mq_initialize.c ************************************/
|
||||
|
||||
EXTERN void weak_function mq_initialize(void);
|
||||
EXTERN void mq_desblockalloc(void);
|
||||
EXTERN void mq_desblockalloc(void);
|
||||
|
||||
EXTERN mqd_t mq_descreate(FAR _TCB* mtcb, FAR msgq_t* msgq, int oflags);
|
||||
EXTERN FAR msgq_t *mq_findnamed(const char *mq_name);
|
||||
EXTERN void mq_msgfree(FAR mqmsg_t *mqmsg);
|
||||
EXTERN void mq_msgqfree(FAR msgq_t *msgq);
|
||||
EXTERN mqd_t mq_descreate(FAR _TCB* mtcb, FAR msgq_t* msgq, int oflags);
|
||||
EXTERN FAR msgq_t *mq_findnamed(const char *mq_name);
|
||||
EXTERN void mq_msgfree(FAR mqmsg_t *mqmsg);
|
||||
EXTERN void mq_msgqfree(FAR msgq_t *msgq);
|
||||
|
||||
/* mq_waitirq.c ************************************************************/
|
||||
|
||||
EXTERN void mq_waitirq(FAR _TCB *wtcb);
|
||||
|
||||
/* mq_rcvinternal.c ********************************************************/
|
||||
|
||||
EXTERN int mq_verifyreceive(mqd_t mqdes, void *msg, size_t msglen);
|
||||
EXTERN FAR mqmsg_t *mq_waitreceive(mqd_t mqdes);
|
||||
EXTERN ssize_t mq_doreceive(mqd_t mqdes, mqmsg_t *mqmsg, void *ubuffer,
|
||||
int *prio);
|
||||
|
||||
/* mq_sndinternal.c ********************************************************/
|
||||
|
||||
EXTERN int mq_verifysend(mqd_t mqdes, const void *msg, size_t msglen,
|
||||
int prio);
|
||||
EXTERN FAR mqmsg_t *mq_msgalloc(void);
|
||||
EXTERN int mq_waitsend(mqd_t mqdes);
|
||||
EXTERN int mq_dosend(mqd_t mqdes, FAR mqmsg_t *mqmsg, const void *msg,
|
||||
size_t msglen, int prio);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
||||
314
sched/mq_rcvinternal.c
Normal file
314
sched/mq_rcvinternal.c
Normal file
@@ -0,0 +1,314 @@
|
||||
/************************************************************
|
||||
* mq_rcvinternal.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 <sys/types.h>
|
||||
#include <fcntl.h> /* O_NONBLOCK */
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <mqueue.h>
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/os_external.h>
|
||||
#include "os_internal.h"
|
||||
#include "mq_internal.h"
|
||||
|
||||
/************************************************************
|
||||
* Definitions
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Private Type Declarations
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Global Variables
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Private Variables
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Private Functions
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Public Functions
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Name: mq_verifyreceive
|
||||
*
|
||||
* Description:
|
||||
* This is internal, common logic shared by both mq_receive
|
||||
* and mq_timedreceive. This function verifies the
|
||||
* input parameters that are common to both functions.
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message Queue Descriptor
|
||||
* msg - Buffer to receive the message
|
||||
* msglen - Size of the buffer in bytes
|
||||
*
|
||||
* Return Value:
|
||||
* One success, 0 (OK) is returned. On failure, -1 (ERROR) is
|
||||
* returned and the errno is set appropriately:
|
||||
*
|
||||
* EPERM Message queue opened not opened for reading.
|
||||
* EMSGSIZE 'msglen' was less than the maxmsgsize attribute of the
|
||||
* message queue.
|
||||
* EINVAL Invalid 'msg' or 'mqdes'
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
int mq_verifyreceive(mqd_t mqdes, void *msg, size_t msglen)
|
||||
{
|
||||
/* Verify the input parameters */
|
||||
|
||||
if (!msg || !mqdes)
|
||||
{
|
||||
*get_errno_ptr() = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if ((mqdes->oflags & O_RDOK) == 0)
|
||||
{
|
||||
*get_errno_ptr() = EPERM;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (msglen < (size_t)mqdes->msgq->maxmsgsize)
|
||||
{
|
||||
*get_errno_ptr() = EMSGSIZE;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* Function: mq_waitreceive
|
||||
*
|
||||
* Description:
|
||||
* This is internal, common logic shared by both mq_receive
|
||||
* and mq_timedreceive. This function waits for a message to
|
||||
* be received on the specified message queue, removes the
|
||||
* message from the queue, and returns it.
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
*
|
||||
* Return Value:
|
||||
* On success, a reference to the received message. If the
|
||||
* wait was interrupted by a signal or a timeout, then the
|
||||
* errno will be set appropriately and NULL will be returned.
|
||||
*
|
||||
* Assumptions:
|
||||
* - The caller has provided all validity checking of the
|
||||
* input parameters using mq_verifyreceive.
|
||||
* - Interrupts should be disabled throughout this call. This
|
||||
* is necessary because messages can be sent from interrupt
|
||||
* level processing.
|
||||
* - For mq_timedreceive, setting of the timer and this wait
|
||||
* must be atomic.
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
FAR mqmsg_t *mq_waitreceive(mqd_t mqdes)
|
||||
{
|
||||
FAR _TCB *rtcb;
|
||||
FAR msgq_t *msgq;
|
||||
FAR mqmsg_t *rcvmsg;
|
||||
|
||||
/* Get a pointer to the message queue */
|
||||
|
||||
msgq = mqdes->msgq;
|
||||
|
||||
/* Get the message from the head of the queue */
|
||||
|
||||
while ((rcvmsg = (FAR mqmsg_t*)sq_remfirst(&msgq->msglist)) == NULL)
|
||||
{
|
||||
/* Should we block until there the above condition has been
|
||||
* satisfied?
|
||||
*/
|
||||
|
||||
if (!(mqdes->oflags & O_NONBLOCK))
|
||||
{
|
||||
/* Block and try again */
|
||||
|
||||
rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
rtcb->msgwaitq = msgq;
|
||||
msgq->nwaitnotempty++;
|
||||
|
||||
*get_errno_ptr() = OK;
|
||||
up_block_task(rtcb, TSTATE_WAIT_MQNOTEMPTY);
|
||||
|
||||
/* When we resume at this point, either (1) the message queue
|
||||
* is no longer empty, or (2) the wait has been interrupted by
|
||||
* a signal. We can detect the latter case be examining the
|
||||
* errno value (should be either EINTR or ETIMEDOUT).
|
||||
*/
|
||||
|
||||
if (*get_errno_ptr() != OK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The queue was empty, and the O_NONBLOCK flag was set for the
|
||||
* message queue description referred to by 'mqdes'.
|
||||
*/
|
||||
|
||||
*get_errno_ptr() = EAGAIN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we got message, then decrement the number of messages in
|
||||
* the queue while we are still in the critical section
|
||||
*/
|
||||
|
||||
if (rcvmsg)
|
||||
{
|
||||
msgq->nmsgs--;
|
||||
}
|
||||
return rcvmsg;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* Function: mq_doreceive
|
||||
*
|
||||
* Description:
|
||||
* This is internal, common logic shared by both mq_receive
|
||||
* and mq_timedreceive. This function accepts the message
|
||||
* obtained by mq_waitmsg, provides the message content to
|
||||
* the user, notifies any threads that were waiting for
|
||||
* the message queue to become non-full, and disposes of the
|
||||
* message structure
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
* mqmsg - The message obtained by mq_waitmsg()
|
||||
* ubuffer - The address of the user provided buffer to
|
||||
* receive the message
|
||||
* prio - The user-provided location to return the
|
||||
* message priority.
|
||||
*
|
||||
* Return Value:
|
||||
* Returns the length of the received message. This
|
||||
* function does not fail.
|
||||
*
|
||||
* Assumptions:
|
||||
* - The caller has provided all validity checking of the
|
||||
* input parameters using mq_verifyreceive.
|
||||
* - The user buffer, ubuffer, is known to be large enough
|
||||
* to accept the largest message that an be sent on this
|
||||
* message queue
|
||||
* - Pre-emption should be disabled throughout this call.
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
ssize_t mq_doreceive(mqd_t mqdes, mqmsg_t *mqmsg, void *ubuffer, int *prio)
|
||||
{
|
||||
FAR _TCB *btcb;
|
||||
irqstate_t saved_state;
|
||||
FAR msgq_t *msgq;
|
||||
ssize_t rcvmsglen;
|
||||
|
||||
/* Get the length of the message (also the return value) */
|
||||
|
||||
rcvmsglen = mqmsg->msglen;
|
||||
|
||||
/* Copy the message into the caller's buffer */
|
||||
|
||||
memcpy(ubuffer, (const void*)mqmsg->mail, rcvmsglen);
|
||||
|
||||
/* Copy the message priority as well (if a buffer is provided) */
|
||||
|
||||
if (prio)
|
||||
{
|
||||
*prio = mqmsg->priority;
|
||||
}
|
||||
|
||||
/* We are done with the message. Deallocate it now. */
|
||||
|
||||
mq_msgfree(mqmsg);
|
||||
|
||||
/* Check if any tasks are waiting for the MQ not full event. */
|
||||
|
||||
msgq = mqdes->msgq;
|
||||
if (msgq->nwaitnotfull > 0)
|
||||
{
|
||||
/* Find the highest priority task that is waiting for
|
||||
* this queue to be not-full in g_waitingformqnotfull list.
|
||||
* This must be performed in a critical section because
|
||||
* messages can be sent from interrupt handlers.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
for (btcb = (FAR _TCB*)g_waitingformqnotfull.head;
|
||||
btcb && btcb->msgwaitq != msgq;
|
||||
btcb = btcb->flink);
|
||||
|
||||
/* If one was found, unblock it. NOTE: There is a race
|
||||
* condition here: the queue might be full again by the
|
||||
* time the task is unblocked
|
||||
*/
|
||||
|
||||
if (!btcb)
|
||||
{
|
||||
PANIC(OSERR_MQNOTFULLCOUNT);
|
||||
}
|
||||
else
|
||||
{
|
||||
btcb->msgwaitq = NULL;
|
||||
msgq->nwaitnotfull--;
|
||||
up_unblock_task(btcb);
|
||||
}
|
||||
irqrestore(saved_state);
|
||||
}
|
||||
|
||||
/* Return the length of the message transferred to the user buffer */
|
||||
|
||||
return rcvmsglen;
|
||||
}
|
||||
@@ -37,20 +37,12 @@
|
||||
* Included Files
|
||||
************************************************************/
|
||||
|
||||
#include <sys/types.h> /* uint32, etc. */
|
||||
#include <stdarg.h> /* va_list */
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h> /* O_NONBLOCK */
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <mqueue.h>
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/os_external.h>
|
||||
#include "os_internal.h"
|
||||
#include "sig_internal.h"
|
||||
#include "mq_internal.h"
|
||||
|
||||
/************************************************************
|
||||
@@ -86,7 +78,7 @@
|
||||
* "mqdes." If the size of the buffer in bytes (msglen) is
|
||||
* less than the "mq_msgsize" attribute of the message
|
||||
* queue, mq_receive will return an error. Otherwise, the
|
||||
* select message is removed from the queue and copied to
|
||||
* selected message is removed from the queue and copied to
|
||||
* "msg."
|
||||
*
|
||||
* If the message queue is empty and O_NONBLOCK was not
|
||||
@@ -102,134 +94,72 @@
|
||||
* mqdes - Message Queue Descriptor
|
||||
* msg - Buffer to receive the message
|
||||
* msglen - Size of the buffer in bytes
|
||||
* prio - If not NULL, the location to store message
|
||||
* priority.
|
||||
* prio - If not NULL, the location to store message priority.
|
||||
*
|
||||
* Return Value:
|
||||
* Length of the selected message in bytes, otherwise -1
|
||||
* (ERROR).
|
||||
* One success, the length of the selected message in bytes.is
|
||||
* returned. On failure, -1 (ERROR) is returned and the errno
|
||||
* is set appropriately:
|
||||
*
|
||||
* EAGAIN The queue was empty, and the O_NONBLOCK flag was set
|
||||
* for the message queue description referred to by 'mqdes'.
|
||||
* EPERM Message queue opened not opened for reading.
|
||||
* EMSGSIZE 'msglen' was less than the maxmsgsize attribute of the
|
||||
* message queue.
|
||||
* EINTR The call was interrupted by a signal handler.
|
||||
* EINVAL Invalid 'msg' or 'mqdes'
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
int mq_receive(mqd_t mqdes, void *msg, size_t msglen, int *prio)
|
||||
ssize_t mq_receive(mqd_t mqdes, void *msg, size_t msglen, int *prio)
|
||||
{
|
||||
FAR _TCB *rtcb;
|
||||
FAR _TCB *btcb;
|
||||
FAR msgq_t *msgq;
|
||||
FAR mqmsg_t *curr;
|
||||
FAR mqmsg_t *mqmsg;
|
||||
irqstate_t saved_state;
|
||||
ubyte rcvmsglen;
|
||||
int ret = ERROR;
|
||||
ssize_t ret = ERROR;
|
||||
|
||||
/* Verify the input parameters */
|
||||
DEBUGASSERT(!up_interrupt_context());
|
||||
|
||||
/* Verify the input parameters and, in case of an error, set
|
||||
* errno appropriately.
|
||||
*/
|
||||
|
||||
if (mq_verifyreceive(mqdes, msg, msglen) != OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Get the next mesage from the message queue. We will disable
|
||||
* pre-emption until we have completed the message received. This
|
||||
* is not too bad because if the receipt takes a long time, it will
|
||||
* be because we are blocked waiting for a message and pre-emption
|
||||
* will be re-enabled while we are blocked
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
if (msg && mqdes && (mqdes->oflags & O_RDOK) != 0 &&
|
||||
msglen >= (size_t)mqdes->msgq->maxmsgsize)
|
||||
|
||||
/* Furthermore, mq_waitreceive() expects to have interrupts disabled
|
||||
* because messages can be sent from interrupt level.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
|
||||
/* Get the message from the message queue */
|
||||
|
||||
mqmsg = mq_waitreceive(mqdes);
|
||||
irqrestore(saved_state);
|
||||
|
||||
/* Check if we got a message from the message queue. We might
|
||||
* not have a message if:
|
||||
*
|
||||
* - The message queue is empty and O_NONBLOCK is set in the mqdes
|
||||
* - The wait was interrupted by a signal
|
||||
*/
|
||||
|
||||
if (mqmsg)
|
||||
{
|
||||
/* Get a pointer to the message queue */
|
||||
|
||||
msgq = mqdes->msgq;
|
||||
|
||||
/* Several operations must be performed below: We must determine if
|
||||
* a message is pending and, if not, wait for the message. Since
|
||||
* messages can be sent from the interrupt level, there is a race
|
||||
* condition that can only be eliminated by disabling interrupts!
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
|
||||
/* Get the message from the head of the queue */
|
||||
|
||||
while ((curr = (FAR mqmsg_t*)sq_remfirst(&msgq->msglist)) == NULL)
|
||||
{
|
||||
/* Should we block until there the above condition has been
|
||||
* satisfied?
|
||||
*/
|
||||
|
||||
if (!(mqdes->oflags & O_NONBLOCK))
|
||||
{
|
||||
/* Block and try again */
|
||||
|
||||
rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
rtcb->msgwaitq = msgq;
|
||||
msgq->nwaitnotempty++;
|
||||
up_block_task(rtcb, TSTATE_WAIT_MQNOTEMPTY);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we got message, then decrement the number of messages in
|
||||
* the queue while we are still in the critical section
|
||||
*/
|
||||
|
||||
if (curr)
|
||||
{
|
||||
msgq->nmsgs--;
|
||||
}
|
||||
irqrestore(saved_state);
|
||||
|
||||
/* Check (again) if we got a message from the message queue*/
|
||||
|
||||
if (curr)
|
||||
{
|
||||
/* Get the length of the message (also the return value) */
|
||||
|
||||
ret = rcvmsglen = curr->msglen;
|
||||
|
||||
/* Copy the message into the caller's buffer */
|
||||
|
||||
memcpy(msg, (const void*)curr->mail, rcvmsglen);
|
||||
|
||||
/* Copy the message priority as well (if a buffer is provided) */
|
||||
|
||||
if (prio)
|
||||
{
|
||||
*prio = curr->priority;
|
||||
}
|
||||
|
||||
/* We are done with the message. Deallocate it now. */
|
||||
|
||||
mq_msgfree(curr);
|
||||
|
||||
/* Check if any tasks are waiting for the MQ not full event. */
|
||||
|
||||
if (msgq->nwaitnotfull > 0)
|
||||
{
|
||||
/* Find the highest priority task that is waiting for
|
||||
* this queue to be not-full in g_waitingformqnotfull list.
|
||||
* This must be performed in a critical section because
|
||||
* messages can be sent from interrupt handlers.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
for (btcb = (FAR _TCB*)g_waitingformqnotfull.head;
|
||||
btcb && btcb->msgwaitq != msgq;
|
||||
btcb = btcb->flink);
|
||||
|
||||
/* If one was found, unblock it. NOTE: There is a race
|
||||
* condition here: the queue might be full again by the
|
||||
* time the task is unblocked
|
||||
*/
|
||||
|
||||
if (!btcb)
|
||||
{
|
||||
PANIC(OSERR_MQNOTFULLCOUNT);
|
||||
}
|
||||
else
|
||||
{
|
||||
btcb->msgwaitq = NULL;
|
||||
msgq->nwaitnotfull--;
|
||||
up_unblock_task(btcb);
|
||||
}
|
||||
irqrestore(saved_state);
|
||||
}
|
||||
}
|
||||
ret = mq_doreceive(mqdes, mqmsg, msg, prio);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
|
||||
409
sched/mq_send.c
409
sched/mq_send.c
@@ -1,4 +1,4 @@
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* mq_send.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
@@ -31,164 +31,65 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/compiler.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <sys/types.h> /* uint32, etc. */
|
||||
#include <fcntl.h>
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <mqueue.h>
|
||||
#include <string.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include "os_internal.h"
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
# include "sig_internal.h"
|
||||
#endif
|
||||
#include "mq_internal.h"
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Function: mq_msgalloc
|
||||
*
|
||||
* Description:
|
||||
* The mq_msgalloc function will get a free message for use
|
||||
* by the operating system. The message will be allocated
|
||||
* from the g_msgfree list.
|
||||
*
|
||||
* If the list is empty AND the message is NOT being
|
||||
* allocated from the interrupt level, then the message
|
||||
* will be allocated. If a message cannot be obtained,
|
||||
* the operating system is dead and therefore cannot
|
||||
* continue.
|
||||
*
|
||||
* If the list is empty AND the message IS being allocated
|
||||
* from the interrupt level. This function will attempt to
|
||||
* get a message from the g_msgfreeirq list. If this is
|
||||
* unsuccessful, the calling interrupt handler will be
|
||||
* notified.
|
||||
*
|
||||
* Inputs:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* A reference to the allocated msg structure
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
FAR mqmsg_t *mq_msgalloc(void)
|
||||
{
|
||||
FAR mqmsg_t *mqmsg;
|
||||
irqstate_t saved_state;
|
||||
|
||||
/* If we were called from an interrupt handler, then try to
|
||||
* get the message from generally available list of messages.
|
||||
* If this fails, then try the list of messages reserved for
|
||||
* interrupt handlers
|
||||
*/
|
||||
|
||||
if (up_interrupt_context())
|
||||
{
|
||||
/* Try the general free list */
|
||||
|
||||
mqmsg = (FAR mqmsg_t*)sq_remfirst(&g_msgfree);
|
||||
if (!mqmsg)
|
||||
{
|
||||
/* Try the free list reserved for interrupt handlers */
|
||||
|
||||
mqmsg = (FAR mqmsg_t*)sq_remfirst(&g_msgfreeirq);
|
||||
}
|
||||
}
|
||||
|
||||
/* We were not called from an interrupt handler. */
|
||||
|
||||
else
|
||||
{
|
||||
/* Try to get the message from the generally available free list.
|
||||
* Disable interrupts -- we might be called from an interrupt handler.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
mqmsg = (FAR mqmsg_t*)sq_remfirst(&g_msgfree);
|
||||
irqrestore(saved_state);
|
||||
|
||||
/* If we cannot a message from the free list, then we will have to allocate one. */
|
||||
|
||||
if (!mqmsg)
|
||||
{
|
||||
mqmsg = (FAR mqmsg_t *)kmalloc((sizeof (mqmsg_t)));
|
||||
|
||||
/* Check if we got an allocated message */
|
||||
|
||||
if (mqmsg)
|
||||
{
|
||||
mqmsg->type = MQ_ALLOC_DYN;
|
||||
}
|
||||
|
||||
/* No? We are dead */
|
||||
|
||||
else
|
||||
{
|
||||
dbg("Out of messages\n");
|
||||
PANIC((uint32)OSERR_OUTOFMESSAGES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(mqmsg);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************
|
||||
/****************************************************************************
|
||||
* Function: mq_send
|
||||
*
|
||||
* Description:
|
||||
* This function adds the specificied message (msg) to the
|
||||
* message queue (mqdes). The "msglen" parameter specifies
|
||||
* the length of the message in bytes pointed to by "msg."
|
||||
* This length must not exceed the maximum message length
|
||||
* from the mq_getattr().
|
||||
* This function adds the specificied message (msg) to the message queue
|
||||
* (mqdes). The "msglen" parameter specifies the length of the message
|
||||
* in bytes pointed to by "msg." This length must not exceed the maximum
|
||||
* message length from the mq_getattr().
|
||||
*
|
||||
* If the message queue is not full, mq_send() will in the
|
||||
* message in the message queue at the position indicated
|
||||
* by the "prio" argrument. Messages with higher priority
|
||||
* will be inserted before lower priority messages. The
|
||||
* value of "prio" must not exceed MQ_PRIO_MAX.
|
||||
* If the message queue is not full, mq_send() place the message in the
|
||||
* message queue at the position indicated by the "prio" argrument.
|
||||
* Messages with higher priority will be inserted before lower priority
|
||||
* messages. The value of "prio" must not exceed MQ_PRIO_MAX.
|
||||
*
|
||||
* If the specified message queue is full and O_NONBLOCK
|
||||
* is not set in the message queue, then mq_send() will
|
||||
* block until space becomes available to the queue the
|
||||
* message.
|
||||
* If the specified message queue is full and O_NONBLOCK is not set in the
|
||||
* message queue, then mq_send() will block until space becomes available
|
||||
* to the queue the message.
|
||||
*
|
||||
* If the message queue is full and O_NONBLOCK is set,
|
||||
* the message is not queued and ERROR is returned.
|
||||
* If the message queue is full and O_NONBLOCK is set, the message is not
|
||||
* queued and ERROR is returned.
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
@@ -197,214 +98,84 @@ FAR mqmsg_t *mq_msgalloc(void)
|
||||
* prio - The priority of the message
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
* On success, mq_send() returns 0 (OK); on error, -1 (ERROR)
|
||||
* is returned, with errno set to indicate the error:
|
||||
*
|
||||
* EAGAIN The queue was empty, and the O_NONBLOCK flag was set for the
|
||||
* message queue description referred to by mqdes.
|
||||
* EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
|
||||
* EPERM Message queue opened not opened for writing.
|
||||
* EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
|
||||
* message queue.
|
||||
* EINTR The call was interrupted by a signal handler.
|
||||
*
|
||||
* Assumptions/restrictions:
|
||||
*
|
||||
************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
int mq_send(mqd_t mqdes, const void *msg, size_t msglen, int prio)
|
||||
{
|
||||
FAR _TCB *rtcb;
|
||||
FAR _TCB *btcb;
|
||||
FAR msgq_t *msgq;
|
||||
FAR mqmsg_t *curr;
|
||||
FAR mqmsg_t *next;
|
||||
FAR mqmsg_t *prev;
|
||||
FAR mqmsg_t *mqmsg = NULL;
|
||||
irqstate_t saved_state;
|
||||
int ret = ERROR;
|
||||
|
||||
/* Verify the input parameters */
|
||||
/* Verify the input parameters -- setting errno appropriately
|
||||
* on any failures to verify.
|
||||
*/
|
||||
|
||||
if (mq_verifysend(mqdes, msg, msglen, prio) != OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Get a pointer to the message queue */
|
||||
|
||||
sched_lock();
|
||||
if (msg && mqdes && (mqdes->oflags & O_WROK) != 0 &&
|
||||
msglen > 0 && msglen <= (size_t)mqdes->msgq->maxmsgsize &&
|
||||
prio >= 0 && prio <= MQ_PRIO_MAX)
|
||||
msgq = mqdes->msgq;
|
||||
|
||||
/* Allocate a message structure:
|
||||
* - Immediately if we are called from an interrupt handler.
|
||||
* - Immediately if the message queue is not full, or
|
||||
* - After successfully waiting for the message queue to become
|
||||
* non-FULL. This would fail with EAGAIN, EINTR, or ETIMEOUT.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
if (up_interrupt_context() || /* In an interrupt handler */
|
||||
msgq->nmsgs < msgq->maxmsgs || /* OR Message queue not full */
|
||||
mq_waitsend(mqdes) == OK) /* OR Successfully waited for mq not full */
|
||||
{
|
||||
/* Get a pointer to the message queue */
|
||||
/* Allocate the message */
|
||||
|
||||
msgq = mqdes->msgq;
|
||||
|
||||
/* If we are sending a message from an interrupt handler, then
|
||||
* try to get message structure unconditionally.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
if (up_interrupt_context())
|
||||
{
|
||||
curr = mq_msgalloc();
|
||||
}
|
||||
|
||||
/* Otherwise, arbitrarily limit the number of messages in the
|
||||
* queue to the value determined when the message queue was opened.
|
||||
* This makes us more POSIX-like as well as prohibits one slow
|
||||
* responding task from consuming all available memory.
|
||||
*/
|
||||
|
||||
else if (msgq->nmsgs >= msgq->maxmsgs)
|
||||
{
|
||||
/* Should we block until there is sufficient space in the
|
||||
* message queue?
|
||||
*/
|
||||
|
||||
if ((mqdes->oflags & O_NONBLOCK) != 0)
|
||||
{
|
||||
/* No... We will return an error to the caller. */
|
||||
|
||||
curr = NULL;
|
||||
}
|
||||
|
||||
/* Yes... We will not return control until the message queue is
|
||||
* available.
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* Loop until there are fewer than max allowable messages in the
|
||||
* receiving message queue
|
||||
*/
|
||||
|
||||
while (msgq->nmsgs >= msgq->maxmsgs)
|
||||
{
|
||||
/* Block until the message queue is no longer full.
|
||||
* When we are unblocked, we will try again
|
||||
*/
|
||||
|
||||
rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
rtcb->msgwaitq = msgq;
|
||||
(msgq->nwaitnotfull)++;
|
||||
up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL);
|
||||
}
|
||||
|
||||
/* It should be okay to get add a message to the receiving
|
||||
* message queue now.
|
||||
*/
|
||||
|
||||
curr = mq_msgalloc();
|
||||
}
|
||||
}
|
||||
|
||||
/* We are not in an interrupt handler and the receiving message queue
|
||||
* is not full
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* Just allocate a message */
|
||||
|
||||
curr = mq_msgalloc();
|
||||
}
|
||||
irqrestore(saved_state);
|
||||
mqmsg = mq_msgalloc();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We cannot send the message (and didn't even try to allocate it)
|
||||
* because:
|
||||
* - We are not in an interrupt handler AND
|
||||
* - The message queue is full AND
|
||||
* - When we tried waiting, the wait was unsuccessful.
|
||||
*/
|
||||
|
||||
/* Check if we were able to get a message structure */
|
||||
irqrestore(saved_state);
|
||||
}
|
||||
|
||||
if (curr)
|
||||
{
|
||||
/* Construct the current message header info */
|
||||
/* Check if we were able to get a message structure -- this can fail
|
||||
* either because we cannot send the message (and didn't bother trying
|
||||
* to allocate it) or because the allocation failed.
|
||||
*/
|
||||
|
||||
curr->priority = (ubyte)prio;
|
||||
curr->msglen = (ubyte)msglen;
|
||||
if (mqmsg)
|
||||
{
|
||||
/* Yes, peforrm the message send. */
|
||||
|
||||
/* Copy the message data into the message */
|
||||
|
||||
memcpy((void*)curr->mail, (const void*)msg, msglen);
|
||||
|
||||
/* Insert the new message in the message queue */
|
||||
|
||||
saved_state = irqsave();
|
||||
|
||||
/* Search the message list to find the location to insert the new
|
||||
* message. Each is list is maintained in ascending priority order.
|
||||
*/
|
||||
|
||||
for (prev = NULL, next = (FAR mqmsg_t*)msgq->msglist.head;
|
||||
next && prio <= next->priority;
|
||||
prev = next, next = next->next);
|
||||
|
||||
/* Add the message at the right place */
|
||||
|
||||
if (prev)
|
||||
{
|
||||
sq_addafter((FAR sq_entry_t*)prev, (FAR sq_entry_t*)curr,
|
||||
&msgq->msglist);
|
||||
}
|
||||
else
|
||||
{
|
||||
sq_addfirst((FAR sq_entry_t*)curr, &msgq->msglist);
|
||||
}
|
||||
|
||||
/* Increment the count of message in the queue */
|
||||
|
||||
msgq->nmsgs++;
|
||||
irqrestore(saved_state);
|
||||
|
||||
/* Check if we need to notify any tasks that are attached to the
|
||||
* message queue
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
if (msgq->ntmqdes)
|
||||
{
|
||||
/* Remove the message notification data from the message queue. */
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
union sigval value = msgq->ntvalue;
|
||||
#else
|
||||
void *sival_ptr = msgq->ntvalue.sival_ptr;
|
||||
#endif
|
||||
int signo = msgq->ntsigno;
|
||||
int pid = msgq->ntpid;
|
||||
|
||||
/* Detach the notification */
|
||||
|
||||
msgq->ntpid = INVALID_PROCESS_ID;
|
||||
msgq->ntsigno = 0;
|
||||
msgq->ntvalue.sival_int = 0;
|
||||
msgq->ntmqdes = NULL;
|
||||
|
||||
/* Queue the signal -- What if this returns an error? */
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
sig_mqnotempty(pid, signo, value);
|
||||
#else
|
||||
sig_mqnotempty(pid, signo, sival_ptr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
/* Check if any tasks are waiting for the MQ not empty event. */
|
||||
|
||||
saved_state = irqsave();
|
||||
if (msgq->nwaitnotempty > 0)
|
||||
{
|
||||
/* Find the highest priority task that is waiting for
|
||||
* this queue to be non-empty in g_waitingformqnotempty
|
||||
* list. sched_lock() should give us sufficent protection since
|
||||
* interrupts should never cause a change in this list
|
||||
*/
|
||||
|
||||
for (btcb = (FAR _TCB*)g_waitingformqnotempty.head;
|
||||
btcb && btcb->msgwaitq != msgq;
|
||||
btcb = btcb->flink);
|
||||
|
||||
/* If one was found, unblock it */
|
||||
|
||||
if (!btcb)
|
||||
{
|
||||
PANIC(OSERR_MQNONEMPTYCOUNT);
|
||||
}
|
||||
else
|
||||
{
|
||||
btcb->msgwaitq = NULL;
|
||||
msgq->nwaitnotempty--;
|
||||
up_unblock_task(btcb);
|
||||
}
|
||||
}
|
||||
irqrestore(saved_state);
|
||||
ret = OK;
|
||||
}
|
||||
ret = mq_dosend(mqdes, mqmsg, msg, msglen, prio);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
return(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
448
sched/mq_sndinternal.c
Normal file
448
sched/mq_sndinternal.c
Normal file
@@ -0,0 +1,448 @@
|
||||
/****************************************************************************
|
||||
* mq_send.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 <nuttx/kmalloc.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <mqueue.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include "os_internal.h"
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
# include "sig_internal.h"
|
||||
#endif
|
||||
#include "mq_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_verifysend
|
||||
*
|
||||
* Description:
|
||||
* This is internal, common logic shared by both mq_send and mq_timesend.
|
||||
* This function verifies the input parameters that are common to both
|
||||
* functions.
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
* msg - Message to send
|
||||
* msglen - The length of the message in bytes
|
||||
* prio - The priority of the message
|
||||
*
|
||||
* Return Value:
|
||||
* One success, 0 (OK) is returned. On failure, -1 (ERROR) is returned and
|
||||
* the errno is set appropriately:
|
||||
*
|
||||
* EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
|
||||
* EPERM Message queue opened not opened for writing.
|
||||
* EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
|
||||
* message queue.
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mq_verifysend(mqd_t mqdes, const void *msg, size_t msglen, int prio)
|
||||
{
|
||||
/* Verify the input parameters */
|
||||
|
||||
if (!msg || !mqdes || prio < 0 || prio > MQ_PRIO_MAX)
|
||||
{
|
||||
*get_errno_ptr() = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if ((mqdes->oflags & O_WROK) == 0)
|
||||
{
|
||||
*get_errno_ptr() = EPERM;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (msglen < 0 || msglen > (size_t)mqdes->msgq->maxmsgsize)
|
||||
{
|
||||
*get_errno_ptr() = EMSGSIZE;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: mq_msgalloc
|
||||
*
|
||||
* Description:
|
||||
* The mq_msgalloc function will get a free message for use by the
|
||||
* operating system. The message will be allocated from the g_msgfree list.
|
||||
*
|
||||
* If the list is empty AND the message is NOT being allocated from the
|
||||
* interrupt level, then the message will be allocated. If a message
|
||||
* cannot be obtained, the operating system is dead and therefore cannot
|
||||
* continue.
|
||||
*
|
||||
* If the list is empty AND the message IS being allocated from the
|
||||
* interrupt level. This function will attempt to get a message from
|
||||
* the g_msgfreeirq list. If this is unsuccessful, the calling interrupt
|
||||
* handler will be notified.
|
||||
*
|
||||
* Inputs:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* A reference to the allocated msg structure. On a failure to allocate,
|
||||
* this function PANICs.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR mqmsg_t *mq_msgalloc(void)
|
||||
{
|
||||
FAR mqmsg_t *mqmsg;
|
||||
irqstate_t saved_state;
|
||||
|
||||
/* If we were called from an interrupt handler, then try to get the message
|
||||
* from generally available list of messages. If this fails, then try the
|
||||
* list of messages reserved for interrupt handlers
|
||||
*/
|
||||
|
||||
if (up_interrupt_context())
|
||||
{
|
||||
/* Try the general free list */
|
||||
|
||||
mqmsg = (FAR mqmsg_t*)sq_remfirst(&g_msgfree);
|
||||
if (!mqmsg)
|
||||
{
|
||||
/* Try the free list reserved for interrupt handlers */
|
||||
|
||||
mqmsg = (FAR mqmsg_t*)sq_remfirst(&g_msgfreeirq);
|
||||
}
|
||||
}
|
||||
|
||||
/* We were not called from an interrupt handler. */
|
||||
|
||||
else
|
||||
{
|
||||
/* Try to get the message from the generally available free list.
|
||||
* Disable interrupts -- we might be called from an interrupt handler.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
mqmsg = (FAR mqmsg_t*)sq_remfirst(&g_msgfree);
|
||||
irqrestore(saved_state);
|
||||
|
||||
/* If we cannot a message from the free list, then we will have to allocate one. */
|
||||
|
||||
if (!mqmsg)
|
||||
{
|
||||
mqmsg = (FAR mqmsg_t *)kmalloc((sizeof (mqmsg_t)));
|
||||
|
||||
/* Check if we got an allocated message */
|
||||
|
||||
if (mqmsg)
|
||||
{
|
||||
mqmsg->type = MQ_ALLOC_DYN;
|
||||
}
|
||||
|
||||
/* No? We are dead */
|
||||
|
||||
else
|
||||
{
|
||||
dbg("Out of messages\n");
|
||||
PANIC((uint32)OSERR_OUTOFMESSAGES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mqmsg;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: mq_waitsend
|
||||
*
|
||||
* Description:
|
||||
* This is internal, common logic shared by both mq_send and mq_timesend.
|
||||
* This function waits until the message queue is not full.
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
*
|
||||
* Return Value:
|
||||
* On success, mq_send() returns 0 (OK); on error, -1 (ERROR) is
|
||||
* returned, with errno set to indicate the error:
|
||||
*
|
||||
* EAGAIN The queue was empty, and the O_NONBLOCK flag was set for the
|
||||
* message queue description referred to by mqdes.
|
||||
* EINTR The call was interrupted by a signal handler.
|
||||
* ETIMEOUT A timeout expired before the message queue became non-full
|
||||
* (mq_timedsend only).
|
||||
*
|
||||
* Assumptions/restrictions:
|
||||
* - The caller has verified the input parameters using mq_verifysend().
|
||||
* - Interrupts are disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mq_waitsend(mqd_t mqdes)
|
||||
{
|
||||
FAR _TCB *rtcb;
|
||||
FAR msgq_t *msgq;
|
||||
|
||||
/* Get a pointer to the message queue */
|
||||
|
||||
msgq = mqdes->msgq;
|
||||
|
||||
/* Verify that the queue is indeed full as the caller thinks */
|
||||
|
||||
if (msgq->nmsgs >= msgq->maxmsgs)
|
||||
{
|
||||
/* Should we block until there is sufficient space in the
|
||||
* message queue?
|
||||
*/
|
||||
|
||||
if ((mqdes->oflags & O_NONBLOCK) != 0)
|
||||
{
|
||||
/* No... We will return an error to the caller. */
|
||||
|
||||
*get_errno_ptr() = EAGAIN;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Yes... We will not return control until the message queue is
|
||||
* available or we receive a signal or at timout occurs.
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* Loop until there are fewer than max allowable messages in the
|
||||
* receiving message queue
|
||||
*/
|
||||
|
||||
while (msgq->nmsgs >= msgq->maxmsgs)
|
||||
{
|
||||
/* Block until the message queue is no longer full.
|
||||
* When we are unblocked, we will try again
|
||||
*/
|
||||
|
||||
rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
rtcb->msgwaitq = msgq;
|
||||
(msgq->nwaitnotempty)++;
|
||||
|
||||
*get_errno_ptr() = OK;
|
||||
up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL);
|
||||
|
||||
/* When we resume at this point, either (1) the message queue
|
||||
* is no longer empty, or (2) the wait has been interrupted by
|
||||
* a signal. We can detect the latter case be examining the
|
||||
* errno value (should be EINTR or ETIMEOUT).
|
||||
*/
|
||||
|
||||
if (*get_errno_ptr() != OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: mq_dosend
|
||||
*
|
||||
* Description:
|
||||
* This is internal, common logic shared by both mq_send and mq_timesend.
|
||||
* This function adds the specificied message (msg) to the message queue
|
||||
* (mqdes). Then it notifies any tasks that were waiting for message
|
||||
* queue notifications setup by mq_notify. And, finally, it awakens any
|
||||
* tasks that were waiting for the message not empty event.
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
* msg - Message to send
|
||||
* msglen - The length of the message in bytes
|
||||
* prio - The priority of the message
|
||||
*
|
||||
* Return Value:
|
||||
* This function always returns OK.
|
||||
*
|
||||
* Assumptions/restrictions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mq_dosend(mqd_t mqdes, FAR mqmsg_t *mqmsg, const void *msg, size_t msglen, int prio)
|
||||
{
|
||||
FAR _TCB *btcb;
|
||||
FAR msgq_t *msgq;
|
||||
FAR mqmsg_t *next;
|
||||
FAR mqmsg_t *prev;
|
||||
irqstate_t saved_state;
|
||||
|
||||
/* Get a pointer to the message queue */
|
||||
|
||||
sched_lock();
|
||||
msgq = mqdes->msgq;
|
||||
|
||||
/* Construct the message header info */
|
||||
|
||||
mqmsg->priority = prio;
|
||||
mqmsg->msglen = msglen;
|
||||
|
||||
/* Copy the message data into the message */
|
||||
|
||||
memcpy((void*)mqmsg->mail, (const void*)msg, msglen);
|
||||
|
||||
/* Insert the new message in the message queue */
|
||||
|
||||
saved_state = irqsave();
|
||||
|
||||
/* Search the message list to find the location to insert the new
|
||||
* message. Each is list is maintained in ascending priority order.
|
||||
*/
|
||||
|
||||
for (prev = NULL, next = (FAR mqmsg_t*)msgq->msglist.head;
|
||||
next && prio <= next->priority;
|
||||
prev = next, next = next->next);
|
||||
|
||||
/* Add the message at the right place */
|
||||
|
||||
if (prev)
|
||||
{
|
||||
sq_addafter((FAR sq_entry_t*)prev, (FAR sq_entry_t*)mqmsg,
|
||||
&msgq->msglist);
|
||||
}
|
||||
else
|
||||
{
|
||||
sq_addfirst((FAR sq_entry_t*)mqmsg, &msgq->msglist);
|
||||
}
|
||||
|
||||
/* Increment the count of messages in the queue */
|
||||
|
||||
msgq->nmsgs++;
|
||||
irqrestore(saved_state);
|
||||
|
||||
/* Check if we need to notify any tasks that are attached to the
|
||||
* message queue
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
if (msgq->ntmqdes)
|
||||
{
|
||||
/* Remove the message notification data from the message queue. */
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
union sigval value = msgq->ntvalue;
|
||||
#else
|
||||
void *sival_ptr = msgq->ntvalue.sival_ptr;
|
||||
#endif
|
||||
int signo = msgq->ntsigno;
|
||||
int pid = msgq->ntpid;
|
||||
|
||||
/* Detach the notification */
|
||||
|
||||
msgq->ntpid = INVALID_PROCESS_ID;
|
||||
msgq->ntsigno = 0;
|
||||
msgq->ntvalue.sival_int = 0;
|
||||
msgq->ntmqdes = NULL;
|
||||
|
||||
/* Queue the signal -- What if this returns an error? */
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
sig_mqnotempty(pid, signo, value);
|
||||
#else
|
||||
sig_mqnotempty(pid, signo, sival_ptr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
/* Check if any tasks are waiting for the MQ not empty event. */
|
||||
|
||||
saved_state = irqsave();
|
||||
if (msgq->nwaitnotempty > 0)
|
||||
{
|
||||
/* Find the highest priority task that is waiting for
|
||||
* this queue to be non-empty in g_waitingformqnotempty
|
||||
* list. sched_lock() should give us sufficent protection since
|
||||
* interrupts should never cause a change in this list
|
||||
*/
|
||||
|
||||
for (btcb = (FAR _TCB*)g_waitingformqnotempty.head;
|
||||
btcb && btcb->msgwaitq != msgq;
|
||||
btcb = btcb->flink);
|
||||
|
||||
/* If one was found, unblock it */
|
||||
|
||||
if (!btcb)
|
||||
{
|
||||
PANIC(OSERR_MQNONEMPTYCOUNT);
|
||||
}
|
||||
else
|
||||
{
|
||||
btcb->msgwaitq = NULL;
|
||||
msgq->nwaitnotempty--;
|
||||
up_unblock_task(btcb);
|
||||
}
|
||||
}
|
||||
irqrestore(saved_state);
|
||||
sched_unlock();
|
||||
return OK;
|
||||
}
|
||||
|
||||
308
sched/mq_timedreceive.c
Normal file
308
sched/mq_timedreceive.c
Normal file
@@ -0,0 +1,308 @@
|
||||
/****************************************************************************
|
||||
* mq_timedreceive.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 <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <mqueue.h>
|
||||
#include <wdog.h>
|
||||
#include <debug.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include "os_internal.h"
|
||||
#include "clock_internal.h"
|
||||
#include "mq_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: mq_rcvtimeout
|
||||
*
|
||||
* Description:
|
||||
* This function is called if the timeout elapses before the message queue
|
||||
* becomes non-empty.
|
||||
*
|
||||
* Parameters:
|
||||
* argc - the number of arguments (should be 1)
|
||||
* pid - the task ID of the task to wakeup
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mq_rcvtimeout(int argc, uint32 pid, ...)
|
||||
{
|
||||
FAR _TCB *wtcb;
|
||||
irqstate_t saved_state;
|
||||
|
||||
/* Disable interrupts. This is necessary because an
|
||||
* interrupt handler may attempt to send a message while we are
|
||||
* doing this.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
|
||||
/* Get the TCB associated with this pid. It is possible that
|
||||
* task may no longer be active when this watchdog goes off.
|
||||
*/
|
||||
|
||||
wtcb = sched_gettcb((pid_t)pid);
|
||||
|
||||
/* It is also possible that an interrupt/context switch beat us to the
|
||||
* punch and already changed the task's state.
|
||||
*/
|
||||
|
||||
if (wtcb && wtcb->task_state == TSTATE_WAIT_MQNOTEMPTY)
|
||||
{
|
||||
/* Mark the errno value for the thread. */
|
||||
|
||||
wtcb->errno = ETIMEDOUT;
|
||||
|
||||
/* Restart the the task. */
|
||||
|
||||
up_unblock_task(wtcb);
|
||||
}
|
||||
|
||||
/* Interrupts may now be enabled. */
|
||||
|
||||
irqrestore(saved_state);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: mq_timedreceive
|
||||
*
|
||||
* Description:
|
||||
* This function receives the oldest of the highest
|
||||
* priority messages from the message queue specified by
|
||||
* "mqdes." If the size of the buffer in bytes (msglen) is
|
||||
* less than the "mq_msgsize" attribute of the message
|
||||
* queue, mq_timedreceive will return an error. Otherwise, the
|
||||
* selected message is removed from the queue and copied to
|
||||
* "msg."
|
||||
*
|
||||
* If the message queue is empty and O_NONBLOCK was not
|
||||
* set, mq_timedreceive() will block until a message is added
|
||||
* to the message queue (or until a timeout occurs). If more
|
||||
* than one task is waiting to receive a message, only the
|
||||
* task with the highest priority that has waited the longest
|
||||
* will be unblocked.
|
||||
*
|
||||
* mq_timedreceive() behaves just like mq_receive(), except
|
||||
* that if the queue is empty and the O_NONBLOCK flag is not
|
||||
* enabled for the message queue description, then abstime
|
||||
* points to a structure which specifies a ceiling on the time
|
||||
* for which the call will block. This ceiling is an absolute
|
||||
* timeout in seconds and nanoseconds since the Epoch (midnight
|
||||
* on the morning of 1 January 1970).
|
||||
*
|
||||
* If no message is available, and the timeout has already
|
||||
* expired by the time of the call, mq_timedreceive() returns
|
||||
* immediately.
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message Queue Descriptor
|
||||
* msg - Buffer to receive the message
|
||||
* msglen - Size of the buffer in bytes
|
||||
* prio - If not NULL, the location to store message priority.
|
||||
* abstime - the absolute time to wait until a timeout is declared.
|
||||
*
|
||||
* Return Value:
|
||||
* One success, the length of the selected message in bytes.is
|
||||
* returned. On failure, -1 (ERROR) is returned and the errno
|
||||
* is set appropriately:
|
||||
*
|
||||
* EAGAIN The queue was empty, and the O_NONBLOCK flag was set
|
||||
* for the message queue description referred to by 'mqdes'.
|
||||
* EPERM Message queue opened not opened for reading.
|
||||
* EMSGSIZE 'msglen' was less than the maxmsgsize attribute of the
|
||||
* message queue.
|
||||
* EINTR The call was interrupted by a signal handler.
|
||||
* EINVAL Invalid 'msg' or 'mqdes' or 'abstime'
|
||||
* ETIMEDOUT The call timed out before a message could be transferred.
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t mq_timedreceive(mqd_t mqdes, void *msg, size_t msglen,
|
||||
int *prio, const struct timespec *abstime)
|
||||
{
|
||||
WDOG_ID wdog;
|
||||
FAR mqmsg_t *mqmsg;
|
||||
irqstate_t saved_state;
|
||||
int ret = ERROR;
|
||||
|
||||
DEBUGASSERT(!up_interrupt_context());
|
||||
|
||||
/* Verify the input parameters and, in case of an error, set
|
||||
* errno appropriately.
|
||||
*/
|
||||
|
||||
if (mq_verifyreceive(mqdes, msg, msglen) != OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (!abstime || abstime->tv_sec < 0 || abstime->tv_nsec > 1000000000)
|
||||
{
|
||||
*get_errno_ptr() = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Create a watchdog. We will not actually need this watchdog
|
||||
* unless the queue is not empty, but we will reserve it up front
|
||||
* before we enter the following critical section.
|
||||
*/
|
||||
|
||||
wdog = wd_create();
|
||||
if (!wdog)
|
||||
{
|
||||
*get_errno_ptr() = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Get the next mesage from the message queue. We will disable
|
||||
* pre-emption until we have completed the message received. This
|
||||
* is not too bad because if the receipt takes a long time, it will
|
||||
* be because we are blocked waiting for a message and pre-emption
|
||||
* will be re-enabled while we are blocked
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Furthermore, mq_waitreceive() expects to have interrupts disabled
|
||||
* because messages can be sent from interrupt level.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
|
||||
/* Check if the message queue is empty. If it is NOT empty, then we
|
||||
* will not need to start timer.
|
||||
*/
|
||||
|
||||
if (mqdes->msgq->msglist.head == NULL)
|
||||
{
|
||||
sint32 ticks;
|
||||
|
||||
/* Convert the timespec to clock ticks. We must have interrupts
|
||||
* disabled here so that this time stays valid until the wait begins.
|
||||
*/
|
||||
|
||||
int result = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
||||
|
||||
/* If the time has already expired and the message queue is empty,
|
||||
* return immediately.
|
||||
*/
|
||||
|
||||
if (result == OK && ticks <= 0)
|
||||
{
|
||||
result = ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Handle any time-related errors */
|
||||
|
||||
if (result != OK)
|
||||
{
|
||||
*get_errno_ptr() = result;
|
||||
irqrestore(saved_state);
|
||||
sched_unlock();
|
||||
wd_delete(wdog);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Start the watchdog */
|
||||
|
||||
wd_start(wdog, ticks, (wdentry_t)mq_rcvtimeout, 1, getpid());
|
||||
}
|
||||
|
||||
/* Get the message from the message queue */
|
||||
|
||||
mqmsg = mq_waitreceive(mqdes);
|
||||
|
||||
/* Stop the watchdog timer (this is not harmful in the case where
|
||||
* it was never started)
|
||||
*/
|
||||
|
||||
wd_cancel(wdog);
|
||||
|
||||
/* We can now restore interrupts */
|
||||
|
||||
irqrestore(saved_state);
|
||||
|
||||
/* Check if we got a message from the message queue. We might
|
||||
* not have a message if:
|
||||
*
|
||||
* - The message queue is empty and O_NONBLOCK is set in the mqdes
|
||||
* - The wait was interrupted by a signal
|
||||
* - The watchdog timeout expired
|
||||
*/
|
||||
|
||||
if (mqmsg)
|
||||
{
|
||||
ret = mq_doreceive(mqdes, mqmsg, msg, prio);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
wd_delete(wdog);
|
||||
return ret;
|
||||
}
|
||||
320
sched/mq_timedsend.c
Normal file
320
sched/mq_timedsend.c
Normal file
@@ -0,0 +1,320 @@
|
||||
/****************************************************************************
|
||||
* mq_timedsend.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 <unistd.h>
|
||||
#include <mqueue.h>
|
||||
#include <wdog.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include "clock_internal.h"
|
||||
#include "os_internal.h"
|
||||
#include "mq_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: mq_sndtimeout
|
||||
*
|
||||
* Description:
|
||||
* This function is called if the timeout elapses before the message queue
|
||||
* becomes non-full.
|
||||
*
|
||||
* Parameters:
|
||||
* argc - the number of arguments (should be 1)
|
||||
* pid - the task ID of the task to wakeup
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mq_sndtimeout(int argc, uint32 pid, ...)
|
||||
{
|
||||
FAR _TCB *wtcb;
|
||||
irqstate_t saved_state;
|
||||
|
||||
/* Disable interrupts. This is necessary because an
|
||||
* interrupt handler may attempt to send a message while we are
|
||||
* doing this.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
|
||||
/* Get the TCB associated with this pid. It is possible that
|
||||
* task may no longer be active when this watchdog goes off.
|
||||
*/
|
||||
|
||||
wtcb = sched_gettcb((pid_t)pid);
|
||||
|
||||
/* It is also possible that an interrupt/context switch beat us to the
|
||||
* punch and already changed the task's state.
|
||||
*/
|
||||
|
||||
if (wtcb && wtcb->task_state == TSTATE_WAIT_MQNOTFULL)
|
||||
{
|
||||
/* Mark the errno value for the thread. */
|
||||
|
||||
wtcb->errno = ETIMEDOUT;
|
||||
|
||||
/* Restart the the task. */
|
||||
|
||||
up_unblock_task(wtcb);
|
||||
}
|
||||
|
||||
/* Interrupts may now be enabled. */
|
||||
|
||||
irqrestore(saved_state);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: mq_send
|
||||
*
|
||||
* Description:
|
||||
* This function adds the specificied message (msg) to the message queue
|
||||
* (mqdes). The "msglen" parameter specifies the length of the message
|
||||
* in bytes pointed to by "msg." This length must not exceed the maximum
|
||||
* message length from the mq_getattr().
|
||||
*
|
||||
* If the message queue is not full, mq_timedsend() place the message in the
|
||||
* message queue at the position indicated by the "prio" argrument.
|
||||
* Messages with higher priority will be inserted before lower priority
|
||||
* messages. The value of "prio" must not exceed MQ_PRIO_MAX.
|
||||
*
|
||||
* If the specified message queue is full and O_NONBLOCK is not set in the
|
||||
* message queue, then mq_timedsend() will block until space becomes available
|
||||
* to the queue the message or a timeout occurs.
|
||||
*
|
||||
* mq_timedsend() behaves just like mq_send(), except that if the queue
|
||||
* is full and the O_NONBLOCK flag is not enabled for the message queue
|
||||
* description, then abstime points to a structure which specifies a
|
||||
* ceiling on the time for which the call will block. This ceiling is an
|
||||
* absolute timeout in seconds and nanoseconds since the Epoch (midnight
|
||||
* on the morning of 1 January 1970).
|
||||
*
|
||||
* If the message queue is full, and the timeout has already expired by
|
||||
* the time of the call, mq_timedsend() returns immediately.
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
* msg - Message to send
|
||||
* msglen - The length of the message in bytes
|
||||
* prio - The priority of the message
|
||||
* abstime - the absolute time to wait until a timeout is decleared
|
||||
*
|
||||
* Return Value:
|
||||
* On success, mq_send() returns 0 (OK); on error, -1 (ERROR)
|
||||
* is returned, with errno set to indicate the error:
|
||||
*
|
||||
* EAGAIN The queue was empty, and the O_NONBLOCK flag was set for the
|
||||
* message queue description referred to by mqdes.
|
||||
* EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
|
||||
* EPERM Message queue opened not opened for writing.
|
||||
* EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
|
||||
* message queue.
|
||||
* EINTR The call was interrupted by a signal handler.
|
||||
*
|
||||
* Assumptions/restrictions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mq_timedsend(mqd_t mqdes, const char *msg, size_t msglen, int prio,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
WDOG_ID wdog;
|
||||
FAR msgq_t *msgq;
|
||||
FAR mqmsg_t *mqmsg = NULL;
|
||||
irqstate_t saved_state;
|
||||
int ret = ERROR;
|
||||
|
||||
DEBUGASSERT(!up_interrupt_context());
|
||||
|
||||
/* Verify the input parameters -- setting errno appropriately
|
||||
* on any failures to verify.
|
||||
*/
|
||||
|
||||
if (mq_verifysend(mqdes, msg, msglen, prio) != OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (!abstime || abstime->tv_sec < 0 || abstime->tv_nsec > 1000000000)
|
||||
{
|
||||
*get_errno_ptr() = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Get a pointer to the message queue */
|
||||
|
||||
msgq = mqdes->msgq;
|
||||
|
||||
/* Create a watchdog. We will not actually need this watchdog
|
||||
* unless the queue is full, but we will reserve it up front
|
||||
* before we enter the following critical section.
|
||||
*/
|
||||
|
||||
wdog = wd_create();
|
||||
if (!wdog)
|
||||
{
|
||||
*get_errno_ptr() = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Allocate a message structure:
|
||||
* - If we are called from an interrupt handler, or
|
||||
* - If the message queue is not full, or
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
saved_state = irqsave();
|
||||
if (up_interrupt_context() || /* In an interrupt handler */
|
||||
msgq->nmsgs < msgq->maxmsgs) /* OR Message queue not full */
|
||||
{
|
||||
/* Allocate the message */
|
||||
|
||||
irqrestore(saved_state);
|
||||
mqmsg = mq_msgalloc();
|
||||
}
|
||||
else
|
||||
{
|
||||
sint32 ticks;
|
||||
|
||||
/* We are not in an interupt handler and the message queue is full.
|
||||
* set up a timed wait for the message queue to become non-full.
|
||||
*
|
||||
* Convert the timespec to clock ticks. We must have interrupts
|
||||
* disabled here so that this time stays valid until the wait begins.
|
||||
*/
|
||||
|
||||
int result = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
||||
|
||||
/* If the time has already expired and the message queue is empty,
|
||||
* return immediately.
|
||||
*/
|
||||
|
||||
if (result == OK && ticks <= 0)
|
||||
{
|
||||
result = ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Handle any time-related errors */
|
||||
|
||||
if (result != OK)
|
||||
{
|
||||
*get_errno_ptr() = result;
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
/* Start the watchdog and begin the wait for MQ not full */
|
||||
|
||||
if (result == OK)
|
||||
{
|
||||
/* Start the watchdog */
|
||||
|
||||
wd_start(wdog, ticks, (wdentry_t)mq_sndtimeout, 1, getpid());
|
||||
|
||||
/* And wait for the message queue to be non-empty */
|
||||
|
||||
ret = mq_waitsend(mqdes);
|
||||
|
||||
/* This may return with an error and errno set to either EINTR
|
||||
* or ETIMEOUT. Cancel the watchdog timer in any event.
|
||||
*/
|
||||
|
||||
wd_cancel(wdog);
|
||||
}
|
||||
|
||||
/* That is the end of the atomic operations */
|
||||
|
||||
irqrestore(saved_state);
|
||||
|
||||
/* If any of the above failed, set the errno. Otherwise, there should
|
||||
* be space for another message in the message queue. NOW we can allocate
|
||||
* the message structure.
|
||||
*/
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
mqmsg = mq_msgalloc();
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we were able to get a message structure -- this can fail
|
||||
* either because we cannot send the message (and didn't bother trying
|
||||
* to allocate it) or because the allocation failed.
|
||||
*/
|
||||
|
||||
if (mqmsg)
|
||||
{
|
||||
/* Yes, peform the message send. */
|
||||
|
||||
ret = mq_dosend(mqdes, mqmsg, msg, msglen, prio);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
wd_delete(wdog);
|
||||
return ret;
|
||||
}
|
||||
|
||||
125
sched/mq_waitirq.c
Normal file
125
sched/mq_waitirq.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/************************************************************
|
||||
* mq_waitirq.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 <sys/types.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include "sem_internal.h"
|
||||
|
||||
/************************************************************
|
||||
* Compilation Switches
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Definitions
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Private Type Declarations
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Global Variables
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Private Variables
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Private Functions
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Public Functions
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Function: sem_waitirq
|
||||
*
|
||||
* Description:
|
||||
* This function is called when a signal is received by a
|
||||
* task that is waiting on a message queue -- either for a
|
||||
* queue to becoming not full (on mq_send) or not empty
|
||||
* (on mq_receive).
|
||||
*
|
||||
* Parameters:
|
||||
* wtcb - A pointer to the TCB of the task that is waiting
|
||||
* on a message queue, but has received a signal instead.
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
void mq_waitirq(FAR _TCB *wtcb)
|
||||
{
|
||||
irqstate_t saved_state;
|
||||
|
||||
/* Disable interrupts. This is necessary because an
|
||||
* interrupt handler may attempt to send a message while we are
|
||||
* doing this.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
|
||||
/* It is possible that an interrupt/context switch beat us to the
|
||||
* punch and already changed the task's state.
|
||||
*/
|
||||
|
||||
if (wtcb->task_state == TSTATE_WAIT_MQNOTEMPTY ||
|
||||
wtcb->task_state == TSTATE_WAIT_MQNOTFULL)
|
||||
{
|
||||
/* Mark the errno value for the thread. */
|
||||
|
||||
wtcb->errno = EINTR;
|
||||
|
||||
/* Restart the the task. */
|
||||
|
||||
up_unblock_task(wtcb);
|
||||
}
|
||||
|
||||
/* Interrupts may now be enabled. */
|
||||
|
||||
irqrestore(saved_state);
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ extern void task_start(void);
|
||||
extern STATUS task_schedsetup(FAR _TCB *tcb, int priority,
|
||||
start_t start, main_t main);
|
||||
extern STATUS task_argsetup(FAR _TCB *tcb, const char *name,
|
||||
char *argv[]);
|
||||
const char *argv[]);
|
||||
|
||||
extern boolean sched_addreadytorun(FAR _TCB *rtrtcb);
|
||||
extern boolean sched_removereadytorun(FAR _TCB *rtrtcb);
|
||||
|
||||
@@ -418,10 +418,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, (char **)NULL);
|
||||
(main_t)user_start, (const char **)NULL);
|
||||
#else
|
||||
init_taskid = task_create("init", SCHED_PRIORITY_DEFAULT,
|
||||
(main_t)user_start, (char **)NULL);
|
||||
(main_t)user_start, (const char **)NULL);
|
||||
#endif
|
||||
ASSERT(init_taskid != ERROR);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user