You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/11/05 04:11:19 UTC

(nuttx) branch master updated (43ecf36d78 -> fdc671fa3e)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


    from 43ecf36d78 udp: modify ipv4 multicast to allow different conn to join simultaneously
     new bfd342b4eb Documentation: fix warning
     new 63558cf72f Documentation: migrate "NuttX Graphics Subsystem (NX)" from wiki
     new de564d38e9 Documentation: migrate "Wide Font Support" from wiki
     new 03b4ec60a5 Documentation: migrate "Running Applications from NSH" from wiki
     new 3b23a693ac Documentation: migrate "Linux Processes vs NuttX Tasks" from wiki
     new adc557f545 Documentation: migrate "apps/tools/mkromfsimg.sh" from wiki
     new 20fd7f588f Documentation: CONFIG_USER_ENTRYPOINT was changed to CONFIG_INIT_ENTRYPOINT
     new f96064db75 Documentation: migrate "SMP Critical Sections" from wiki
     new fdc671fa3e Documentation: migrate "Critical Section Monitor" from wiki

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Documentation/applications/nsh/index.rst           |   1 +
 Documentation/applications/nsh/running_apps.rst    | 180 +++++++++
 Documentation/applications/tools/index.rst         |  70 +++-
 Documentation/components/nxgraphics/nx.rst         |  57 +++
 Documentation/components/nxgraphics/nxfonts.rst    |  84 ++++
 Documentation/guides/customapps.rst                |   2 +-
 Documentation/implementation/critical_sections.rst | 432 +++++++++++++++++++++
 Documentation/implementation/index.rst             |  10 +
 .../implementation/processes_vs_tasks.rst          | 263 +++++++++++++
 Documentation/index.rst                            |   1 +
 .../arm/stm32f4/boards/stm32f401rc-rs485/index.rst |  11 +-
 11 files changed, 1104 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/applications/nsh/running_apps.rst
 create mode 100644 Documentation/implementation/critical_sections.rst
 create mode 100644 Documentation/implementation/index.rst
 create mode 100644 Documentation/implementation/processes_vs_tasks.rst


(nuttx) 07/09: Documentation: CONFIG_USER_ENTRYPOINT was changed to CONFIG_INIT_ENTRYPOINT

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 20fd7f588ff4d72527c1f3e768b1464effed0ee6
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Nov 4 20:56:10 2023 +0100

    Documentation: CONFIG_USER_ENTRYPOINT was changed to CONFIG_INIT_ENTRYPOINT
---
 Documentation/guides/customapps.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/guides/customapps.rst b/Documentation/guides/customapps.rst
index f2930f4704..44eeb6e953 100644
--- a/Documentation/guides/customapps.rst
+++ b/Documentation/guides/customapps.rst
@@ -160,7 +160,7 @@ In order to build with the new custom configuration, you will need the following
 
 :menuselection:`CONFIG_APPS_DIR="../CustomApps"`
 
-:menuselection:`CONFIG_USER_ENTRYPOINT="custom_hello"`
+:menuselection:`CONFIG_INIT_ENTRYPOINT="custom_hello"`
 
 Note that you can only access the ``../CustomApps/Kconfig`` configuration file if ``CONFIG_APPS_DIR`` is set
 to ``../CustomApps`` BEFORE ``make menuconfig`` is executed


(nuttx) 02/09: Documentation: migrate "NuttX Graphics Subsystem (NX)" from wiki

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 63558cf72f31b46e578d8ffd3d6618347b9d44d8
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Nov 4 17:58:33 2023 +0100

    Documentation: migrate "NuttX Graphics Subsystem (NX)" from wiki
    
    link to wiki: https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=139629474
---
 Documentation/components/nxgraphics/nx.rst | 57 ++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/Documentation/components/nxgraphics/nx.rst b/Documentation/components/nxgraphics/nx.rst
index 82c96ce6af..899ebc5712 100644
--- a/Documentation/components/nxgraphics/nx.rst
+++ b/Documentation/components/nxgraphics/nx.rst
@@ -2,6 +2,63 @@
 NX
 ==
 
+Overview
+========
+
+NX provides a tiny windowing system in the spirit of X, but greatly scaled
+down and appropriate for most resource-limited embedded environments.
+The current NX implementation supports the general following, high-level
+features:
+
+* **Virtual Vertical Graphics Space** Windows that reside in a virtual,
+  vertical space so that it makes sense to talk about one window being
+  on top of another and obscuring the window below it.
+
+* **Client/Server Model** A standard client server/model was adopted.
+  NX may be considered a server and other logic that presents the windows
+  are NX clients.
+
+* **Multi-User Support** NX includes front-end logic to an NX server
+  daemon that can serve multiple NX client threads. The NX sever
+  thread/daemon serializes graphics operations from multiple clients.
+  
+* **Minimal Graphics Toolset** The actual implementation of the graphics
+  operations is performed by common, back-end logic. This back-end supports
+  only a primitive set of graphic and rendering operations.
+
+* **Device Interface** NX supports any graphics device either of two
+  device interfaces:
+
+  #. Any device with random accesss video memory using the NuttX framebuffer
+     driver interface (see include/nuttx/video/fb.h).
+  #. Any LCD-like device than can accept raster line runs through a parallel
+     or serial interface (see include/nuttx/lcd/lcd.h). By default, NX is
+     configured to use the frame buffer driver unless CONFIG_NX_LCDDRIVER
+     is defined =y in your NuttX configuration file.
+
+* **Transparent to NX Client** The window client on "sees" the sub-window
+  that is operates in and does not need to be concerned with the virtual,
+  vertical space (other that to respond to redraw requests from NX when needed).
+
+* **Framed Windows and Toolbars** NX also adds the capability to support
+  windows with frames and toolbars on top of the basic windowing support.
+  These are windows such as those shown in the screenshot above. These framed
+  windows sub-divide one one window into three relatively independent
+  subwindows: A frame, the contained window and an (optional) toolbar window.
+
+* **Mouse Support** NX provides support for a mouse or other X/Y pointing
+  devices. APIs are provided to allow external devices to give X/Y position
+  information and mouse button presses to NX. NX will then provide the mouse
+  input to the relevant window clients via callbacks. Client windows only
+  receive the mouse input callback if the mouse is positioned over a visible
+  portion of the client window; X/Y position is provided to the client in the
+  relative coordinate system of the client window.
+
+* **Keyboard input** NX also supports keyboard/keypad devices. APIs are provided
+  to allow external devices to give keypad information to NX. NX will then
+  provide the mouse input to the top window on the display (the window that
+  has the focus) via a callback function.
+
 Pre-Processor Definitions
 =========================
 


