[PATCH rtems-docs 1/1] TFTPFS: New documentation

Frank Kühndel frank.kuehndel at embedded-brains.de
Thu Jun 9 13:20:17 UTC 2022


Hello Chris,
Hello Joel,
Hello Sebastian,

many thanks for your reviews and comments. I will send an updated v2 of
this patch. It will take your comments in account.

On 6/7/22 18:56, Joel Sherrill wrote:
> 
> On Sun, Jun 5, 2022 at 8:56 PM Chris Johns <chrisj at rtems.org> wrote:
> 
>> Hi Frank,
>>
>> Thanks for the documentation and the TFTP file system update.
>>
>> On 4/6/2022 1:22 am, Frank Kuehndel wrote:
>>> From: Frank Kühndel <frank.kuehndel at embedded-brains.de>
>>>
>>> ---
>>>  filesystem/index.rst       |   1 +
>>>  filesystem/trivial_ftp.rst | 638 ++++++++++++++++++++++++++++++++++++-
>>>  2 files changed, 636 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/filesystem/index.rst b/filesystem/index.rst
>>> index f4e2ed6..64a2f1d 100644
>>> --- a/filesystem/index.rst
>>> +++ b/filesystem/index.rst
>>> @@ -9,6 +9,7 @@ RTEMS Filesystem Design Guide (|version|).
>>>  .. topic:: Copyrights and License
>>>
>>>      | |copy| 1988, 2015 On-Line Applications Research Corporation (OAR)
>>> +    | |copy| 2022 embedded brains GmbH (http://www.embedded-brains.de)
>>>
>>>      .. include:: ../common/license.rst
>>>
>>> diff --git a/filesystem/trivial_ftp.rst b/filesystem/trivial_ftp.rst
>>> index e43c036..f5940c6 100644
>>> --- a/filesystem/trivial_ftp.rst
>>> +++ b/filesystem/trivial_ftp.rst
>>> @@ -3,7 +3,639 @@
>>>  Trivial FTP Client Filesystem
>>>  *****************************
>>>
>>> -This chapter describes the Trivial FTP (TFTP) Client Filesystem.
>>> +This chapter describes the Trivial File Transfer Protocol (TFTP) Client
>>> +Filesystem.  TFTP is designed to be an especially simple protocol which
>>> +uses the User Datagram Protocol (UDP) for data transfer over the
>> Internet.
>>> +Its purpose is to send a single file between to network nodes (client
>> and
>>> +server).  A file can be sent in both directions, i.e. a client can
>> either
>>> +read a file from a server or write a file to the server.
>>>
>>> -This chapter should be written after the IMFS chapter is completed and
>> describe
>>> -the implementation of the TFTP.
>>> +Besides reading or writing a file no other operations are supported.
>> That
>>> +is, one cannot seek the file, not append to the end of a file, not open
>>> +the file for reading and writing at the same time, not list directories,
>>> +not move files and so on.
>>> +
>>> +TFTP is inherent insecure as it does not provide any means for
>>> +authentication or encryption.  Therefore, it cannot be used over the
>> public
>>> +Internet.
>> Recommended or highly recommended to not be used on public networks?

Ok. I change it to "highly recommended".

>>
>>> Nevertheless, it is still widely used to load software and
>>> +configuration data during early boot stages over a Local Area Network
>>> +(LAN).
>> With regard to security the TFTP port is secure and so the server runs as
>> root.
>> In rtems-tools there is a TFTP proxy to provide a central instance that can
>> proxy sessions out to other machines on a network at any port, ie ones
>> that a
>> user can connect with. This works with the rtems-tftp-server also included
>> in
>> rtems-tools. The rtems-tftp-server (and proxy) and in Python so should be
>> portable.

I did not try this server. It seems not to support the windowsize option
anyway.

>>
>>> +
>>> +RTEMS TFTP Filesystem Implementation
>>> +====================================
>>> +
>>> +The RTEMS TFTP filesystem implements a TFTP client which can be used
>>> +through the file system.  With other words, one needs to mount the
>>> +TFTP filesystem and can afterwards open a file for reading or writing
>>> +below that mount point.  The content of that file is then effectively
>>> +read from or written to the remote server.  The RTEMS implementation
>>> +implements the following features:
>>> +
>>> +* RFC 1350 *The TFTP Protocol (Revision 2)*
>>> +* RFC 2347 *TFTP Option Extension*
>>> +* RFC 2348 *TFTP Blocksize Option*
>>> +* RFC 7440 *TFTP Windowsize Option*
>>
> Would you kindly put the URLs for these in?

OK. I add the URLs as links.
> 
> 
>>> +Many simple TFTP server do not support options (RFC 2347). Therefore, in
>>> +case the server rejects the first request with options, the RTEMS client
>>> +makes automatically a second attempt using only the "classical" RFC
>> 1350.
>>> +
>>> +The implementation has the following shortcomings:
>>> +
>>> +* IPv6 is not supported (yet).
>>> +
>>> +* No congestion control is implemented.
>>> +
>>> +  (Congestion is simply expressed a network traffic jam which involves
>>> +  package loss.)  This implementation would worsen a congestion
>> situation
>>> +  and squeeze out TCP connections.  If that is a concern in your setup,
>>> +  it can be prevented by using value `1` as `windowsize`.
>> Where is this set, the server or the client?

OK. I change the text a bit.

Basically, all options are requested by the client. The server only
confirms those suggested options it supports. Therefore, setting
`windowsize` to 1 is only possible at the client side. Yet, most TFTP
servers do not support this option at all. In case yours does, it has
usually a configuration which permits disabling the `windowsize` option.
 This has the same effect as setting it 1 at the client side.

>>
>>> +
>>> +* One must call ``open()``, ``read()``, ``write()`` and ``close()``
>>> +  at a good pace.
>>> +
>>> +  TFTP uses timeouts (of unspecified length).
>> What about the option (RFC2437) to allow a timeout to be exchanged? The
>> rtems-tools supports proxing of this option.

Support of RFC2437 was not requested and is hence not implemented.

If it does what I think it does, then I would permit the user to request
an large timeout from the server. If the server would agree to this
larger timeout, it will permit the end user code to "idle a while
around" between read()/write() calls.

I doupt this is a frequent scenario. Hence it it not worth the trouble
implementing it (beside that I will not permitted time to implement it).

Moreover, increasing the timeout means also to slow down the data
transfer significantly as soon as critical packets get lost.

I added this paragraph to make the programmer aware of the fact that the
file must be read or written in more or less a "tight loop". For
example, open and writing a file at the beginning of an application but
closing it at the end of the application is not a good idea.
>>
>>> It does not know keep-alive
>>> +  messages.  If the client does not respond to the server in due time,
>>> +  the server sets the connection faulty and drops it.  To avoid this,
>>> +  the user must read or write enough data fast enough.
>> Servers can retry by sending the same packet again?

The RFC do not know any keep-alive procedure. You can invent some saying
"the serve send the last packet and the client should respond with an
old packet to keep the session alive". Yet, this is not RFC conform.

The idea of TFTP is that the client reads or write one file in a single
go. TFTP cannot be use for applications like writing a log file where
five minutes no line is written to the log. If you have such an
application, I would suggest not to use TFTP in the first place instead
of extending the TFTP protocol.

This whole topic with the end user shall read/write the file fast, does
impact our implementation because it is not a client application but a
file system where the user could potentially idle around before
providing are reading the next chunk of data. A true client application
reads or writes the file in the speed the server needs.
>>
>>> +  "Enough data" means at least so much data which fills a single data
>>> +  package or all packages of a window if windows are used.  The data
>>> +  can be read or written in anything from one single large chunk to
>>> +  byte-by-byte pieces.  The point is, one cannot pause the reading
>>> +  or writing for longer periods of time.
>> Can packets vary the data size in a sequence of packets? I thought doing
>> that
>> signalled the end of the transmission? May be I am not understanding this
>> paragraph?

You are right. The end of transfer is signaled by an not "full" DATA packet.

I confess the issue is difficult to exress in a few words - or maybe I
fail to express the concept. I will give it a second try and reformulate
the paragraphs.

>>> +
>>> +* The transfer mode is always ``octet``.  The only alternative
>>> +  ``netascii`` cannot be selected.
>>> +
>>> +* Block number roll-over is currently not supported.  Therefore,
>>> +  the maximum file size is limited to max-block-number times blocksize.
>>> +  For RFC 1350 blocksize is would be 65535 * 512 = 32 MB.  For the
>>> +  default blocksize is would be 65535 * 1456 = 90 MB.
>>> +
>>> +* The inherent insecurity of the protocol has already be mentioned but
>>> +  it is worth repeating.
>>> +
>>> +Prerequisites
>>> +=============
>>> +
>>> +To use the RTEMS TFTP filesystem one needs:
>>> +
>>> +* The RTEMS tools (cross-compiler, linker, debugger etc.) compiled
>>> +  for the target architecture and installed at a prefix
>>> +* The RTEMS Board Support Package (BSP) compiled for the
>>> +  target board and installed at the same prefix
>>> +* The RTEMS libbsd compiled to match the BSP and installed at the same
>>> +  prefix
>> A prefix can vary. These items are already detailed in the user manual so
>> would
>> it make more sense to mention looking there rather than detailing it again
>> here?

OK. I reduce the list to the essence and point to the user manual.
>>
>>> +
>>> +Note, this text does not cover RTEMS legacy networking because it is
>>> +outdated.
>> Depreciated for new works?
>>
> It shouldn't matter for the purposes of discussing the user facing TFTPFS
> capabilities. It worked with the legacy stack and has not been used at all
> with lwip.
> 
> It needs a network stack to operate and you have to build one to be able
> to link this into your application. That's all I'd be prone to just say.
> Anything
> else is volatile.
> 
> Plus adding references to the legacy stack is just begging for us to delete
> them later. :)
> 
OK. I remove the sentence.
> 
>>> +
>>> +As an example the ARM architecture and a xilinx_zynq_a9 BSP is used
>> below.
>>> +The instructions are tested with RTEMS version 6.  It is
>>> +recommended to actually use ``arm/xilinx_zynq_a9_qemu`` for the first
>>> +experiments as other BSPs tend to require different configuration values
>>> +and/or command line options.
>>> +
>>> +Moreover, it is recommended to first execute any code using QEMU as
>>> +simulator so that no hardware is needed.  Therefore, ``qemu-system-arm``
>>> +must be installed.  In Linux distributions this executable is usually
>>> +available in the repositories as package ``qemu-arm``.
>>> +
>>> +RTEMS Tools
>>> +-----------
>>> +
>>> +Instructions on how to obtain, compile and install the RTEMS tools can
>>> +be found in the *RTEMS User Manual* chapter `2. Quick Start
>>> +<https://docs.rtems.org/branches/master/user/start/index.html>`_.
>> Sorry, no links like this in the documentation. It breaks release branches.
>>

