Compare commits

...

59 Commits

Author SHA1 Message Date
patacongo
13f01b4cf3 update
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@182 42af7a65-404d-4744-a932-0658087f49c3
2007-03-30 13:21:20 +00:00
patacongo
d2410c93c6 Fix another potential pthread_join race condition
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@181 42af7a65-404d-4744-a932-0658087f49c3
2007-03-30 13:11:19 +00:00
patacongo
f29250c671 Correct a race condition in the pthread join logic. Sometimes the join structure was being deallocated while it was still needed.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@180 42af7a65-404d-4744-a932-0658087f49c3
2007-03-30 00:49:11 +00:00
patacongo
2a929796b9 Add timed mqueue test.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@179 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 23:44:55 +00:00
patacongo
b1127822ed Fix bugs detected by timed mqueue test.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@178 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 23:43:54 +00:00
patacongo
448c7f4618 Container being deallocated before buffers in container. Caused memory leak.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@177 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 16:53:03 +00:00
patacongo
ed4fe71b96 Updated test results
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@176 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 14:27:23 +00:00
patacongo
63f134f988 Wrong task state
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@175 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 14:22:29 +00:00
patacongo
8b9fcf354e Moved exclusion logic to a higher level so that printf output is more readable when the same stdout FILE* is shared
by many pthreads (tasks did not have this probablem because they have separate stdout streams).


git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@174 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 14:21:31 +00:00
patacongo
b1d5b6899a Signal mask is now inherited by both child tasks and threads; this has the side-effect of changing the initia
l state of all signals from blocked to unblocked.