(nuttx) 09/09: Documentation: migrate "Critical Section Monitor" from wiki

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit fdc671fa3e59e31154e44c439ae7ec0dd8e56206
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Nov 4 21:59:24 2023 +0100

    Documentation: migrate "Critical Section Monitor" from wiki
    
    links: https://cwiki.apache.org/confluence/display/NUTTX/Critical+Section+Monitor
---
 Documentation/implementation/critical_sections.rst | 269 +++++++++++++++++++++
 1 file changed, 269 insertions(+)

diff --git a/Documentation/implementation/critical_sections.rst b/Documentation/implementation/critical_sections.rst
index 45b30e21f1..4939e153ba 100644
--- a/Documentation/implementation/critical_sections.rst
+++ b/Documentation/implementation/critical_sections.rst
@@ -2,6 +2,40 @@
 Critical Sections
 =================
 
+Types and Effects of Critical Sections
+======================================
+
+A critical section is a short sequence of code where exclusive execution is
+assured by globally disabling other activities while that code sequence executes.
+When we discuss critical sections here we really refer to one of two mechanisms:
+
+* **Critical Section proper** A critical section is established by calling
+  ``enter_critical_section()``; the code sequence exits the critical section by
+  calling ``leave_critical_section()``. For the single CPU case, this amounts to
+  simply disabling interrupts but is more complex in the SMP case where spinlocks
+  are also involved.
+
+* **Disabling Pre-emption** This is a related mechanism that is lumped into this
+  discussion because of the similarity of its effects on the system. When pre-emption
+  is disabled (via ``sched_lock()``), interrupts remain enabled, but context switches
+  may not occur; the current task is locked in place and cannot be suspended until
+  the scheduler is unlocked (via ``sched_unlock()``).
+
+The use of either mechanism will always harm real-time performance.
+The effects of critical sections on real-time performance is discussed in
+`Effects of Disabling Interrupts or Pre-Emption on Response Latency <https://cwiki.apache.org/confluence/display/NUTTX/Effects+of+Disabling+Interrupts+or+Pre-Emption+on+Response+Latency>`_ [TODO: move to documentation].
+The end result is that a certain amount of **jitter** is added to the real-time response.
+
+Critical sections cannot be avoided within the OS and, as a consequence, a certain
+amount of "jitter" in the response time is expected. The important thing is to monitor
+the maximum time that critical sections are in place in order to manage that jitter so
+that the variability in response time is within an acceptable range.
+
+NOTE: This discussion applies to Normal interrupt processing. Most of this discussion
+does not apply to :doc:`/guides/zerolatencyinterrupts`. Those interrupts are not masked
+in the same fashion and none of the issues address in this page apply to those
+interrupts.
+
 Single CPU Critical Sections
 ============================
 
@@ -161,3 +195,238 @@ the single CPU case. Here are the caveats:
   themselves at any time (say, via ``sleep()``). In that case, only the CPU's
   IDLE task will be permitted to run.
 