OK. I remove all links but add the ones to the RFCs as requested above.

>>> To
>>> +follow the suggested example ``6/rtems-arm`` should be used as
>>> +target architecture argument of the ``../source-builder/sb-set-builder``
>>> +command.
>>> +
>>> +RTEMS Board Support Package
>>> +---------------------------
>>> +
>>> +Instructions on how to obtain, compile and install a BSP can be found
>>> +in the *RTEMS User Manual* section `Build a Board Support Package (BSP)
>>> +<https://docs.rtems.org/branches/master/user/start/bsp-build.html>`_.
>> Same here.

OK.
>>
>>> +The bsp-option should have the following value to match the example BSP:
>>> +
>>> +.. code-block:: none
>>> +
>>> +  --rtems-bsps=arm/xilinx_zynq_a9_qemu
>>> +
>>> +The POSIX API must be enabled, e.g. in ``config.ini``:
>>> +``RTEMS_POSIX_API = True``.  Enabling tests and debug is recommended:
>>> +``BUILD_TESTS = True`` and ``RTEMS_DEBUG = True``.  It is mandatory that
>>> +RTEMS legacy networking is disabled when use of libbsd is intended
>>> +(``RTEMS_NETWORKING`` must be ``False``).
>> I see this as out of scope for the TFTP file system.
>>
> 
> +1 This should document the TFTPFS capabilities and usage. How to build
> a BSP to use it just means you build with a network stack.