git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@173 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 13:34:37 +00:00
patacongo
2aab4d3c3a Unmatched sched_lock()/sched_unlock()
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@172 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 13:32:13 +00:00
patacongo
b765d17818 Don't allow signals to wake up blocked task if the signal is blocked.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@171 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 13:31:08 +00:00
patacongo
54339607da Block signals while pthread exits.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@170 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 13:29:29 +00:00
patacongo
0c2ff4a47c typo
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@169 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 13:28:27 +00:00
patacongo
23dffb8f23 Eliminate warnings
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@168 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 13:27:43 +00:00
patacongo
0db3f5c256 task_delete() calls sched_unlock(); _exit must keep pre-emption disabled until pending queue emptied.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@167 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 13:26:24 +00:00
patacongo
56f7399200 Added mq_timedsend() and mq_timedreceive()
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@166 42af7a65-404d-4744-a932-0658087f49c3
2007-03-29 13:25:18 +00:00
patacongo
5f5d5496d9 Update mq_send() and mq_receive() description
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@165 42af7a65-404d-4744-a932-0658087f49c3
2007-03-28 16:00:57 +00:00
patacongo
3e352ca10b mq_receive/send: Return appropriate errnos and stop waiting if signal received.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@164 42af7a65-404d-4744-a932-0658087f49c3
2007-03-28 14:48:42 +00:00
patacongo
c5971231da updates
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@163 42af7a65-404d-4744-a932-0658087f49c3
2007-03-27 21:27:41 +00:00
patacongo
b7a85058a4 update
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@162 42af7a65-404d-4744-a932-0658087f49c3
2007-03-27 16:35:48 +00:00
patacongo
4ee22e2307 Board-specific LED logic moved to board-specific directory
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@161 42af7a65-404d-4744-a932-0658087f49c3
2007-03-27 16:35:17 +00:00
patacongo
daffb73624 Use gzip instead of bzip2
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@160 42af7a65-404d-4744-a932-0658087f49c3
2007-03-27 16:20:47 +00:00
patacongo
c5af51943b Move PJRC led support into board-specific logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@159 42af7a65-404d-4744-a932-0658087f49c3
2007-03-27 16:19:51 +00:00
patacongo
795ffc3829 Remove leftover debug echo
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@158 42af7a65-404d-4744-a932-0658087f49c3
2007-03-27 16:19:01 +00:00
patacongo
efa97ac0f5 Add DM320 LED support
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@157 42af7a65-404d-4744-a932-0658087f49c3
2007-03-27 16:17:23 +00:00
patacongo
b441f43a6e Fix DM320 CFLAGS
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@156 42af7a65-404d-4744-a932-0658087f49c3
2007-03-27 16:16:09 +00:00
patacongo
c9011c0f30 Create a place to hold board-specific drivers
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@155 42af7a65-404d-4744-a932-0658087f49c3
2007-03-26 22:32:58 +00:00
patacongo
03771dd514 Bad import
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@154 42af7a65-404d-4744-a932-0658087f49c3
2007-03-26 22:28:03 +00:00
patacongo
18149c3b98 Was delete link then delete link in directory referenced by link
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@153 42af7a65-404d-4744-a932-0658087f49c3
2007-03-26 22:22:20 +00:00
patacongo
aa56898b82 Moved to board-specific directory
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@152 42af7a65-404d-4744-a932-0658087f49c3
2007-03-26 22:16:07 +00:00
patacongo
8e8fc062a5 Add a directory to hold board-specific drivers
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@151 42af7a65-404d-4744-a932-0658087f49c3
2007-03-26 22:14:28 +00:00
patacongo
c0934f429d Initial Revision
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@148 42af7a65-404d-4744-a932-0658087f49c3
2007-03-26 22:05:53 +00:00
patacongo
bf9cc8b7ab Initial Revision
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@147 42af7a65-404d-4744-a932-0658087f49c3
2007-03-26 16:51:05 +00:00
patacongo
47118057ea Create a place to hold board specific header files
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@146 42af7a65-404d-4744-a932-0658087f49c3
2007-03-26 16:47:17 +00:00
patacongo
468beb1305 Makefile would sometimes create spurious links
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@145 42af7a65-404d-4744-a932-0658087f49c3
2007-03-25 13:16:27 +00:00
patacongo
df2a08cf9b Add test of pthread barrier logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@144 42af7a65-404d-4744-a932-0658087f49c3
2007-03-24 22:32:53 +00:00
patacongo
a02374bb45 updates
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@143 42af7a65-404d-4744-a932-0658087f49c3
2007-03-24 15:57:35 +00:00
patacongo
3631d1e1ad Eliminate warnings
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@142 42af7a65-404d-4744-a932-0658087f49c3
2007-03-24 15:57:00 +00:00
patacongo
16e8906ed5 Add logic to protect the user task errno when errno access are performed from interrupt handlers.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@141 42af7a65-404d-4744-a932-0658087f49c3
2007-03-24 15:56:27 +00:00
patacongo
d551204f84 Cosmetic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@140 42af7a65-404d-4744-a932-0658087f49c3
2007-03-24 15:55:21 +00:00
patacongo
3d5eebad25 Add pthread_setschedprio() prototype
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@139 42af7a65-404d-4744-a932-0658087f49c3
2007-03-24 15:54:42 +00:00
patacongo
b9d2a2b971 Add SCHED_SPORADIC (even though we don't use it)
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@138 42af7a65-404d-4744-a932-0658087f49c3
2007-03-24 15:53:52 +00:00
patacongo
768a214d63 Don't all sched_setparam; call up_prrioritize_rtr directly
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@137 42af7a65-404d-4744-a932-0658087f49c3
2007-03-24 15:52:45 +00:00
patacongo
b282cd3f42 Correct errno handling
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@136 42af7a65-404d-4744-a932-0658087f49c3
2007-03-24 15:51:50 +00:00
patacongo
e689e148e8 Added pthread_setschedprio()
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@135 42af7a65-404d-4744-a932-0658087f49c3
2007-03-24 15:51:01 +00:00
patacongo
7a1f5f61bd Add new pthread_* APIs
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@134 42af7a65-404d-4744-a932-0658087f49c3
2007-03-23 23:22:22 +00:00
patacongo
1e8eaa90c1 Fix memory leaks
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@133 42af7a65-404d-4744-a932-0658087f49c3
2007-03-23 16:06:22 +00:00
patacongo
5af89ab5eb Needs prototype for timer_test()
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@132 42af7a65-404d-4744-a932-0658087f49c3
2007-03-23 16:05:52 +00:00
patacongo
a2ed490c11 should not include pthread.h
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@131 42af7a65-404d-4744-a932-0658087f49c3
2007-03-23 16:04:58 +00:00
patacongo
a2c26f080a argv parameter should be 'const'
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@130 42af7a65-404d-4744-a932-0658087f49c3
2007-03-23 16:03:28 +00:00
patacongo
30c1d1028d limits.h is also a required file
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@129 42af7a65-404d-4744-a932-0658087f49c3
2007-03-23 16:02:36 +00:00
patacongo
0baf1522b1 Initial Release
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@128 42af7a65-404d-4744-a932-0658087f49c3
2007-03-23 16:00:16 +00:00
patacongo
5325f906c7 Move to the configs subdirectory
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@127 42af7a65-404d-4744-a932-0658087f49c3
2007-03-23 02:29:35 +00:00
patacongo
ef4d567b78 Create configs/ dir; separate board configuration from processor architecture
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@126 42af7a65-404d-4744-a932-0658087f49c3
2007-03-23 02:25:54 +00:00
patacongo
aae8532783 Initial Release
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@125 42af7a65-404d-4744-a932-0658087f49c3
2007-03-23 02:24:38 +00:00
patacongo
1367c062f7 Remove duplicated instruction
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@124 42af7a65-404d-4744-a932-0658087f49c3
2007-03-23 00:27:05 +00:00
patacongo
136e3d9fca update
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@123 42af7a65-404d-4744-a932-0658087f49c3
2007-03-22 19:17:38 +00:00
patacongo
8abec4bbb0 This platform does not need rrload format
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@122 42af7a65-404d-4744-a932-0658087f49c3
2007-03-22 19:15:18 +00:00
132 changed files with 10446 additions and 3740 deletions

View File

@@ -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

View File

@@ -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%">

View File

@@ -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>&lt;arch-name&gt;</i>/
| | |-- include/
| | | |--<i>&lt;chip-name&gt;</i>/
| | | | `-- <i>(chip-specific header files)</i>
| | | |--<i>&lt;other-chips&gt;</i>/
| | | `-- <i>(architecture-specific header files)</i>
| | `-- src/
| | |--<i>&lt;chip-name&gt;</i>/
| | | `-- <i>(chip-specific source files)</i>
| | |--<i>&lt;other-chips&gt;</i>/
| | `-- <i>(architecture-specific source files)</i>
| `-- <i>&lt;other-architectures&gt;</i>/
|-- <a href="#DirStructConfigs">configs</a>/
| |-- <i>&lt;board-name&gt;</i>/
| | |-- include/
| | | `-- <i>(board-specific header files)</i>
| | |-- src/
| | | |-- Makefile
| | | `-- <i>(board-specific source files)</i>
| | `-- <i>(board-specific configuration files)</i>
| `-- <i>&lt;other-boards&gt;</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>&lt;arch-name&gt;</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>&lt;arch-name&gt;</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>&lt;board-name&gt;</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, &lt;<i>arch-name</i>&gt;
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>&lt;arch-name&gt;</i>
under <code>arch/</code> with the following characteristics:
</p>
<ul><pre>
&lt;<i>arch-name</i>&gt;
|-- Make.defs
|-- defconfig
|-- setenv.sh
|-- include
<i>&lt;arch-name&gt;</i>/
|-- include/
| |--<i>&lt;chip-name&gt;</i>/
| | `-- <i>(chip-specific header files)</i>
| |--<i>&lt;other-chips&gt;</i>/
| |-- arch.h
| |-- irq.h
| `-- types.h
`-- src
| |-- types.h
| `-- limits.h
`-- src/
|--<i>&lt;chip-name&gt;</i>/
| `-- <i>(chip-specific source files)</i>
|--<i>&lt;other-chips&gt;</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>&lt;chip-name&gt;</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>&lt;chip-name&gt;</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>&lt;arch-name&gt;</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/&lt;<i>arch-name</i>&gt;/Make.def</code> to <code>${TOPDIR}/Make.defs</code>,
<code>arch/&lt;<i>arch-name</i>&gt;/setenv.sh</code> to <code>${TOPDIR}/setenv.sh</code>, and
<code.arch/&lt;<i>arch-name</i>&gt;/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 &lt;board-name&gt; under <code>configs/</code> with the following characteristics:
</p>
<ul><pre>
cd tools
./configure.sh &lt;<i>arch-name</i>&gt;
<i>&lt;board-name&gt;</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 &lt;arch/board/header.h&gt;</code>.
These header file can only be included by files in <code>arch/</code><i>&lt;arch-name&gt;</i><code>/include/</code>
and <code>arch/</code><i>&lt;arch-name&gt;</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>&lt;arch-name&gt;</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>&lt;board-name&gt;</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>&lt;board-name&gt;</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>&lt;board-name&gt;</i></code>/Make.def</code> to <code>${TOPDIR}/Make.defs</code>,<li>
<li>Copy <code>configs/</code><i>&lt;board-name&gt;</i></code>/setenv.sh</code> to <code>${TOPDIR}/setenv.sh</code>, and</li>
<li>Copy <code>configs/</code><i>&lt;board-name&gt;</i></code>/defconfig</code> to <code>${TOPDIR}/.config</code></li>
</ul>
<p>
Where <i>&lt;board-name&gt;</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>&lt;board-name&gt;</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>&lt;arch-name&gt;</i><code>/include</code> at <code>${TOPDIR}/include/arch</code>.
<li>Creating a link to <code>${TOPDIR}/configs/</code><i>&lt;board-name&gt;</i><code>/include</code> at <code>${TOPDIR}/include/arch/board</code>.
<li>Creating a link to <code>${TOPDIR}/configs/</code><i>&lt;board-name&gt;</i><code>/src</code> at <code>${TOPDIR}/arch/</code><i>&lt;arch-name&gt;</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

View File

@@ -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

View File

@@ -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
View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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.
*/

View File

@@ -117,7 +117,7 @@ __start:
#endif
/* Initialize onboard LEDs */
#ifdef CONFIG_C5471_LEDS
#ifdef CONFIG_ARCH_LEDS
bl up_ledinit
#endif

View File

@@ -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);