+The Critical Section Monitor
+============================
+
+Internal OS Hooks
+-----------------
+
+**The Critical Section Monitor**
+
+In order to measure the time that tasks hold critical sections, the OS supports
+a Critical Section Monitor. This is internal instrumentation that records the
+time that a task holds a critical section. It also records the amount of time
+that interrupts are disabled globally. The Critical Section Monitor then retains
+the maximum time that the critical section is in place, both per-task and globally.
+
+The Critical Section Monitor is enabled with the following setting in the
+configuration::
+
+  CONFIG_SCHED_CRITMONITOR=y
+
+**Perf Timers interface**
+
+.. todo:: missing description for perf_xxx interface
+
+**Per Thread and Global Critical Sections**
+
+In NuttX critical sections are controlled on a per-task basis. For example,
+consider the following code sequence:
+
+.. code-block:: C
+
+   irqstate_t flags = enter_critical_section();
+   sleep(5);
+   leave_critical_section(flags);
+
+The task, say Task A, establishes the critical section with
+``enter_critical_section()``, but when Task A is suspended by the ``sleep(5)``
+statement, it relinquishes the critical section. The state of the system will
+then be determined by the next task to be resumed, say Task B: Typically, the
+next task will not be in a critical section and so the critical section is
+broken while the task sleeps. That critical section will be re-established when
+that Task A runs again after the sleep time expires.
+
+However, if Task B that is resumed is also within a critical section, then the
+critical section will be extended even longer! This is why the global time that
+the critical section in place may be longer than any time that an individual
+thread holds the critical section.
+
+ProcFS
+------
+
+The OS reports these maximum times via the ProcFS file system, typically
+mounted at ``/proc``:
+
+* The ``/proc/<ID>/critmon`` pseudo-file reports the per-thread maximum value
+  for thread ID = <ID>. There is one instance of this critmon file for each
+  active task in the system.
+
+* The ``/proc/critmon`` pseuo-file reports similar information for the global
+  state of the CPU.
+
+The form of the output from the ``/proc/<ID>/critmon`` file is::
+
+  X.XXXXXXXXX,X.XXXXXXXXX
+
+Where ``X.XXXXXXXXX`` is the time in seconds with nanosecond precision
+(but not necessarily accuracy, accuracy is dependent on the timing clock
+source). The first number is the maximum time that the held pre-emption
+disabled; the second number number is the longest duration that the critical
+section was held.
+
+This file cat be read from NSH like:
+
+.. code-block:: bash
+
+   nsh> cat /proc/1/critmon
+   0.000009610,0.000001165
+
+The form of the output from the ``/proc/critmon`` file is simlar::
+
+  X,X.XXXXXXXXX,X.XXXXXXXXX
+
+Where the first X is the CPU number and the following two numbers have the
+same interpretation as for ``/proc/<ID>/critmon``. In the single CPU case,
+there will be one line in the pseudo-file with ``X=0``; in the SMP case
+there will be multiple lines, one for each CPU.
+
+This file can also be read from NSH:
+
+.. code-block:: bash
+
+   nsh> cat /proc/critmon
+   0,0.000009902,0.000023590
+
+These statistics are cleared each time that the pseudo-file is read so that
+the reported values are the maximum since the last time that the ProcFS pseudo
+file was read.
+
+``apps/system/critmon``
+-----------------------
+
+Also available is a application daemon at ``apps/sysem/critmon``. This daemon
+periodically reads the ProcFS files described above and dumps the output to
+stdout. This daemon is enabled with:
+
+.. code-block:: bash
+
+   nsh> critmon_start
+   Csection Monitor: Started: 3
+   Csection Monitor: Running: 3
+   nsh>
+   PRE-EMPTION CSECTION    PID   DESCRIPTION
+   MAX DISABLE MAX TIME
+   0.000100767 0.000005242  ---  CPU 0
+   0.000000292 0.000023590     0 Idle Task
+   0.000036696 0.000004078     1 init
+   0.000000000 0.000014562     3 Csection Monitor
+   ...
+
+And can be stopped with:
+
+.. code-block:: bash
+
+   nsh> critmon_stop
+   Csection Monitor: Stopping: 3
+   Csection Monitor: Stopped: 3
+
+IRQ Monitor and Worst Case Response Time
+========================================
+
+The IRQ Monitor is additional OS instrumentation. A full discusssion of the
+IRQ Monitor is beyond the scope of this page. Suffice it to say:
+
+* The IRQ Monitor is enabled with ``CONFIG_SCHED_IRQMONITOR=y``.
+
+* The data collected by the IRQ Monitor is provided in ``/proc/irqs``.
+
+* This data can also be viewed using the ``nsh> irqinfo`` command.
+
+* This data includes the number of interrupts received for each IRQ and the
+  time required to process the interrupt, from entry into the attached
+  interrupt handler until exit from the interrupt handler.
+
+From this information we can calculate the worst case response time from
+interrupt request until a task runs that can process the the interrupt.
+That worst cast response time, ``Tresp``, is given by:
+
+* ``Tresp1 = Tcrit + Tintr + C1``
+
+* ``Tresp2 = Tintr + Tpreempt + C2``
+
+* ``Tresp = MAX(Tresp1, Tresp2)``
+
+Where:
+
+* ``C1`` and ``C2`` are unknown, irreducible constants that reflect such things as
+  hardware interrupt latency and context switching time,
+
+* ``Tcrit`` is the longest observed time within a critical section,
+
+* ``Tintr`` is the time required for interrupt handler execution for the event
+  of interest, and
+
+* ``Tpreempt`` is the longest observed time with preemption disabled.
+
+NOTES:
+
+#. This calculation assumes that the task of interest is the highest priority task
+   in the system. It does not consider the possibility of the responding task being
+   delayed due to insufficient priority.
+
+#. This calculation does not address the case where the interfering task has both
+   preemption disabled and holds the critical section. Certainly Tresp1 is valid
+   in this case, but Tresp2 is not. There might some additional, unmeasured delay
+   after the interrupt and before the responding task can run depending on the order
+   in which the critical section is released and preemption is re-enabled:
+
+     * When the task leaves the critical section, the pending interrupt will execute
+       immediately with or without preemption enabled.
+
+     * If preemption is enabled first, then the will be no delay after the interrupt
+       because preemption will be enabled when the interrupt returns.
+
+     * If the task leaves critical section first, then there will be some small delay
+       of unknown duration after the interrupts returns and before the responding
+       task can run because preemption will be disabled when the interrupt returns.
+
+#. This calculation does not address concurrent interrupts. All interrupts run at the
+   same priority and if an interrupt request occurs while within an interrupt handler,
+   then it must pend until completion of that interrupt. So perhaps the above formula
+   for ``Tresp1`` should instead be the following? (This assumes that hardware arbitration
+   is such that the interrupt of interest will be deferred by no more than one interrupt).
+   Concurrent, nested interrupts might be better supported with prioritized.
+   See more: :doc:`/guides/nestedinterrupts`.
+
+     * ``Tresp1 = Tcrit + Tintrmax + Tintr + C1``
+
+       Where:
+
+       * ``Tintrmax`` is the longest interrupt processing time of all interrupt sources
+         (excluding the interrupt for the event under consideration).
+
+What can you do?
+----------------
+
+What can you do if the timing data indicates that you cannot meet your deadline?
+You have these options:
+
+#. Use these tools to find the exact function that holds the critical section or
+   disables preemption too long. Then optimize that function so that it releases
+   that resource sooner. Often critical sections are established over long sequences
+   or code when they could be re-designed to use critical sections over shorter code
+   sequences.
+
+#. In some cases, use of critical sections or disabling of pre-emption could replaced
+   with a locking semaphore. The scope of the locking effect for the use of such locks
+   is not global but is limited only to tasks that share the same resource. Critical
+   sections should correctly be used only to protect resources that are shared between
+   tasking level logic and interrupt level logic.
+
+#. Switch to :doc:`/guides/zerolatencyinterrupts`. Those interrupts are not subject
+   to most of the issues discussed in this page.
+
+**NOTE**
+
+There are a few places in the OS were preemption is disabled via ``sched_lock()`` in
+order to establish a critical section. That is an incorrect use of ``sched_lock()``.
+``sched_lock()`` simply prevents the currently executing task from being suspended.
+For the case of the single CPU platform, that does effectively create a critical
+section: Since no other task can run, the locking task does have exclusive access
+to all resources that are not shared with interrupt level logic.
+
+But in the multi-CPU SMP case that is not true. ``sched_lock()`` still keeps the
+current task running on CPU from being suspended, but it does not support any
+exclusivity in accesses because there will be other tasks running on other CPUs
+that may access the same resources.


(nuttx) 03/09: Documentation: migrate "Wide Font Support" from wiki

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit de564d38e9d8d03084c417ca141ea68372ac7eb9
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Nov 4 18:07:46 2023 +0100

    Documentation: migrate "Wide Font Support" from wiki
    
    link: https://cwiki.apache.org/confluence/display/NUTTX/Wide+Font+Support
---
 Documentation/components/nxgraphics/nxfonts.rst | 84 +++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/Documentation/components/nxgraphics/nxfonts.rst b/Documentation/components/nxgraphics/nxfonts.rst
index 4c7095b01a..a780a65343 100644
--- a/Documentation/components/nxgraphics/nxfonts.rst
+++ b/Documentation/components/nxgraphics/nxfonts.rst
@@ -124,3 +124,87 @@ NXFONTS types
 
   :return: ``OK`` on success; ``ERROR`` on failure with ``errno`` set appropriately.
 