OK. I remove this paragraph then.

> 
> I also question why you say RTEMS_POSIX_API needs to be True. That
> does not enable much anymore. I only know of signals and the Sporadic
> Scheduler.
> 
Because when I build libbsd without RTEMS_POSIX_API, I get this error:

RTEMS kernel POSIX support is disabled; configure RTEMS with --enable-posix
(complete log in /home/EB/frank_k/src/rtems-libbsd/build/config.log)

The TFTP FS and test suite do compile and work without RTEMS_POSIX_API
set true.

> 
>>> +
>>> +RTEMS libbsd
>>> +------------
>>> +
>>> +Instructions on how to obtain, compile and install RTEMS libbsd can be
>>> +found in the `README.rst
>>> +<https://git.rtems.org/rtems-libbsd/tree/README.rst>`_
>> Not sure about this link as well.

OK. I remove it.

>>
>>> +of the ``rtems-libbsd`` GIT repository:
>>> +``git://git.rtems.org/rtems-libbsd.git``
>> <http://git.rtems.org/rtems-libbsd.git>.
>>> +Make sure to compile and install libbsd for the correct RTEMS version
>>> +(here ``6``).  The default build set
>> (``--buildset=buildset/default.ini``)
>>> +does suffice and as BSP ``--rtems-bsp=arm/xilinx_zynq_a9_qemu`` is
>>> +to be used in the ``waf configure`` command.
>>> +
>>> +RTEMS Configuration
>>> +-------------------
>>> +
>>> +To make the TFTP filesystem available to the application and have it
>>> +initialized, the macro ``CONFIGURE_FILESYSTEM_TFTPFS`` must be defined
>>> +when configuring RTEMS (typically in the ``init.c`` file).  In addition
>>> +the value for ``CONFIGURE_MAXIMUM_FILE_DESCRIPTORS`` must be increased:
>>> +
>>> +.. code-block:: c
>>> +
>>> +  #define CONFIGURE_FILESYSTEM_TFTPFS
>>> +  #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 64
>> Mentioning the TFTPFS configure option is OK.
> Everything else is more appropriate for an example. FWIW I really
> want a collection of network examples that are independent of any
> network stack. When configured, you'd specify your BSP and some
> network initialization support. By default, you could have localhost
> and DHCP but anything else (real NIC or static IP) would require
> BSP specific knowledge.

