You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pr...@apache.org on 2020/09/04 23:02:42 UTC
[incubator-nuttx] 01/10: add sim and drivers guides,
contributing workflow
This is an automated email from the ASF dual-hosted git repository.
protobits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 56b89a89f20fb78490c945e4c9f582db8863ff17
Author: Adam Feuer <ad...@adamfeuer.com>
AuthorDate: Sun Aug 30 17:48:30 2020 -0700
add sim and drivers guides, contributing workflow
---
Documentation/contributing/coding_style.rst | 3 +
Documentation/contributing/index.rst | 1 +
Documentation/contributing/making-changes.rst | 256 ++++++++++++++++++++++++++
Documentation/guides/drivers.rst | 211 +++++++++++++++++++++
Documentation/guides/index.rst | 2 +
Documentation/guides/simulator.rst | 145 +++++++++++++++
6 files changed, 618 insertions(+)
diff --git a/Documentation/contributing/coding_style.rst b/Documentation/contributing/coding_style.rst
index 5f0aeda..d83910d 100644
--- a/Documentation/contributing/coding_style.rst
+++ b/Documentation/contributing/coding_style.rst
@@ -1,4 +1,7 @@
=================
+.. include:: /substitutions.rst
+.. _coding-standard:
+
C Coding Standard
=================
diff --git a/Documentation/contributing/index.rst b/Documentation/contributing/index.rst
index a69411b..b2428f0 100644
--- a/Documentation/contributing/index.rst
+++ b/Documentation/contributing/index.rst
@@ -8,6 +8,7 @@ and documentation (the one you are reading now):
:maxdepth: 2
workflow.rst
+ making-changes.rst
coding_style.rst
documentation.rst
diff --git a/Documentation/contributing/making-changes.rst b/Documentation/contributing/making-changes.rst
new file mode 100644
index 0000000..0c9c871
--- /dev/null
+++ b/Documentation/contributing/making-changes.rst
@@ -0,0 +1,256 @@
+.. include:: /substitutions.rst
+.. _making-changes:
+
+Making Changes
+==============
+
+If you want to make changes to NuttX, for your own personal use, or to submit them back to project to improve NuttX,
+that's easy. For the purposes of this guide, you'll need a `GitHub <https://www.github.com>`_ account, since
+the Apache NuttX team uses GitHub. (You could also use git locally, or save your changes to other sites like
+`GitLab <https://about.gitlab.com/>`_ or `BitBucket <https://bitbucket.org>`_, but that's beyond the scope of this
+guide).
+
+Here's how to do it:
+
+#. Set your git user name and email
+
+ .. code-block:: bash
+
+ $ cd nuttx/
+ $ git config --global user.name "Your Name"
+ $ git config --global user.email "yourname@somedomaincom"
+
+#. Sign in to GitHub
+
+ If you don't have a `GitHub <https://www.github.com>`_ account, it's free to
+ sign up.
+ |br|
+ |br|
+
+
+#. Fork the Project
+
+ Visit both these links and hit the Fork button in the upper right of the page:
+
+ * `NuttX <https://github.com/apache/incubator-nuttx/>`_
+ * `NuttX Apps <https://github.com/apache/incubator-nuttx-apps/>`_
+
+
+#. Change the Git Remotes
+
+ The git repositories in your project are currently connected to the official NuttX repositories, but you don't
+ have permission to push software there. But you can push them to your forks, and from there create Pull Requests
+ if you want to send them to the NuttX project.
+
+ First, remove the current remote, ``origin`` (we'll add it back later):
+
+ .. code-block:: bash
+
+ $ cd nuttx/
+ $ # display the remote
+ $ git remote -v
+
+ You should see something like this:
+
+ .. code-block:: bash
+
+ origin https://github.com/apache/incubator-nuttx.git
+
+ Now, on the GitHub web page for your forked ``incubator-nuttx`` project, copy the clone url – get it by hitting the
+ green ``Clone or Download`` button in the upper right. Then do this:
+
+ .. code-block:: bash
+
+ $ git remote rm origin
+ $ git remote add origin <your forked incubator-nuttx project clone url>
+ $ git remote add upstream https://github.com/apache/incubator-nuttx.git
+
+ Do the same for your forked ``incubator-nuttx-apps`` project:
+
+ .. code-block:: bash
+
+ $ cd ../apps
+ $ git remote rm origin
+ $ git remote add origin <your forked incubator-nuttx-apps project clone url>
+ $ git remote add upstream https://github.com/apache/incubator-nuttx-apps.git
+
+
+#. Create a Local Git Branch
+
+ Now you can create local git branches and push them to GitHub:
+
+ .. code-block:: bash
+
+ $ git checkout -b test/my-new-branch
+ $ git push
+
+
+Git Workflow With an Upstream Repository
+----------------------------------------
+
+The main NuttX git repository is called an "upstream" repository - this is because it's the main source of truth, and
+its changes flow downstream to people who've forked that repository, like us.
+
+Working with an upstream repo is a bit more complex, but it's worth it since you can submit fixes and features
+to the main NuttX repos. One of the things you need to do regularly is keep your local repo in sync
+with the upstream. I work with a local branch, make changes, pull new software from the upstream and merge it in,
+maybe doing that several times. Then when everything works, I get my branch ready to do a Pull Request. Here's how:
+
+#. Fetch upstream changes and merge into my local master:
+
+ .. code-block:: bash
+
+ $ git checkout master
+ $ git fetch upstream
+ $ git merge upstream/master
+ $ git push
+
+#. Merge my local master with my local branch:
+
+ .. code-block:: bash
+
+ $ git checkout my-local-branch
+ $ git merge master
+ $ git push
+
+#. Make changes and push them to my fork
+
+ .. code-block:: bash
+
+ $ vim my-file.c
+ $ git add my-file.c
+ $ git commit my-file.c
+ $ git push
+
+#. Repeat 1-3 as necessary
+
+#. Run the ``tools/checkpatch.sh`` script on your files
+
+ When your code runs, then you're almost ready to submit it. But first you need to check the code to ensure
+ that it conforms to the NuttX :ref:`contributing/coding_style:C Coding Standard`.
+ The ``tools/checkpatch.sh`` script will do that. Here's the usage info:
+
+ .. code-block:: bash
+
+ $ ./tools/checkpatch.sh -h
+ USAGE: ./tools/checkpatch.sh [options] [list|-]
+
+ Options:
+ -h
+ -c spell check with codespell(install with: pip install codespell
+ -r range check only (used with -p and -g)
+ -p <patch list> (default)
+ -g <commit list>
+ -f <file list>
+ - read standard input mainly used by git pre-commit hook as below:
+ git diff --cached | ./tools/checkpatch.sh -
+
+ Run it against your files and correct all the errors in the code you added, so that
+ ``tools/checkpatch.sh`` reports no errors. Then commit the result.
+ For example:
+
+ .. code-block:: bash
+
+ $ ./tools/checkpatch.sh -f my-file.c
+ arch/arm/src/sama5/hardware/my-file.c:876:82: warning: Long line found
+ $ # fix errors
+ $ vim my-file.c
+ $ # run again
+ $ ./tools/checkpatch.sh -f my-file.c
+
+ If you have made a lot of changes, you can also use this bash commandline to see the errors for all the changed C
+ files in your branch (assumes you are currently on the branch that has the changed files):
+
+ .. code-block:: bash
+
+ $ git diff --name-only master | egrep "\.c|\.h" | xargs echo | xargs ./tools/checkpatch.sh -f | less
+
+ Note that there are some bugs in the ``nxstyle`` program that ``checkpatch.sh`` uses, so
+ it may report a few errors that are not actually errors. The committers will help you
+ find these. (Or view the
+ `nxstyle Issues <https://github.com/apache/incubator-nuttx/issues?q=is%3Aissue+is%3Aopen+nxstyle>`_.)
+ |br|
+ |br|
+
+#. Commit the fixed files
+
+ .. code-block:: bash
+
+ $ git add my-file.c
+ $ git commit my-file.c
+ $ git push
+
+
+Submitting Your Changes to NuttX
+--------------------------------
+
+ Pull requests let you tell others about changes you've pushed to a branch in a repository on GitHub. Once a pull
+ request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits
+ before your changes are merged into the base branch.
+
+ (from GitHub's `About pull requests <https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests>`_ page)
+
+Before you do a Pull Request, the NuttX team will usually want all the changes you made in your branch "squashed" into
+a single commit, so that when they review your changes, there's a clean view of the history. If there are changes
+after Pull Request review feedback, they can be separate commits. Here's the easiest way I found to do that initial
+squash before submitting the Pull Request:
+
+#. Check out my branch
+
+ .. code-block:: bash
+
+ $ git checkout my-branch
+
+#. Rename it to ``my-branch-old`` to save it, because we're going to create new clean branch to push:
+
+ .. code-block:: bash
+
+ $ git branch -m my-branch-old
+
+#. Create a new clean branch with the same name you were using before the last step:
+
+ .. code-block:: bash
+
+ $ git checkout master
+ $ git checkout -b my-branch
+
+#. Merge your saved old branch into the new one, telling git to "squash" all your commits into one (note this will
+ not commit the result; the changed files will be in your staging area, ready to be committed):
+
+ .. code-block:: bash
+
+ $ git merge --squash my-branch-old
+
+#. Commit the result
+
+ .. code-block:: bash
+
+ $ git commit
+
+#. Force-push your new clean branch to the remote— this will overwrite all your previous changes in that branch:
+
+ .. code-block:: bash
+
+ $ git push -f --set-upstream origin my-branch
+
+#. Create a GitHub Pull Request
+
+ A Pull Request is how you ask your upstream to review and merge your changes.
+
+ Here's `GitHub's instructions for creating a Pull Request <https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request>`_.
+
+ |br|
+
+#. Get Pull Request feedback and implement changes
+
+ Get suggestions for improvements from reviewers, make changes, and push them to the branch. Once the reviewers are
+ happy, they may suggest squashing and merging again to make a single commit. In this case you would repeat steps
+ 1 through 6.
+
+Git Resources
+-------------
+
+* `Git Cheat Sheet (by GitHub) <https://github.github.com/training-kit/downloads/github-git-cheat-sheet.pdf>`_
+* `Git Book (online) <https://git-scm.com/book/en/v2>`_
+* `NuttX Code Contribution Workflow <https://cwiki.apache.org/confluence/display/NUTTX/Code+Contribution+Workflow>`_ –
+ All the details are here if you need them!
diff --git a/Documentation/guides/drivers.rst b/Documentation/guides/drivers.rst
new file mode 100644
index 0000000..86586cb
--- /dev/null
+++ b/Documentation/guides/drivers.rst
@@ -0,0 +1,211 @@
+.. include:: /substitutions.rst
+.. _drivers:
+
+Drivers
+=======
+
+Some NuttX boards don't have full support for all the on-chip peripherals. If you need support for this hardware,
+you will either need to port a driver from another chip, or write one yourself. This section discusses how to do that.
+
+Porting a Driver
+----------------
+
+Often support for on-chip peripherals exists in a closely related chip, or even a different family or from a different
+manufacturer. Many chips are made up of different Intellectual Property (IP) blocks that are licensed from vendors like
+Cadence, Synopsys, and others. The IP blocks may be similar enough to use another chip's driver with little
+modification.
+
+* Find a similar driver in NuttX source code:
+
+ * Look at register names listed in the datasheet for the peripheral.
+ * Search the NuttX codebase for the register names (try several different ones).
+ * Note that you'll have to compare the datasheet to the header and code files to see if there are differences; there
+ will usually be some differences between architectures, and they can be significant.
+
+* Find a similar driver in U-Boot source code:
+
+ * Only for inspiration, you can't copy code because of license incompatibility.
+ * But you can debug to see how the driver works.
+ * `U-Boot <https://www.denx.de/wiki/U-Boot>`_ drivers are often easier to understand than BSD Unix drivers because
+ U-Boot is simpler.
+
+* Find a similar driver in Zephyr or BSD Unix (OpenBSD, FreeBSD, NetBSD):
+
+ * If you find one, you can borrow code directly (Apache 2.0 and BSD licenses are compatible).
+
+* Understanding how the driver works
+
+ Here are a couple of techniques that helped me.
+
+ * printf debugging
+
+ * Sprinkle ``custinfo()`` logging statements through your code to see execution paths and look at variables
+ while the code is running. The reason to use ``custinfo()`` as opposed to the other logging shortcuts
+ (``mcinfo()``, etc.) is that you can turn on and off other other logging and still see your custom debug
+ logging. Sometimes it's useful to quiet the flood of logging that comes from a particular debug logging
+ shortcut.
+ * Note that printing info to the console will affect timing.
+ * Keep a file with just your debug settings in it, like this (``debugsettings``):
+
+ .. code-block:: c
+
+ CONFIG_DEBUG_CUSTOM_INFO=y
+ (etc..)
+
+ * Add the settings to the end of your ``.config`` file after running ``make menuconfig`` (that will reorder
+ the file, making it harder to see and change the debug settings if you need to).
+
+ .. code-block:: bash
+
+ $ cat .config debugsettings > .config1 ; mv .config1 .config
+
+ * If you are using interrupts and threads (many things in NuttX run in different threads as a response to interrupts),
+ you can use printf debugging to see overlapping execution.
+
+ * Interrupts - here's how to inspect the C stack frame to see what execution environment is currently running:
+
+ .. code-block:: c
+
+ uint32_t frame = 0; /* MUST be the very first thing in the function */
+ uint32_t p_frame;
+ frame++; /* make sure that frame doesn't get optimized out */
+ p_frame = (uint32_t)(&frame);
+ custinfo("p_frame: %08x\n", p_frame);
+
+ * Threads - here's how to get the thread identifier to see which thread is currently executing:
+
+ .. code-block:: c
+
+ pthread_t thread_id = pthread_self();
+ custinfo("pthread_id: %08x\n", thread_id);
+
+ * stack frame printf
+ * thread printf
+
+ * `GDB — the Gnu Debugger <https://www.gnu.org/software/gdb/>`_
+
+ GDB is a great tool. In this guide we've already used it to load our program and run it. But it can do a lot
+ more. You can single-step through code, examine variables and memory, set breakpoints, and more. I generally use
+ it from the commandline, but have also used it from an IDE like JetBrains' Clion, where it's easier to see the
+ code context.
+
+ One add-on that I found to be essential is the ability to examine blocks of memory, like buffers that NuttX uses
+ for reading and writing to storage media or network adapters. This `Stack Overflow question on using GDB to
+ examine memory <https://stackoverflow.com/a/54784260/431222>`_ includes a GDB command that is very handy. Add
+ this to your ``.gdbinit`` file, and then use the ``xxd`` command to dump memory in an easy-to-read format:
+
+ .. code-block::
+
+ define xxd
+ if $argc < 2
+ set $size = sizeof(*$arg0)
+ else
+ set $size = $arg1
+ end
+ dump binary memory dump.bin $arg0 ((void *)$arg0)+$size
+ eval "shell xxd -o %d dump.bin; rm dump.bin", ((void *)$arg0)
+ end
+ document xxd
+ Dump memory with xxd command (keep the address as offset)
+
+ xxd addr [size]
+ addr -- expression resolvable as an address
+ size -- size (in byte) of memory to dump
+ sizeof(*addr) is used by default end
+
+ Here's a short GDB session that shows what this looks like in practice. Note that the memory location being
+ examined (``0x200aa9eo`` here) is a buffer being passed to ``mmcsd_readsingle``:
+
+ .. code-block::
+
+ Program received signal SIGTRAP, Trace/breakpoint trap.
+ 0x200166e8 in up_idle () at common/arm_idle.c:78
+ 78 }
+ (gdb) b mmcsd_readsingle
+ Breakpoint 1 at 0x2006ea70: file mmcsd/mmcsd_sdio.c, line 1371.
+ (gdb) c
+ Continuing.
+
+ Breakpoint 1, mmcsd_readsingle (priv=0x200aa8c0, buffer=0x200aa9e0 "WRTEST TXT \030", startblock=2432) at mmcsd/mmcsd_sdio.c:1371
+ 1371 finfo("startblock=%d\n", startblock);
+ (gdb) xxd 0x200aa9e0 200
+ 200aa9e0: 5752 5445 5354 2020 5458 5420 1800 0000 WRTEST TXT ....
+ 200aa9f0: 0000 0000 0000 0000 0000 5500 1100 0000 ..........U.....
+ 200aaa00: 5752 5445 5354 3520 5458 5420 1800 0000 WRTEST5 TXT ....
+ 200aaa10: 0000 0000 0000 0000 0000 5800 1500 0000 ..........X.....
+ 200aaa20: e552 5445 5854 3620 5458 5420 1800 0000 .RTEXT6 TXT ....
+ 200aaa30: 0000 0000 0000 0000 0000 5600 1200 0000 ..........V.....
+ 200aaa40: 5752 5445 5354 3620 5458 5420 1800 0000 WRTEST6 TXT ....
+ 200aaa50: 0000 0000 0000 0000 0000 5600 1200 0000 ..........V.....
+ 200aaa60: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+ 200aaa70: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+ 200aaa80: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+ 200aaa90: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+ 200aaaa0: 0000 0000 0000 0000 ........
+
+
+NuttX Drivers as a Reference
+----------------------------
+
+If you're not porting a NuttX driver from another architecture, it still helps to look at other similar NuttX
+drivers, if there are any. For instance, when implementing an Ethernet driver, look at other NuttX Ethernet drivers;
+for an SD Card driver, look at other NuttX Ethernet drivers. Even if the chip-specific code won't be the same, the
+structure to interface with NuttX can be used.
+
+Using Chip Datasheets
+---------------------
+
+To port or write a driver, you'll have to be familiar with the information in the chip datasheet. Definitely find
+the datasheet for your chip, and read the sections relevant to the peripheral you're working with. Doing so ahead
+of time will save a lot of time later.
+
+Another thing that's often helpful is to refer to sample code provided by the manufacturer, or driver code from
+another operating system (like U-Boot, Zephyr, or FreeBSD) while referring to the datasheet — seeing how working
+code implements the necessary algorithms often helps one understand how the driver needs to work.
+
+* How to use a datasheet
+
+ Key pieces of information in System-on-a-Chip (SoC) datasheets are usually:
+
+ * Chip Architecture Diagram — shows how the subsections of the chip (CPU, system bus, peripherals, I/O, etc.) connect
+ to each other.
+ * Memory Map — showing the location of peripheral registers in memory. This info usually goes into a header file.
+ * DMA Engine — if Direct Memory Access (DMA) is used, this may have info on how to use it.
+ * Peripheral — the datasheet usually has a section on how the peripheral works. Key parts of this include:
+
+ * Registers List — name and offset from the base memory address of the peripheral. This needs to go into a header
+ file.
+ * Register Map — what is the size of each register, and what do the bits mean? You will need to create ``#defines``
+ in a header file that your code will use to operate on the registers. Refer to other driver header files for
+ examples.
+
+`Logic analyzers <https://en.wikipedia.org/wiki/Logic_analyzer>`_
+-----------------------------------------------------------------
+
+For drivers that involve input and output (I/O), especially that involve complex protocols like SD Cards, SPI, I2C,
+etc., actually seeing the waveform that goes in and out the chip's pins is extremely helpful. Logic analyzers can
+capture that information and display it graphically, allowing you to see if the driver is doing the right thing
+on the wire.
+
+DMA Debugging
+-------------
+
+* Dump registers before, during, and after transfer. Some NuttX drivers (``sam_sdmmc.c`` or ``imxrt_sdmmc.c`` for
+ example) have built-in code for debugging register states, and can sample registers before, during, and
+ immediately after a DMA transfer, as well as code that can dump the peripheral registers in a nicely-formatted
+ way onto the console device (which can be a serial console, a network console, or memory). Consider using something
+ like this to see what's happening inside the chip if you're trying to debug DMA transfer code.
+* Compare register settings to expected settings determined from the datasheet or from dumping registers from working
+ code in another operating system (U-Boot, Zephyr, FreeBSD, etc.).
+* Use the ``xxd`` GDB tool mentioned above to dump NuttX memory buffers before, during, and after a transfer to see if
+ data is being transferred correctly, if there are over- or under-runs, or to diagnose data being stored in incorrect
+ locations.
+* printf debugging register states can also help here.
+* Remember that logging can change the timing of any algorithms you might be using, so things may start or stop
+ working when logging is added or removed. Definitely test with logging disabled.
+
+
+
+
+
+
diff --git a/Documentation/guides/index.rst b/Documentation/guides/index.rst
index c592db1..74f7873 100644
--- a/Documentation/guides/index.rst
+++ b/Documentation/guides/index.rst
@@ -7,3 +7,5 @@ Guides
.. toctree::
nfs.rst
usbtrace.rst
+ simulator.rst
+ drivers.rst
diff --git a/Documentation/guides/simulator.rst b/Documentation/guides/simulator.rst
new file mode 100644
index 0000000..4340492
--- /dev/null
+++ b/Documentation/guides/simulator.rst
@@ -0,0 +1,145 @@
+.. include:: /substitutions.rst
+.. _simulator:
+
+Simulator
+=========
+
+Apache NuttX has a simulator that can run as a regular program on Linux, Mac, and Windows computers.
+It's useful for debugging operating system features that aren't associated with particular
+device drivers— for instance the TCP/IP stack itself, a web interface or API for your
+application, or other communication protocols. It's also handy for trying out Apache NuttX without
+having a piece of embedded hardware.
+
+This guide assumes you're on Linux. It works on Windows and Mac too— if you know how,
+submit a PR the NuttX Companion to update this guide!
+
+Compiling
+---------
+
+#. Configure the Simulator
+
+ There are a lot of simulator configurations available that set you up to test various
+ operating system features.
+
+ Here we'll use the ``sim:tcpblaster`` configuration because it comes with networking
+ that is ready to use.
+
+ .. code-block:: bash
+
+ $ cd nuttx
+ $ ./tools/configure.sh sim:tcpblaster
+
+#. Compile
+
+ .. code-block:: bash
+
+ $ make clean; make
+
+Running
+-------
+
+#. Give the Simulator Privileges
+
+ On recent Linux distributions, you need to give the ``nuttx`` program the capabilities
+ (similar to permissions) to access the network:
+
+ .. code-block:: bash
+
+ $ sudo setcap cap_net_admin+ep ./nuttx
+
+#. Run the simulator:
+
+ .. code-block:: bash
+
+ $ ./nuttx
+
+#. Bring Up the Network Interfaces
+
+ On Apache NuttX:
+
+ .. code-block:: bash
+
+ nsh> ifup eth0
+
+ On Linux, first you need to find your main network interface— this will usually either
+ be an ethernet or wireless network adapter. Do this:
+
+ .. code-block:: bash
+
+ $ ifconfig
+ lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
+ inet 127.0.0.1 netmask 255.0.0.0
+ inet6 ::1 prefixlen 128 scopeid 0x10<host>
+ loop txqueuelen 1000 (Local Loopback)
+ RX packets 5846 bytes 614351 (614.3 KB)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 5846 bytes 614351 (614.3 KB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+ wlp0s20f3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
+ inet 192.168.1.209 netmask 255.255.255.0 broadcast 192.168.1.255
+ inet6 fe80::1161:c26b:af05:d784 prefixlen 64 scopeid 0x20<link>
+ ether 24:41:8c:a8:30:d1 txqueuelen 1000 (Ethernet)
+ RX packets 219369 bytes 176416490 (176.4 MB)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 108399 bytes 27213617 (27.2 MB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+ ``lo0`` is the Loopback Interface, so ``wlp0s20f3`` is the wireless interface. Note
+ that it has an IP address on the local net. There may be other interfaces listed, you'll
+ need to pick the one that's right for your system.
+
+ Then, on Linux do this to set up the tap network interface and route that will let
+ the Apache Nuttx simulator access the network:
+
+ .. code-block:: bash
+
+ $ sudo ./tools/simhostroute.sh wlp0s20f3 on
+ $ ping -c 1 10.0.1.2 # nuttx system
+ PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.
+ 64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=7.52 ms
+
+ --- 10.0.1.2 ping statistics ---
+ 1 packets transmitted, 1 received, 0% packet loss, time 0ms
+ rtt min/avg/max/mdev = 7.529/7.529/7.529/0.000 m
+
+#. Test that Apache NuttX can access the Internet
+
+ First let's ping the network interface of our Linux host to prove we can see the
+ gateway to the Internet:
+
+ .. code-block:: bash
+
+ nsh> ping -c 1 10.0.1.1
+ nsh> ping -c 1 10.0.1.1
+ PING 10.0.1.1 56 bytes of data
+ 56 bytes from 10.0.1.1: icmp_seq=0 time=0 ms
+ 1 packets transmitted, 1 received, 0% packet loss, time 1010 ms
+
+ Now let's ping one of Google's DNS servers to prove we can access the rest of the
+ Internet:
+
+ .. code-block:: bash
+
+ nsh> ping -c 1 8.8.8.8
+ PING 8.8.8.8 56 bytes of data
+ 56 bytes from 8.8.8.8: icmp_seq=0 time=10 ms
+ 1 packets transmitted, 1 received, 0% packet loss, time 1010 ms
+
+ Success!
+
+Stopping
+--------
+
+The only really effective way to stop the simulator is kill it from another terminal:
+
+ .. code-block:: bash
+
+ $ pkill nuttx
+
+
+
+Debugging
+---------
+
+You can debug the simulator like any regular Linux program.