+Wide Font Support
+=================
+
+Question::
+
+  > My team is trying the nuttx graphics with chinese fonts, but nx seems not
+  > support fonts quantity more than 256 chars, right?
+
+Answer::
+
+  NuttX currently only uses fonts with 7-bit and 8-bit character sets. But
+  I believe that that limitation is mostly arbitrary. It should be a simple
+  extension to the font subsystem to use 16-bit fonts.
+
+Adding 16-Bit Font support
+--------------------------
+
+Current 7/8-bit Font Implementation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All of critical font interfaces allow for 16-bit character sets:
+
+.. code-block:: C
+
+   FAR const struct nx_fontbitmap_s *nxf_getbitmap(NXHANDLE handle, uint16_t ch)
+
+The character code is only used to look-up of a glyph in a table. There is a
+definition that controls the width of the character set: CONFIG_NXFONTS_CHARBITS.
+This currently defaults to 7 but all existing fonts support 8-bits.
+
+My first guess is that the only thing that would have to change is that single
+file nxfonts_bitmaps.c (and the function nxf_getglyphset() in the file
+nxfonts_getfont.c) . nxfonts_bitmaps.c is used to auto-generate 7/8-bit font
+data sents. Here is how that works:
+
+* Each 7-8 bit file is described by a header file like, for example,
+  nxfonts_sans17x22.h.
+
+* At build time each of these header files is used to create a C file,
+  like, nxfonts_bitmaps_sans17x22.c.
+
+* It creates the C file (like nxfonts_bitmaps_sans17x22.c) by compiling
+  nxfonts_bitmaps.c and including nxfonts_sans17x22.h to create the font
+  dataset at build time.
+
+The function nxf_getglyphset() in the file nxfonts_getfont.c selects the 7-bit
+font range (codes < 128) or the 8-bit range (code >= 128 > 256). The fonts are
+kept in simple arrays splitting the data up into ranges of values lets you above
+the non-printable codes at the beginning and end of each range. There is even a
+comment in the code there "Someday, perhaps 16-bit fonts will go here".
+
+Adding Wide Fonts
+~~~~~~~~~~~~~~~~~
+
+To add a single wide font, the easiest way would be to simply add the final
+.C file without going through the C auto-generation step. That should be VERY
+easy. (But since it has never been used with larger character sets, I am sure
+that there are bugs and things that need to be fixed).
+
+If you want to add many wide fonts, then perhaps you would have to create a new
+version of the C auto-generation logic. That would require more effort.
+
+I am willing to help and advise. Having good wide character support in the NuttX
+graphics would be an important improvement to NuttX. This is not a lot of code
+nor is it very difficult code so you should not let it be an obstacle for you.
+
+Font Storage Issues
+-------------------
+
+One potential problem may be the amount of memory required by fonts with
+thousands of characters. If you have a lot of flash, it may not be a problem,
+but on many microcontrollers it will be quite limiting.
+
+Options are:
+
+* **Font Compression** Addition of some font compression algorithm in NuttX.
+  However, Chinese character bitmaps do not compress well: Many of them contain
+  so much data that there is not much of anything to compress. Some actually
+  expand under certain compression algorithms.
+
+* **Mass Storage** A better option would be put the wide the fonts in file
+  system, in NAND or serial FLASH or on an SD card. In this case, additional
+  logic would be required to (1) format a font binary file and to (2) access
+  the font binary from the file system as needed.


(nuttx) 01/09: Documentation: fix warning

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit bfd342b4ebc0bf10d0695f1e909218b46ee4c0e8
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Nov 4 20:17:59 2023 +0100

    Documentation: fix warning
---
 .../platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst  | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst b/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst
index 8398b67e49..ae44e18aab 100644
--- a/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst
+++ b/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst
@@ -86,16 +86,17 @@ The STM32F4-RS485 has 1 USART available for user.
 USART2
 ------
 
-========== =====
+========== =======
 UART/USART PINS
-========== =====
+========== =======
 CTS        PA0
 RTS        PA1
-TX         PA2  *Warning you make need to reverse RX/TX on
-RX         PA3   some RS-232 converters
+TX         PA2 [1]
+RX         PA3
 CK         PA4
-========== =====
+========== =======
 
+[1] Warning you make need to reverse RX/TX on some RS-232 converters
 
 SDCARD
 ======


(nuttx) 04/09: Documentation: migrate "Running Applications from NSH" from wiki

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 03b4ec60a5ceaad3f5491635ef311bf26d88aa98
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Nov 4 20:12:22 2023 +0100

    Documentation: migrate "Running Applications from NSH" from wiki
    
    link: https://cwiki.apache.org/confluence/display/NUTTX/Running+Applications+from+NSH
---
 Documentation/applications/nsh/index.rst        |   1 +
 Documentation/applications/nsh/running_apps.rst | 180 ++++++++++++++++++++++++
 2 files changed, 181 insertions(+)

diff --git a/Documentation/applications/nsh/index.rst b/Documentation/applications/nsh/index.rst
index 8f62f5cca4..f2b5d5608d 100644
--- a/Documentation/applications/nsh/index.rst
+++ b/Documentation/applications/nsh/index.rst
@@ -22,3 +22,4 @@ starts a given task instead of the main ``nsh`` application.
   builtin.rst
   installation.rst
   login.rst