OK. I remove the CONFIGURE_MAXIMUM_FILE_DESCRIPTORS but I will keep the
example below.
> 
> 
>>> +Moreover, libbsd and RTEMS must be configured appropriately as well.
>>> +For orientation, the code below is from an application using TFTP FS
>>> +(file ``tftp_init.c``).
>>> +
>>> +.. code-block:: c
>>> +
>>> +  /* Configure libbsd. */
>>> +  #define RTEMS_BSD_CONFIG_NET_PF_UNIX
>>> +  #define RTEMS_BSD_CONFIG_NET_IF_BRIDGE
>>> +  #define RTEMS_BSD_CONFIG_NET_IF_LAGG
>>> +  #define RTEMS_BSD_CONFIG_NET_IF_VLAN
>>> +  #define RTEMS_BSD_CONFIG_BSP_CONFIG
>>> +  #define RTEMS_BSD_CONFIG_INIT
>>> +
>>> +  #include <machine/rtems-bsd-config.h>
>>> +
>>> +  /* RTEMS configuration for libbsd */
>>> +  #define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
>>> +  #define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024)
>>> +  #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
>>> +  #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
>>> +  #define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
>>> +
>>> +  /* RTEMS configuration for tftp */
>>> +  #define CONFIGURE_FILESYSTEM_TFTPFS
>>> +  #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 64
>>> +
>>> +  /* Simple RTEMS configuration */
>>> +  #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
>>> +  #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
>>> +  #define CONFIGURE_UNLIMITED_OBJECTS
>>> +  #define CONFIGURE_UNIFIED_WORK_AREAS
>>> +  #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
>>> +  #define CONFIGURE_INIT
>>> +
>>> +  #include <rtems/confdefs.h>
>>> +
>>> +Application Linkage
>>> +-------------------
>>> +
>>> +The TFTP filesystem is compiled and linked into ``libtftpfs``.  After
>>> +installation it should be in a place like:
>>> +
>>> +.. code-block:: none
>>> +
>>> +  <PREFIX>/arm-rtems6/xilinx_zynq_a9_qemu/lib/libtftpfs.a
>>> +
>>> +An RTEMS application which wants to use the TFTP filesystem must be
>> linked
>>> +with the libraries ``libtftpfs``, ``libbsd``, and ``libm`` --- in this
>> order.
>>> +An example build target in a ``wscript`` for use with the RTEMS WAF
>> build
>>> +system could be:
>>> +
>>> +.. code-block:: python
>>> +
>>> +  def build(ctx):
>>> +      rtems.build(ctx)
>>> +      ctx(features = 'c cprogram',
>>> +          target = 'tftp_app.exe',
>>> +          cflags = '-g -O2',
>>> +          source = ['tftp_app.c', 'tftp_init.c'],
>>> +          lib    = ['tftpfs', 'bsd', 'm'])
>>> +
>>> +Network Configuration and TFTP Server
>>> +-------------------------------------
>>> +
>>> +QEMU has a simple build-in TFTP server which can serve files for reading
>>> +only.  By default it is reachable from the application executed by QEMU
>>> +at IP address ``10.0.2.2`` if SLIRP networking is used.  For the
>>> +example ``arm/xilinx_zynq_a9_qemu`` BSP, the QEMU option
>>> +
>>> +.. code-block:: none
>>> +
>>> +  -nic user,model=cadence_gem,tftp=/tmp
>>> +
>>> +will cause this TFTP server to deliver files found below directory
>>> +``/tmp``.  Note that SLIRP requires that the application uses DHCP.
>>> +
>>> +Alternatively, it is of course possible to use other kinds of QEMU
>>> +networking (as for example the TAP virtual Ethernet interface described
>>> +in the above mentioned
>>> +`README.rst <https://git.rtems.org/rtems-libbsd/tree/README.rst>`_
>>> +in section *Qemu and Networking*).
>> Thanks for the references here. It is hard to document how to use qemu and
>> then
>> remain generic for all the hosts we support. For example I use vdewsitch
>> with qemu.
>>
>> I am not sure about the the link to libbsd's README because a release
>> needs that
>> documentation not vary in time but I do not have a better solution.

I remove all links to README.rst. So, I remove this one, too - at least
to be consitent.

>>
>> Can the following be sectioned as a specific example for Linux on OpenSUSE
>> so it
>> is clear there can be differences?

