<div dir="ltr">Thanks for the ping. Sorry I was out of town and didn't get to it until today.<div><br></div><div>Verify this was merged correctly and this was it.</div><div><br></div><div>Thanks.</div><div><br></div><div>--joel</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jun 9, 2022 at 8:21 AM Frank Kuehndel <<a href="mailto:frank.kuehndel@embedded-brains.de">frank.kuehndel@embedded-brains.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Frank Kühndel <<a href="mailto:frank.kuehndel@embedded-brains.de" target="_blank">frank.kuehndel@embedded-brains.de</a>><br>
<br>
---<br>
 filesystem/index.rst       |   1 +<br>
 filesystem/trivial_ftp.rst | 564 ++++++++++++++++++++++++++++++++++++-<br>
 2 files changed, 562 insertions(+), 3 deletions(-)<br>
<br>
diff --git a/filesystem/index.rst b/filesystem/index.rst<br>
index f4e2ed6..64a2f1d 100644<br>
--- a/filesystem/index.rst<br>
+++ b/filesystem/index.rst<br>
@@ -9,6 +9,7 @@ RTEMS Filesystem Design Guide (|version|).<br>
 .. topic:: Copyrights and License<br>
<br>
     | |copy| 1988, 2015 On-Line Applications Research Corporation (OAR)<br>