+  running_apps.rst
diff --git a/Documentation/applications/nsh/running_apps.rst b/Documentation/applications/nsh/running_apps.rst
new file mode 100644
index 0000000000..b8aa0d646f
--- /dev/null
+++ b/Documentation/applications/nsh/running_apps.rst
@@ -0,0 +1,180 @@
+=============================
+Running Applications from NSH
+=============================
+
+This page describes current and planned features for the NuttX NuttShell (NSH).
+Think of this page as a roadmap. Most of the features have been implemented and
+incorporated into NSH; others are just ideas that are being tossed around (noted
+as NOT implemented). The NSH document will be updated as new features are included.
+
+There are currently be three ways to execute applications from NSH:
+
+#. Executing Builtin Applications
+
+   **Builtin Applications**
+   The current implementation of NSH allows for the execution
+   of "named" or "builtin" applications. The applications are simply task entry points
+   in the common FLASH image that have names assigned to them. Simply entering that name
+   from the NSH command line will cause the associated application to run.
+
+   See the NSH documentation for further details.
+
+   **Example**
+
+   For example:
+
+     .. code-block:: bash
+
+        NuttShell (NSH) NuttX-6.24
+        nsh> hello
+        Hello, World!!
+        nsh>
+
+   **Configuration Settings**
+
+   This functionality depends on these configuration settings:
+
+     * ``CONFIG_BUILTIN=y`` Enables NuttX support for builtin applications, and
+     * ``CONFIG_NSH_BUILTIN_APPS=y`` Enables NSH support for builtin applications
+
+   In additional to other configuration needed by NSH.
+
+#. Executing Application from a File System
+
+   **OS Interfaces**
+
+   NuttX supports running applications that reside on a file system as well.
+   The standard interfaces used to do this include:
+
+     * ``execv()``
+     * ``execl()``
+     * ``posix_spawn()``
+
+
+   **Configuration Settings**
+
+   Execution of applications on a file system is currently supported by Nuttx.
+   This feature is enabled with:
+
+     * ``CONFIG_LIBC_EXECFUNCS=y`` Enable support for ``execv()``, ``execl()``,
+       and ``posix_spawn()``, and
+     * ``CONFIG_NSH_FILE_APPS=y`` Enable execution of programs in a file system by NSH.
+
+   **Example**
+
+   When this feature is enabled, you will be able to do the following:
+
+   .. code-block:: bash
+
+      NuttShell (NSH) NuttX-6.24
+      nsh> mount -t vfat /dev/mmcsd0 /mnt/sdcard
+      nsh> ls -l /mnt/sdcard
+      /mnt/sdcard:
+      -rw-r--r--  198 hello
+      nsh> /mnt/sdcard/hello
+      Hello, World!!
+      nsh>
+
+   **The PATH Variable**
+
+   Notice that the absolute path to the hello program was used. This can be
+   simplified by setting the following in your configuration:
+
+     * ``CONFIG_BINFMT_EXEPATH=y`` Enable use of the path variable to find executable programs.
+
+
+   **Example**
+
+   Then, the example becomes:
+
+   .. code-block:: bash
+
+      NuttShell (NSH) NuttX-6.24
+      nsh> mount -t vfat /dev/mmcsd0 /mnt/sdcard
+      nsh> ls -l /mnt/sdcard
+      /mnt/sdcard:
+        -rw-r--r--  198 hello
+      nsh> set PATH /mnt/sdcard
+      nsh> hello
+      Hello, World!!
+      nsh>
+
+   **Pre-initialized PATH Variables**
+
+   One final simplification: The initial PATH variable can be configured so that
+   the PATH to your executable programs is already defined when NSH starts. This
+   is down with:
+
+     * ``CONFIG_PATH_INITIAL="/mnt/sdcard"``
+
+   This functionality is already in place.
+
+#. Executing Builtin Applications from a File System
+
+   **Namespace Management**
+
+   NuttX supports a virtual file system (VFS) that may used to manage namespaces.
+   Linux uses its VFS to manage nearly all named objects (pipes, locks, message
+   queues, etc.). And it is a good policy for NuttX to do this too. NuttX already
+   does this for things like drivers and mountpoints. Why not extend this mechanism
+   to handle named, builtin applications too?
+
+   **Proposed Configuration Options**
+
+   The following configuration options are planned:
+
+     * ``CONFIG_BUILTIN=y`` Will still be needed to enable NuttX support for
+       builtin applications, and
+     * ``CONFIG_NSH_BUILTIN_APPS=y`` Will still be needed enable to stimulate
+       programs to register themselves as builtin applications.
+
+   And in addition:
+
+     * ``CONFIG_FS_BINFS=y`` Enable the BINFS file system that is used to access
+       builtin applications as files,
+     * ``CONFIG_LIBC_EXECFUNCS=y`` Enable support for ``execv()``, ``execl()``, and
+       ``posix_spawn()``,
+     * ``CONFIG_NSH_FILE_APPS=y`` Enable execution of programs in a file system by NSH,
+     * ``CONFIG_BINFMT_EXEPATH=y`` Enable the (optional) use of the path variable to
+       find executable programs, and
+     * ``CONFIG_PATH_INITIAL="/mnt/sdcard:/bin"`` Optional initial value of the
+       PATH variable.
+
+   **Example**
+
+   When this feature is enable, will will be able to do this (where myapplication is
+   the name of some, arbitrary "built-in" application):
+
+   .. code-block:: bash
+
+      NuttShell (NSH) NuttX-6.24
+      nsh> mount -t binfs /bin
+      nsh> ls -l /bin
+      /bin:
+        -rw-r--r--  0 myapplication
+      nsh> echo $PATH
+      /mnt/sdcard:/bin
+      nsh> myapplication
+      ... and your FLASH based application runs ...
+      nsh>
+
+   **Auto-Mounting BINFS**
+
+   BINFS, like any file system, could be mounted by an startup script
+   at ``/etc/init.d/rcS``.
+
+   But since BINFS may be used in many configurations that don't otherwise
+   need a startup script, perhaps some configurations would be helpful:
+
+     * ``CONFIG_NSH_AUTOMOUNT_BINFS=y`` Automatically mount the BINFS file
+       system on startup (**NOT implemented**)
+     * ``CONFIG_NSH_BINFS_MOUNTPOINT="/bin"`` The BINFS mountpoint (NOT implemented).
+
+   Or perhaps a better thing to do would just be to make it easier to add a
+   startup script?
+
+   **Next Steps**
+
+   In the longer term, I would like to see an option to move most of the larger
+   NSH commands out of RAM and built them as standalone programs that can reside,
+   for example, on an SD card (**NOT implemented**).


(nuttx) 06/09: Documentation: migrate "apps/tools/mkromfsimg.sh" from wiki

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit adc557f545fd22996efe4f06ecf4a732b87419c5
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Nov 4 19:55:15 2023 +0100

    Documentation: migrate "apps/tools/mkromfsimg.sh" from wiki
    
    link https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=139629538
---
 Documentation/applications/tools/index.rst | 70 +++++++++++++++++++++++++++++-
 1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/Documentation/applications/tools/index.rst b/Documentation/applications/tools/index.rst
index 7b7329d262..5072ed7ed5 100644
--- a/Documentation/applications/tools/index.rst
+++ b/Documentation/applications/tools/index.rst
@@ -3,7 +3,7 @@ Host Side Tools
 ===============
 
 ``bitmap_converter.py`` NxWidgets
----------------------------------
+=================================
 
 This script converts from any image type supported by Python imaging library to
 the RLE-encoded format used by NxWidgets.
@@ -31,3 +31,71 @@ conversion just to be certain):
   For most simple graphic images this might be as few as 6 or 8 colors.
 - Save the image as PNG or other lossless format (NOT jpeg).
 - Then generate the image.