Of course.
>>
>>> Also an external TFTP
>>> +server can be used.  The code was tested with ``atftp`` compiled
>>> +from the `sources <https://sourceforge.net/projects/atftp/>`_.  On
>>> +an OpenSUSE 15.3 machine, the following commands sets up ``atftp``
>>> +for use with the mentioned TAP interface (these commands must be
>> executed
>>> +as root; ``<APP-USER>`` must be replaced by the name of the "normal"
>>> +user starting the RTEMS application in QEMU later on; for other
>>> +distributions the ``firewall-cmd`` commands must be
>>> +replaced by the equivalent of that distribution):
>>> +
>>> +.. code-block:: shell
>>> +
>>> +  # Create and configure TAP interface
>>> +  ip tuntap add qtap mode tap user <APP-USER>
>>> +  ip link set dev qtap up
>>> +  ip addr add 169.254.1.1/16 dev qtap
>>> +
>>> +  # Open firewalld as non-permanent configuration
>>> +  firewall-cmd --zone=home --add-service=tftp
>>> +  firewall-cmd --zone=home --add-interface=qtap
>>> +
>>> +  # Start TFTP daemon
>>> +  touch /var/log/atftpd/atftp.log
>>> +  chown tftp.tftp /var/log/atftpd/atftp.log
>>> +  atftpd --user tftp --group tftp --daemon --verbose \
>>> +      --logfile /var/log/atftpd/atftp.log /srv/tftpboot
>>> +
>>> +The ``atftp`` server will then be reachable from an application executed
>>> +by QEMU at the address of the TAP interface which is in this case
>>> +``169.254.1.1``.  Note, the IP address in the example code below must
>>> +be changed to the one at which the TFTP server is actually reachable
>>> +from the application running in QEMU.  When used with this TAP
>> interface,
>>> +the QEMU network option must be changed to (replacing the ``-net``
>> options
>>> +in the examples found in the already mentioned `README.rst
>>> +<https://git.rtems.org/rtems-libbsd/tree/README.rst>`_):
>> Links!

OK.

