mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 13:18:50 +08:00
Fix error in MMC/SD SPI driver introduced with some recent changes; Update TODO list
This commit is contained in:
parent
8959fffedc
commit
a60e38e13a
2 changed files with 113 additions and 4 deletions
113
TODO
113
TODO
|
@ -1,4 +1,4 @@
|
||||||
NuttX TODO List (Last updated June 20, 2013)
|
NuttX TODO List (Last updated June 23, 2013)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
||||||
|
@ -13,7 +13,7 @@ nuttx/
|
||||||
(3) Signals (sched/, arch/)
|
(3) Signals (sched/, arch/)
|
||||||
(2) pthreads (sched/)
|
(2) pthreads (sched/)
|
||||||
(8) Kernel Build
|
(8) Kernel Build
|
||||||
(2) C++ Support
|
(4) C++ Support
|
||||||
(6) Binary loaders (binfmt/)
|
(6) Binary loaders (binfmt/)
|
||||||
(16) Network (net/, drivers/net)
|
(16) Network (net/, drivers/net)
|
||||||
(4) USB (drivers/usbdev, drivers/usbhost)
|
(4) USB (drivers/usbdev, drivers/usbhost)
|
||||||
|
@ -512,6 +512,115 @@ o C++ Support
|
||||||
constructor logic will probably have to be performed by
|
constructor logic will probably have to be performed by
|
||||||
user logic in user_start().
|
user logic in user_start().
|
||||||
|
|
||||||
|
Title: STATIC CONSTRUCTORS AND MULTITASKING
|
||||||
|
Description: The logic that calls static constructors operates on the main
|
||||||
|
thread of the initial user application task. Any static
|
||||||
|
constructors that cache task/thread specific information such
|
||||||
|
as C streams or file descriptors will not work in other tasks.
|
||||||
|
See also UCLIBC++ AND STATIC CONSTRUCTORS below.
|
||||||
|
Status: Open
|
||||||
|
Priority: Low and probably will not changed. In these case, there will
|
||||||
|
need to be an application specific solution.
|
||||||
|
|
||||||
|
Title: UCLIBC++ AND STATIC CONSTRUCTORS
|
||||||
|
uClibc++ was designed to work in a Unix environment with
|
||||||
|
processes and with separately linked executables. Each process
|
||||||
|
has its own, separate uClibc++ state. uClibc++ would be
|
||||||
|
instantiated like this in Linux:
|
||||||
|
|
||||||
|
1) When the program is built, a tiny start-up function is
|
||||||
|
included at the beginning of the program. Each program has
|
||||||
|
its own, separate list of C++ constructors.
|
||||||
|
|
||||||
|
2) When the program is loaded into memory, space is set aside
|
||||||
|
for uClibc's static objects and then this special start-up
|
||||||
|
routine is called. It initializes the C library, calls all
|
||||||
|
of the constructors, and calls atexit() so that the destructors
|
||||||
|
will be called when the process exits.
|
||||||
|
|
||||||
|
In this way, you get a per-process uClibc++ state since there
|
||||||
|
is per-process storage of uClibc++ global state and per-process
|
||||||
|
initialization of uClibc++ state.
|
||||||
|
|
||||||
|
Compare this to how NuttX (and most embedded RTOSs) would work:
|
||||||
|
|
||||||
|
1) The entire FLASH image is built as one big blob. All of the
|
||||||
|
constructors are lumped together and all called together at
|
||||||
|
one time.
|
||||||
|
|
||||||
|
This, of course, does not have to be so. We could segregate
|
||||||
|
constructors by some criteria and we could use a task start
|
||||||
|
up routine to call constructors separately. We could even
|
||||||
|
use ELF executables that are separately linked and already
|
||||||
|
have their constructors separately called when the ELF
|
||||||
|
executable starts.
|
||||||
|
|
||||||
|
But this would not do you very much good in the case of
|
||||||
|
uClibc++ because:
|
||||||
|
|
||||||
|
2) NuttX does not support processes, i.e., separate address
|
||||||
|
environments for each task. As a result, the scope of global
|
||||||
|
data is all tasks. Any change to the global state made by
|
||||||
|
one task can effect another task. There can only one
|
||||||
|
uClibc++ state and it will be shared by all tasks. uClibc++
|
||||||
|
apparently relies on global instances (at least for cin and
|
||||||
|
cout) there is no way to to have any unique state for any
|
||||||
|
"task group".
|
||||||
|
|
||||||
|
[NuttX does not support processes because in order to have
|
||||||
|
true processes, your hardware must support a memory management
|
||||||
|
unit (MMU) and I am not aware of any mainstream MCU that has
|
||||||
|
an MMU (or, at least an MMU that is capable enough to support
|
||||||
|
processes).]
|
||||||
|
|
||||||
|
NuttX does not have processes, but it does have "task groups".
|
||||||
|
See http://www.nuttx.org/doku.php?id=wiki:nxinternal:tasksnthreads.
|
||||||
|
A task group is the task plus all of the pthreads created by
|
||||||
|
the task via pthread_create(). Resources like FILE streams
|
||||||
|
are shared within a task group. Task groups are like a poor
|
||||||
|
man's process.
|
||||||
|
|
||||||
|
This means that if the uClibc++ static classes are initialized
|
||||||
|
by one member of a task group, then cin/cout should work
|
||||||
|
correctly with all threads that are members of task group. The
|
||||||
|
destructors would be called when the final member of the task
|
||||||
|
group exists (if registered via atexit()).
|
||||||
|
|
||||||
|
So if you use only pthreads, uClibc++ should work very much like
|
||||||
|
it does in Linux. If your NuttX usage model is like one process
|
||||||
|
with many threads then you have Linux compatibility.
|
||||||
|
|
||||||
|
If you wanted to have uClibc++ work across task groups, then
|
||||||
|
uClibc++ and NuttX would need some extensions. I am thinking
|
||||||
|
along the lines of the following:
|
||||||
|
|
||||||
|
1) There is a per-task group storage are withing the RTOS (see
|
||||||
|
include/nuttx/sched.h). If we add some new, nonstandard APIs
|
||||||
|
then uClibc++ could get access to per-task group storage (in
|
||||||
|
the spirit of pthread_getspecific() which gives you access to
|
||||||
|
per-thread storage).
|
||||||
|
|
||||||
|
2) Then move all of uClibc++'s global state into per-task group
|
||||||
|
storage and add a uClibc++ initialization function that would:
|
||||||
|
a) allocate per-task group storage, b) call all of the static
|
||||||
|
constructors, and c) register with atexit() to perform clean-
|
||||||
|
up when the task group exits.
|
||||||
|
|
||||||
|
That would be a fair amount of effort. I don't really know what
|
||||||
|
the scope of such an effort would be. I suspect that it is not
|
||||||
|
large but probably complex.
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
|
||||||
|
1) See STATIC CONSTRUCTORS AND MULTITASKING
|
||||||
|
|
||||||
|
2) To my knowledge, only some uClibc++ ofstream logic is
|
||||||
|
sensitive to this. All other statically initialized classes
|
||||||
|
seem to work OK across different task groups.
|
||||||
|
Status: Open
|
||||||
|
Priority: Low. I have no plan to change this logic now unless there is
|
||||||
|
some strong demand to do so.
|
||||||
|
|
||||||
o Binary loaders (binfmt/)
|
o Binary loaders (binfmt/)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -365,8 +365,8 @@ static void mmcsd_semtake(FAR struct mmcsd_slot_s *slot)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SPI_SETFREQUENCY(slot->spi, slot->spispeed);
|
SPI_SETFREQUENCY(slot->spi, slot->spispeed);
|
||||||
SPI_SETMODE(slot->sp, CONFIG_MMCSD_SPIMODE);
|
SPI_SETMODE(slot->spi, CONFIG_MMCSD_SPIMODE);
|
||||||
SPI_SETBITS(slot->sp, 8);
|
SPI_SETBITS(slot->spi, 8);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get exclusive access to the MMC/SD device (prossibly un-necessary if
|
/* Get exclusive access to the MMC/SD device (prossibly un-necessary if
|
||||||
|
|
Loading…
Reference in a new issue