+
+``mkromfsimg.sh``
+=================
+
+**Q**: Why are there two versions of the script ``mkromfsimg.sh``, one in
+``apps/tools`` and one in ``nuttx/tools``.
+
+**A**: The version of ``mkromfsimg.sh`` in ``nuttx/tools`` is a generic
+tool to simplify creation of ROMFS file system from any directory contain
+content that you would like to access within the the target.
+
+The version in ``apps/tools``, on the other hand, has a very special purpose.
+It is part of the support that can be used in the KERNEL build mode.
+
+Processes and Programs in the KERNEL Build
+------------------------------------------
+
+In the kernel build, there are no tasks. There are only processes and all
+code lives in its own, private address space.
+See :doc:`/implementation/processes_vs_tasks`.
+
+One consequence of that is that functions like ``task_create()`` and friends
+cannot be used in the KERNEL build mode. Instead, all processes must be loaded
+into a virtual address space from an ELF or NxFLAT file residing in the file
+system. ROMFS is one of many file system, but one that is particularly usable
+for this purpose in deeply embedded systems.
+
+KERNEL Build Differences
+------------------------
+
+In the FLAT and PROTECTED build mode all applications are built into a single
+BLOB, so every symbol must have a unique name to avoid name collisions.
+
+In the KERNEL build mode, all applications are built at separately linked
+programs that reside in a file system. The entry point to ALL programs is the
+function ``main()``.
+
+apps/bin
+--------
+
+When you build the ``apps/`` programs in FLAT or PROTECTED modes, all of the
+object files are put into an archive apps/libapps.a which is, eventually,
+copied to ``nuttx/libs`` and the BLOB is created by linking NuttX archives
+with ``lib/libapps.a``.
+
+But when you build the ``apps/`` programs in the KERNEL mode, the directory
+``apps/bin`` is created by the top-level apps/Makefile. Each source file is
+compiled, but the object files are not added to ayn archive. Instead, the
+object files are linked into a separate compiled and linked program. Each program
+is then installed at ``apps/bin``.
+
+apps/tools/mkromfsimg.sh
+------------------------
+
+When the ``apps/`` kernel build is complete, all of the programs have been installed
+in ``apps/bin``. That is where ``apps/tools/mkromfsimg.sh`` file comes into to play.
+It takes all of the programs in apps/bin and creates a ROMFS file system image
+containing all of the applications. That ROMFS file system image is built into
+the kernel.
+
+Application Initialization
+--------------------------
+
+At run time, when the kernel boots, it will mount that ROMFS file system at ``/bin``.
+In the FLAT build mode, the OS boot logic calls ``task_create()`` to start the initial
+task you have configured with ``CONFIG_INIT_ENTRYPOINT``. But in the KERNEL build, something
+different happens. ``CONFIG_INIT_ENTRYPOINT`` is not used. Instead, ``CONFIG_INIT_FILEPATH``
+is used. This will be the name of the program to stared in ``/bin`` to bring up the system.


(nuttx) 05/09: Documentation: migrate "Linux Processes vs NuttX Tasks" from wiki

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 3b23a693acb2d6e148b0b258d6d13d211fc7389c
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Nov 4 20:41:19 2023 +0100

    Documentation: migrate "Linux Processes vs NuttX Tasks" from wiki
    
    link: https://cwiki.apache.org/confluence/display/NUTTX/Linux+Processes+vs+NuttX+Tasks
---
 Documentation/implementation/index.rst             |   9 +
 .../implementation/processes_vs_tasks.rst          | 263 +++++++++++++++++++++
 Documentation/index.rst                            |   1 +
 3 files changed, 273 insertions(+)