>>
>>> +
>>> +.. code-block:: none
>>> +
>>> +   -nic tap,model=cadence_gem,ifname=qtap,script=no,downscript=no
>>> +
>>> +Usage
>>> +=====
>>> +
>>> +The following diagram shows how the TFTP filesystem is used by an
>>> +application.  The mount point can be any directory.  The name ``/tftp``
>>> +used in the figure serves only as an example.  The final unmounting and
>>> +remove directory steps are optional.
>>> +
>>> +.. figure:: ../images/filesystem/tftpfs_usage.png
>>> +  :width: 90%
>>> +  :align: center
>>> +  :alt: TFTP Usage Diagram
>>> +
>>> +Mounting the TFTP Filesystem
>>> +----------------------------
>>> +
>>> +When mounting the TFTP filesystem, the argument ``filesystemtype`` must
>>> +be ``RTEMS_FILESYSTEM_TYPE_TFTPFS`` (``#include <rtems/libio.h>``).
>>> +
>>> +The argument ``data`` can either be
>>> +
>>> +* a 0-terminated C string of comma separated mount options or
>>> +* ``NULL`` for mounting with default values.
>>> +
>>> +The mount options are case sensitive.  Spaces are not allowed in the
>> string.
>>> +If conflicting options are specified, the ones more to the right (i.e.
>> end
>>> +of the string) take precedence.  These mount options are supported:
>>> +
>>> +``blocksize=N``
>>> +  where ``N`` is a decimal integer number.
>>> +
>>> +  The TFTP blocksize option is introduced in RFC 2348.  It defines the
>>> +  number of octets in the data packages transferred.  Valid values
>>> +  range between 8 and 65464 octets, inclusive.  Values larger
>>> +  than 1468 may cause package fragmentation over standard Ethernet.
>>> +  A value of 512 will prevent this option from being sent to
>>> +  the server.
>>> +
>>> +  The default value is 1456.
>>> +
>>> +``windowsize=N``
>>> +  where ``N`` is a decimal integer number.
>>> +
>>> +  The TFTP windowsize option is introduced in RFC 7440.  It defines the
>>> +  number of data packages send before the receiver must send an
>>> +  acknowledgment package.  Valid values range between 1 and 65535
>>> +  packages, inclusive.  Simple TFTP servers usually do not support this
>>> +  option.  This option may negatively contribute to network
>>> +  congestion.  This can be avoided by using a window size of 1.
>>> +  A value of 1 will prevent this option from being sent to
>>> +  the server.
>>> +
>>> +  The default value is 8.
>>> +
>>> +``rfc1350``
>>> +  The TFTP client should strictly follow RFC 1350 and not send any
>>> +  options to the server.  Many simple TFTP server do still not support
>>> +  the option extension defined in RFC 2347.  The TFTP filesystem will
>>> +  always make a second option-less connection attempt to the TFTP server
>>> +  in case a first attempt with options was rejected with an error
>> message.
>>> +
>>> +  This option is equivalent to ``blocksize=512,windowsize=1``.
>>> +
>>> +``verbose``
>>> +  During operation, print messages to ``stdout``.  This option has
>>> +  currently little effect.  It is kept to be compatible to older
>>> +  implementations.
>>> +
>>> +Opening a File
>>> +--------------
>>> +
>>> +Files must be opened by using either ``O_RDONLY`` or ``O_WRONLY``
>>> +as flags but not both.  Other flags are not supported.
>>> +
>>> +The ``pathname`` argument to ``open()`` has the following format:
>>> +
>>> +.. code-block:: none
>>> +
>>> +  <PREFIX>/<server-address>:<path-on-server>
>>> +
>>> +``<PREFIX>``
>>> +  The path to the point where the TFTP filesystem is mounted.  This can
>>> +  be a relative path from the current working directory or an absolute
>>> +  path.
>>> +
>>> +``<server-address>``
>>> +  The network address for the TFTP server from which to download the
>>> +  file or to which the file should be sent.  This is either
>>> +
>>> +    * an IPv4 address (like `127.0.0.1`) or
>>> +    * the (full-qualified) name of an IPv4 host (acceptable to
>>> +      ``gethostbyname()``)
>>> +
>>> +  The port number cannot be specified and will always be the one
>> reserved
>>> +  for TFTP: 69.
>>> +
>>> +``<path-on-server>``
>>> +  The path and file name at which the TFTP server will find or create
>> the
>>> +  file.  Any directories in this path must already exist.  It is not
>>> +  possible to create or read directories with TFTP.  RFC 1350 specifies
>>> +  that this ``<path-on-server>`` must be in *netascii*:
>>> +
>>> +      This is ascii as defined in "USA Standard Code for Information
>>> +      Interchange" [1] with the modifications specified in "Telnet
>>> +      Protocol Specification" [3].
>>> +
>>> +      [1] USA Standard Code for Information Interchange, USASI
>> X3.4-1968.
>>> +
>>> +      [3] Postel, J., "Telnet Protocol Specification," RFC 764,
>>> +      USC/Information Sciences Institute, June, 1980.
>>> +
>>> +Example pathnames:
>>> +
>>> +.. code-block:: c
>>> +
>>> +  "/tftp/169.254.1.1:file.txt"
>>> +  "/TFTPFS/tftp-server.sample.org:bootfiles/image"
>>> +
>>> +In the above examples, ``/tftp`` and ``/TFTPFS`` are the directory at
>> which
>>> +the TFTP filesystem is mounted.  ``169.254.1.1`` and
>>> +``tftp-server.sample.org`` are the network address of the TFTP server
>> to
>>> +contact.  ``file.txt`` and ``bootfiles/image`` are the file name and
>>> +the path at the server side.
>>> +
>>> +Closing a File
>>> +--------------
>>> +
>>> +Especially, when writing a file to the server, the return
>>> +code of ``close()`` should be checked.  Invoking ``close()`` triggers
>>> +the sending of the last -- not completely filled -- data block.  This
>>> +may fail the same way as any ``write()`` may fail.  Therefore, an error
>>> +returned by ``close()`` likely indicates that the file was not
>> completely
>>> +transferred.
>>> +
>>> +Use From Shell
>>> +==============
>>> +
>>> +It is possible to use the RTEMS shell through test ``media01`` of
>>> +libbsd to exercise the TFTP filesystem.  This text assumes that libbsd
>>> +has already been setup, configured, compiled and installed as described
>>> +in the `README.rst <https://git.rtems.org/rtems-libbsd/tree/README.rst
>>> `_.
>>> +How the test ``media01.exe`` can be executed is described in
>>> +section *Qemu and Networking* of that file.
>>> +
>>> +A TFTP server must be setup and run.  The instructions to setup the TAP
>>> +device and the ``atftp`` server found above in section *Network
>>> +Configuration and TFTP Server* could be followed for this purpose.
>>> +It may be useful to create a sample file for later download in the
>>> +directory served by the TFTP server.  For ``atftp`` "root" could create
>>> +a file with these instructions:
>>> +
>>> +.. code-block:: shell
>>> +
>>> +  # echo "Hello World!" >/srv/tftpboot/hello.txt
>>> +  # chown tftp.tftp /srv/tftpboot/hello.txt
>>> +
>>> +Start the ``media01`` test in one terminal --- as "normal" user:
>>> +
>>> +.. code-block:: shell
>>> +
>>> +  $ qemu-system-arm -serial null -serial mon:stdio -nographic \
>>> +    -M xilinx-zynq-a9 -m 256M \
>>> +    -nic
>> tap,model=cadence_gem,mac=0e:b0:ba:5e:00:01,ifname=qtap,script=no,downscript=no
>> \
>>> +    -kernel build/arm-rtems6-xilinx_zynq_a9_qemu-default/media01.exe
>>> +
>>> +Wait till a line like the following is printed in the terminal:
>>> +
>>> +.. code-block:: none
>>> +
>>> +  info: cgem0: using IPv4LL address 169.254.191.13
>>> +
>>> +Next use the displayed IP address to open a telnet connection in a
>> second terminal:
>>> +
>>> +.. code-block:: shell
>>> +
>>> +  $ telnet 169.254.191.13
>>> +
>>> +At the telnet prompt, enter this command to list the filesystems
>>> +available for mounting:
>>> +
>>> +.. code-block:: none
>>> +
>>> +  TLNT [/] # mount -L
>>> +  File systems: / dosfs tftpfs
>>> +
>>> +``tftpfs`` should be among them.  Create a directory and mount the TFTP
>>> +filesystem:
>>> +
>>> +.. code-block:: none
>>> +
>>> +  TLNT [/] # mkdir /tftp
>>> +  TLNT [/] # mount -t tftpfs -o verbose "" /tftp
>>> +  mounted  -> /tftp
>>> +
>>> +Now, files can be sent to and read from the TFTP server using the usual
>>> +shell commands:
>>> +
>>> +.. code-block:: none
>>> +
>>> +  TLNT [/] # cp /etc/dhcpcd.duid /tftp/169.254.1.1:dhcpcd.duid
>>> +  TFTPFS: /169.254.1.1:dhcpcd.duid
>>> +  TLNT [/] # cat /tftp/169.254.1.1:hello.txt
>>> +  TFTPFS: /169.254.1.1:hello.txt
>>> +  Hello World!
>>> +
>>> +The terminal session can be terminated with key combination "CTRL-]"
>>> +followed by a ``quit`` command; the
>>> +QEMU simulation with "CTRL-a x" and ``tail -f`` with "CTRL-c".
>>> +
>>> +TFTP Client API
>>> +===============
>>> +
>>> +The TFTP filesystem has a TFTP client which is responsible to handle all
>>> +network traffic.  It permits the use of TFTP without filesystem.
>>> +Essentially, one saves the mounting of the filesystem.  Otherwise the
>>> +usage is similar to the one of the filesystem.  The equivalent of the
>>> +``open()``, ``read()``, ``write()``, and ``close()`` functions are:
>>> +
>>> +.. code-block:: c
>>> +
>>> +  int tftp_open(
>>> +    const char *hostname,
>>> +    const char *path,
>>> +    bool is_for_reading,
>>> +    const tftp_net_config *config,
>>> +    void **tftp_handle
>>> +  );
>>> +
>>> +  ssize_t tftp_read( void *tftp_handle, void *buffer, size_t count );
>>> +
>>> +  ssize_t tftp_write( void *tftp_handle, const void *buffer, size_t
>> count );
>>> +
>>> +  int tftp_close( void *tftp_handle );
>>> +
>>> +``tftp_open()`` accepts as input a data structure of type
>>> +``tftp_net_config``.  It can be used to specify certain values governing
>>> +the file transfer such as the already described options.  Data of
>>> +``tftp_net_config`` type can be initialized using function
>>> +
>>> +.. code-block:: c
>>> +
>>> +  void tftp_initialize_net_config( tftp_net_config *config );
>>> +
>>> +The full description can be found in the file
>> ``cpukit/include/rtems/tftp.h``.
>>> +The function ``rtems_tftpfs_initialize()`` found there is only for RTEMS
>>> +internal use by the ``mount()`` function.
>>> +
>>> +Software Design
>>> +===============
>>> +
>>> +The original source code contained only the files
>>> +``cpukit/include/rtems/tftp.h`` and
>> ``cpukit/libfs/src/ftpfs/tftpDriver.c``.
>>> +There was no test suite nor any documentation.
>>> +
>>> +When the code was extended to support options (RFC 2347 and others),
>>> +the code in ``tftpDriver.c`` was split.  The new file ``tftpfs.c`` is
>>> +responsible to handle all filesystem related issues while
>> ``tftpDriver.c``
>>> +provides the network related functions.  In effect ``tftpDriver.c`` is
>>> +a TFTP client library which can be used independently of the filesystem.
>>> +``tftpfs.c`` calls the functions of ``tftpDriver.c`` to do the actual
>>> +TFTP file transfer.
>>> +
>>> +At this occasion a test suite and this documentation in the *RTEMS
>>> +Filesystem Design Guide* was added.
>>> +
>>> +Test Suite
>>> +----------
>>> +
>>> +The TFTP filesystem comes with an extensive test suite.
>>> +
>>> +``libtftpfs`` source code is situated in the RTEMS repository.  For
>>> +testing it, either ``libbsd`` or RTEMS legacy networking would have been
>>> +required.  This implies that the tests for ``libtftpfs`` would have
>>> +needed to be placed in the ``libbsd`` repository --- a different one
>>> +than the ``libtftpfs`` source code.
>>> +
>>> +Yet, ``libtftpfs`` uses only a handful of networking functions.  The
>>> +test suite provides fake implementations of those functions.  These fake
>>> +functions permit to simulate the exchange of UDP packages
>>> +with the ``libtftpfs`` code and thus permits testing the TFTP filesystem
>>> +without the need of a full network stack.
>>> +
>>> +Consequently, the test suite is placed in the RTEMS repository together
>>> +with the TFTP filesystem source code.  Neither ``libbsd`` nor RTEMS
>>> +legacy networking is required to run the tests.
>>> +
>>> +The test suite can be executed using the ``rtems-test`` tool:
>>> +
>>> +.. code-block:: shell
>>> +
>>> +  $ cd <path-to-rtems-git-worktree>
>>> +  $ rtems-test --log-mode=all --rtems-bsp=xilinx_zynq_a9_qemu \
>>> +    build/arm/xilinx_zynq_a9_qemu/testsuites/fstests/tftpfs.exe
>>> +
>>> +TFTP Files in the ``rtems-docs`` GIT
>>> +------------------------------------
>>> +
>>> +``filesystem/trivial_ftp.rst``
>>> +  The file contains the text of chapter *Trivial FTP Client Filesystem*
>>> +  in the *RTEMS Filesystem Design Guide*.
>>> +
>>> +``images/filesystem/*``
>>> +  These graphic files contain the diagrams used in chapter *Trivial FTP
>>> +  Client Filesystem* in the *RTEMS Filesystem Design Guide*.
>>> +
>>> +TFTP Files in the ``rtems`` GIT
>>> +-------------------------------
>> Is this something want here? Would this be better in a README in the
>> source repo?

OK. I remove the file lists.

>>
>> Again thanks
>> Chris
>>

Many thanks for the review.

Greetings
frank

>>> +
>>> +``cpukit/include/rtems/tftp.h``
>>> +  This file declares the public constants, structures, and functions of
>>> +  the Trivial File Transfer Protocol (TFTP) file system.
>>> +
>>> +``cpukit/libfs/src/ftpfs/tftpDriver.c``
>>> +  This source file contains the implementation of a Trivial File
>> Transfer
>>> +  Protocol (TFTP) client library --- the network related part of the
>> code.
>>> +
>>> +``cpukit/libfs/src/ftpfs/tftp_driver.h``
>>> +  This file declares private functions of the Trivial File Transfer
>>> +  Protocol (TFTP) client library.
>>> +
>>> +``cpukit/libfs/src/ftpfs/tftpfs.c``
>>> +  This source file contains the implementation of the Trivial File
>> Transfer
>>> +  Protocol (TFTP) filesystem.  The code in this file handles the file
>> system
>>> +  operations (such as ``mount()``, ``open()``, ``read()``, ``write()``,
>>> +  ``close()`` etc.).
>>> +
>>> +``spec/build/cpukit/libtftpfs.yml``
>>> +  This file specifies how the RTEMS WAF build system has to compile,
>> link
>>> +  and install ``libtftpfs``.
>>> +
>>> +``spec/build/testsuites/fstests/grp.yml``
>>> +  This file specifies how the RTEMS WAF build system has to compile,
>> link
>>> +  and install all filesystem test suites.  The TFTP test suite must
>>> +  be mentioned in this file to be build.
>>> +
>>> +``spec/build/testsuites/fstests/tftpfs.yml``
>>> +  This file specifies how the RTEMS WAF build system has to compile,
>> link
>>> +  and install the TFTP test suite.
>>> +
>>> +``testsuites/fstests/tftpfs/init.c``
>>> +  This source file contains the test suite with all tests for
>> ``libtftpfs``.
>>> +  The test suite uses functions from files ``tftpfs_interactions.c``
>> and ``tftpfs_udp_network_fake.c`` as private helpers.
>>> +
>>> +``testsuites/fstests/tftpfs/tftpfs_interactions.h``
>>> +  This header file provides definitions and declarations of data
>> structures
>>> +  and functions used to implement network interactions of the UDP
>> network
>>> +  fake for ``libtftpfs`` tests.
>>> +
>>> +``testsuites/fstests/tftpfs/tftpfs_interactions.c``
>>> +  This source file contains the implementation of network interaction
>>> +  functions related to the UDP network fake for ``libtftpfs`` tests.
>>> +
>>> +``testsuites/fstests/tftpfs/tftpfs_udp_network_fake.h``
>>> +  This header file provides definitions and declarations of data
>> structures
>>> +  and functions used to implement the UDP network fake for ``libtftpfs``
>>> +  tests.
>>> +
>>> +``testsuites/fstests/tftpfs/tftpfs_udp_network_fake.c``
>>> +  This source file contains the implementation of UDP network fake
>>> +  functions related to ``libtftpfs`` testing.  This code provides fake
>>> +  implementations for functions like ``socket()``, ``bind()``,
>> ``sendto()``,
>>> +  ``recvfrom()``, etc. which would normally be provided by libbsd.
>> _______________________________________________
>> devel mailing list
>> devel at rtems.org
>> http://lists.rtems.org/mailman/listinfo/devel
> 

-- 
embedded brains GmbH
Herr Frank KÜHNDEL
Dornierstr. 4
82178 Puchheim
Germany
email: frank.kuehndel at embedded-brains.de
phone: +49-89-18 94 741 - 23
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/




More information about the devel mailing list