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


The following commit(s) were added to refs/heads/master by this push:
     new dbeaec4cdc Doc: migration 5
dbeaec4cdc is described below

commit dbeaec4cdc58b161d140d149856d795797db4972
Author: Ludovic Vanasse <[email protected]>
AuthorDate: Sat Nov 9 15:40:53 2024 -0500

    Doc: migration 5
    
    Migrate pages:
            * Delayed ACK and TCP Performance
            * TCP Network Performance
            * NxWM Threading
            * Framebuffer Character Driver
    
    From Confluence wiki to official wiki
---
 .../components/net/delay_act_and_tcp_perf.rst      | 195 +++++++++++
 Documentation/components/net/index.rst             |   2 +
 Documentation/components/net/tcp_network_perf.rst  | 193 +++++++++++
 .../components/nxgraphics/GraphicsInterfaces.png   | Bin 0 -> 82985 bytes
 .../nxgraphics/framebuffer_char_driver.rst         | 383 +++++++++++++++++++++
 Documentation/components/nxgraphics/index.rst      |   2 +
 .../components/nxgraphics/nxwm_threading.rst       |  13 +
 .../nxwm_theading_model_page_0.png                 | Bin 0 -> 314995 bytes
 .../nxwm_theading_model_page_1.png                 | Bin 0 -> 172777 bytes
 .../nxwm_theading_model_page_2.png                 | Bin 0 -> 121021 bytes
 .../nxwm_theading_model_page_3.png                 | Bin 0 -> 157603 bytes
 .../nxwm_theading_model_page_4.png                 | Bin 0 -> 252166 bytes
 12 files changed, 788 insertions(+)