View File

@@ -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

View File

@@ -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"

View File

@@ -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.
*/

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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

View File

@@ -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.
*/

View File

@@ -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);

View File

@@ -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
View 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>

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1 @@
This directory contains header files unique to the Spectrum Digital C5471 EVM.

View 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 */

View 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

View File

@@ -0,0 +1,2 @@
This directory contains drivers unique to the Spectrum Digital C5471 EVM.

View File

@@ -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 */

View 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
View 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=

View 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"

View File

@@ -0,0 +1 @@
This directory contains header files unique to the M68322EVB.

View 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
View 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}"

View 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

View File

@@ -0,0 +1 @@
This directory contains drivers unique to the m68332evb.

View File

@@ -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

View File

@@ -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)

View 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

View File

@@ -0,0 +1 @@
This directory contains header files unique to the Neuros dm320-based OSD.

View 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

View File

@@ -0,0 +1 @@
This directory contains drivers unique to the Neuros OSD.

View 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 */

View File

@@ -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

View File

@@ -0,0 +1 @@
This directory contains header files unique to the PJRC 87C52 development board.

View 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

View File

@@ -0,0 +1 @@
This directory contains drivers unique to the PJRC 87C52 board.

View File

@@ -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

View File

@@ -0,0 +1 @@
This directory contains header files unique to the Linux user-mode platform.

76
configs/sim/src/Makefile Normal file
View 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

View File

@@ -0,0 +1 @@
This directory contains drivers unique to the Linux user-mode platform.

View File

@@ -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
View 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);
}
}

View File

@@ -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");
}
}
}

View File

@@ -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");

View File

@@ -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)
{

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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>

View 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");
}

View File

@@ -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"

View File

@@ -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);

View File

@@ -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
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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 \

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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
View 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;
}

View File

@@ -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();

View File

@@ -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
View 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
View 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
View 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
View 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);
}

View File

@@ -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);

View File

@@ -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