diff --git a/Documentation/implementation/index.rst b/Documentation/implementation/index.rst
new file mode 100644
index 0000000000..42f6054e22
--- /dev/null
+++ b/Documentation/implementation/index.rst
@@ -0,0 +1,9 @@
+======================
+Implementation Details
+======================
+
+.. toctree::
+   :maxdepth: 2
+   :caption: Contents:
+   
+   processes_vs_tasks.rst
diff --git a/Documentation/implementation/processes_vs_tasks.rst b/Documentation/implementation/processes_vs_tasks.rst
new file mode 100644
index 0000000000..16626a5834
--- /dev/null
+++ b/Documentation/implementation/processes_vs_tasks.rst
@@ -0,0 +1,263 @@
+==============================
+Linux Processes vs NuttX Tasks
+==============================
+
+You may be used to running programs that are stored in files on Linux or Windows.
+If you transition to using NuttX tasks on an MCU with limited resources, you will
+encounter some behavioral differences. This Wiki page will summarize a few of
+those differences.
+
+NuttX Build Types
+=================
+
+NuttX can be built in several different ways:
+
+* **Kernel Build** The kernal build, selected with ``CONFIG_BUILD_KERNEL``, uses
+  the MCU's Memory Management Unit (MMU) to implement processes very similar to
+  Linux processes. There is no interesting discussion here; NuttX behaves very
+  much like Linux.
+
+* **Flat Build** Most resource-limited MCUs have no MMU and the code is built as
+  a blob that runs in an unprotected, flat address space out of on-chip FLASH
+  memory. This build mode is selected with ``CONFIG_BUILD_FLAT`` and is, by far, the
+  most common way that people build NuttX. This is the interesting case to which
+  this Wiki page is directed.
+
+* **Protected Build** Another build option is the protected build. This is essentially
+  the same as the flat build, but uses the MCU's Memory Protection Unit (MPU) to
+  separate unproctect user address ranges from protected system address ranges.
+  The comments of this Wiki page also apply in this case.
+
+Initialization of Global Variables
+==================================
+
+Linux Behavior
+--------------
+
+If you are used to writing programs for Linux, then one thing you will notice is that
+global variables are initialized only once when the system powers up. For example.
+Consider this tiny program:
+
+.. code-block:: C
+                
+   bool test = true;
+ 
+   int main(int argc, char **argv)
+   {
+     printf("test: %i\n", test);
+     test = false;
+     printf("test: %i\n", test);
+     return 0;
+   }
+
+If you build and run this program under Linux, you will always see this output::
+
+  test: 1
+  test: 0
+
+In this case, the global variables are re-initialized each time that you load the
+file into memory and run it.
+
+NuttX Flat-Build Behavior
+-------------------------
+
+But if you build this program into on-chip FLASH and start it as a task (via, say,
+``task_start()``) you will see this the first time that you run the program::
+
+  test: 1
+  test: 0
+
+But after that, you will always see::
+
+  test: 0
+  test: 0
+
+The test variable was initialized to true (1) only once at power up, but reset to
+false (0) each time that the program runs.
+
+If you want the same behavior when the program is built into the common FLASH blob,
+then you will have modify the code so that global variables are explicitly reset
+each time the program runs like:
+
+.. code-block:: C
+
+   bool test;
+   
+   int main(int argc, char **argv)
+   {
+     test = true;
+     printf("test: %i\n", test);
+     test = false;
+     printf("test: %i\n", test);
+     return 0;
+   }
+
+NuttX Load-able Programs
+------------------------
+
+If you load programs from an file into RAM and execute them, as Linux does, then
+NuttX will again behave like Linux. Because the flat build NuttX works the same way:
+When you execute a NuttX ELF or NxFLAT module in a file, the file is copied into RAM
+and the global variables are initialized before the program runs.
+
+But code that is built into FLASH works differently. There is only one set of global
+variables: All of the global variables for the blob that is the monolithic FLASH image.
+They are all initialized  once at power-up reset.
+
+This is one of the things that makes porting Linux applications into the FLASH blob
+more complex. You have to manually initialize each global variable in the ``main()``
+each time your start the task.
+
+Global Variables and Multiple Task Copies
+=========================================
+
+It is better to avoid the use of global variables in the flat build context whenever
+possible because that usage adds another limitation:  No more that one copy of the
+program can run at any given time.  That is because the global variables are shared
+by each instance (unlike, again, running a program from a file where there is a private
+copy of each global variable).
+
+One way to support multiple copies of an in-FLASH program is to move all global variables
+into a structure. If the amount of memory need for global variables is small, then each
+``main()`` could simply allocate a copy of that structure on the stack. In the simple
+example above, this might be:
+
+.. code-block:: C
+
+   struct my_globals_s
+   {
+     bool test;
+   };
+ 
+   int main(int argc, char **argv)
+   {
+     struct my_globals_s my_globals = { true };
+ 
+     printf("test: %i\n", my_globals.test);
+     my_globals.test = false;
+     printf("test: %i\n", my_globals.test);
+     return EXIT_SUCCESS;
+   }
+
+A pointer to the structure containing the allocated global variables would then have
+to passed as a parameter to every internal function that needs access to the global
+variables. So you would change a internal function like:
+
+.. code-block:: C
+
+   static void print_value(void)
+   {
+     printf("test: %i\n", test);
+   }
+
+to:
+
+.. code-block:: C
+
+   static void print_value(FAR struct my_globals_s *globals)
+   {
+     printf("test: %i\n", globals->test);
+   }
+
+Then pass a reference to the allocated global data structure each time that the
+function is called like:
+
+.. code-block:: C
+
+   print_value(&my_globals);
+
+If the size of the global variable structure is large, then allocating the instance
+on the stack might not be such a good idea. In that case, it might be better to
+allocate the global variable structure using ``malloc()``. But don't forget to ``free()``
+the allocated variable structure before exiting! (See the following Memory Clean-Up
+discussion).
+
+.. code-block:: C
+
+   struct my_globals_s
+   {
+     bool test;
+   };
+ 
+   int main(int argc, char **argv)
+   {
+     FAR struct my_globals_s *my_globals;
+ 
+     my_globals = (FAR struct my_globals_s *)malloc(sizeof(struct my_globals_s));
+     if (my_globals = NULL)
+       {
+         fprintf(stderr, "ERROR: Failed to allocate state structure\n");
+         return EXIT_FAILURE;
+       }
+ 
+     my_globals=>test = true;
+     printf("test: %i\n", my_globals->test);
+     my_globals=>test = false;
+     printf("test: %i\n", my_globals->test);
+ 
+     free(my_globals);
+     return EXIT_SUCCESS;
+   }
+
+Memory Clean-Up
+===============
+
+Linux Process Exit
+------------------
+
+Another, unrelated thing that makes porting Linux programs into the FLASH blob
+is the memory clean-up.  When a Linux process exits, its entire address environment
+is destroyed including all of allocated memory. This tiny program will not leak
+memory if implemented as a Linux process:
+
+.. code-block:: C
+
+   int main(int argc, char **argv)
+   {
+     char *buffer = malloc(1024);
+     ... do stuff with buffer ...
+     return 0;
+   }
+
+That same program, if ported into the FLASH blob will now have memory leaks because
+there is no automatic clean-up of allocated memory when the task exits. Instead, you
+must explicitly clean up all allocated memory by freeing it:
+
+.. code-block:: C
+
+   int main(int argc, char **argv)
+   {
+     char *buffer = malloc(1024);
+     ... do stuff with buffer ...
+     free(buffer);
+     return 0;
+   }
+
+The memory clean-up with the Linux process exits is a consequent of the teardown of
+the process address environment when the process terminates. Each process contains
+its own heap; when the process address environment is torndown, that process heap
+is returned to the OS page allocator. So the memory clean-up basically comes for free.
+
+NuttX Task Exit
+---------------
+
+But when you run a task in the monolithic, on-chip FLASH blob, you share the same
+heap with all other tasks. There is no magic clean-up that can find and free your
+tasks's allocations within the common heap (see "Ways to Free Memory on Task Exit").
+
+NuttX Process Exit
+------------------
+
+NOTE that when you run processes on NuttX (with ``CONFIG_BUILD_KERNEL``), NuttX also
+behaves the same way as Linux:  The address environment is destroyed with the task
+exits and all of the memory is reclaimed.  But all other cases will leak memory.
+
+Ways to Free Memory on Task Exit
+--------------------------------
+
+There are ways that you could associate allocated memory with a task so that it could
+cleaned up when the task exits. That approach has been rejected, however, because (1)
+it could not be done reliably, and (2) it would add a memory allocation overhead that
+would not be acceptable in context where memory is constrained.
+
+Related issue can be found on `Github <https://github.com/apache/nuttx/issues/3345>`_.
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 3ef823b56b..8d756ffde7 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -33,6 +33,7 @@ Last Updated: |today|
    platforms/index.rst
    components/index.rst
    applications/index.rst
+   implementation/index.rst
    reference/index.rst
    faq/index.rst
    guides/index.rst


(nuttx) 08/09: Documentation: migrate "SMP Critical Sections" from wiki

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit f96064db75fe79e8ffb2a0d4a51fa7e063a5e068
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Nov 4 21:23:55 2023 +0100

    Documentation: migrate "SMP Critical Sections" from wiki
    
    links: https://cwiki.apache.org/confluence/display/NUTTX/SMP+Critical+Sections
---
 Documentation/implementation/critical_sections.rst | 163 +++++++++++++++++++++
 Documentation/implementation/index.rst             |   1 +
 2 files changed, 164 insertions(+)