diff --git a/Documentation/components/net/delay_act_and_tcp_perf.rst 
b/Documentation/components/net/delay_act_and_tcp_perf.rst
new file mode 100644
index 0000000000..50247b9a57
--- /dev/null
+++ b/Documentation/components/net/delay_act_and_tcp_perf.rst
@@ -0,0 +1,195 @@
+===============================
+Delayed ACK and TCP Performance
+===============================
+
+.. warning:: 
+    Migrated from: 
+    
https://cwiki.apache.org/confluence/display/NUTTX/Delayed+ACK+and+TCP+Performance
+
+uIP and NuttX
+=============
+
+The heart of the NuttX IP stack derived from Adam Dunkel's tiny `uIP 
+stack <http://sourceforge.net/projects/uip-stack/>`_ back at version 1.0.
+The NuttX TCP/IP stack contains the uIP TCP state machine and 
+some uIP "ways of doing things," but otherwise, there is 
+now little in common between these two designs.
+
+**NOTE**: uIP is also built into Adam Dunkel's 
+`Contiki <http://contiki.sourceforge.net/docs/2.6/a01793.html>`_ 
+operating system.
+
+uIP, Delayed ACKs, and Split Packets
+====================================
+
+In uIP, TCP packets are sent and ACK'ed one at a time.
+That is, after one TCP packet is sent, the next packet cannot 
+be sent until the previous packet has been ACKed by the 
+receiving side.
+The TCP protocol, of course, supports sending multiple packets 
+which can be ACKed be the receiving time asynchronously.
+This one-packet-at-a-time logic is a simplification in the 
+uIP design; because of this, uIP needs only a single packet 
+buffer any you can use uIP in even the tiniest environments.
+This is a good thing for the objectives of uIP.
+
+Improvements in packet buffering is the essential improvement 
+that you get if upgrade from Adam Dunkel's uIP to his 
+`lwIP <http://savannah.nongnu.org/projects/lwip/>`_ stack.
+The price that you pay is in memory usage.
+
+This one-at-a-time packet transfer does create a performance 
+problem for uIP:
+RFC 1122 states that a host may delay ACKing a packet for up 
+to 500ms but must respond with an ACK to every second segment.
+In the baseline uIP, the effectively adds a one half second 
+delay between the transfer of every packet to a recipient 
+that employs this delayed ACK policy!
+
+uIP has an option to work around this:
+It has logic that can be enable to split each packet into half, 
+sending half as much data in each packet.
+Sending more, smaller packets does not sound like a performance 
+improvement.
+This tricks the recipient that follows RFC 1122 into receiving 
+the two, smaller back-to-back packets and ACKing the second 
+immediately.
+References: `uip-split.c 
<http://contiki.sourceforge.net/docs/2.6/a00427_source.html>`_ 
+and `uip-split.h <http://contiki.sourceforge.net/docs/2.6/a00428.html>`_.
+
+The NuttX TCP/IP Stack and Delay ACKs
+=====================================
+
+The NuttX, low-level TCP/IP stack does not have the 
+limitations of the uIP TCP/IP stack.
+It can send numerous TCP/IP packets regardless of 
+whether they have been ACKed or not.
+That is because in NuttX, the accounting for which 
+packets have been ACKed and which have not has been 
+moved to a higher level in the architecture.
+
+NuttX includes a standard, BSD socket interface on top 
+of the low-level TCP/IP stack.
+It is in this higer-level, socket layer where the ACK 
+accounting is done, specifically in the function 
+`send() <http://pubs.opengroup.org/onlinepubs/009695399/functions/send.html>`_.
+If you send a large, multi-packet buffer via ``send()``, 
+it will be broken up into individual packets and each 
+packet will be sent as quickly as possible, with no 
+concern for whether the previous packet has been ACKed or not.
+
+However, the NuttX ``send()`` function will not return to 
+the caller until the final packet has been ACKed.
+It does this to assure that the callers data was sent 
+successfully (or not).
+This behavior means that if an odd number of packets 
+were sent, there could still be a delay after the final 
+packet before ``send()`` receives the ACK and returns.
+
+So the NuttX approach is similar to the uIP way of doing 
+things, but does add one more buffer, the user provided 
+buffer to ``send()``, that can be used to improve TCP/IP 
+performance (of course, this user provided buffer is 
+also required by in order to be compliant with ``send()``"" 
+`specification 
<http://pubs.opengroup.org/onlinepubs/009695399/functions/send.html>`_.
+
+The NuttX Split Packet Configuration
+====================================
+
+But what happens if all of the user buffer is smaller than 
+the MSS of one TCP packet?
+Suppose the MTU is 1500 and the user I/O buffer is only 
+512 bytes?
+In this case, ``send()`` performance degenerates to the same 
+behavior as uIP:
+An ACK is required for each packet before ``send()`` can 
+return and before ``send()`` can be called again to send 
+the next packet.
+
+And the fix? A fix has recently been contributed by 
+Yan T that works in a similar way to uIP split 
+packet logic:
+In ``send()``, the logic normally tries to send a full packet 
+of data each time it has the opportunity to do so.
+However, if the configuration option ``CONFIG_NET_TCP_SPLIT=y`` 
+is defined, the behavior of ``send()`` will change in the 
+following way:
+
+* ``send()`` will keep track of `even` and `odd` packets; `even` 
+  packets being those that we do not expect to be ACKed 
+  and `odd` packets being the those that we do expect to 
+  be ACKed.
+* ``send()`` will then reduce the size of even packets as 
+  necessary to assure that an even number of packets is 
+  always sent. Every call to send will result in an even 
+  number of packets being sent.
+
+This clever solution tricks the RFC 1122 recipient in the 
+same way that uIP split logic does.
+So if you are working with hosts the following the RFC 1122 
+ACKing behavior and you have MSS sizes that are larger that 
+the average size of the user buffers, then your throughput 
+can probably be greatly improved by enabling ``CONFIG_NET_TCP_SPLIT=y``
+
+NOTE: NuttX is `not` an RFC 1122 recipient; NuttX will ACK 
+every TCP/IP packet that it receives.
+
+Write Buffering
+===============
+
+The best technical solution to the delayed ACK problem 
+would be to support `write buffering`.
+Write buffering is enabled with ``CONFIG_NET_TCP_WRITE_BUFFERS``. 
+If this option is selected, the NuttX networking layer will 
+pre-allocate several write buffers at system initialization 
+time. The sending a buffer of data then works like this:
+
+* ``send()`` (1) obtains a pre-allocated write buffer from a free 
+  list, and then (2) simply copies the buffer of data that the 
+  user wishes to send into the allocated write buffer. If no 
+  write buffer is available, ``send()`` would have to block waiting 
+  for free write buffer space.
+* ``send()`` then (3) adds the write buffer to a queue of outgoing 
+  data for a TCP socket. Each open TCP socket has to support 
+  such a queue. ``send()`` could then (4) return success to the 
+  caller (even thought the transfer could still fail later).
+* Logic outside of the ``send()`` implementation manages the actual 
+  transfer of data from the write buffer. When the Ethernet 
+  driver is able to send a packet on the TCP connection, this 
+  external logic (5) copies a packet of data from the write 
+  buffer so that the Ethernet driver can perform the 
+  transmission (a `zero-copy` implementation would be preferable). 
+  Note that the data has to remain in the write buffer for now; 
+  it may need to be re-transmitted.
+* This external logic would also manage the receipt TCP ACKs. 
+  When TCP peer acknowledges the receipt of data, the 
+  acknowledged portion of the data can the (6) finally 
+  be deleted from the write buffer.
+
+The following options configure TCP write buffering:
+
+* ``CONFIG_NET_TCP_WRITE_BUFSIZE``: The size of one TCP write buffer.
+* ``CONFIG_NET_NTCP_WRITE_BUFFERS``: The number of TCP 
+  write buffers (may be zero to disable TCP/IP write buffering)
+
+NuttX also supports TCP read-ahead buffering. This option 
+is enabled with ``CONFIG_NET_TCP_READAHEAD``. TCP read-ahead 
+buffer is necessary on TCP connections; otherwise data 
+received while there is no ``recv()`` in place would be lost. 
+For consistency, it would be best if such a TCP write 
+buffer implementation worked in a manner similar to the 
+existing TCP read-ahead buffering.
+
+The following lists the NuttX configuration options 
+available to configure the TCP read-ahead buffering feature:
+
+* ``CONFIG_NET_TCP_READAHEAD_BUFSIZE``: The size of one TCP read-ahead buffer.
+* ``CONFIG_NET_NTCP_READAHEAD_BUFFERS``: The number of TCP 
+  read-ahead buffers (may be zero to disable TCP/IP read-ahead buffering)
+
+A future enhancement is to combine the TCP write buffer 
+management logic and the TCP read-ahead buffer management 
+so that one common pool of buffers can be used for both 
+functions (this would probably also require additional logic 
+to `throttle` read-buffering so that received messages do not 
+consume all of the buffers).
\ No newline at end of file
diff --git a/Documentation/components/net/index.rst 
b/Documentation/components/net/index.rst
index ebefe8d32c..025966919b 100644
--- a/Documentation/components/net/index.rst
+++ b/Documentation/components/net/index.rst
@@ -16,6 +16,8 @@ Network Support
   netlink.rst
   slip.rst
   wqueuedeadlocks.rst
+  tcp_network_perf.rst
+  delay_act_and_tcp_perf.rst
 
 ``net`` Directory Structure ::
 
diff --git a/Documentation/components/net/tcp_network_perf.rst 
b/Documentation/components/net/tcp_network_perf.rst
new file mode 100644
index 0000000000..33e89d8efd
--- /dev/null
+++ b/Documentation/components/net/tcp_network_perf.rst
@@ -0,0 +1,193 @@
+=======================
+TCP Network Performance
+=======================
+
+.. warning:: 
+    Migrated from: 
+    https://cwiki.apache.org/confluence/display/NUTTX/TCP+Network+Performance
+
+
+(Abstracted and extended from a discussion from the NuttX Google group)
+
+Question
+========
+
+For some unknown reason, I am seeing poor TCP network performance.
+
+Answer
+======
+
+First let's talk about TCP send performance.
+
+Source of Performance Bottlenecks
+---------------------------------
+
+General TCP send performance is not determined by the TCP stack as much 
+as it is by the network device driver. Bad network performance is due 
+to time lost `BETWEEN` packet transfers. The packet transfers themselves 
+go at the wire speed*. So if you want to improve performance on a 
+given network, you have to reduce time lost between transfers. 
+There is no other way.
+
+Ignoring Ethernet issues like collisions, back-off delays, 
+inter-packet gaps (IPG), etc.
+
+The time between packets is limited primarily by the buffering 
+design of the network driver. If you want to improve performance, 
+then you must improve the buffering at the network driver. 
+You need to support many full size (1500 byte) packet buffers. 
+You must be able to query the network for new data to transfer, 
+and queue those transfers in packet buffers. In order to reach 
+peak performance, the network driver must have the next transfer 
+buffered and ready-to-go before the previous transfer is finished 
+to minimize the GAP between packet transfers.
+
+Different network devices also support more or less efficient 
+interfaces: The worst performing support interfaces that can 
+handle only one packet at a time, the best performing are able 
+to retain linked lists of packet buffers in memory and perform 
+scatter-gather DMA for a sequence of packets.
+
+In the NuttX TCP stack, you can also improve performance by 
+enabling TCP write buffering. But the driver is the real key.
+
+It would be good to have a real in-depth analysis of the 
+network stack performance to identify bottlenecks and 
+generate ideas for performance improvement. No one has 
+ever done that. If I were aware of any stack related 
+performance issue, I would certainly address it.
+
+RFC 1122
+--------
+
+There is one important feature missing the NuttX TCP that 
+can help when there is no write buffering: Without write 
+buffering send() will not return until the transfer has 
+been ACKed by the recipient. But under RFC 1122, the host 
+need not ACK each packet immediately; the host may wait 
+for 500 MS before ACKing. This combination can cause very 
+slow performance when small, non-buffered transfers are 
+made to an RFC 1122 client. However, the RFC 1122 must 
+ACK at least every second (odd) packet so sequences of 
+packets with write buffering enabled do not suffer from 
+this problem.
+
+`Update:  RFC 1122 support was added to the NuttX TCP 
+stack with commit 66ef6d143a627738ad7f3ce1c065f9b1f3f303b0 
+in December of 2019.  That, however, that affects only 
+received packet ACK behavior and has no impact on transmitted 
+packet performance; write buffering is still recommended.`
+
+TCPBlaster
+----------
+
+I created a new test application at ``apps/examples/tcpblaster`` to 
+measure TCP performance and collected some data for the 
+configuration that happens to be on my desk. The `tcpblaster` 
+test gives you the read and write transfer rates in ``Kb/sec`` 
+(I won't mention the numbers because I don't believe they 
+would translate any other setup and, hence, would be 
+misleading).
+
+There is a nifty `TCP Throughput Tool 
<https://www.switch.ch/network/tools/tcp_throughput/>`_ 
+that gives some theoretical upper limits on performance. 
+The tool needs to know the ``MSS`` (which is the Ethernet 
+packet size that you configured minus the size of the 
+Ethernet header, 14), the round-trip time (``RTT``)in 
+milliseconds (which you can 
+get from the Linux host ping), and a loss constant (which 
+I left at the default). With these values, I can determine 
+that the throughput for the NuttX TCP stack is approximately 
+at the theoretical limits. You should not be able to do 
+better any better than that (actually, it performs above 
+the theoretical limit, but I suppose that is why it is 
+"theoretical").
+
+So, If you are unhappy with your network performance, the I 
+suggest you run the `tcpblaster` test, use that data 
+(along with the ``RTT`` from ping) with the 
+`TCP Throughput Tool <https://www.switch.ch/network/tools/tcp_throughput/>`_. 
+If you are still unhappy with the performance, don't go 
+immediately pointing fingers at the stack (which everyone does). 
+Instead, you should focus on optimizing your network 
+configuration settings and reviewing the buffer handling 
+of the Ethernet driver in you MCU.
+
+If you do discover any significant performance issues 
+with the stack I will of course gladly help you resolve 
+them. Or if you have ideas for improved performance, 
+I would also be happy to hear those.
+
+What about Receive Performance?
+-------------------------------
+
+All of the above discussion concerns `transmit performance`, 
+i.e., "How fast can we send data over the network?" The other 
+side is receive performance. Receive performance is very 
+different thing. In this case it is the remote peer who is 
+in complete control of the rate at which packets appear on 
+the network and, hence, responsible for all of the raw bit 
+transfer rates.
+
+However, we might also redefine performance as the number of 
+bytes that were `successfully` transferred. In order for the 
+bytes to be successfully transferred they must be successfully 
+received and processed on the NuttX target. If we fail in 
+this if the packet is `lost` or `dropped`. A packet is lost if 
+the network driver is not prepared to receive the packet when 
+it was sent. A packet is dropped by the network if it is 
+received but could not be processed either because there 
+is some logical issue with the packet (not the case here) 
+or if we have no space to buffer the newly received packet.
+
+If a TCP packet is lost or dropped, then the penalty is big: 
+The packet will not be ACKed, the remote peer may send a 
+few more out-of-sequence packets which will also be dropped. 
+Eventually, the remote peer will time out and retransmit 
+the data from the point of the lost packet.
+
+There is logic in the TCP protocol to help manage these data 
+overruns. The TCP header includes a TCP `receive window` which 
+tells the remote peer how much data the receiver is able to 
+buffer. This value is sent in the ACK to each received 
+packet. If well tuned, this receive window could possibly 
+prevent packets from being lost due to the lack of 
+read-ahead storage. This is a little better. The remote 
+peer will hold off sending data instead of timing out and 
+re-transmitting. But this is still a loss of performance; 
+the gap between the transfer of packets caused by the hold-off 
+will result in a reduced transfer rate.
+
+So the issues for good reception are buffering and processing 
+time. Buffering again applies to handling within the driver 
+but unlike the transmit performance, this is not typically 
+the bottleneck. And there is also a NuttX configuration 
+option that controls `read-ahead` buffering of TCP packets. 
+The buffering in the driver must be optimized to avoid lost 
+packets; the ` buffering can be tuned to minimize 
+the number packets dropped because we have no space to buffer them.
+
+But the key to receive perform is management of processing 
+delays. Small processing delays can occur in the network 
+driver or in the TCP stack. But the major source of 
+processing delay is the application which is the ultimate 
+consumer of the incoming data. Imagine, for example, 
+and FTP application that is receiving a file over a 
+TCP and writing the file into FLASH memory. The primary 
+bottleneck here will be the write to FLASH memory which 
+is out of the control of software.
+
+We obtain optimal receive performance when the processing 
+delays keep up with the rate of the incoming packets. 
+If the processing data rate is even slightly slower 
+then the receive data rate, then there will be a 
+growing `backlog` of buffered, incoming data to be 
+processed. If this backlog continues to grow then 
+eventually our ability to buffer data will be exhausted, 
+packets will be held off or dropped, and performance 
+will deteriorate. In an environment where a high-end, 
+remote peer is interacting with the low-end, embedded 
+system, that remote peer can easily overrun the 
+embedded system due to the embedded system's limited 
+buffering space, its much lower processing capability, 
+and its slower storage peripherals.
\ No newline at end of file
diff --git a/Documentation/components/nxgraphics/GraphicsInterfaces.png 
b/Documentation/components/nxgraphics/GraphicsInterfaces.png
new file mode 100644
index 0000000000..4fe1177b2c
Binary files /dev/null and 
b/Documentation/components/nxgraphics/GraphicsInterfaces.png differ
diff --git a/Documentation/components/nxgraphics/framebuffer_char_driver.rst 
b/Documentation/components/nxgraphics/framebuffer_char_driver.rst
new file mode 100644
index 0000000000..a7afce5b17
--- /dev/null
+++ b/Documentation/components/nxgraphics/framebuffer_char_driver.rst
@@ -0,0 +1,383 @@
+============================
+Framebuffer Character Driver
+============================
+
+.. warning:: 
+    Migrated from: 
+    
https://cwiki.apache.org/confluence/display/NUTTX/Framebuffer+Character+Driver 
+    
+
+NX Graphics
+===========
+
+NuttX has supported higher level graphics for some time with 
+the OS's :doc:`/components/nxgraphics/index` and application 
+oriented :doc:`NxWidgets </applications/graphics/nxwidgets/index>` and the 
tiny 
+window manager :doc:`NxWM </applications/graphics/nxwm/index>`. 
+These are higher level in the sense that the primary 
+graphical function is to support windowing and control 
+of tools and toolbars within windows. These graphics 
+tools often do not meet the needs 
+of developers with very low end graphics and minimal display 
+requirements.
+
+Figure 1
+========
+
+The framebuffer character driver, along with the option LCD 
+framebuffer interface, is an optional lighter-weight graphics interface.
+
+.. image:: GraphicsInterfaces.png
+
+Framebuffer Character Driver details
+====================================
+
+A `framebuffer character driver` has been recently been added 
+to bypass the complexity of `NX` and to provide a direct 
+application interface to the framebuffer graphic device. 
+The framebuffer buffer character devices, as with all 
+character devices, provides the interface to the graphics 
+device via stand POSIX VFS commands (``open()``, ``close()``, 
+``read()``, ``write()``, ``seek()``, ...), through IOCTL commands, 
+and for this driver via the ``mmap()`` function. These 
+interfaces are described below,
+
+The framebuffer character driver is located in the NuttX 
+source tree at ``drivers/video/fb.c``. It is enabled in the 
+build with ``CONFIG_VIDEO_FB=y``. In order to register the 
+framebuffer driver, you will need to include logic in the 
+your board-specific start-up function that calls 
+``fb_register()`` That code sequence might look something 
+like:
+
+.. code-block:: c 
+
+    #include <nuttx/video/fb.h>
+ 
+    #ifdef CONFIG_VIDEO_FB
+    /* Initialize and register the simulated framebuffer driver */
+    
+    ret = fb_register(0, 0);
+    if (ret < 0)
+        {
+        syslog(LOG_ERR, "ERROR: fb_register() failed: %d\n", ret);
+        }
+    #endif
+
+The ``fb_register()`` function takes two parameters:
+
+* `display`. The display number for the case of boards 
+  supporting multiple displays or for hardware that supports 
+  multiple layers (each layer is consider a display). Typically zero.
+* `plane`. Identifies the color plane on hardware that supports 
+  separate framebuffer "planes" for each color component. 
+  Should be zero because no planar hardware is currently 
+  supported by NuttX.
+
+``fb_register()`` will register the framebuffer character device 
+at ``/dev/fb`` `N` where `N` is the display number if the devices 
+supports only a single plane. If the hardware supports 
+multiple color planes, then the device will be registered 
+at ``/dev/fb`` `N-M` where `N` is the again display number but `M` 
+is the display plane.
+
+There is a simple example at ``apps/examples/fb`` that provides 
+an illustration of most of the following interfacing methods.
+
+POSIX Interfaces
+================
+
+The interaction with the framebuffer character driver via POSIX 
+VFS interface calls is the same as for other character drivers. 
+The only aspect that might require some additional discussion 
+is the use of ``read()``, ``write()``, and ``seek()``.
+
+* ``read()`` returns data from the framebuffer memory and 
+  updates the file position based on the number of bytes read.
+* ``write()`` puts data into the framebuffer memory and 
+  also updates the file position.
+
+That file position is initially set to the position 
+zero meaning the beginning of the framebuffer. It is 
+advanced each time you ``read()`` from or ``write()`` to the 
+framebuffer. Is also updated by ``seek()``:
+
+* ``seek()`` sets the file position to any desired 
+  location within the framebuffer.
+
+The file position is in units of `bytes`. This can be 
+confusing because other positional data may be in units 
+`pixels`. Pixels have different `depth` in different displays, 
+that is, different graphic hardware may support pixels with 
+differing bits-per-pixel. The pixel depth can be obtained 
+using one of the IOCTL commands listed below. Since the file 
+position is in bytes, the bits-per-pixel must be taken account 
+when using ``read()``, ``write()``, and ``seek()``. The usual conversion 
+from pixels to bytes is:
+
+.. code-block:: C
+
+    start_byte = (start_pixel * bits_per_pixel) >> 3;
+    end_byte   = (end_pixel * bits_per_pixel + 7) >> 3;
+
+While the framebuffer may be accessed with these POSIX interfaces, 
+a more typical way of interacting with the framebuffer from an 
+application would involve use of ``mmap()`` as described below.
+
+IOCTL Commands
+==============
+
+* ``FBIOGET_VIDEOINFO``. Get color plane info. Its argument is 
+  pointer a writable instance of ``struct fb_videoinfo_s``:
+
+  .. code-block:: c 
+
+    struct fb_videoinfo_s
+    {
+        uint8_t    fmt;         /* see FB_FMT_*  */
+        fb_coord_t xres;        /* Horizontal resolution in pixel columns */
+        fb_coord_t yres;        /* Vertical resolution in pixel rows */
+        uint8_t    nplanes;     /* Number of color planes supported */
+    };
+
+* ``FBIOGET_PLANEINFO``. Get video plane info. It received 
+  a pointer to a writable instance of ``struct fb_planeinfo_s`` as its 
argument:
+
+  .. code-block:: C
+
+    struct fb_planeinfo_s
+    {
+        FAR void  *fbmem;       /* Start of frame buffer memory */
+        uint32_t   fblen;       /* Length of frame buffer memory in bytes */
+        fb_coord_t stride;      /* Length of a line in bytes */
+        uint8_t    display;     /* Display number */
+        uint8_t    bpp;         /* Bits per pixel */
+    };
+
+* ``FBIOGET_CMAP`` and ``FBIOPUT_CMAP``. Get/Put RGB color mapping. 
+  These commands are available only if the hardware and 
+  framebuffer driver support color mapping (``CONFIG_FB_CMAP=y``). 
+  They each take a pointer to an instance of ``struct fb_cmap_s`` 
+  as an argument (writeable for ``FBIOGET_CMAP`` and read-only 
+  for ``FBIOPUT_CMAP``).
+
+  .. code-block:: c 
+
+    #ifdef CONFIG_FB_CMAP
+    struct fb_cmap_s
+    {
+        uint16_t  first;        /* Offset offset first color entry in tables */
+        uint16_t  len;          /* Number of color entries  in tables */
+        
+        /* Tables of  color component.  Any may be NULL if not used */
+        
+        uint8_t *red;           /* Table of 8-bit red values */
+        uint8_t *green;         /* Table of 8-bit green values */
+        uint8_t *blue;          /* Table of 8-bit blue values */
+    #ifdef CONFIG_FB_TRANSPARENCY
+        uint8_t *transp;        /* Table of 8-bit transparency */
+    #endif
+    };
+    #endif
+
+* ``FBIOGET_CURSOR``. Get cursor attributes. This command is 
+  available only if the hardware and framebuffer driver 
+  support cursors (``CONFIG_FB_HWCURSOR=y``). It take a pointer 
+  to a writable instance of ``struct fb_cursorattrib_s``:
+
+  .. code-block:: c 
+
+    #ifdef CONFIG_FB_HWCURSOR
+    #ifdef CONFIG_FB_HWCURSORIMAGE
+    struct fb_cursorimage_s
+    {
+        fb_coord_t     width;    /* Width of the cursor image in pixels */
+        fb_coord_t     height    /* Height of the cursor image in pixels */
+        const uint8_t *image;    /* Pointer to image data */
+    };
+    #endif
+    
+    struct fb_cursorpos_s
+    {
+        fb_coord_t x;            /* X position in pixels */
+        fb_coord_t y;            /* Y position in rows */
+    };
+    
+    #ifdef CONFIG_FB_HWCURSORSIZE
+    struct fb_cursorsize_s
+    {
+        fb_coord_t h;             /* Height in rows */
+        fb_coord_t w;             /* Width in pixels */
+    };
+    #endif
+    
+    struct fb_cursorattrib_s
+    {
+    #ifdef CONFIG_FB_HWCURSORIMAGE
+        uint8_t fmt;                   /* Video format of cursor */
+    #endif
+        struct fb_cursorpos_s  pos;    /* Current cursor position */
+    #ifdef CONFIG_FB_HWCURSORSIZE
+        struct fb_cursorsize_s mxsize; /* Maximum cursor size */
+        struct fb_cursorsize_s size;   /* Current size */
+    #endif
+    };
+    #endif
+
+* ``FBIOPUT_CURSOR``. Set cursor attributes. This command is 
+  available only if the hardware and framebuffer driver 
+  support cursors (``CONFIG_FB_HWCURSOR=y``). It take a 
+  pointer to a writable instance of ``struct fb_setcursor_s``:
+
+  .. code-block:: c 
+
+    #ifdef CONFIG_FB_HWCURSOR
+    struct fb_setcursor_s
+    {
+        uint8_t flags;                /* See FB_CUR_* definitions */
+        struct fb_cursorpos_s pos;    /* Cursor position */
+    #ifdef CONFIG_FB_HWCURSORSIZE
+        struct fb_cursorsize_s  size; /* Cursor size */
+    #endif
+    #ifdef CONFIG_FB_HWCURSORIMAGE
+        struct fb_cursorimage_s img;  /* Cursor image */
+    #endif
+    };
+    #endif
+
+* ``FBIO_UPDATE``. This IOCTL command updates a rectangular region 
+  in the framebuffer. Some hardware requires that there be 
+  such a notification when a change is made to the 
+  framebuffer (see, for example, the discussion of LCD drivers 
+  below). This IOTCL command is if ``CONFIG_NX_UPDATE=y`` is 
+  defined. It takes a pointer to a read-only instance of 
+  ``struct nxgl_rect_s`` that describes the region to be updated:
+
+  .. code-block:: c 
+
+    struct nxgl_rect_s
+    {
+        struct nxgl_point_s pt1; /* Upper, left-hand corner */
+        struct nxgl_point_s pt2; /* Lower, right-hand corner */
+    };
+
+``mmap()``
+==========
+
+Above we talked about using ``read()``, ``write()``, and ``seek()`` to 
+access the framebuffer. The simplest way to access the 
+framebuffer, however, is by using the ``mmap()`` to map 
+the framebuffer memory into the application memory 
+space. The following ``mmap()`` command, for example, can 
+be used to obtain a pointer to a read-able, write-able 
+copy of the framebuffer:
+
+.. code-block:: c 
+
+    FAR void *fbmem;
+ 
+    fbmem = mmap(NULL, fblen, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FILE, fd, 
0);
+    if (state.fbmem == MAP_FAILED)
+    {
+        /* Handle failure */
+        ...
+    }
+    
+    printf("Mapped FB: %p\n", fbmem);
+
+Where fd is the file descriptor of the opened framebuffer 
+character driver and ``fblen`` was obtained via an IOCTL 
+command as described above. NOTE that the framebuffer 
+buffer pointer is also available within the values 
+returned by the IOCTL commands. The address is a 
+kernel memory address and may not be valid in all 
+build configurations. Hence, ``mmap()`` is the preferred, 
+portable way to get the framebuffer address.
+
+Framebuffer vs. LCD Graphics Drivers
+====================================
+
+Framebuffer graphics drivers are very common in high-end CPUs 
+but most low-end, embedded hardware will not support a 
+framebuffer.
+
+A framebuffer graphics driver supports a region of memory 
+that is shared both by the software and by the graphics 
+hardware. Any modification to the framebuffer memory 
+results in a corresponding modification on the display 
+with no intervening software interaction. Some video 
+memory is dual ported to support concurrent video processor 
+and application processor accesses; or perhaps the LCD 
+peripheral just constantly DMAs the framebuffer memory 
+to the graphics hardware.
+
+Most low-end embedded MCUs have a much simpler hardware 
+interface: The interface to the LCD may be through a simple 
+parallel interface or, more commonly, through a slower serial 
+interface such as SPI. In order to support such low-end 
+hardware with the framebuffer character driver, a special 
+software layer called the `Framebuffer LCD Front End` has 
+been developed. This is the topic of the next paragraph.
+
+LCD Framebuffer Front-End
+=========================
+
+The `LCD Framebuffer Front-End` provides a standard NuttX 
+framebuffer interface, but works on top of a standard 
+parallel or serial LCD driver. It provides the framebuffer, 
+the framebuffer interface, and the hooks to adapt the LCD 
+driver. The LCD framebuffer front-end can be found in the 
+NuttX source tree at ``drivers/lcd/lcd_framebuffer.c``.
+
+In order to provide updates to the LCD hardware after 
+updates to the framebuffer, the LCD framebuffer front-end 
+must be notified when significant changes to the framebuffer 
+have been made. This notification is supported when 
+``CONFIG_NX_UPDATE=y`` is defined in the configuration. In 
+this case, the LCD framebuffer front-end will support 
+the special. OS-internal interface function ``nx_notify_rectangle()`` 
+which defines the rectangular region in the framebuffer that 
+has been changed. In response to a call to ``nx_notify_rectangle()`` 
+will use the lower-level LCD interface to update only that 
+rectangular region on the display.
+
+This kind of update for standard LCD drivers is very efficient: 
+It is usually more efficient to update a region on the 
+display than it is for form a complex image with text and 
+line drawing; the updated region seems to update very 
+quickly because of that. In fact, many of the low-end 
+LCD drivers already include an internal framebuffer to 
+support this style of LCD update.
+
+When used with LCD character driver, the ``nx_notify_rectangle()`` 
+function will be called by the character river in response 
+to the ``FBIO_UPDATE IOCTL`` command.
+
+Another advantage of the framebuffer, both the LCD internal 
+framebuffer and the framebuffer character driver, is 
+that super-efficient reading of the LCD display memory: 
+The LCD display memory is not read at all! The read is 
+from the copy in the framebuffer.
+
+Of course, using both an LCD internal framebuffer with the 
+framebuffer character drivers is wasteful; one framebuffer 
+is enough!
+
+As a caution, it is important to remember that a framebuffer 
+can be quite large. For example, a 480x320 display with 
+16-bit RGB pixels would require an allocated framebuffer 
+of size 300 KiB. This is inappropriate with most small 
+MCUs (unless they support external memory). For tiny displays, 
+such as 128x64 1-bit monochromatic displays, the framebuffer 
+memory usage is not bad: 1 KiB in that example.
+
+Framebuffer Graphics Library
+============================
+
+Now the missing part is some kind of application-space 
+framebuffer graphics library. The NuttX framebuffer 
+driver is superficially similar to the Linux framebuffer 
+driver so there is a lot of support for Linux 
+framebuffer graphics support that should be easily ported to 
+NuttX – Perhaps DirectFB would be an GPL option? SDL with its 
+MIT license might be a more compatible source for such a port.
\ No newline at end of file
diff --git a/Documentation/components/nxgraphics/index.rst 
b/Documentation/components/nxgraphics/index.rst
index f5740a45c8..318f3bd98e 100644
--- a/Documentation/components/nxgraphics/index.rst
+++ b/Documentation/components/nxgraphics/index.rst
@@ -171,6 +171,8 @@ NX Header Files
   nxtk.rst
   nxfonts.rst
   nxcursor.rst
+  nxwm_threading.rst
+  framebuffer_char_driver.rst
   sample.rst
   appendix.rst
 
diff --git a/Documentation/components/nxgraphics/nxwm_threading.rst 
b/Documentation/components/nxgraphics/nxwm_threading.rst
new file mode 100644
index 0000000000..ea5c8ac965
--- /dev/null
+++ b/Documentation/components/nxgraphics/nxwm_threading.rst
@@ -0,0 +1,13 @@
+==============
+NxWM Threading
+==============
+
+.. warning:: 
+    Migrated from: 
+    https://cwiki.apache.org/confluence/display/NUTTX/NxWM+Threading 
+
+.. image:: nxwm_threading_model/nxwm_theading_model_page_0.png
+.. image:: nxwm_threading_model/nxwm_theading_model_page_1.png
+.. image:: nxwm_threading_model/nxwm_theading_model_page_2.png
+.. image:: nxwm_threading_model/nxwm_theading_model_page_3.png
+.. image:: nxwm_threading_model/nxwm_theading_model_page_4.png
diff --git 
a/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_0.png
 
b/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_0.png
new file mode 100644
index 0000000000..eb95bc5a3f
Binary files /dev/null and 
b/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_0.png
 differ
diff --git 
a/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_1.png
 
b/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_1.png
new file mode 100644
index 0000000000..3e38e9b0db
Binary files /dev/null and 
b/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_1.png
 differ
diff --git 
a/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_2.png
 
b/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_2.png
new file mode 100644
index 0000000000..8bde18ebf7
Binary files /dev/null and 
b/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_2.png
 differ
diff --git 
a/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_3.png
 
b/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_3.png
new file mode 100644
index 0000000000..80020f0e34
Binary files /dev/null and 
b/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_3.png
 differ
diff --git 
a/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_4.png
 
b/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_4.png
new file mode 100644
index 0000000000..cbdc132904
Binary files /dev/null and 
b/Documentation/components/nxgraphics/nxwm_threading_model/nxwm_theading_model_page_4.png
 differ


Reply via email to