+    | |copy| 2022 embedded brains GmbH (<a href="http://www.embedded-brains.de" rel="noreferrer" target="_blank">http://www.embedded-brains.de</a>)<br>
<br>
     .. include:: ../common/license.rst<br>
<br>
diff --git a/filesystem/trivial_ftp.rst b/filesystem/trivial_ftp.rst<br>
index e43c036..3ef8bba 100644<br>
--- a/filesystem/trivial_ftp.rst<br>
+++ b/filesystem/trivial_ftp.rst<br>
@@ -3,7 +3,565 @@<br>
 Trivial FTP Client Filesystem<br>
 *****************************<br>
<br>
-This chapter describes the Trivial FTP (TFTP) Client Filesystem.<br>
+This chapter describes the Trivial File Transfer Protocol (TFTP) Client<br>
+Filesystem.  TFTP is designed to be an especially simple protocol which<br>
+uses the User Datagram Protocol (UDP) for data transfer over the Internet.<br>
+Its purpose is to send a single file between to network nodes (client and<br>
+server).  A file can be sent in both directions, i.e. a client can either<br>
+read a file from a server or write a file to the server.<br>
<br>
-This chapter should be written after the IMFS chapter is completed and describe<br>
-the implementation of the TFTP.<br>
+Besides reading or writing a file no other operations are supported.  That<br>
+is, one cannot seek the file, not append to the end of a file, not open<br>
+the file for reading and writing at the same time, not list directories,<br>
+not move files and so on.<br>
+<br>
+TFTP is inherent insecure as it does not provide any means for<br>
+authentication or encryption.  Therefore, it is highly recommended not<br>
+to employ it on public networks.  Nevertheless, it is still widely used<br>
+to load software and configuration data during early boot stages over<br>
+a Local Area Network (LAN).<br>
+<br>
+RTEMS TFTP Filesystem Implementation<br>
+====================================<br>
+<br>
+The RTEMS TFTP filesystem implements a TFTP client which can be used<br>
+through the file system.  With other words, one needs to mount the<br>
+TFTP filesystem and can afterwards open a file for reading or writing<br>
+below that mount point.  The content of that file is then effectively<br>
+read from or written to the remote server.  The RTEMS implementation<br>
+implements the following features:<br>
+<br>
+* `RFC 1350 <<a href="https://www.rfc-editor.org/rfc/rfc1350.html" rel="noreferrer" target="_blank">https://www.rfc-editor.org/rfc/rfc1350.html</a>>`_<br>
+  *The TFTP Protocol (Revision 2)*<br>
+* `RFC 2347 <<a href="https://www.rfc-editor.org/rfc/rfc2347.html" rel="noreferrer" target="_blank">https://www.rfc-editor.org/rfc/rfc2347.html</a>>`_<br>
+  *TFTP Option Extension*<br>
+* `RFC 2348 <<a href="https://www.rfc-editor.org/rfc/rfc2348.html" rel="noreferrer" target="_blank">https://www.rfc-editor.org/rfc/rfc2348.html</a>>`_<br>
+  *TFTP Blocksize Option*<br>
+* `RFC 7440 <<a href="https://www.rfc-editor.org/rfc/rfc7440.html" rel="noreferrer" target="_blank">https://www.rfc-editor.org/rfc/rfc7440.html</a>>`_<br>
+  *TFTP Windowsize Option*<br>
+<br>
+Many simple TFTP server do not support options (RFC 2347). Therefore, in<br>
+case the server rejects the first request with options, the RTEMS client<br>
+makes automatically a second attempt using only the "classical" RFC 1350.<br>
+<br>
+The implementation has the following shortcomings:<br>
+<br>
+* IPv6 is not supported (yet).<br>
+<br>
+* No congestion control is implemented.<br>
+<br>
+  (Congestion is simply expressed a network traffic jam which involves<br>
+  package loss.)  This implementation would worsen a congestion situation<br>
+  and squeeze out TCP connections.  If that is a concern in your setup,<br>
+  it can be prevented by using value `1` as `windowsize` when mounting<br>
+  the TFTP file system.<br>
+<br>
+* One must call ``open()``, ``read()``, ``write()`` and ``close()``<br>
+  at a good pace.<br>
+<br>
+  TFTP is designed to read or write a whole already existing file in<br>
+  one sweep.  It uses timeouts (of unspecified length) and it does not<br>
+  know keep-alive messages.  If the client does not respond to the<br>
+  server in due time, the server sets the connection faulty and drops it.<br>
+  To avoid this, the user must read or write enough data fast enough.<br>
+<br>
+  The point here is, one cannot pause the reading or writing for longer<br>
+  periods of time.  TFTP cannot be used for example to write log files<br>
+  where all few seconds a line is written.  Also opening the<br>
+  file at the beginning of an application and closing it that the end<br>
+  will certainly lead to a timeout.  As another example, one cannot<br>
+  read a file by reading one byte per second, this will trigger a<br>
+  timeout and the server closes the connection.  The opening, reading<br>
+  or writing and closing must happen in swift consecutive steps.<br>
+<br>
+* The transfer mode is always ``octet``.  The only alternative<br>
+  ``netascii`` cannot be selected.<br>
+<br>
+* Block number roll-over is currently not supported.  Therefore,<br>
+  the maximum file size is limited to max-block-number times blocksize.<br>
+  For RFC 1350 blocksize is would be 65535 * 512 = 32 MB.  For the<br>
+  default blocksize is would be 65535 * 1456 = 90 MB.<br>
+<br>
+* The inherent insecurity of the protocol has already be mentioned but<br>
+  it is worth repeating.<br>
+<br>
+Prerequisites<br>
+=============<br>
+<br>
+To use the RTEMS TFTP filesystem one needs:<br>
+<br>
+* The RTEMS tools (cross-compiler, linker, debugger etc.)<br>
+* The RTEMS Board Support Package (BSP)<br>
+* A network stack for RTEMS, for example RTEMS libbsd<br>
+<br>
+As an example the ARM architecture and a xilinx_zynq_a9 BSP is used below<br>
+together with RTEMS libbsd.  The instructions are tested with RTEMS<br>
+version 6.  It is recommended to actually use ``arm/xilinx_zynq_a9_qemu``<br>
+for the first experiments as other BSPs tend to require different<br>
+configuration values and/or command line options.<br>
+<br>
+Moreover, it is recommended to first execute any code using QEMU as<br>
+simulator so that no hardware is needed.  Therefore, ``qemu-system-arm``<br>
+must be installed.  In Linux distributions this executable is usually<br>
+available in the repositories as package ``qemu-arm``.<br>
+<br>
+RTEMS Tools<br>
+-----------<br>
+<br>
+Instructions on how to obtain, compile and install the RTEMS tools can<br>
+be found in the *RTEMS User Manual* chapter *2. Quick Start*.  To<br>
+follow the suggested example ``6/rtems-arm`` should be used as<br>
+target architecture argument of the ``../source-builder/sb-set-builder``<br>
+command.<br>
+<br>
+RTEMS Board Support Package<br>
+---------------------------<br>
+<br>
+Instructions on how to obtain, compile and install a BSP can be found<br>
+in the *RTEMS User Manual* section *Build a Board Support Package (BSP)*.<br>
+The bsp-option should have the following value to match the example BSP:<br>
+<br>
+.. code-block:: none<br>
+<br>
+  --rtems-bsps=arm/xilinx_zynq_a9_qemu<br>
+<br>
+RTEMS libbsd<br>
+------------<br>
+<br>
+Instructions on how to obtain, compile and install RTEMS libbsd can be<br>
+found in the ``README.rst`` of the ``rtems-libbsd`` GIT repository:<br>
+``git://<a href="http://git.rtems.org/rtems-libbsd.git" rel="noreferrer" target="_blank">git.rtems.org/rtems-libbsd.git``</a>.<br>
+Make sure to compile and install libbsd for the correct RTEMS version<br>
+(here ``6``).  The default build set (``--buildset=buildset/default.ini``)<br>
+does suffice and as BSP ``--rtems-bsp=arm/xilinx_zynq_a9_qemu`` is<br>
+to be used with the ``waf configure`` command.<br>
+<br>
+RTEMS Configuration<br>
+-------------------<br>
+<br>
+To make the TFTP filesystem available to an RTEMS application and have<br>
+it initialized, the macro ``CONFIGURE_FILESYSTEM_TFTPFS`` must be<br>
+defined when configuring RTEMS (typically in the ``init.c`` file):<br>
+<br>
+.. code-block:: c<br>
+<br>
+  #define CONFIGURE_FILESYSTEM_TFTPFS<br>
+<br>
+Moreover, libbsd and RTEMS must be configured appropriately as well.<br>
+For orientation, the code below is from an application using TFTP FS<br>
+(file ``tftp_init.c``).<br>
+<br>
+.. code-block:: c<br>
+<br>
+  /* Configure libbsd. */<br>
+  #define RTEMS_BSD_CONFIG_NET_PF_UNIX<br>
+  #define RTEMS_BSD_CONFIG_NET_IF_BRIDGE<br>
+  #define RTEMS_BSD_CONFIG_NET_IF_LAGG<br>
+  #define RTEMS_BSD_CONFIG_NET_IF_VLAN<br>
+  #define RTEMS_BSD_CONFIG_BSP_CONFIG<br>
+  #define RTEMS_BSD_CONFIG_INIT<br>
+<br>
+  #include <machine/rtems-bsd-config.h><br>
+<br>
+  /* RTEMS configuration for libbsd */<br>
+  #define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1<br>
+  #define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024)<br>
+  #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES<br>
+  #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT<br>
+  #define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK<br>
+<br>
+  /* RTEMS configuration for tftp */<br>
+  #define CONFIGURE_FILESYSTEM_TFTPFS<br>
+  #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 64<br>
+<br>
+  /* Simple RTEMS configuration */<br>
+  #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER<br>
+  #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER<br>
+  #define CONFIGURE_UNLIMITED_OBJECTS<br>
+  #define CONFIGURE_UNIFIED_WORK_AREAS<br>
+  #define CONFIGURE_RTEMS_INIT_TASKS_TABLE<br>
+  #define CONFIGURE_INIT<br>
+<br>
+  #include <rtems/confdefs.h><br>
+<br>
+Application Linkage<br>
+-------------------<br>
+<br>
+The TFTP filesystem is compiled and linked into ``libtftpfs``.  After<br>
+installation it should be in a place like:<br>
+<br>
+.. code-block:: none<br>
+<br>
+  <PREFIX>/arm-rtems6/xilinx_zynq_a9_qemu/lib/libtftpfs.a<br>
+<br>
+An RTEMS application which wants to use the TFTP filesystem must be linked<br>
+with the libraries ``libtftpfs``, ``libbsd``, and ``libm`` --- in this order.<br>
+An example build target in a ``wscript`` for use with the RTEMS WAF build<br>
+system could be:<br>
+<br>
+.. code-block:: python<br>
+<br>
+  def build(ctx):<br>
+      rtems.build(ctx)<br>
+      ctx(features = 'c cprogram',<br>
+          target = 'tftp_app.exe',<br>
+          cflags = '-g -O2',<br>
+          source = ['tftp_app.c', 'tftp_init.c'],<br>
+          lib    = ['tftpfs', 'bsd', 'm'])<br>
+<br>
+Network Configuration and TFTP Server<br>
+-------------------------------------<br>
+<br>
+QEMU has a simple build-in TFTP server which can serve files for reading<br>
+only.  By default it is reachable from the application executed by QEMU<br>
+at IP address ``10.0.2.2`` if SLIRP networking is used.  For the<br>
+example ``arm/xilinx_zynq_a9_qemu`` BSP, the QEMU option<br>
+<br>
+.. code-block:: none<br>
+<br>
+  -nic user,model=cadence_gem,tftp=/tmp<br>
+<br>
+will cause this TFTP server to deliver files found below directory<br>
+``/tmp``.  Note that SLIRP requires that the application uses DHCP.<br>
+<br>
+Alternatively, it is of course possible to use other kinds of QEMU<br>
+networking (as for example the TAP virtual Ethernet interface described<br>
+in the above mentioned ``README.rst`` in section *Qemu and Networking*).<br>
+Also an external TFTP server can be used.<br>
+<br>
+External TFTP Server Example for OpenSUSE<br>
+-----------------------------------------<br>
+<br>
+This example uses ``atftp`` as an external TFTP server to which the RTEMS<br>
+TFTP file system running in an QEMU instance connects to.  ``atftp`` was<br>
+compiled from the sources.  Instructions how to compile and install<br>
+``atftp`` can be found in the ``INSTALL`` file which comes with its sources.<br>
+<br>
+On an OpenSUSE 15.3 machine, the following commands sets up ``atftp``<br>
+for use with the mentioned TAP interface (these commands must be executed<br>
+as root; ``<APP-USER>`` must be replaced by the name of the "normal"<br>
+user starting the RTEMS application in QEMU later on; for other<br>
+distributions the ``firewall-cmd`` commands must be<br>
+replaced by the equivalent of that distribution):<br>
+<br>
+.. code-block:: shell<br>
+<br>
+  # Create and configure TAP interface<br>
+  ip tuntap add qtap mode tap user <APP-USER><br>
+  ip link set dev qtap up<br>
+  ip addr add <a href="http://169.254.1.1/16" rel="noreferrer" target="_blank">169.254.1.1/16</a> dev qtap<br>
+<br>
+  # Open firewalld as non-permanent configuration<br>
+  firewall-cmd --zone=home --add-service=tftp<br>
+  firewall-cmd --zone=home --add-interface=qtap<br>
+<br>
+  # Start TFTP daemon<br>
+  touch /var/log/atftpd/atftp.log<br>
+  chown tftp.tftp /var/log/atftpd/atftp.log<br>
+  atftpd --user tftp --group tftp --daemon --verbose \<br>
+      --logfile /var/log/atftpd/atftp.log /srv/tftpboot<br>
+<br>
+The ``atftp`` server will then be reachable from an application executed<br>
+by QEMU at the address of the TAP interface which is in this case<br>
+``169.254.1.1``.  When used with this TAP interface, the QEMU network<br>
+option must be changed to (replacing the ``-net`` options in the examples<br>
+found in the already mentioned ``README.rst`` of the ``rtems-libbsd`` GIT<br>
+repository):<br>
+<br>
+.. code-block:: none<br>
+<br>
+   -nic tap,model=cadence_gem,ifname=qtap,script=no,downscript=no<br>
+<br>
+Usage<br>
+=====<br>
+<br>
+The following diagram shows how the TFTP filesystem is used by an<br>
+application.  The mount point can be any directory.  The name ``/tftp``<br>
+used in the figure serves only as an example.  The final unmounting and<br>
+remove directory steps are optional.<br>
+<br>
+.. figure:: ../images/filesystem/tftpfs_usage.png<br>
+  :width: 90%<br>
+  :align: center<br>
+  :alt: TFTP Usage Diagram<br>
+<br>
+Mounting the TFTP Filesystem<br>
+----------------------------<br>
+<br>
+When mounting the TFTP filesystem, the argument ``filesystemtype`` must<br>
+be ``RTEMS_FILESYSTEM_TYPE_TFTPFS`` (``#include <rtems/libio.h>``).<br>
+<br>
+The argument ``data`` can either be<br>
+<br>
+* a 0-terminated C string of comma separated mount options or<br>
+* ``NULL`` for mounting with default values.<br>
+<br>
+The mount options are case sensitive.  Spaces are not allowed in the string.<br>
+If conflicting options are specified, the ones more to the right (i.e. end<br>
+of the string) take precedence.  These mount options are supported:<br>
+<br>
+``blocksize=N``<br>
+  where ``N`` is a decimal integer number.<br>
+<br>
+  The TFTP blocksize option is introduced in RFC 2348.  It defines the<br>
+  number of octets in the data packages transferred.  Valid values<br>
+  range between 8 and 65464 octets, inclusive.  Values larger<br>
+  than 1468 may cause package fragmentation over standard Ethernet.<br>
+  A value of 512 will prevent this option from being sent to<br>
+  the server.<br>
+<br>
+  The default value is 1456.<br>
+<br>
+``windowsize=N``<br>
+  where ``N`` is a decimal integer number.<br>
+<br>
+  The TFTP windowsize option is introduced in RFC 7440.  It defines the<br>
+  number of data packages send before the receiver must send an<br>
+  acknowledgment package.  Valid values range between 1 and 65535<br>
+  packages, inclusive.  Simple TFTP servers usually do not support this<br>
+  option.  This option may negatively contribute to network<br>
+  congestion.  This can be avoided by using a window size of 1.<br>
+  A value of 1 will prevent this option from being sent to<br>
+  the server.<br>
+<br>
+  The default value is 8.<br>
+<br>
+``rfc1350``<br>
+  The TFTP client should strictly follow RFC 1350 and not send any<br>
+  options to the server.  Many simple TFTP server do still not support<br>
+  the option extension defined in RFC 2347.  The TFTP filesystem will<br>
+  always make a second option-less connection attempt to the TFTP server<br>
+  in case a first attempt with options was rejected with an error message.<br>
+<br>
+  This option is equivalent to ``blocksize=512,windowsize=1``.<br>
+<br>
+``verbose``<br>
+  During operation, print messages to ``stdout``.  This option has<br>
+  currently little effect.  It is kept to be compatible to older<br>
+  implementations.<br>
+<br>
+Opening a File<br>
+--------------<br>
+<br>
+Files must be opened by using either ``O_RDONLY`` or ``O_WRONLY``<br>
+as flags but not both.  Other flags are not supported.<br>
+<br>
+The ``pathname`` argument to ``open()`` has the following format:<br>
+<br>
+.. code-block:: none<br>
+<br>
+  <PREFIX>/<server-address>:<path-on-server><br>
+<br>
+``<PREFIX>``<br>
+  The path to the point where the TFTP filesystem is mounted.  This can<br>
+  be a relative path from the current working directory or an absolute<br>
+  path.<br>
+<br>
+``<server-address>``<br>
+  The network address for the TFTP server from which to download the<br>
+  file or to which the file should be sent.  This is either<br>
+<br>
+    * an IPv4 address (like `127.0.0.1`) or<br>
+    * the (full-qualified) name of an IPv4 host (acceptable to<br>
+      ``gethostbyname()``)<br>
+<br>
+  The port number cannot be specified and will always be the one reserved<br>
+  for TFTP: 69.<br>
+<br>
+``<path-on-server>``<br>
+  The path and file name at which the TFTP server will find or create the<br>
+  file.  Any directories in this path must already exist.  It is not<br>
+  possible to create or read directories with TFTP.  RFC 1350 specifies<br>
+  that this ``<path-on-server>`` must be in *netascii*:<br>
+<br>
+      This is ascii as defined in "USA Standard Code for Information<br>
+      Interchange" [1] with the modifications specified in "Telnet<br>
+      Protocol Specification" [3].<br>
+<br>
+      [1] USA Standard Code for Information Interchange, USASI X3.4-1968.<br>
+<br>
+      [3] Postel, J., "Telnet Protocol Specification," RFC 764,<br>
+      USC/Information Sciences Institute, June, 1980.<br>
+<br>
+Example pathnames:<br>
+<br>
+.. code-block:: c<br>
+<br>
+  "/tftp/169.254.1.1:file.txt"<br>
+  "/TFTPFS/tftp-server.sample.org:bootfiles/image"<br>
+<br>
+In the above examples, ``/tftp`` and ``/TFTPFS`` are the directory at which<br>
+the TFTP filesystem is mounted.  ``169.254.1.1`` and<br>
+``<a href="http://tftp-server.sample.org" rel="noreferrer" target="_blank">tftp-server.sample.org</a>`` are the network address of the TFTP server to<br>
+contact.  ``file.txt`` and ``bootfiles/image`` are the file name and<br>
+the path at the server side.<br>
+<br>
+Closing a File<br>
+--------------<br>
+<br>
+Especially, when writing a file to the server, the return<br>
+code of ``close()`` should be checked.  Invoking ``close()`` triggers<br>
+the sending of the last -- not completely filled -- data block.  This<br>
+may fail the same way as any ``write()`` may fail.  Therefore, an error<br>
+returned by ``close()`` likely indicates that the file was not completely<br>
+transferred.<br>
+<br>
+Use From Shell<br>
+==============<br>
+<br>
+It is possible to use the RTEMS shell through test ``media01`` of<br>
+libbsd to exercise the TFTP filesystem.  This text assumes that libbsd<br>
+has already been setup, configured, compiled and installed as described<br>
+in the ``README.rst`` of the ``rtems-libbsd`` GIT repository.<br>
+How the test ``media01.exe`` can be executed is described in<br>
+section *Qemu and Networking* of that file.<br>
+<br>
+A TFTP server must be setup and run.  The instructions to setup an TAP<br>
+device and an ``atftp`` server found above in section `External TFTP<br>
+Server Example for OpenSUSE`_ could be followed for this purpose.<br>
+It may be useful to create a sample file for later download in the<br>
+directory served by the TFTP server.  For ``atftp`` "root" could create<br>
+a file with these instructions:<br>
+<br>
+.. code-block:: shell<br>
+<br>
+  # echo "Hello World!" >/srv/tftpboot/hello.txt<br>
+  # chown tftp.tftp /srv/tftpboot/hello.txt<br>
+<br>
+Start the ``media01`` test in one terminal --- as "normal" user:<br>
+<br>
+.. code-block:: shell<br>
+<br>
+  $ qemu-system-arm -serial null -serial mon:stdio -nographic \<br>
+    -M xilinx-zynq-a9 -m 256M \<br>
+    -nic tap,model=cadence_gem,ifname=qtap,script=no,downscript=no \<br>
+    -kernel build/arm-rtems6-xilinx_zynq_a9_qemu-default/media01.exe<br>
+<br>
+Wait till a line like the following is printed in the terminal:<br>
+<br>
+.. code-block:: none<br>
+<br>
+  info: cgem0: using IPv4LL address 169.254.191.13<br>
+<br>
+Next use the displayed IP address to open a telnet connection in a second terminal:<br>
+<br>
+.. code-block:: shell<br>
+<br>
+  $ telnet 169.254.191.13<br>
+<br>
+At the telnet prompt, enter this command to list the filesystems<br>
+available for mounting:<br>
+<br>
+.. code-block:: none<br>
+<br>
+  TLNT [/] # mount -L<br>
+  File systems: / dosfs tftpfs<br>
+<br>
+``tftpfs`` should be among them.  Create a directory and mount the TFTP<br>
+filesystem:<br>
+<br>
+.. code-block:: none<br>
+<br>
+  TLNT [/] # mkdir /tftp<br>
+  TLNT [/] # mount -t tftpfs -o verbose "" /tftp<br>
+  mounted  -> /tftp<br>
+<br>
+Now, files can be sent to and read from the TFTP server using the usual<br>
+shell commands:<br>
+<br>
+.. code-block:: none<br>
+<br>
+  TLNT [/] # cp /etc/dhcpcd.duid /tftp/169.254.1.1:dhcpcd.duid<br>
+  TFTPFS: /169.254.1.1:dhcpcd.duid<br>
+  TLNT [/] # cat /tftp/169.254.1.1:hello.txt<br>
+  TFTPFS: /169.254.1.1:hello.txt<br>
+  Hello World!<br>
+<br>
+The terminal session can be terminated with key combination "CTRL-]"<br>
+followed by a ``quit`` command; the<br>
+QEMU simulation with "CTRL-a x" and ``tail -f`` with "CTRL-c".<br>
+<br>
+TFTP Client API<br>
+===============<br>
+<br>
+The TFTP filesystem has a TFTP client which is responsible to handle all<br>
+network traffic.  It permits the use of TFTP without filesystem.<br>
+Essentially, one saves the mounting of the filesystem.  Otherwise the<br>
+usage is similar to the one of the filesystem.  The equivalent of the<br>
+``open()``, ``read()``, ``write()``, and ``close()`` functions are:<br>
+<br>
+.. code-block:: c<br>
+<br>
+  int tftp_open(<br>
+    const char *hostname,<br>
+    const char *path,<br>
+    bool is_for_reading,<br>
+    const tftp_net_config *config,<br>
+    void **tftp_handle<br>
+  );<br>
+<br>
+  ssize_t tftp_read( void *tftp_handle, void *buffer, size_t count );<br>
+<br>
+  ssize_t tftp_write( void *tftp_handle, const void *buffer, size_t count );<br>
+<br>
+  int tftp_close( void *tftp_handle );<br>
+<br>
+``tftp_open()`` accepts as input a data structure of type<br>
+``tftp_net_config``.  It can be used to specify certain values governing<br>
+the file transfer such as the already described options.  Data of<br>
+``tftp_net_config`` type can be initialized using function<br>
+<br>
+.. code-block:: c<br>
+<br>
+  void tftp_initialize_net_config( tftp_net_config *config );<br>
+<br>
+The full description can be found in the file ``cpukit/include/rtems/tftp.h``.<br>
+The function ``rtems_tftpfs_initialize()`` found there is only for RTEMS<br>
+internal use by the ``mount()`` function.<br>
+<br>
+Software Design<br>
+===============<br>
+<br>
+The original source code contained only the files<br>
+``cpukit/include/rtems/tftp.h`` and ``cpukit/libfs/src/ftpfs/tftpDriver.c``.<br>
+There was no test suite nor any documentation.<br>
+<br>
+When the code was extended to support options (RFC 2347 and others),<br>
+the code in ``tftpDriver.c`` was split.  The new file ``tftpfs.c`` is<br>
+responsible to handle all filesystem related issues while ``tftpDriver.c``<br>
+provides the network related functions.  In effect ``tftpDriver.c`` is<br>
+a TFTP client library which can be used independently of the filesystem.<br>
+``tftpfs.c`` calls the functions of ``tftpDriver.c`` to do the actual<br>
+TFTP file transfer.<br>
+<br>
+At this occasion a test suite and this documentation in the *RTEMS<br>
+Filesystem Design Guide* was added.<br>
+<br>
+Test Suite<br>
+----------<br>
+<br>
+The TFTP filesystem comes with an extensive test suite.<br>
+<br>
+``libtftpfs`` source code is situated in the RTEMS repository.  For<br>
+testing it, either ``libbsd`` or RTEMS legacy networking would have been<br>
+required.  This implies that the tests for ``libtftpfs`` would have<br>
+needed to be placed in the ``libbsd`` repository --- a different one<br>
+than the ``libtftpfs`` source code.<br>
+<br>
+Yet, ``libtftpfs`` uses only a handful of networking functions.  The<br>
+test suite provides fake implementations of those functions.  These fake<br>
+functions permit to simulate the exchange of UDP packages<br>
+with the ``libtftpfs`` code and thus permits testing the TFTP filesystem<br>
+without the need of a full network stack.<br>
+<br>
+Consequently, the test suite is placed in the RTEMS repository together<br>
+with the TFTP filesystem source code.  Neither ``libbsd`` nor RTEMS<br>
+legacy networking is required to run the tests.<br>
+<br>
+The test suite can be executed using the ``rtems-test`` tool:<br>
+<br>
+.. code-block:: shell<br>
+<br>
+  $ cd <path-to-rtems-git-worktree><br>
+  $ rtems-test --log-mode=all --rtems-bsp=xilinx_zynq_a9_qemu \<br>
+    build/arm/xilinx_zynq_a9_qemu/testsuites/fstests/tftpfs.exe<br>
-- <br>
2.35.3<br>
<br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org" target="_blank">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a></blockquote></div>