diff --git a/Documentation/implementation/critical_sections.rst b/Documentation/implementation/critical_sections.rst
new file mode 100644
index 0000000000..45b30e21f1
--- /dev/null
+++ b/Documentation/implementation/critical_sections.rst
@@ -0,0 +1,163 @@
+=================
+Critical Sections
+=================
+
+Single CPU Critical Sections
+============================
+
+OS Interfaces
+-------------
+
+Before we talk about SMP Critical Sections let's first review the internal OS
+interfaces avaiable and what they do in the single CPU case:
+
+* ``up_irq_save()`` (and its companion, ``up_irq_restore()``). These simple
+  interfaces just enable and disable interrupts globally. This is the simplest
+  way to establish a critical section in the single CPU case. It does have
+  side-effects to real-time behavior as discussed elsewhere.
+
+* ``up_irq_save()`` should never be called directly, however. Instead, the wrapper
+  macros enter_critical_section() (and its companion ``leave_critical_section()``)
+  or ``spin_lock_irqsave()`` (and ``spin_unlock_irqrestore()``) should be used.
+  In the single CPU case, these macros are defined to be simply ``up_irq_save()``
+  (or ``up_irq_save()``). Rather than being called directly, they should always
+  be called indirectly through these macros so that the code will function in the
+  SMP environment as well.
+
+* Finally, there is ``sched_lock()`` (and ``sched_unlock()``) that disable (and
+  enable) pre-emption. That is, ``sched_lock()`` will lock your kernel thread in
+  place and prevent other tasks from running. Interrupts are still enabled, but
+  other tasks cannot run.
+
+
+Using sched_lock() for Critical Sections – **DON'T**
+----------------------------------------------------
+
+In the single CPU case, ``sched_lock()`` can do a pretty good job of establishing a
+critical section too. After all, if no other tasks can run on the single CPU,
+then that task has pretty much exclusive access to all resources (provided that
+those resources are not shared with interrupt handlers). However, ``sched_lock()``
+must never be used to establish a critical section because it does not work the
+same way in the SMP case. In the SMP case, locking the scheduer does not provide
+any kind of exclusive access to resources. Tasks running on other CPUs are still
+free to do whatever they wish.
+
+SMP Critical Sections
+=====================
+
+``up_irq_save()`` and ``up_irq_restore()``
+------------------------------------------
+
+As mentioned, ``up_irq_save()`` and ``up_irq_restore()`` should never be called
+directly. That is because the behavior is different in multiple CPU systems. In
+the multiple CPU case, these functions only enable (or disable) interrupts on the
+local CPU. They have no effect on interrupts in the other CPUs and hence really
+accomplish very little. Certainly they do not provide a critical section in any
+sense.
+
+``enter_critical_section()`` and ``leave_critical_section()``
+-------------------------------------------------------------
+
+**spinlocks**
+
+In order to establish a critical section, we also need to employ spinlocks. Spins
+locks are simply loops that execute in one processor. If processor A sets spinlock
+x, then processor B would have to wait for the spinlock like:
+
+.. code-block:: C
+
+  while (test_and_set(x))
+   {
+   }
+
+Where test and set is an atomic operation that sets the value of a memory location
+but also returns its previous value. Here we are talking about atomic in terms of
+memory bus operations: The testing and setting of the memory location must be atomic
+with respect to other bus operations. Special hardware support of some kind is
+necessary to implement ``test_and_set()`` logic.
+
+When Task A released the lock x, Task B will successfully take the spinlock and
+continue.
+
+**Implementation**
+
+Without going into the details of the implementation of ``enter_critical_section()``
+suffice it to say that it (1) disables interrupts on the local CPU and (2) uses
+spinlocks to assure exclusive access to a code sequence across all CPUs.
+
+NOTE that a critical section is indeed created: While within the critical section,
+the code does have exclusive access to the resource being protected. However the
+behavior is really very different:
+
+* In the single CPU case, disable interrupts stops all possible activity from any
+  other task. The single CPU becomes single threaded and un-interruptible.
+* In the SMP case, tasks continue to run on other CPUs. It is only when those other
+  tasks attempt to enter a code sequence protected by the critical section that those
+  tasks on other CPUs will be stopped. They will be stopped waiting on a spinlock.
+
+``spin_lock_irqsave()`` and ``spin_unlock_irqrestore()``
+--------------------------------------------------------
+
+**Generic Interrupt Controller (GIC)**
+
+ARM provides a special, optional sub-system called MPCore that provides
+multi-core support. One MPCore component is the Generic Interrupt Controller
+or GIC. The GIC supports 16 inter-processor interrupts and is a key component for
+implementing SMP on those platforms. The are called Software Generated Interrupts
+or SGIs.
+
+One odd behavior of the GIC is that the SGIs cannot be disabled (at least not
+using the standard ARM global interrupt disable logic). So disabling local
+interrupts does not prevent these GIC interrupts.
+
+This causes numerous complexities and significant overhead in establishing a
+critical section.
+
+**ARMv7-M NVIC**
+
+The GIC is available in all recent ARM architectures. However, most embedded
+ARM7-M multi-core CPUs just incorporate the inter-processor interrupts as a
+normal interrupt that is mask-able via the NVIC (each CPU will have its own NVIC).
+
+This means in those cases, the critical section logic can be greatly simplified.
+
+**Implementation**
+
+For the case of the GIC with no support for disabling interrupts,
+``spin_lock_irqsave()`` and ``spin_unlock_irqstore()`` are equivalent to
+``enter_critical_section()`` and ``leave_critical_section()``. In is only in the
+case where inter-processor interrupts can be disabled that there is a difference.
+
+In that case, ``spin_lock_irqsave()`` will disable local interrupts and take
+a spinlock. This is really very simple and efficient implementation of a critical
+section.
+
+There are two important things to note, however:
+
+* The logic within this critical section must never suspend! For example, if
+  code were to call ``spin_lock_irqsave()`` then ``sleep()``, then the sleep
+  would occur with the spinlock in the lock state and the whole system could
+  be blocked. Rather, ``spin_lock_irqsave()`` can only be used with straight
+  line code.
+
+* This is a different critical section than the one established via
+  ``enter_critical_section()``. Taking one critical section, does not prevent
+  logic on another CPU from taking the other critical section and the result
+  is that you make not have the protection that you think you have.
+
+``sched_lock()`` and ``sched_unlock()``
+---------------------------------------
+
+Other than some details, the SMP ``sched_lock()`` works much like it does in
+the single CPU case. Here are the caveats:
+
+* As in the single CPU case, the case that calls ``sched_lock()`` is locked
+  in place and cannot be suspected.
+
+* However, tasks will continue to run on other CPUs so ``sched_lock()`` cannot
+  be used as a critical section.
+
+* Tasks on other CPUs are also locked in place. However, they may opt to suspend
+  themselves at any time (say, via ``sleep()``). In that case, only the CPU's
+  IDLE task will be permitted to run.
+
diff --git a/Documentation/implementation/index.rst b/Documentation/implementation/index.rst
index 42f6054e22..f1aac1feb4 100644
--- a/Documentation/implementation/index.rst
+++ b/Documentation/implementation/index.rst
@@ -7,3 +7,4 @@ Implementation Details
    :caption: Contents:
    
    processes_vs_tasks.rst
+   critical_sections.rst