diff --git a/_data/docs.yml b/_data/docs.yml index fc30773f..54a0637f 100644 --- a/_data/docs.yml +++ b/_data/docs.yml @@ -56,10 +56,13 @@ - title: Advanced Tutorials with Nuttx docs: - tutorials/advanced/nuttx/nuttx_getting_started - - tutorials/advanced/nuttx/add_a_microros_application + - tutorials/advanced/nuttx/nsh_usb + - tutorials/advanced/nuttx/nsh_uart + - tutorials/advanced/nuttx/udp_echo + - tutorials/advanced/nuttx/tcp_echo + - tutorials/advanced/nuttx/6lowpan_config - tutorials/advanced/nuttx/debugging_gdb_openocd - tutorials/advanced/nuttx/debugging_vscode - - tutorials/advanced/nuttx/6lowpan_nuttx_rpi - tutorials/advanced/nuttx/microros_nuttx_bsp - tutorials/advanced/nuttx/microros_6lowpan_tutorial diff --git a/_docs/tutorials/advanced/nuttx/6lowpan_nuttx_rpi/index.md b/_docs/tutorials/advanced/nuttx/6lowpan_config/index.md similarity index 81% rename from _docs/tutorials/advanced/nuttx/6lowpan_nuttx_rpi/index.md rename to _docs/tutorials/advanced/nuttx/6lowpan_config/index.md index 056090b4..7eb949b3 100644 --- a/_docs/tutorials/advanced/nuttx/6lowpan_nuttx_rpi/index.md +++ b/_docs/tutorials/advanced/nuttx/6lowpan_config/index.md @@ -1,22 +1,29 @@ --- -title: 6LOWPAN communications between NuttX and a Raspberry Pi -permalink: /docs/tutorials/advanced/nuttx/6lowpan_nuttx_rpi/ +title: Configure 6LoWPAN communications +permalink: /docs/tutorials/advanced/nuttx/6lowpan_config/ --- +| RTOS | Board Compatible | +|:-----:|:-----------------:| +| NuttX | Olimex-STM32-E407 | This guide will show how to set-up a Raspberry Pi 3 (RPI) running Raspbian and an Olimex STM32 E407 board running NuttX to have 6lowpan communication between them. -## What do we need? + +**Disclaimer**: This tutorial doesn't use micro-ROS, it is just a proof of concept of the 6LoWPAN communication. + +## Hardware requirements: - Raspberry Pi 3 - micro-SD card (almost 16gb) with Raspbian lite already installed. - Olimex-STM32-E407 board. -- Two PMODRF2 module which are base on the MRF24J40 module. +- Two PMODRF2 modules which are based on the MRF24J40 module. - PC with Ubuntu (It works fine with Ubuntu 16.04) - NuttX source code, you can find a Docker file with all the tools [here](https://github.com/micro-ROS/docker/tree/pre_refactor/Embedded/NuttX/development/stm32-e407). -## How to set-up 6lowpan RPI? -First, we need to connect the PMODRF2 module to the RPI, so we need to set the next connections: +## Set-up 6LoWPAN communications on the Raspberry PI + +First, we need to connect the PMODRF2 module to the RPI, so we need to set the following connections: | | RPI | PMODRF2 | | -- | -- | -- | @@ -34,10 +41,10 @@ In the next links you can see the pinout of each board: - [PMODRF2 pionut.](https://reference.digilentinc.com/reference/pmod/pmodrf2/start) Once you've set all the wires, power-on the RPI and download the next repository inside the RPI: -- https://github.com/micro-ROS/micro-ROS-bridge_RPI +- https://github.com/micro-ROS/micro-ROS-bridge_RPI/ -Execute the next command: -```sudo ./micro-ROS-bridge_RPI/RPI_6lowpan/script.sh``` +Execute the command: +```sudo ./micro-ROS-bridge_RPI/micro-ROS-HB.sh``` If everything goes fine, at the end of the script, the board should restart. After the start-up, type the next command to see if the configuration and the connections are fine: ```dmesg | grep mrf24j40``` @@ -51,7 +58,6 @@ The last point is to set-up the network. - Set the PAN ID: ``sudo iwpan dev wpan0 set pan_id 0xabcd`` - Set the page and channel: ``sudo iwpan phy phy0 set channel 0 26`` -- Set the short address: ``sudo iwpan dev wpan0 set short_addr 0x4204`` (Each board must a different one) - Attach the phy layer to the lowpan: ``sudo ip link add link wpan0 name lowpan0 type lowpan`` - Bring up the WPAN0 interface: ``sudo ip link set wpan0 up`` - Bring up the RPI lowpan: ``sudo ip link set lowpan0 up`` @@ -60,7 +66,7 @@ The last point is to set-up the network. Now the RPI is ready to send and receive messages from a NuttX board or another RPI. -## How to set-up 6lowpan in NuttX? +## Set-Up 6LoWPAN communications on NuttX First, we need to do the connections between the [Olimex board](/docs/overview/hardware) and the PMODRF2 module. @@ -70,39 +76,46 @@ First, we need to do the connections between the [Olimex board](/docs/overview/h - `Board D10` -> `MRF24J40 CS` - `Board D8` -> `MRF24J40 INT` -Once the wiring is finished, we need to compile and upload the firmware. Type the next commands: - -Go to the main folder of NuttX and type the command to configure the board: -`./scripts/configure.sh olimex-stm32-e407 mrf24j40-6lowpan` - -Compile: -`make` +### Create firmware -Upload: -`./scripts/flash.sh olimex-stm32-e407` - -It should return somenthing like this: - -- Configuration: -``` -Copy files -Refreshing... +For this tutorial we're going to execute the configuration below in the Micro-ROS build system: +```bash +ros2 run micro_ros_setup create_firmware_ws.sh nuttx olimex-stm32-e407 +ros2 run micro_ros_setup configure_firmware.sh mrf24j40-6lowpan ``` -- Compilation: + +Once the board is configured, we need to build it by typing the command: +```bash +ros2 run micro_ros_setup build_firmware.sh ``` + +If the compilation succeds, it should return the following output: +```bash CP: nuttx.hex CP: nuttx.bin ``` -- Upload the firmware + +### Flash the firmware +Once the firmware is ready, you need to do the following connections: +- Connect the JTAG flasher device to the JTAG port. +- Connect the mini-USB port to the USB-OTG2 port. +- Check if the radio connections are fine. + +Now flash the board by typing the command: +```bash +ros2 run micro_ros_setup flash_firmware.sh ``` -wrote 131072 bytes from file nuttx.bin in 3.763846s (34.008 KiB/s) + +This should return this output once the process is finished: +```bash +wrote 49152 bytes from file nuttx.bin in 6.279262s (7.644 KiB/s) Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections ``` -(The number of written bytes could be different in each board) +## NuttX network configuration -Finally, connect the mini USB cable to the USB OTG2, and the console should return the next: +Push the reset button and type Enter two times. Now the NSH console should be output through the terminal. Type ``?`` to check if every application is flashed. The following output should appear. ```bash nsh> ? @@ -161,10 +174,6 @@ Available commands ``` -**At this point the network is ready to work!** - -Finally type ``quit`` two times to close the app and come back to the main menu. - ## Sending a message from NuttX to Raspbian: ### Raspberry Part: @@ -228,18 +237,18 @@ lowpan0: flags=4163 mtu 1280 TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ``` -As you can see there is two IP in this network interface. But you need to remember the second one. We will use later with NuttX. +As you can see, there are two IPs in this network interface, but we are interested only in the second one. Save it because we will use it later with NuttX. `fe80::9c6e:87a5:eb60:84d0`` -Go to the place where lives the repo that you downloaded previously. Go to ``micro-ROS-bridge_RPI/RPI_6lowpan/Examples/6lowpan_recv`` -Finally, execute `recv_demo` telling to open the `61616` port. Type this command: ``./recv_demo 61616`` +Go to the place where you previously downloaded the repo. From there, go to ``micro-ROS-bridge_RPI/6LowPAN_Tests/6lowpan_recv`` +Finally, execute `recv_demo`, specifying to open the `61616` port. To do so, type this command: ``./recv_demo 61616`` At this point, the RPI is ready to receive incoming packages. -### NuttX part: +### NuttX side Execute ``udp_6lowpan`` application. -This will ask you if you want to configure the network. Type N, because is already configured. +This will ask you if you want to configure the network. Type N, because it is already configured. Now you're in the main menu of the App. Type ``write`` to start the sending mode and will ask for the next data: - The destination IP: This is the IP of the RPI which we saved previously. - The destination port: For this specific example is 61617. @@ -282,24 +291,22 @@ The Linux 6lowpan utility needs to have a ping response before sending a data pa If this does not work, do as follow: -Check if the Nuttx address is part within the Linux/Raspbian neighborhood table. +Check if the Nuttx address is part of the Linux/Raspbian neighborhood table. If it is saved there, remove it: ```bash - $ ip neigh # a bunch of address shall appear including yours (if you send a - message already) + $ ip neigh fe80::2be:adde:de:fa00 dev lowpan0 FAILED $ sudo ip neigh delete fe80::2be:adde:de:fa00 dev lowpan0 # Remove it. ``` -Then, once deleted, add the Nuttx device it permanently (until reboot): +Then, once deleted, add the Nuttx device permanently (until reboot): ```bash - $ sudo ip neigh add fe80::2be:adde:de:fa00 dev lowpan0 00:be:ad:de:00:de:fa:00 # Add it with the -corret Hardware address. + $ sudo ip neigh add fe80::2be:adde:de:fa00 dev lowpan0 00:be:ad:de:00:de:fa:00 ``` -### NuttX part: -First, we need the ip of the board, so type ``ifconfig`` in the main menu. This should return somenthing like this: +### NuttX side +First, we need the IP of the board, so type ``ifconfig`` in the main menu. This should return something like this: ```bash wpan0 Link encap:6LoWPAN HWaddr 00:be:ad:de:00:de:fa:00 at UP inet6 addr: fe80::2be:adde:de:fa00/64 @@ -339,12 +346,12 @@ Introduce the reception port Listening on 61616 for input packets ``` -### Raspbian Part: +### Raspbian side -Go to the places that lives the previous download repo. Then go to this folder: ``/micro-ROS-bridge_RPI/RPI_6lowpan/Examples/6lowpan_send`` +Go to the place where you previously downloaded the repo. Then go to this folder: ``/micro-ROS-bridge_RPI/6LowPAN_Tests/6lowpan_send``. -And execute with root privileges the next app: ``send_demo``. -These demos have two arguments: The first is the port to open in the destination and the second is the destination IP. An example of this specific demo could be: +Now execute with root privileges the next app: ``send_demo``. +These demos have two arguments: The first is the port to open in the destination and the second is the destination IP. A specific example for this demo could be: ``sudo send_demo 61616 fe80::2be:adde:de:fa00`` This app returns any data. diff --git a/_docs/tutorials/advanced/nuttx/add_a_microros_application/index.md b/_docs/tutorials/advanced/nuttx/add_a_microros_application/index.md deleted file mode 100644 index ee1c2539..00000000 --- a/_docs/tutorials/advanced/nuttx/add_a_microros_application/index.md +++ /dev/null @@ -1,465 +0,0 @@ ---- -title: Add a new Micro-ROS application -permalink: /docs/tutorials/advanced/nuttx/add_a_microros_application/ ---- - -| RTOS | Board Compatible | ROS2 Version | -|:-----:|-------------------|:------------:| -| NuttX | Olimex-STM32-E407 | Dashing | - -In this tutorial, we will follow a guide of how to **add a new Micro-ROS application** on the NuttX RTOS. During this guide, we will start with how to create a configuration profile for our application, following of how to create a micro-ROS pingpong application and finalizing of how we can add our new application to NuttX. - -## Build the Micro-ROS build system - -```bash -source /opt/ros/$ROS_DISTRO/setup.bash - -mkdir uros_ws && cd uros_ws - -git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro-ros-build.git src/micro-ros-build - -sudo apt update && rosdep update -rosdep install --from-path src --ignore-src -y - -colcon build - -source install/local_setup.bash -``` -## Create micro-ROS firmware - -This step will download all the required software. -```bash -ros2 run micro_ros_setup create_firmware_ws.sh nuttx olimex-stm32-e407 -``` -At this point we have everything ready in our workspace to develop a new application. With the next steps, we will start the development of the app itself. - -## Aplication development - -- Go to: ``uros_ws/firmware/apps/examples`` -- Create a folder called ``uros_pingpong`` - -Now we're going to considerer the folder application the next folder: ``uros_ws/firmware/apps/examples/uros_ws/firmware/apps/examples`` - -### Create Kconfig file - -For this step, you need to create an empty file called **Kconfig**, inside the application folder. These files contain the configuration menu to configure the application and add it to the build system list of NuttX. - -In the next lines you can see an example of a basic generic implementation: -```bash -config UROS_PINGPONG_EXAMPLE - bool "micro-ROS Ping Pong" - default n - depends on UROS - ---help--- - - -if UROS_PINGPONG_EXAMPLE - -config UROS_PINGPONG_EXAMPLE_PROGNAME - string "Program name" - default "uros_ping_pong" - depends on BUILD_KERNEL - ---help--- - This is the name of the program that will be use when the NSH ELF - program is installed. - -endif -``` - -### Create Makefile - -Create an empty file called **Makefile**, inside of the application folder. -Below, you can see an example of a generic implementation: -```Makefile --include $(TOPDIR)/Make.defs - -#Set the scheduler priority for the app. -CONFIG_UROS_PINGPONG_EXAMPLE_PRIORITY ?= SCHED_PRIORITY_DEFAULT -#Set the stack size to the app. The minimum stack size on NuttX for a micro-ROS App is 65000 bytes -CONFIG_UROS_PINGPONG_EXAMPLE_STACKSIZE ?= 65000 - -#This is the name of the app on the NSH console -APPNAME = uros_pingpong -PRIORITY = $(CONFIG_UROS_PINGPONG_EXAMPLE_PRIORITY) -STACKSIZE = $(CONFIG_UROS_PINGPONG_EXAMPLE_STACKSIZE) - -#Add the source files. -ASRCS = -CSRCS = -MAINSRC = uros_pingpong_main.c - -CONFIG_UROS_PINGPONG_EXAMPLE_PROGNAME ?= uros_pingpong$(EXEEXT) -PROGNAME = $(CONFIG_UROS_PINGPONG_EXAMPLE_PROGNAME) -UROS_PINGPONG_INCLUDES = $(shell find $(APPDIR)/$(CONFIG_UROS_DIR)/install -type d -name include) -CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" "$(UROS_PINGPONG_INCLUDES)"} -std=c99 - -MODULE = CONFIG_UROS_PINGPONG_EXAMPLE - -include $(APPDIR)/Application.mk -``` - -### Create Make.defs file -Create an empty file called **Make.defs**, inside of the application folder. -You need to add the following lines: -```Makefile -ifeq ($(CONFIG_UROS_PINGPONG_EXAMPLE),y) - CONFIGURED_APPS += examples/uros_pingpong -endif -``` - -This file will add the folder as an application if you set the option on the configuration menu of NuttX. - -### Create the main file - -Create a file named ``uros_pingpong_main.c``. -In the box below, we will show a pinpong example: -```c -//Nuttx specific library -#include - -// Micro-ROS specific library -#include -#include -#include "rosidl_generator_c/string_functions.h" -#include -#include - -// C standard library -#include -#include -#include -#include - -#define STRING_BUFFER_LEN 100 - -// Thread to trigger a publication guard condition -void * trigger_guard_condition(void *args){ - rcl_guard_condition_t * guard_condition = (rcl_guard_condition_t *)args; - - while(true){ - rcl_trigger_guard_condition(guard_condition); - sleep(5); - } -} - -#if defined(BUILD_MODULE) -int main(int argc, char *argv[]) -#else -int uros_pingpong_main(int argc, char* argv[]) -#endif -{ - //Init RCL options - rcl_init_options_t options = rcl_get_zero_initialized_init_options(); - rcl_init_options_init(&options, rcl_get_default_allocator()); - - // Init RCL context - rcl_context_t context = rcl_get_zero_initialized_context(); - rcl_init(0, NULL, &options, &context); - - // Create a node - rcl_node_options_t node_ops = rcl_node_get_default_options(); - rcl_node_t node = rcl_get_zero_initialized_node(); - rcl_node_init(&node, "pingpong_node", "", &context, &node_ops); - - // Create a reliable ping publisher - rcl_publisher_options_t ping_publisher_ops = rcl_publisher_get_default_options(); - rcl_publisher_t ping_publisher = rcl_get_zero_initialized_publisher(); - rcl_publisher_init(&ping_publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/ping", &ping_publisher_ops); - - // Create a best effort pong publisher - rcl_publisher_options_t pong_publisher_ops = rcl_publisher_get_default_options(); - pong_publisher_ops.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT; - rcl_publisher_t pong_publisher = rcl_get_zero_initialized_publisher(); - rcl_publisher_init(&pong_publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/pong", &pong_publisher_ops); - - // Create a reliable pong subscriber - rcl_subscription_options_t pong_subscription_ops = rcl_subscription_get_default_options(); - rcl_subscription_t pong_subscription = rcl_get_zero_initialized_subscription(); - rcl_subscription_init(&pong_subscription, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/pong", &pong_subscription_ops); - - // Create a best effort ping subscriber - rcl_subscription_options_t ping_subscription_ops = rcl_subscription_get_default_options(); - ping_subscription_ops.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT; - rcl_subscription_t ping_subscription = rcl_get_zero_initialized_subscription(); - rcl_subscription_init(&ping_subscription, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/ping", &ping_subscription_ops); - - // Create a guard condition - rcl_guard_condition_t guard_condition = rcl_get_zero_initialized_guard_condition(); - rcl_guard_condition_options_t guard_condition_options = rcl_guard_condition_get_default_options(); - rcl_guard_condition_init(&guard_condition, &context, guard_condition_options); - - // Create a thread that triggers the guard condition - pthread_t guard_condition_thread; - pthread_create(&guard_condition_thread, NULL, trigger_guard_condition, &guard_condition); - - // Create a wait set - rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); - rcl_wait_set_init(&wait_set, 2, 1, 0, 0, 0, 0, &context, rcl_get_default_allocator()); - - // Create and allocate the pingpong publication message - std_msgs__msg__Header msg; - char msg_buffer[STRING_BUFFER_LEN]; - msg.frame_id.data = msg_buffer; - msg.frame_id.capacity = STRING_BUFFER_LEN; - - // Create and allocate the pingpong subscription message - std_msgs__msg__Header rcv_msg; - char rcv_buffer[STRING_BUFFER_LEN]; - rcv_msg.frame_id.data = rcv_buffer; - rcv_msg.frame_id.capacity = STRING_BUFFER_LEN; - - // Set device id and sequence number; - int device_id = rand(); - int seq_no; - - int pong_count = 0; - struct timespec ts; - rcl_ret_t rc; - - do { - // Clear and set the waitset - rcl_wait_set_clear(&wait_set); - - size_t index_pong_subscription; - rcl_wait_set_add_subscription(&wait_set, &pong_subscription, &index_pong_subscription); - - size_t index_ping_subscription; - rcl_wait_set_add_subscription(&wait_set, &ping_subscription, &index_ping_subscription); - - size_t index_guardcondition; - rcl_wait_set_add_guard_condition(&wait_set, &guard_condition, &index_guardcondition); - - // Run session for 100 ms - rcl_wait(&wait_set, RCL_MS_TO_NS(100)); - - // Check if it is time to send a ping - if (wait_set.guard_conditions[index_guardcondition]) { - // Generate a new random sequence number - seq_no = rand(); - sprintf(msg.frame_id.data, "%d_%d", seq_no, device_id); - msg.frame_id.size = strlen(msg.frame_id.data); - - // Fill the message timestamp - clock_gettime(CLOCK_REALTIME, &ts); - msg.stamp.sec = ts.tv_sec; - msg.stamp.nanosec = ts.tv_nsec; - - // Reset the pong count and publish the ping message - pong_count = 0; - rcl_publish(&ping_publisher, (const void*)&msg, NULL); - // printf("Ping send seq 0x%x\n", seq_no); - } - - // Check if some pong message is received - if (wait_set.subscriptions[index_pong_subscription]) { - rc = rcl_take(wait_set.subscriptions[index_pong_subscription], &rcv_msg, NULL, NULL); - - if(rc == RCL_RET_OK && strcmp(msg.frame_id.data,rcv_msg.frame_id.data) == 0) { - pong_count++; - // printf("Pong for seq 0x%x (%d)\n", seq_no, pong_count); - } - } - - // Check if some ping message is received and pong it - if (wait_set.subscriptions[index_ping_subscription]) { - rc = rcl_take(wait_set.subscriptions[index_ping_subscription], &rcv_msg, NULL, NULL); - - // Dont pong my own pings - if(rc == RCL_RET_OK && strcmp(msg.frame_id.data,rcv_msg.frame_id.data) != 0){ - // printf("Ping received with seq 0x%x (%d). Answering.\n", seq_no); - rcl_publish(&pong_publisher, (const void*)&rcv_msg, NULL); - } - } - - usleep(10000); - } while (true); -} -``` - -Once the application is ready, the only thing left to do is to create the right configuration. - -## Create a config profile - -Create a specific configuration from scratch can be a challenging task, so we're going to start from an already existing one and modify it for our new application. - -Execute the next command: -```bash -cd ~/uros_ws -ros2 run micro_ros_setup configure_firmware.sh uros -``` - -This sets the Ethernet and Micro-ROS required configuration. However, in order to add our application, we're going to modify it. - -### Modify the configuration -Now type the following commands: -```bash -cd uros_ws/firmware/NuttX -make menuconfig -``` - -This will open the NuttX menu config, which allows you to modify the configuration of the RTOS, including adding a new application. - - -- On the menu, you need to follow the next path: -``Application Configuration -> Examples `` -![](images/nuttx_menuconfig.png) - -- This will show a list of the available applications. You need to find: ``micro-ROS Ping-Pong`` and click ``y`` to add it. -![](images/nuttx_examples.png) - -- Now push three times the key ``ESC`` to close the menu. You will be asked if you want to save the save your new configuration, and you need to click ``Yes``. - - -### Add your configuration - -Execute the following commands: -```bash -cd uros_ws/firmware/NuttX -make savedefconfig -``` - -This will generate a file called ``defconfig`` inside of ``uros_ws/firmware/NuttX``. This file is a config profile with all the required configuration to run your specific configuration which includes your application. - -Finally create a folder called ``uros_pingpong`` into ``uros_ws/firmware/NuttX/configs/olimex-stm32-e407`` and move the defconfig file to uros_pingpong folder. - -## Build your application - -Now that everything is ready, the only thing left to do is to continue with the build system instructions. Execute the next command on the build system to start the build process: -```bash -cd ~/uros_ws -ros2 run micro_ros_setup configure_firmware.sh uros_pingpong -ros2 run micro_ros_setup build_firmware.sh -``` - -If it returns the next output, your build step succeded and your application was implemented properly. - -```bash -AR: stm32_boot.o stm32_bringup.o stm32_spi.o libatomic.o stm32_autoleds.o stm32_buttons.o stm32_appinit.o stm32_usb.o -make[2]: Leaving directory '/home/juan/uros_pinpong/firmware/NuttX/configs/olimex-stm32-e407/src' -LD: nuttx -arm-none-eabi-ld --entry=__start -nostartfiles -nodefaultlibs -g -T/home/juan/uros_pinpong/firmware/NuttX/configs/olimex-stm32-e407/scripts/ld.script -L"/home/juan/uros_pinpong/firmware/NuttX/staging" -L"/home/juan/uros_pinpong/firmware/NuttX/arch/arm/src/board" -L "/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/lib/thumb/v7e-m" \ - -o "/home/juan/uros_pinpong/firmware/NuttX/nuttx" \ - --start-group -lsched -ldrivers -lconfigs -lc -lmm -larch -lxx -lapps -lnet -lfs -lbinfmt -lxx -lboard -lsupc++ "/usr/lib/gcc/arm-none-eabi/6.3.1/thumb/v7e-m/libgcc.a" --end-group -make[1]: Leaving directory '/home/juan/uros_pinpong/firmware/NuttX/arch/arm/src' -CP: nuttx.hex -CP: nuttx.bin - -``` -Now the firmware is ready, is just necessary to flash the board. First, connect Olimex ARM-USB-TINY-H JTAG programmer to the board's JTAG port: - - - -Make sure that the board power supply jumper (PWR_SEL) is in the 3-4 position in order to power the board from the JTAG connector: - - - -You should see the red LED lighting. It is time to flash the board: - -```bash -# Flash step -ros2 run micro_ros_setup flash_firmware.sh -``` -## Running the micro-ROS app - -The micro-ROS app is ready to connect to a micro-ROS-Agent and start talking with the rest of the ROS 2 world. - -First of all, create and build a micro-ROS agent: - -```bash -# Download micro-ROS-Agent packages -ros2 run micro_ros_setup create_agent_ws.sh - -# Build micro-ROS-Agent packages, this may take a while. -colcon build --metas src -source install/local_setup.bash -``` - -Then connect the Olimex development board to the computer using the usb to serial cable: - - - -***TIP:** Color codes are applicable to [this cable](https://www.olimex.com/Products/Components/Cables/USB-Serial-Cable/USB-Serial-Cable-F/). Make sure to match Olimex Rx with Cable Tx and vice-versa. Remember GND!* - -Then run the agent: - -```bash -# Run a micro-ROS agent -ros2 run micro_ros_agent micro_ros_agent serial --dev [device] -``` - -***TIP:** you can use this command to find your serial device name: `ls /dev/serial/by-id/*`* - -And finally, let's check that everything is working in a new command line. We are going to listen to ping topic to check whether the Ping Pong node is publishing its own pings - -```bash -source /opt/ros/$ROS_DISTRO/setup.bash - -# Subscribe to micro-ROS ping topic -ros2 topic echo /microROS/ping -``` - -You should see the topic messages published by the Ping Pong node every 5 seconds: - -``` -user@user:~$ ros2 topic echo /microROS/ping -stamp: - sec: 20 - nanosec: 867000000 -frame_id: '1344887256_1085377743' ---- -stamp: - sec: 25 - nanosec: 942000000 -frame_id: '730417256_1085377743' ---- -``` - -On another command line, let's subscribe to the pong topic - -```bash -source /opt/ros/$ROS_DISTRO/setup.bash - -# Subscribe to micro-ROS pong topic -ros2 topic echo /microROS/pong -``` - -At this point, we know that our app is publishing pings. Let's check if it also answers to someone else pings in a new command line: - -```bash -source /opt/ros/$ROS_DISTRO/setup.bash - -# Send a fake ping -ros2 topic pub --once /microROS/ping std_msgs/msg/Header '{frame_id: "fake_ping"}' -``` - -Now, we should see on the ping subscriber our fake ping along with the board pings: - -``` -user@user:~$ ros2 topic echo /microROS/ping -stamp: - sec: 0 - nanosec: 0 -frame_id: fake_ping ---- -stamp: - sec: 305 - nanosec: 973000000 -frame_id: '451230256_1085377743' ---- -stamp: - sec: 310 - nanosec: 957000000 -frame_id: '2084670932_1085377743' ---- -``` - -And in the pong subscriber, we should see the board's answer to our fake ping: - -``` -user@user:~$ ros2 topic echo /microROS/pong -stamp: - sec: 0 - nanosec: 0 -frame_id: fake_ping ---- -``` \ No newline at end of file diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_uart.jpg b/_docs/tutorials/advanced/nuttx/nsh_uart/images/olimex_uart.jpg similarity index 100% rename from _docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_uart.jpg rename to _docs/tutorials/advanced/nuttx/nsh_uart/images/olimex_uart.jpg diff --git a/_docs/tutorials/advanced/nuttx/nsh_uart/index.md b/_docs/tutorials/advanced/nuttx/nsh_uart/index.md new file mode 100644 index 00000000..395f855f --- /dev/null +++ b/_docs/tutorials/advanced/nuttx/nsh_uart/index.md @@ -0,0 +1,100 @@ +--- +title: NSH console over UART +permalink: /docs/tutorials/advanced/nuttx/nsh_uart/ +--- + +| RTOS | Board Compatible | +|:-----:|:-----------------:| +| NuttX | Olimex-STM32-E407 | + +NSH is a system console that can be used through different interfaces. In this tutorial, we will show how to use it over the UART peripheral. The UART (Universal Asynchronous Receiver-Transmitter) is a communication peripheral implemented on a micro-controller, which allows bidirectional serial communication. + +## Hardware requirements: +- [Olimex-STM32-E407 board](https://www.olimex.com/Products/ARM/ST/STM32-E407/open-source-hardware) +- [JTAG Flasher device](https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY/) +- USB-TTL232 cable. + +## Create the firmware + +For this tutorial we're going to execute the following configuration in the Micro-ROS build system: +```bash +ros2 run micro_ros_setup create_firmware_ws.sh nuttx olimex-stm32-e407 +ros2 run micro_ros_setup configure_firmware.sh nsh_uart +``` + +Once the board is configured, we need to build it by typing the command: +```bash +ros2 run micro_ros_setup build_firmware.sh +``` + +If the compilation succeds, it should return this output: +```bash +CP: nuttx.hex +CP: nuttx.bin +``` +## Flash the firmware + +The firmware is ready, it is just necessary to upload it. Now you need to do the following connection: +- Connect the JTAG flasher device. +- Connect the USB TTL-232 with these pins out: + - `USART3 TX` -> `TTL232 RX` + - `USART3 RX` -> `TTL232 TX` + - `GND Board` -> `TTL232 GND` + +It should look like this: +![](images/olimex_uart.jpg) + +Note: You can find multiple USB-TTL232 devices available. But, even though the Olimex board is 5V tolerant, we recommend to use a 3V3 USB-TTL232 cable. The [Olimex Official cable](https://www.olimex.com/Products/Components/Cables/USB-Serial-Cable/USB-Serial-Cable-F/) is our recommendation but any is compatible. + +Now flash the board by typing the next command: +```bash +ros2 run micro_ros_setup flash_firmware.sh +``` + +This should return this output once the process is finished: +```bash +wrote 49152 bytes from file nuttx.bin in 6.279262s (7.644 KiB/s) +Info : Listening on port 6666 for tcl connections +Info : Listening on port 4444 for telnet connections +``` +## Connect to the console + +Finally, connect the USB cable to the PC and open a terminal. Type the command ``dmesg`` to know the direction of the device. It should return something like this: +```bash +[17154.225244] usb 1-2: new full-speed USB device number 6 using xhci_hcd +[17154.380060] usb 1-2: New USB device found, idVendor=0403, idProduct=6001, bcdDevice= 6.00 +[17154.380066] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[17154.380069] usb 1-2: Product: USB <-> Serial Cable +[17154.380072] usb 1-2: Manufacturer: FTDI +[17154.380075] usb 1-2: SerialNumber: 12TBZ31 +[17154.400389] usbcore: registered new interface driver usbserial_generic +[17154.400395] usbserial: USB Serial support registered for generic +[17154.402690] usbcore: registered new interface driver ftdi_sio +[17154.402699] usbserial: USB Serial support registered for FTDI USB Serial Device +[17154.402745] ftdi_sio 1-2:1.0: FTDI USB Serial Device converter detected +[17154.402762] usb 1-2: Detected FT232RL +[17154.403058] usb 1-2: FTDI USB Serial Device converter now attached to ttyUSB0 + +``` + +In this specific situation, the device is assigned to ``dev/ttyUSB0`` but it could be a different number. + +Finally, execute the next command to open the NSH console: +``` +sudo minicom -D /dev/ttyUSB0 +``` + +Once the application is executed, push enter and it should return the next menu: +```bash +nsh> ? +help usage: help [-v] [] + + ? exec hexdump mb sleep + cat exit kill mh usleep + echo help ls mw xd + +Builtin Apps: +nsh> +``` + +Note: If you don't succeed with theses steps, check if you set a baud rate of 115200 bps and the configuration is set to 8N1 with no hardware and software flow control. diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_nsh_usb.jpg b/_docs/tutorials/advanced/nuttx/nsh_usb/images/olimex_nsh_usb.jpg similarity index 100% rename from _docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_nsh_usb.jpg rename to _docs/tutorials/advanced/nuttx/nsh_usb/images/olimex_nsh_usb.jpg diff --git a/_docs/tutorials/advanced/nuttx/nsh_usb/index.md b/_docs/tutorials/advanced/nuttx/nsh_usb/index.md new file mode 100644 index 00000000..7679e5a7 --- /dev/null +++ b/_docs/tutorials/advanced/nuttx/nsh_usb/index.md @@ -0,0 +1,85 @@ +--- +title: NSH console over USB +permalink: /docs/tutorials/advanced/nuttx/nsh_usb/ +--- + +| RTOS | Board Compatible | +|:-----:|:-----------------:| +| NuttX | Olimex-STM32-E407 | + +NSH is a system console that can be used through the following interfaces: USB,UART and Telnet. With this console you can execute apps, set system configurations and see the state of the system. + +## Hardware requirements: +- [Olimex-STM32-E407 board](https://www.olimex.com/Products/ARM/ST/STM32-E407/open-source-hardware) +- [JTAG Flasher device](https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY/) +- Mini USB cable. + + +## Create the firmware + +For this tutorial we're going to execute the following configuration in the Micro-ROS build system: +```bash +ros2 run micro_ros_setup create_firmware_ws.sh nuttx olimex-stm32-e407 +ros2 run micro_ros_setup configure_firmware.sh nsh +``` + +Once the board is configured, we need to build it by typing the next: +```bash +ros2 run micro_ros_setup build_firmware.sh +``` + +If the compilation succeds, it should return this output: +```bash +CP: nuttx.hex +CP: nuttx.bin +``` +## Flash the firmware + +Now you're ready to upload the firmware to the board. Connect the JTAG flasher device to the board and the mini USB cable to the USB-OTG2 port like in the image below. +![](images/olimex_nsh_usb.jpg) + +Now flash the board by typing the next command: +```bash +ros2 run micro_ros_setup flash_firmware.sh +``` + +This should return this output once the process is finished: +```bash +wrote 49152 bytes from file nuttx.bin in 6.279262s (7.644 KiB/s) +Info : Listening on port 6666 for tcl connections +Info : Listening on port 4444 for telnet connections +``` +## Connect to the console + +Finally, to use the NSH console you need to follow the steps listed below: +- Push the reset button. The green LED will turn on to say that it is working properly. +- Look for the device by typing ``dmesg`` on the console, this should return somenthing like this: +```bash +[20614.570781] usb 1-2: new full-speed USB device number 7 using xhci_hcd +[20614.724366] usb 1-2: New USB device found, idVendor=0525, idProduct=a4a7, bcdDevice= 1.01 +[20614.724372] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[20614.724375] usb 1-2: Product: CDC/ACM Serial +[20614.724378] usb 1-2: Manufacturer: NuttX +[20614.724381] usb 1-2: SerialNumber: 0 +[20614.745693] cdc_acm 1-2:1.0: ttyACM0: USB ACM device +[20614.746274] usbcore: registered new interface driver cdc_acm +[20614.746277] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters +``` +- In this example the device is the ``ttyACM0``. +- Open this port with your serial communication app. There are different serial communication applications, but in this tutorial we're going to use [minicom](https://linux.die.net/man/1/minicom). Type the following command to execute it. +```bash +sudo minicom -D /dev/ttyACM0 +``` + +Once the port is open, **you need to push two times the Enter key** and it should the menu below should pop up: +```bash +nsh> ? +help usage: help [-v] [] + + ? exec hexdump mb sleep + cat exit kill mh usleep + echo help ls mw xd + +Builtin Apps: +nsh> +``` diff --git a/_docs/tutorials/advanced/nuttx/add_a_microros_application/images/1.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/images/1.jpg similarity index 100% rename from _docs/tutorials/advanced/nuttx/add_a_microros_application/images/1.jpg rename to _docs/tutorials/advanced/nuttx/nuttx_getting_started/images/1.jpg diff --git a/_docs/tutorials/advanced/nuttx/add_a_microros_application/images/2.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/images/2.jpg similarity index 100% rename from _docs/tutorials/advanced/nuttx/add_a_microros_application/images/2.jpg rename to _docs/tutorials/advanced/nuttx/nuttx_getting_started/images/2.jpg diff --git a/_docs/tutorials/advanced/nuttx/add_a_microros_application/images/5.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/images/5.jpg similarity index 100% rename from _docs/tutorials/advanced/nuttx/add_a_microros_application/images/5.jpg rename to _docs/tutorials/advanced/nuttx/nuttx_getting_started/images/5.jpg diff --git a/_docs/tutorials/advanced/nuttx/add_a_microros_application/images/nuttx_examples.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/images/nuttx_examples.png similarity index 100% rename from _docs/tutorials/advanced/nuttx/add_a_microros_application/images/nuttx_examples.png rename to _docs/tutorials/advanced/nuttx/nuttx_getting_started/images/nuttx_examples.png diff --git a/_docs/tutorials/advanced/nuttx/add_a_microros_application/images/nuttx_menuconfig.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/images/nuttx_menuconfig.png similarity index 100% rename from _docs/tutorials/advanced/nuttx/add_a_microros_application/images/nuttx_menuconfig.png rename to _docs/tutorials/advanced/nuttx/nuttx_getting_started/images/nuttx_menuconfig.png diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_accept.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_accept.png deleted file mode 100644 index 96ec6333..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_accept.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_assoc.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_assoc.png deleted file mode 100644 index c4cbb6f5..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_assoc.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_autoconfiguration.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_autoconfiguration.png deleted file mode 100644 index 8c87b874..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_autoconfiguration.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_client.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_client.png deleted file mode 100644 index 8c25012d..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_client.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_ip.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_ip.png deleted file mode 100644 index 4668b2e9..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_ip.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_nsh.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_nsh.png deleted file mode 100644 index f8e1c34b..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_nsh.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_server.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_server.png deleted file mode 100644 index 62e714f9..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/6lowpan_server.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/adc_measure.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/adc_measure.png deleted file mode 100644 index 719fbf70..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/adc_measure.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/adc_nsh.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/adc_nsh.png deleted file mode 100644 index 78b6bab3..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/adc_nsh.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/aux_board.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/aux_board.png deleted file mode 100644 index 2d202b34..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/aux_board.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/aux_console.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/aux_console.png deleted file mode 100644 index 0018baf9..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/aux_console.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/bmp180.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/bmp180.jpg deleted file mode 100644 index 57bb1d5c..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/bmp180.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/hih6130.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/hih6130.jpg deleted file mode 100644 index cbdaeb53..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/hih6130.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1.jpg deleted file mode 100644 index 7a806f33..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1_bmp180.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1_bmp180.jpg deleted file mode 100644 index 0747ee5b..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1_bmp180.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1_hih6130.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1_hih6130.jpg deleted file mode 100644 index 032d7fc9..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1_hih6130.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1_uxd.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1_uxd.jpg deleted file mode 100644 index 41e9fd34..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/l1_uxd.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_agent (1).png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_agent (1).png deleted file mode 100644 index c8ce69aa..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_agent (1).png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_agent.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_agent.png deleted file mode 100644 index c8ce69aa..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_agent.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_agentattach.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_agentattach.png deleted file mode 100644 index 366896bc..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_agentattach.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_pub.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_pub.png deleted file mode 100644 index 399baa52..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_pub.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_ros2.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_ros2.png deleted file mode 100644 index 09139456..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_ros2.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_sub.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_sub.png deleted file mode 100644 index 104631ca..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/microros_sub.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/mrf24j40.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/mrf24j40.jpg deleted file mode 100644 index 8b979cc8..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/mrf24j40.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_bmp.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_bmp.jpg deleted file mode 100644 index 007afb73..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_bmp.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_hih.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_hih.jpg deleted file mode 100644 index b5c0b4eb..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_hih.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_mrf24j40.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_mrf24j40.jpg deleted file mode 100644 index 113065a3..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_mrf24j40.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_nsh_uart.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_nsh_uart.jpg deleted file mode 100644 index 3a8b6943..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_nsh_uart.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_uxd.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_uxd.jpg deleted file mode 100644 index c3d4b533..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_uxd.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/sd_detect.png b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/sd_detect.png deleted file mode 100644 index f5801db0..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/sd_detect.png and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/tcp.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/tcp.jpg deleted file mode 100644 index 60282ac1..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/tcp.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/tcp_1.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/tcp_1.jpg deleted file mode 100644 index dbf9362d..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/tcp_1.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_1.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_1.jpg deleted file mode 100644 index d4cafb82..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_1.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_2.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_2.jpg deleted file mode 100644 index f8b37edb..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_2.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_3.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_3.jpg deleted file mode 100644 index 85afd1fb..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_3.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_4.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_4.jpg deleted file mode 100644 index fda1b46d..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_4.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_5.jpg b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_5.jpg deleted file mode 100644 index 467230d6..00000000 Binary files a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/udp_5.jpg and /dev/null differ diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/index.md b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/index.md index ddfe9810..22e61b66 100644 --- a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/index.md +++ b/_docs/tutorials/advanced/nuttx/nuttx_getting_started/index.md @@ -1,1424 +1,465 @@ --- -title: NuttX Getting Started +title: NuttX getting started permalink: /docs/tutorials/advanced/nuttx/nuttx_getting_started/ -redirect_from: /docs/tutorials/advanced/ -redirect_from: /docs/tutorials/ --- -This document wants to be a small guideline for rapidly start using -the defconfig files for NuttX, OFERA project has created. +| RTOS | Board Compatible | ROS2 Version | +|:-----:|-------------------|:------------:| +| NuttX | Olimex-STM32-E407 | Dashing | -# Example list +In this tutorial, we will follow a guide of how to **add a new Micro-ROS application** on the NuttX RTOS. During this guide, we will start with how to create a configuration profile for our application, following of how to create a micro-ROS pingpong application and finalizing of how we can add our new application to NuttX. -## Olimex STM32-E407 +## Build the Micro-ROS build system -- [NSH over USB](#NSH-USB-Olimex) -- [NSH over UART](#NSH-UART-Olimex) -- [Auxiliar UART port](#Auxiliar-UART-Olimex) -- [BMP180 through I2C](#BMP180-Olimex) -- [HIH6130 through I2C](#HIH6130-Olimex) -- [UDP echo server](#UDPEcho-Olimex) -- [TCP echo server](#TCPEcho-Olimex) -- [MRF24J40-6LowPan through SPI](#MRF24j40-6LowPan-Olimex) -- [ADC](#ADC-Olimex) -- [Telemetry](#Telemetry-Olimex) -- [Power Manager](#Power-Manager-Olimex) -- [SD Card](#SD-Card-Olimex) -- [Micro XRCE-DDS through serial](#Micro-XRCE-DDS-Olimex) -- [micro-ROS demo](#micro-ROS-demo-Olimex) - - - - -## STM32L Discovery - -- [NSH through UART](#NSH-UART-Discovery) -- [BMP180 through I2C](#BMP180-Discovery) -- [HIH6130 through I2C](#HIH6130-Discovery) -- [Power Manager](#Power-Manager-Discovery) -- [Micro XRCE-DDS through serial](#Micro-XRCE-DDS-Discovery) - - - -# Repositories to be used - -For the examples listed below, please make use of the branch called `master` for this two repositories: - -- [NuttX](https://github.com/micro-ROS/Nuttx) fork, where NuttX RTOS is stored. -- [Apps](https://github.com/micro-ROS/apps) fork, whee NuttX applications and examples are placed. - ----------------------- - -# How to configure and flash a board - -We have developed two scripts that will help you to configure and flash the board. Go to the `NuttX` folder and write the next commands: - -- To configure: `$ ./scripts/configure.sh ` -- To compile: `make` -- To flash: `./scripts/flash.sh `, where the script expects `olimex-stm32-e407` or `stm32l1`. - -The configuration script will clean the previous project and set the new configuration. - -The flash script will execute the proper command to upload the firmware to the board and execute it. The use of `OpenOCD` gives you the chance to debug the MCU. - -# Step-by-step tutorials - -This section provides step-by-step tutorials so you can start executing the examples we have created. These tutorials starts using NuttX, using many different peripherals and tools, and ends up showing how to execute Micro XRCE-DDS client and micro-ROS client. - -## How to execute NSH over USB under Olimex-STM32-E40 {#NSH-USB-Olimex} - -NSH is a system console that can be use throught the next interfaces: USB,UART and Telnet. With this console you can execute apps, set system configuration and see the state of the system. - -Go to the main folder of NuttX and execute the next command to configure the board: -`./scripts/configure.sh olimex-stm32-e407 nsh` - -This script will clean NuttX and set the configuration that we need. You should see something like this at the end of process at the terminal. - -``` - Copy files - Refreshing... -``` - -Once the board is configured, the next step will be to compile the firmware: -Type `make` and you should see something like this when it finishes in the terminal: -``` -CP: nuttx.hex -CP: nuttx.bin -``` - -Now it's ready for uploading the firmware into the board, so plug the micro USB cable an type the next command: -`./scripts/flash.sh olimex-stm32-e407` - -If everything goes right, the loader will return the next message: -``` -wrote 49152 bytes from file nuttx.bin in 6.279262s (7.644 KiB/s) -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections -``` - -Connect the mini USB cable to the USB OTG1 - -![img](imgs/olimex_nsh_usb.jpg) - -Open a new terminal and use a serial client, i.e. `minicom` to open the serial port, `sudo minicom -D /dev/ttyACM0`. Once done, you should be able to see how `NSH` pops up when pressing key: - -``` -nsh> -nsh> -nsh> -nsh> ? -help usage: help [-v] [] - - ? exec hexdump mb sleep - cat exit kill mh usleep - echo help ls mw xd - -Builtin Apps: -nsh> -``` -If you don't know which interface is the micro USB, type `dmesg` command at a terminal, this command should let you know which is the last USB device that has been connected to your computer and at what interface is attached. - -## How to execute NSH with the UART. - - -### Olimex-STM32-E407 {#NSH-UART-Olimex} - -This board have the possibility to show the console through the UART or through USB. - -Go to the main folder of NuttX and execute the next command to configure the board: -`./scripts/configure.sh olimex-stm32-e407 nsh_uart` - -This script will clean NuttX and set the configuration that we need. You should see something like this at the end of process at the terminal. - -``` - Copy files - Refreshing... -``` -Once the board is configured, the next step will be to compile the firmware: -Type `make` and you should see something like this when it finishes in the terminal: -``` -CP: nuttx.hex -CP: nuttx.bin -``` -Now it's ready for uploading the firmware into the board, so plug the micro USB cable an type the next command: -`./scripts/flash.sh olimex-stm32-e407` - -If everything goes right, the loader will return the next message: -``` -wrote 49152 bytes from file nuttx.bin in 6.279262s (7.644 KiB/s) -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections -``` -For this demo we need to connect a USB cable to the mini USB port and a serial cable (TTL232) to the UART3 with the next pinout: - -- `USART3 TX` -> `TTL232 RX` -- `USART3 RX` -> `TTL232 TX` -- `GND Board` -> `TTL232 GND` - -It should look like this: -![img](imgs/olimex_nsh_uart.jpg) - -Open a new terminal and use a serial client, i.e. `minicom` to open the serial port, `sudo minicom -D /dev/ttyUSB0`. Once done, you should be able to see how `NSH` pops up when pressing key: - -``` -nsh> -nsh> -nsh> -nsh> ? -help usage: help [-v] [] - - ? exec hexdump mb sleep - cat exit kill mh usleep - echo help ls mw xd - -Builtin Apps: -nsh> -``` - - -### STM32L1Discovery {#NSH-UART-Discovery} - -**This board only can show the NSH console throught the UART** - -Go to the main folder of NuttX and execute the next command to configure the board: -`./scripts/configure.sh stm32l1 nsh` - -This script will clean NuttX and set the configuration that we need. You should see something like this at the end of process at the terminal. - -``` - Copy files - Refreshing... -``` - -Once the board is configured, the next step will be to compile the firmware: -Type `make` and you should see something like this when it finishes in the terminal: -``` -CP: nuttx.hex -CP: nuttx.bin -``` - -Now it's ready for uploading the firmware into the board, so plug the micro USB cable an type the next command: -`./scripts/flash.sh stm32l1` - -If everything goes right, the loader will return the next message: -``` -wrote 49152 bytes from file nuttx.bin in 6.279262s (7.644 KiB/s) -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections -``` - -Connect the serial cable `RX` to pin `PA9` and `TX` to pin `PA10` and the GND wire to a `GND` pin. - -![img](imgs/l1.jpg) - -Open a new terminal and use a serial client, i.e. `minicom` to open the serial port, `sudo minicom -D /dev/ttyUSB0`. Once done, you should be able to see how `NSH` pops up when pressing key: - -``` -nsh> -nsh> -nsh> -nsh> ? -help usage: help [-v] [] - - ? exec hexdump mb sleep - cat exit kill mh usleep - echo help ls mw xd - -Builtin Apps: -nsh> -``` -If you don't know which interface is the micro USB, type `dmesg` command at a terminal, this command should let you know which is the last USB device that has been connected to your computer and at what interface is attached. - -## How to use an auxiliary UART {#Auxiliar-UART-Olimex} - -In this demo we will show how to use an auxiliary UART to send and receive messages. -When we run this demos, we will send the first argument to the auxiliary terminal and we will wait for an input from the auxiliary terminal. - -*Note: The STM32L1Discovery board can use a auxiliary port, but the application it's not compatible.* - -You need to configure, compile and upload the firmware, so execute the next commands: -- `./scripts/configure.sh olimex-stm32-e407 aux_serial` -- `make` -- `./scripts/flash.sh olimex-stm32-e407` - -For this demo we need to connect a USB cable to the mini USB port and a serial cable (TTL232) to the UART3 with the next pinout: - -- `USART3 TX` -> `TTL232 RX` -- `USART3 RX` -> `TTL232 TX` -- `GND Board` -> `TTL232 GND` - -And it should look like this: - -![image](imgs/olimex_uxd.jpg) - -Start the board, find which is the port of the auxiliary serial cable and open a terminal in that port. Init the application `aux_serial `. - -The message will appear in the other terminal and you need to push any key in the terminal to unlock the board console. This image is the board console: - -![image](imgs/aux_board.png) - -This image is the auxiliary console: - -![image](imgs/aux_console.png) - -## How to execute BMP180 example - -BMP180 is a I2C barometric pressure sensor. With this sensor you can obtain the atmospheric pressure and with that data you can calculate the altitude. - - - -[BMP180 breakout link](https://www.adafruit.com/product/1603) - -### Olimex STM32-E407 {#BMP180-Olimex} - -Go to the main folder of NuttX and type the command to configure the board: -`./scripts/configure.sh olimex-stm32-e407 bmp180` - -Compile: -`make` - -Upload: -`./scripts/flash.sh olimex-stm32-e407` - -### STM32L Discovery {#BMP180-Discovery} - -Go to the main folder of NuttX and type the command to configure the board: -`./scripts/configure.sh stm32l1 bmp180` - -Compile: -`make` - -Upload the firmware: -`./scripts/flash.sh stm32l1` - -In both cases it should return somenthing like this: - -- Configuration: -``` -Copy files -Refreshing... -``` -- Compilation: -``` -CP: nuttx.hex -CP: nuttx.bin -``` -- Upload the firmware -``` -wrote 131072 bytes from file nuttx.bin in 3.763846s (34.008 KiB/s) -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections -``` -(The number of writen bytes could be different in each board) - - -### Olimex - -Connect the sensor, as in the next image: - -![img](imgs/olimex_bmp.jpg) - -### STM32L Discovery - -Place Serial debugger `RX` to pin `PA10`, `TX`to `PA9` and `GND` to `GND , and connect the sensor `Vin` to `EXT_5V`, `GND` to `GND`, `SCL` to `PB9` and `SDA` to `PB8` (Board pin names are specified in silkscreen). For feeding the sensor, use the `EXT_5V` pin. Like in the image below: - -![img](imgs/l1_bmp180.jpg) - -In a new terminal, open a serial session attached to your serial cable. Once you have done it, press "RESET" button. You should see NuttX console popping up: - -``` -NuttShell (NSH) -nsh> -``` -Now type `?` command for checking if the example binary is available: - -``` -nsh> ? -help usage: help [-v] [] - - [ cmp false mkdir rm true - ? dirname free mh rmdir uname - basename dd help mount set umount - break df hexdump mv sh unset - cat echo kill mw sleep usleep - cd exec ls ps test xd - cp exit mb pwd time - -Builtin Apps: - adc_simple - hello - helloxx - bmp180 -``` - -Now, execute the example: - -`nsh>bmp180` - -This is the expected outoput: -``` -Pressure: 95988 -Pressure: 95987 -Pressure: 95987 -Pressure: 95985 -Pressure: 95988 -``` - -## How to execute HIH6130 example {#HIH6130-Olimex} - -The HIH6130 is humidity/temperature that works through I2C interface. - - - -[HIH6130 breakout link](https://www.sparkfun.com/products/11295) - -Go to the main folder of NuttX and type the command to configure the board: -`./scripts/configure.sh olimex-stm32-e407 hih6130` - -Compile: -`make` - -Upload: -`./scripts/flash.sh olimex-stm32-e407` - -### STM32L Discovery {#HIH6130-Discovery} - -Go to the main folder of NuttX and type the command to configure the board: -`./scripts/configure.sh stm32l1 hih6130` - -Compile: -`make` - -Upload the firmware: -`./scripts/flash.sh stm32l1` - -In both cases, it should return at the end something like this: -- Configuration: -``` -Copy files -Refreshing... -``` -- Compilation: -``` -CP: nuttx.hex -CP: nuttx.bin -``` -- Upload the firmware -``` -wrote 131072 bytes from file nuttx.bin in 3.763846s (34.008 KiB/s) -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections -``` -(The number of writen bytes could be different in each board) - -### Hardware connection - -### Olimex - -Connect the sensor as in the following image: - -![img](imgs/olimex_hih.jpg) - -Sensor `SDA` to `CON3` header `D0` pin -Sensor `SCL` to `CON3` header `D1` pin - -Sensor `VIN` to `PD` header `19` pin -Sensor `GND` to `PD` header `20` pin - -### STM32L Discovery - -Connect the sensor as in the following image: - -![img](imgs/l1_hih6130.jpg) - -Place the serial debugger `RX`to `PA10`, `TX`to `PA9` and `GND` to `GNDb, and connect the sensor `Vin` to `EXT_5V`, `GND` to `GND`, `SCL` to `PB9` and `SDA` to `PB8` (Board pin names are specified in the silkscreen). For feeding the sensor use the `EXT_5V` pin. - -In a new terminal, open a serial session attached to your serial cable, once you have done it, press "RESET" button. You should see NuttX console popping up: - -``` -NuttShell (NSH) -nsh> -``` -Now type `?` command for checking if the example binary is there: - -``` -nsh> ? -help usage: help [-v] [] - - [ cmp false mkdir rm true - ? dirname free mh rmdir uname - basename dd help mount set umount - break df hexdump mv sh unset - cat echo kill mw sleep usleep - cd exec ls ps test xd - cp exit mb pwd time - -Builtin Apps: - adc_simple - hello - helloxx - hih6130 -``` - -Now, execute the example: - -`nsh>hih6130` -This is the expected outoput: -``` -nsh> hih6130 -Temperature: 31 �ºC Humidity: 49 -Temperature: 31 �ºC Humidity: 45 -Temperature: 31 �ºC Humidity: 44 -Temperature: 31 �ºC Humidity: 44 -``` - -## How to execute UDP Echo server example {#UDPEcho-Olimex} - -Go to the main folder of NuttX and type the next command to configure the board: -`./scripts/configure.sh olimex-stm32-e407 udpecho` - -Compile: -`make` - -Upload: -`./scripts/flash.sh olimex-stm32-e407` - -This print the next: - -- Configuration: -``` -Copy files -Refreshing... -``` -- Compilation: -``` -CP: nuttx.hex -CP: nuttx.bin -``` -- Upload the firmware -``` -wrote 131072 bytes from file nuttx.bin in 3.763846s (34.008 KiB/s) -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections -``` - -Once the code it's uploaded to the board, do the next: -- Connect the ethernet cable to the ethernet port of the board. -- Connect the mini USB cable to the USB_OTG 1 port. - - -![img_20180903_101218_026](imgs/olimex_ethernet.jpg) - - -- Configure the console with a baud rate of 115200 bauds. -- Once you open the console, you should check if the app was correctly upload typing `?`. You should see the next: -![image](imgs/udp_1.jpg) - -- Then type `ifup eth0` to bring up the network: -![image](imgs/udp_2.jpg) - -- Mount the file system of NuttX typing `mount -t procfs /proc` -- See which IP was assigned to your board typing `ifconfig` and you should see this: -![image](imgs/udp_3.jpg) - -With this command, you can see statistics of the network, the IP of the board, the state of the connection... -In this case the IP that was assigned was the 192.168.1.35 -**By default this board will use the port 80.** To change it, you must do it in the app's code. - -- The last step in the board side is to type `udpecho` to run the udp echo server. --Then in the computer side, use `netcat` command. Type the next command: `netcat -u 192.168.1.35 80` - -Now if you type something in the computer, the board should echo the same and show the data of the messages, like in the image: - -**Computer side** - -![image](imgs/udp_4.jpg) - -**Board side** - -![image](imgs/udp_5.jpg) - -## How to execute TCP Echo server example {#TCPEcho-Olimex} - - -Go to the main folder of NuttX and type the next command to configure the board: -`./scripts/configure.sh olimex-stm32-e407 tcpecho` - -Compile: -`make` - -Upload: -`./scripts/flash.sh olimex-stm32-e407` - -This should be the result: - -- Configuration: -``` -Copy files -Refreshing... -``` -- Compilation: -``` -CP: nuttx.hex -CP: nuttx.bin -``` -- Upload the firmware -``` -wrote 131072 bytes from file nuttx.bin in 3.763846s (34.008 KiB/s) -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections -``` - -Once the code it's uploaded to the board, do the next steps: -- Connect the ethernet cable to the ethernet port of the board. -- Connect the mini USB cable to the USB_OTG 1 port. - -*Note:This example has been made using router in the middle of the computer and the Olimex board.* - -Once you reset the board, it should appear the NSH console and, if you type `?`, you should see the `tcpecho` application. - -![image](imgs/tcp_1.jpg) - -You need to bring up the network: - -![image](imgs/udp_2.jpg) - -Type `ifconfig` and you will see the IP. - -![image](imgs/udp_3.jpg) - -Finally execute the app, it should return the next: -``` -Start Echo Server - -``` - -Then, in your computer, you can open an TCP/IP client with the next command in the console: -` netcat -t 192.168.1.133 80` - -This command connects to the IP 192.168.1.133 and to the port 80 - -Now wright some characters in the terminal: - -``` -~$ netcat -t 192.168.1.133 80 -sfd -sfd -aaa -aaa -jjj -jjj -``` - -At the client, in your computer, you should see the reply of what you're writing. - -If you want to check or modify the connection data, you can do it in the next path: -`make menuconfig` - -`Application configuration` - -`Examples` - -And you will see something like this: - -![image](imgs/tcp.jpg) - -This shows the IP direction, the netmask and the router IP in hexadecimal format and the port to connect. - -The variables are shown in two hexadecimal numbers per each field. In case of the IP: -`0xCA` = 192 - -`0xA8` = 168 - -`0x01` = 1 - -`0x85` = 133 - - -## How to use MRF24j40-6LowPan {#MRF24j40-6LowPan-Olimex} - -With this demo, we'll be able to create a point to point connection with the MRF24J40 module using the protocol 6LowPan. This network, allows you to have hundreds of nodes with very little power consumption. -One of the nodes is a TCP or UDP server, and the other nodes are TCP or UDP clients that they connect to the server. - - -[mrf24j40 breakout link](https://store.digilentinc.com/pmod-rf2-ieee-802-15-rf-transceiver/) +```bash +source /opt/ros/$ROS_DISTRO/setup.bash -Go to the main folder of NuttX and type the command to configure the board: -`./scripts/configure.sh olimex-stm32-e407 mrf24j40-6lowpan` +mkdir uros_ws && cd uros_ws -Compile: -`make` +git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro-ros-build.git src/micro-ros-build -Upload: -`./scripts/flash.sh olimex-stm32-e407` +sudo apt update && rosdep update +rosdep install --from-path src --ignore-src -y -It should return somenthing like this: +colcon build -- Configuration: -``` -Copy files -Refreshing... -``` -- Compilation: -``` -CP: nuttx.hex -CP: nuttx.bin +source install/local_setup.bash ``` -- Upload the firmware -``` -wrote 131072 bytes from file nuttx.bin in 3.763846s (34.008 KiB/s) -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections -``` -(The number of written bytes could be different in each board) - -Once the firmware was configured and uploaded, we need to connect the breakout board like this: -- `Board D13` -> `MRF24J40 SCLK` -- `Board D12` -> `MRF24J40 MISO` -- `Board D11` -> `MRF24J40 MOSI` -- `Board D10` -> `MRF24J40 CS` -- `Board D8` -> `MRF24J40 INT` - -Finally, connect the mini USB cable to the USB OTG1, and the connections should look like this: - - -![image](imgs/olimex_mrf24j40.jpg) - -Once the wiring is done, open a console and you should see this: +## Create micro-ROS firmware +This step will download all the required software. ```bash -nsh> ? -help usage: help [-v] [] - - [ cd df help ls mw set true - ? cp echo hexdump mb ps sh uname - addroute cmp exec ifconfig mkdir pwd sleep umount - basename dirname exit ifdown mh rm test unset - break dd false ifup mount rmdir telnetd usleep - cat delroute free kill mv route time xd - -Builtin Apps: - udp_6lowpan ping6 i8sak +ros2 run micro_ros_setup create_firmware_ws.sh nuttx olimex-stm32-e407 ``` +At this point we have everything ready in our workspace to develop a new application. With the next steps, we will start the development of the app itself. -Execute the App ``udp_6lowpan``. -When you execute it, the app will ask you if you want to do an auto-configuration. -The first time that we execute this app after the initialization of the board, we need to configure the network. If you execute the autoconfiguration, the configuration process will be simplified, otherwise, you will need to configure manually. **If you don't configure the board, it won't work properly.** -If you type 'Y', it should appear the next output: +## Aplication development -```bash -nsh> udp_6lowpan -Do you want to execute the automatic WPAN configuration? (y/n) -Starting WPAN configuration -Type C to be coordinator -Type N to be node - -``` +- Go to: ``uros_ws/firmware/apps/examples`` +- Create a folder called ``uros_pingpong`` -This is asking if you want to be a coordinator or a node. -The difference between a coordinator and a node is that the first one can work as a router, coordinating the network traffic of up to 8 nodes. -On the other hand, the node is an endpoint device which only sends and receive data, it doesn't coordinate the traffic of the other devices. +Now we're going to considerer the folder application the next folder: ``uros_ws/firmware/apps/examples/uros_ws/firmware/apps/examples`` -**Note:** A coordinator should be bring-up before the node configuration. +### Create Kconfig file -If you choose coordinator, type 'C' and it should return the next output: +For this step, you need to create an empty file called **Kconfig**, inside the application folder. These files contain the configuration menu to configure the application and add it to the build system list of NuttX. +In the next lines you can see an example of a basic generic implementation: ```bash -ifdown wpan0...OK -i8sak: resetting MAC layer -i8sak: starting PAN -Choose your ID (00 to FF) -``` -Type the ID that you want, it should be between 00 and FF (Hexadecimal value). -**Caution:** Avoid to use the same ID in two devices,or you will get and IP conflict.The ID must be unique. - -Once you write your ID, it should return the next data: +config UROS_PINGPONG_EXAMPLE + bool "micro-ROS Ping Pong" + default n + depends on UROS + ---help--- + + +if UROS_PINGPONG_EXAMPLE + +config UROS_PINGPONG_EXAMPLE_PROGNAME + string "Program name" + default "uros_ping_pong" + depends on BUILD_KERNEL + ---help--- + This is the name of the program that will be use when the NSH ELF + program is installed. + +endif +``` + +### Create Makefile + +Create an empty file called **Makefile**, inside of the application folder. +Below, you can see an example of a generic implementation: +```Makefile +-include $(TOPDIR)/Make.defs + +#Set the scheduler priority for the app. +CONFIG_UROS_PINGPONG_EXAMPLE_PRIORITY ?= SCHED_PRIORITY_DEFAULT +#Set the stack size to the app. The minimum stack size on NuttX for a micro-ROS App is 65000 bytes +CONFIG_UROS_PINGPONG_EXAMPLE_STACKSIZE ?= 65000 + +#This is the name of the app on the NSH console +APPNAME = uros_pingpong +PRIORITY = $(CONFIG_UROS_PINGPONG_EXAMPLE_PRIORITY) +STACKSIZE = $(CONFIG_UROS_PINGPONG_EXAMPLE_STACKSIZE) + +#Add the source files. +ASRCS = +CSRCS = +MAINSRC = uros_pingpong_main.c + +CONFIG_UROS_PINGPONG_EXAMPLE_PROGNAME ?= uros_pingpong$(EXEEXT) +PROGNAME = $(CONFIG_UROS_PINGPONG_EXAMPLE_PROGNAME) +UROS_PINGPONG_INCLUDES = $(shell find $(APPDIR)/$(CONFIG_UROS_DIR)/install -type d -name include) +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" "$(UROS_PINGPONG_INCLUDES)"} -std=c99 + +MODULE = CONFIG_UROS_PINGPONG_EXAMPLE + +include $(APPDIR)/Application.mk +``` + +### Create Make.defs file +Create an empty file called **Make.defs**, inside of the application folder. +You need to add the following lines: +```Makefile +ifeq ($(CONFIG_UROS_PINGPONG_EXAMPLE),y) + CONFIGURED_APPS += examples/uros_pingpong +endif +``` + +This file will add the folder as an application if you set the option on the configuration menu of NuttX. + +### Create the main file + +Create a file named ``uros_pingpong_main.c``. +In the box below, we will show a pinpong example: +```c +//Nuttx specific library +#include + +// Micro-ROS specific library +#include +#include +#include "rosidl_generator_c/string_functions.h" +#include +#include + +// C standard library +#include +#include +#include +#include + +#define STRING_BUFFER_LEN 100 + +// Thread to trigger a publication guard condition +void * trigger_guard_condition(void *args){ + rcl_guard_condition_t * guard_condition = (rcl_guard_condition_t *)args; + + while(true){ + rcl_trigger_guard_condition(guard_condition); + sleep(5); + } +} + +#if defined(BUILD_MODULE) +int main(int argc, char *argv[]) +#else +int uros_pingpong_main(int argc, char* argv[]) +#endif +{ + //Init RCL options + rcl_init_options_t options = rcl_get_zero_initialized_init_options(); + rcl_init_options_init(&options, rcl_get_default_allocator()); + + // Init RCL context + rcl_context_t context = rcl_get_zero_initialized_context(); + rcl_init(0, NULL, &options, &context); + + // Create a node + rcl_node_options_t node_ops = rcl_node_get_default_options(); + rcl_node_t node = rcl_get_zero_initialized_node(); + rcl_node_init(&node, "pingpong_node", "", &context, &node_ops); + + // Create a reliable ping publisher + rcl_publisher_options_t ping_publisher_ops = rcl_publisher_get_default_options(); + rcl_publisher_t ping_publisher = rcl_get_zero_initialized_publisher(); + rcl_publisher_init(&ping_publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/ping", &ping_publisher_ops); + + // Create a best effort pong publisher + rcl_publisher_options_t pong_publisher_ops = rcl_publisher_get_default_options(); + pong_publisher_ops.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT; + rcl_publisher_t pong_publisher = rcl_get_zero_initialized_publisher(); + rcl_publisher_init(&pong_publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/pong", &pong_publisher_ops); + + // Create a reliable pong subscriber + rcl_subscription_options_t pong_subscription_ops = rcl_subscription_get_default_options(); + rcl_subscription_t pong_subscription = rcl_get_zero_initialized_subscription(); + rcl_subscription_init(&pong_subscription, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/pong", &pong_subscription_ops); + + // Create a best effort ping subscriber + rcl_subscription_options_t ping_subscription_ops = rcl_subscription_get_default_options(); + ping_subscription_ops.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT; + rcl_subscription_t ping_subscription = rcl_get_zero_initialized_subscription(); + rcl_subscription_init(&ping_subscription, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/ping", &ping_subscription_ops); + + // Create a guard condition + rcl_guard_condition_t guard_condition = rcl_get_zero_initialized_guard_condition(); + rcl_guard_condition_options_t guard_condition_options = rcl_guard_condition_get_default_options(); + rcl_guard_condition_init(&guard_condition, &context, guard_condition_options); + + // Create a thread that triggers the guard condition + pthread_t guard_condition_thread; + pthread_create(&guard_condition_thread, NULL, trigger_guard_condition, &guard_condition); + + // Create a wait set + rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); + rcl_wait_set_init(&wait_set, 2, 1, 0, 0, 0, 0, &context, rcl_get_default_allocator()); + + // Create and allocate the pingpong publication message + std_msgs__msg__Header msg; + char msg_buffer[STRING_BUFFER_LEN]; + msg.frame_id.data = msg_buffer; + msg.frame_id.capacity = STRING_BUFFER_LEN; + + // Create and allocate the pingpong subscription message + std_msgs__msg__Header rcv_msg; + char rcv_buffer[STRING_BUFFER_LEN]; + rcv_msg.frame_id.data = rcv_buffer; + rcv_msg.frame_id.capacity = STRING_BUFFER_LEN; + + // Set device id and sequence number; + int device_id = rand(); + int seq_no; + + int pong_count = 0; + struct timespec ts; + rcl_ret_t rc; + + do { + // Clear and set the waitset + rcl_wait_set_clear(&wait_set); + + size_t index_pong_subscription; + rcl_wait_set_add_subscription(&wait_set, &pong_subscription, &index_pong_subscription); + + size_t index_ping_subscription; + rcl_wait_set_add_subscription(&wait_set, &ping_subscription, &index_ping_subscription); + + size_t index_guardcondition; + rcl_wait_set_add_guard_condition(&wait_set, &guard_condition, &index_guardcondition); + + // Run session for 100 ms + rcl_wait(&wait_set, RCL_MS_TO_NS(100)); + + // Check if it is time to send a ping + if (wait_set.guard_conditions[index_guardcondition]) { + // Generate a new random sequence number + seq_no = rand(); + sprintf(msg.frame_id.data, "%d_%d", seq_no, device_id); + msg.frame_id.size = strlen(msg.frame_id.data); + + // Fill the message timestamp + clock_gettime(CLOCK_REALTIME, &ts); + msg.stamp.sec = ts.tv_sec; + msg.stamp.nanosec = ts.tv_nsec; + + // Reset the pong count and publish the ping message + pong_count = 0; + rcl_publish(&ping_publisher, (const void*)&msg, NULL); + // printf("Ping send seq 0x%x\n", seq_no); + } + + // Check if some pong message is received + if (wait_set.subscriptions[index_pong_subscription]) { + rc = rcl_take(wait_set.subscriptions[index_pong_subscription], &rcv_msg, NULL, NULL); + + if(rc == RCL_RET_OK && strcmp(msg.frame_id.data,rcv_msg.frame_id.data) == 0) { + pong_count++; + // printf("Pong for seq 0x%x (%d)\n", seq_no, pong_count); + } + } + + // Check if some ping message is received and pong it + if (wait_set.subscriptions[index_ping_subscription]) { + rc = rcl_take(wait_set.subscriptions[index_ping_subscription], &rcv_msg, NULL, NULL); + + // Dont pong my own pings + if(rc == RCL_RET_OK && strcmp(msg.frame_id.data,rcv_msg.frame_id.data) != 0){ + // printf("Ping received with seq 0x%x (%d). Answering.\n", seq_no); + rcl_publish(&pong_publisher, (const void*)&rcv_msg, NULL); + } + } + + usleep(10000); + } while (true); +} +``` + +Once the application is ready, the only thing left to do is to create the right configuration. + +## Create a config profile + +Create a specific configuration from scratch can be a challenging task, so we're going to start from an already existing one and modify it for our new application. + +Execute the next command: ```bash -Your hardware address is: i8sak set eaddr 00:fa:de:00:de:ad:be:00 - -i8sak: accepting all assoc requests -i8sak: daemon started -ifup wpan0...OK -Mounting proc file system -wpan0 Link encap:6LoWPAN HWaddr 00:be:ad:de:00:de:fa:00 at UP - inet6 addr: fe80::2be:adde:de:fa00/64 - inet6 DRaddr: ::/64 - - RX: Received Fragment Errors - 00000000 00000000 00000000 - IPv6 Dropped - 00000000 00000000 - TX: Queued Sent Errors Timeouts - 00000000 00000000 00000000 00000000 - Total Errors: 00000000 - - - - -Available commands - -To send a package type: write - -To receive a package type: read - -To exit type: quit - +cd ~/uros_ws +ros2 run micro_ros_setup configure_firmware.sh uros ``` -Now the coordinator network is ready to send and receive packages. Also is prepared to receive an association request from the nodes. This association request is a tool of node to be coordinated by a coordinator. - -Coming back to the role menu, if you choose a node, will also ask for an ID (**Remember, the ID must be unique.**). And it should look like this: +This sets the Ethernet and Micro-ROS required configuration. However, in order to add our application, we're going to modify it. +### Modify the configuration +Now type the following commands: ```bash -nsh> udp_6lowpan -Do you want to execute the automatic WPAN configuration? (y/n) -Starting WPAN configuration -Type C to be coordinator -Type N to be node - - -ifdown wpan0...OK -Choose your ID (00 to FF) - +cd uros_ws/firmware/NuttX +make menuconfig ``` -The node can send and receive a message with and without a coordinator. After giving a valid ID, we can have the next two output: -- If a coordinator is available in the network: - -```bash -Your hardware address is: i8sak set eaddr 00:fa:de:00:de:ad:be:01 +This will open the NuttX menu config, which allows you to modify the configuration of the RTOS, including adding a new application. -i8sak: daemon started -i8sak: issuing ASSOC. request 1 -i8sak: ASSOC.request succeeded -ifup wpan0...OK -Mounting proc file system -i8sak: daemon closing -wpan0 Link encap:6LoWPAN HWaddr 01:be:ad:de:00:de:fa:00 at UP - inet6 addr: fe80::3be:adde:de:fa00/64 - inet6 DRaddr: ::/64 - RX: Received Fragment Errors - 00000000 00000000 00000000 - IPv6 Dropped - 00000000 00000000 - TX: Queued Sent Errors Timeouts - 00000000 00000000 00000000 00000000 - Total Errors: 00000000 +- On the menu, you need to follow the next path: +``Application Configuration -> Examples `` +![](images/nuttx_menuconfig.png) +- This will show a list of the available applications. You need to find: ``micro-ROS Ping-Pong`` and click ``y`` to add it. +![](images/nuttx_examples.png) +- Now push three times the key ``ESC`` to close the menu. You will be asked if you want to save the save your new configuration, and you need to click ``Yes``. -Available commands - -To send a package type: write - -To receive a package type: read - -To exit type: quit - -``` -- No coordinator is available: +### Add your configuration +Execute the following commands: ```bash -Your hardware address is: i8sak set eaddr 00:fa:de:00:de:ad:be:01 - -i8sak: daemon started -i8sak: issuing ASSOC. request 1 -i8sak: ASSOC.request failed: No ack -ifup wpan0...OK -Mounting proc file system -i8sak: daemon closing -wpan0 Link encap:6LoWPAN HWaddr 01:be:ad:de:00:de:fa:00 at UP - inet6 addr: fe80::3be:adde:de:fa00/64 - inet6 DRaddr: ::/64 - - RX: Received Fragment Errors - 00000000 00000000 00000000 - IPv6 Dropped - 00000000 00000000 - TX: Queued Sent Errors Timeouts - 00000000 00000000 00000000 00000000 - Total Errors: 00000000 - - - - -Available commands - -To send a package type: write - -To receive a package type: read - -To exit type: quit - +cd uros_ws/firmware/NuttX +make savedefconfig ``` -You can notice that the difference is at the ```ASSOC.request``` which failed or succeed. If in the future you want to have a coordinator in your network, you can associate a node to it, as easy as executing again the autoconfiguration. - -At this point, remember to copy the IP address of your device. The IP of the board is the value of **inet6 addr**. For this example is fe80::3be:adde: de:fa00. -If you can't find in the output of this app, just type ```quit``` and the application will close and you will be at the NSH console again. At this moment, type ```ifconfig``` and all the data of the connection will be shown. -```bash -nsh> ifconfig -wpan0 Link encap:6LoWPAN HWaddr 01:be:ad:de:00:de:fa:00 at UP - inet6 addr: fe80::3be:adde:de:fa00/64 - inet6 DRaddr: ::/64 - - RX: Received Fragment Errors - 00000000 00000000 00000000 - IPv6 Dropped - 00000000 00000000 - TX: Queued Sent Errors Timeouts - 00000000 00000000 00000000 00000000 - Total Errors: 00000000 - - IPv6 TCP UDP ICMPv6 -Received 0000 0000 0000 0000 -Dropped 0000 0000 0000 0000 - IPv6 VHL: 0000 - Checksum ---- 0000 0000 ---- - TCP ACK: 0000 SYN: 0000 - RST: 0000 0000 - Type 0000 ---- ---- 0000 -Sent 0000 0000 0000 0000 - Rexmit ---- 0000 ---- ---- -``` +This will generate a file called ``defconfig`` inside of ``uros_ws/firmware/NuttX``. This file is a config profile with all the required configuration to run your specific configuration which includes your application. -Everything is ready to send and receive UDP package from/to the 6lowpan network. The way to use it is exactly the same in both modes (coordinator and node). +Finally create a folder called ``uros_pingpong`` into ``uros_ws/firmware/NuttX/configs/olimex-stm32-e407`` and move the defconfig file to uros_pingpong folder. -The ```udp_6lowpan``` give us the next options: +## Build your application +Now that everything is ready, the only thing left to do is to continue with the build system instructions. Execute the next command on the build system to start the build process: ```bash -Available commands - -To send a package type: write - -To receive a package type: read - -To exit type: quit - +cd ~/uros_ws +ros2 run micro_ros_setup configure_firmware.sh uros_pingpong +ros2 run micro_ros_setup build_firmware.sh ``` -To send a package, type ```write``` and push enter. -The application will ask for the next information: -- Destination IP: The IPV6 of the board that we want to send a package. -- Destination Port: The open port of the destination board. -- Origin port: The port that we want to use to send the data in the emitter board. -(Is mandatory to push enter once you write the asked data). +If it returns the next output, your build step succeded and your application was implemented properly. -Once all the data are introduced, it should return something like this: ```bash -Introduce the IVP6 Destination -Introduce the port destination -Introduce the port origin -Conection data: - -Dest_IP: fe80::2be:adde:de:fa00 - -Dest_Port: 61616 - -Origin_Port: 61617 -Introduce a message to send: +AR: stm32_boot.o stm32_bringup.o stm32_spi.o libatomic.o stm32_autoleds.o stm32_buttons.o stm32_appinit.o stm32_usb.o +make[2]: Leaving directory '/home/juan/uros_pinpong/firmware/NuttX/configs/olimex-stm32-e407/src' +LD: nuttx +arm-none-eabi-ld --entry=__start -nostartfiles -nodefaultlibs -g -T/home/juan/uros_pinpong/firmware/NuttX/configs/olimex-stm32-e407/scripts/ld.script -L"/home/juan/uros_pinpong/firmware/NuttX/staging" -L"/home/juan/uros_pinpong/firmware/NuttX/arch/arm/src/board" -L "/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/lib/thumb/v7e-m" \ + -o "/home/juan/uros_pinpong/firmware/NuttX/nuttx" \ + --start-group -lsched -ldrivers -lconfigs -lc -lmm -larch -lxx -lapps -lnet -lfs -lbinfmt -lxx -lboard -lsupc++ "/usr/lib/gcc/arm-none-eabi/6.3.1/thumb/v7e-m/libgcc.a" --end-group +make[1]: Leaving directory '/home/juan/uros_pinpong/firmware/NuttX/arch/arm/src' +CP: nuttx.hex +CP: nuttx.bin ``` -Now you're able to send messages to fe80::2be:adde:de:fa00 port 61616. -If you want to close the connection and not send any more packages, you can type ```quit``` plus enter, and it should return to the main app menu. - -If you want to use your device as receiver, just type ```read``` in the main app menu. This will ask you which port should it use to accept packages. -(Is possible to receive and send messages at the same type, but you will need to create a custom app) -After type the number of the port and press enter(For this example, we're going to use the port 61616), it should output the next: -```bash -Available commands - -To send a package type: write - -To receive a package type: read - -To exit type: quit -Introduce the reception port -Listening on 61616 for input packets +Now the firmware is ready, is just necessary to flash the board. First, connect Olimex ARM-USB-TINY-H JTAG programmer to the board's JTAG port: -``` + -This the output that you should see when you send a package and when you receive: -- Sending a package: +Make sure that the board power supply jumper (PWR_SEL) is in the 3-4 position in order to power the board from the JTAG connector: -```bash -wpan0 Link encap:6LoWPAN HWaddr 00:be:ad:de:00:de:fa:00 at UP - inet6 addr: fe80::2be:adde:de:fa00/64 - inet6 DRaddr: ::/64 - - RX: Received Fragment Errors - 00000000 00000000 00000000 - IPv6 Dropped - 00000000 00000000 - TX: Queued Sent Errors Timeouts - 00000000 00000000 00000000 00000000 - Total Errors: 00000000 - - - - -Available commands - -To send a package type: write - -To receive a package type: read - -To exit type: quit -Introduce the IVP6 Destination -Introduce the port destination -Introduce the port origin -Conection data: - -Dest_IP: fe80::3be:adde:de:fa00 - -Dest_Port: 61616 - -Origin_Port: 61617 -Introduce a message to send: -Sending 13 characters: micro-ROS - -Introduce a message to send: -``` + -- Receiving a package: +You should see the red LED lighting. It is time to flash the board: ```bash -wpan0 Link encap:6LoWPAN HWaddr 01:be:ad:de:00:de:fa:00 at UP - inet6 addr: fe80::3be:adde:de:fa00/64 - inet6 DRaddr: ::/64 - - RX: Received Fragment Errors - 00000000 00000000 00000000 - IPv6 Dropped - 00000000 00000000 - TX: Queued Sent Errors Timeouts - 00000000 00000000 00000000 00000000 - Total Errors: 00000000 - - - - -Available commands - -To send a package type: write - -To receive a package type: read - -To exit type: quit -Introduce the reception port -Listening on 61616 for input packets -Received 13 bytes from 80fe:0000:0000:0000:be02:dead:de00:00fa port 61617 -Received packet: micro-ROS - +# Flash step +ros2 run micro_ros_setup flash_firmware.sh ``` +## Running the micro-ROS app -This version of the 6lowpan stack, have interoperability with 6lowpan stack of Linux. So we can have communication between NuttX and 6lowpan. - -The ping between NuttX devices work properly, but with Linux, devices don't work properly and a final point to know is the dynamic association and multi-hop communication doesn't work properly. So, communications are only point-to-point. - - - -## How to use the ADC demo {#ADC-Olimex} - -In this demo we will take the analog value pin A1, that is attached to channel 4 of the ADC number 3. This demo only works in the Olimex board. - -First we need to configure, compile and upload the firmware: - -- `./scripts/configure.sh olimex-stm32-e407 adc` - -To compile: -- `make` - -To upload: -- `./scripts/flash.sh olimex-stm32-e407` - -For this demo it's only necessary to connect a minim USB cable to the USB-OTG 1 port, to see the console. -Once you run the console, you should see this apps: - -![image](imgs/adc_nsh.png) - -If you execute the application typing `adc_simple`, you will see a measurement of the A1 pin every 100ms like in the image: +The micro-ROS app is ready to connect to a micro-ROS-Agent and start talking with the rest of the ROS 2 world. -![image](imgs/adc_measure.png) - -# How to execute CPU performance telemetry app {#Telemetry-Olimex} - -Go to the main folder of NuttX and type the next command to configure the board: -`./scripts/configure.sh olimex-stm32-e407 telemetry` - -Compile: -`make` - -Upload: -`./scripts/flash.sh olimex-stm32-e407` - -This print the next: - -- Configuration: -``` -Copy files -Refreshing... -``` -- Compilation: -``` -CP: nuttx.hex -CP: nuttx.bin -``` -- Upload the firmware -``` -wrote 131072 bytes from file nuttx.bin in 3.763846s (34.008 KiB/s) -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections -``` +First of all, create and build a micro-ROS agent: -Once the code it's uploaded to the board, do the next: -- Connect the mini USB cable to the USB_OTG 1 port. - -When you reset the board, yo should see this app: - -``` -NuttShell (NSH) -nsh> ? -help usage: help [-v] [] - - [ cmp false mkdir rm true - ? dirname free mh rmdir uname - basename dd help mount set umount - break df hexdump mv sh unset - cat echo kill mw sleep usleep - cd exec ls ps test xd - cp exit mb pwd time - -Builtin Apps: - telemetry -nsh> -``` - -The App, will perform the next tests: -## CPU Performance test: -This test is to show the percentage of CPU usage under heavy floating operations. -We have the variable 'e' which have the value of the first digits of Pi. So we will do the next operations 100000 times: 'e'='e'*'e'. -This unit doesn't have a DSP unit, so the floating point operations have a high cost for the CPU. -This test could also use as a benchmark to compare different MCUs. +```bash +# Download micro-ROS-Agent packages +ros2 run micro_ros_setup create_agent_ws.sh -``` -nsh> telemetry -Mounting file system - -Pushing the CPU to the limits -We will do the next floating operation: -e=3.141592653589793 -e=e*e -This operation 100000 times -================================================================================ - -Max CPU load achieve: - 30.9% +# Build micro-ROS-Agent packages, this may take a while. +colcon build --metas src +source install/local_setup.bash ``` -## Show the interruptions raised internally: +Then connect the Olimex development board to the computer using the usb to serial cable: -This show the interruption raised internally, the ID of the interruption if it has any argument and the number of times raised. -``` -Showing interruptions - -IRQ HANDLER ARGUMENT COUNT RATE - 3 080009cd 00000000 27 3.400 - 15 080035e1 00000000 794 100.000 - 83 080042c9 00000000 3314 417.380 -``` + -## Memory usage test: +***TIP:** Color codes are applicable to [this cable](https://www.olimex.com/Products/Components/Cables/USB-Serial-Cable/USB-Serial-Cable-F/). Make sure to match Olimex Rx with Cable Tx and vice-versa. Remember GND!* -This test will show the usage of the RAM memory. If you want to calculate the RAM that has been used, you can do the next calculus: -192K- free/1024 = Used RAM. -``` -Memory ussage +Then run the agent: - total used free largest -Umem: 190800 16192 174608 123072 +```bash +# Run a micro-ROS agent +ros2 run micro_ros_agent micro_ros_agent serial --dev [device] ``` -## Stack info of the App: - -``` -Stack of the application +***TIP:** you can use this command to find your serial device name: `ls /dev/serial/by-id/*`* -StackBase: 0x10003110 -StackSize: 2004 -``` +And finally, let's check that everything is working in a new command line. We are going to listen to ping topic to check whether the Ping Pong node is publishing its own pings -## Info of a running App: -In this last test, you can see the priority of an App, the scheduling algorithm, what it is (a task or a thread) and the state: -``` -Status of the running task - -Name: popen -Type: Task -State: Running -Flags: --- -Priority: 100 -Scheduler: SCHED_RR -SigMask: 00000000 -``` +```bash +source /opt/ros/$ROS_DISTRO/setup.bash -If you run this command: `cat /proc/self/status `, you will see that the task has changed, and scheduling algorithm. +# Subscribe to micro-ROS ping topic +ros2 topic echo /microROS/ping ``` -nsh> cat /proc/self/status -Name: init -Type: Task -State: Running -Flags: --- -Priority: 100 -Scheduler: SCHED_FIFO -SigMask: 00000000 -``` -# How to execute Power Manager example - -This example is simple. After some seconds, the board enter into a sleep mode that could be re-waken up, writing into the serial season. As the MCU is in low power mode, some data is lost, until the complete wake up is done. - -### Olimex STM32-E407 {#Power-Manager-Olimex} -Go to the main folder of NuttX and type the command to configure the board: -`./scripts/configure.sh olimex-stm32-e407 pm` +You should see the topic messages published by the Ping Pong node every 5 seconds: -Compile: -`make` - -Upload: -`./scripts/flash.sh olimex-stm32-e407` - -### STM32L Discovery {#Power-Manager-Discovery} - -Go to the main folder of NuttX and type the command to configure the board: -`./scripts/configure.sh stm32l1 pm` - -Compile: -`make` - -Upload the firmware: -`./scripts/flash.sh stm32l1` - -In both cases, it should return at the end something like this: -- Configuration: -``` -Copy files -Refreshing... ``` -- Compilation: -``` -CP: nuttx.hex -CP: nuttx.bin -``` -- Upload the firmware -``` -wrote 131072 bytes from file nuttx.bin in 3.763846s (34.008 KiB/s) -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections +user@user:~$ ros2 topic echo /microROS/ping +stamp: + sec: 20 + nanosec: 867000000 +frame_id: '1344887256_1085377743' +--- +stamp: + sec: 25 + nanosec: 942000000 +frame_id: '730417256_1085377743' +--- ``` -(The number of writen bytes could be different in each board) - -Now open a serial session for connecting to the board. Once the prompt pops-up, do not type for some seconds and you will see that, in a point, if you type something, it will not appear at the command line. After some seconds, the command line will again work properly. - - -## How to use a micro SD-Card in the Olimex-STM32-E407 board {#SD-Card-Olimex} - -This demo it's only for the Olimex board. This demo shows how to write and read files from a SD card. - -To configure type the next command in the main folder of NuttX: -- `./scripts/configure.sh olimex-stm32-e407 sd` - -Compile it: -- `make` - -Upload the firmware to the board: -- `./scripts/flash.sh olimex-stm32-e407` -This demo doesn't require any special wiring, only connect the mini-USB cable to the USB-OTG port and introduce the SD-Card before power on the board. -This board doesn't have automatic detection of insertion or extraction of SD-Card. +On another command line, let's subscribe to the pong topic -Once you're in the console, type `ls /dev` to see if the card was register: -![image](imgs/sd_detect.png) - -The `mmcsd0` interface is the SD card. - -The next step is to mount the file SD-Card file system, so it's necessary to write the next command: -`mount -t vfat /dev/mmcsd0 /mnt` - -Now the SD Card is ready to use. So you can use the next commands to write something on it: -- See the files available: `ls /mnt` -- Read a file: `cat /mnt/` -- Write or createa file: `echo "Content to write" > /mnt/name_of_your_file` - -## How to execute Micro XRCE-DDS - -In this example, we will execute Micro XRCE-DDS client in NuttX. This example runs a shape demo. -For this demo we need two boards (It doesn't matter if it's the Olimex Board or the STM32L1), one will be the publisher which will send a topic with a shape, the color of the shape and the coordinate of the shape. The other board will subscribe to the topic. -At this moment it's only possible to work through serial, but it could be possible to use with UDP and TCP in a future. - -### Olimex STM32-E407 {#Micro-XRCE-DDS-Olimex} - -Go to the main folder of NuttX and type the command to configure the board: -`./scripts/configure.sh olimex-stm32-e407 microxrcedds` - -Compile: -`make` - -Upload: -`./scripts/flash.sh olimex-stm32-e407` - -### STM32L Discovery {#Micro-XRCE-DDS-Discovery} - -Go to the main folder of NuttX and type the command to configure the board: -`./scripts/configure.sh stm32l1 microxrcedds` - -Compile: -`make` - -Upload the firmware: -`./scripts/flash.sh stm32l1` +```bash +source /opt/ros/$ROS_DISTRO/setup.bash -In both cases it should return at the end something like this: -- Configuration: +# Subscribe to micro-ROS pong topic +ros2 topic echo /microROS/pong ``` -Copy files -Refreshing... -``` -- Compilation: -``` -CP: nuttx.hex -CP: nuttx.bin -``` -- Upload the firmware -``` -wrote 131072 bytes from file nuttx.bin in 3.763846s (34.008 KiB/s) -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections -``` -(The number of wrote bytes could be different in each board) - -At this point the board is ready to work, and we need to attach the next cables: - -### Olimex STM32-E407 - -Connect the micro USB to the USB-OTG1 to have access to the console. -Then we need to connect to the USART3, so follow this diagram: -- `USART3 TX` -> `TTL232 RX` -- `USART3 RX` -> `TTL232 TX` -- `GND Board` -> `TTL232 GND` - -And it should look like this: -![image](imgs/olimex_uxd.jpg) - -### STM32LDiscovery - -For this board we need two TTL232 cables. The first one is used to show the console. -Connect the serial cable `RX` to pin `PA9` and `TX` to pin `PA10` and the GND wire to a `GND` pin. - -Then, you need to connect to the second UART to use Micro XRCE-DDS: -Connect the serial cable `RX` to pin `PA2` and `TX` to pin `PA3` and the GND wire to a `GND` pin. -And it should look like this: -![image](imgs/l1_uxd.jpg) +At this point, we know that our app is publishing pings. Let's check if it also answers to someone else pings in a new command line: +```bash +source /opt/ros/$ROS_DISTRO/setup.bash -In this example, we use an Olimex board and a STM32L1 Board, but you can use any combination between STM32L1, Olimex Board and PC. Now we're going to execute the Agent in the PC. -First, we need to check the port number of the serial cable that we want to use as Micro XRCE-DDS interface. -Note: You must installed Micro XRCE-DDS agent previously, follow this guide -> https://micro-xrce-dds.readthedocs.io/en/latest/installation.html - -Open a console and type the next command: -`MicroXRCE-DDSAgent serial ` - -If you're using the Olimex Board you need to type the command in the console: -`client --serial /dev/ttyS0` -Otherwise, if you using the STM32LDiscovery board, you need to use this command: -`client --serial /dev/ttyS1` - -Now to set a board as **Publisher**, you need to use the next commands: -``` -create_session -create_participant 1 -create_topic 1 1 -create_publisher 1 1 -create_datawriter 1 1 -``` - -If you want to be **Subscriber** you need to use the next commands: -``` -create_session -create_participant 1 -create_topic 1 1 -create_subscriber 1 1 -create_datareader 1 1 +# Send a fake ping +ros2 topic pub --once /microROS/ping std_msgs/msg/Header '{frame_id: "fake_ping"}' ``` -To publish a topic, you need to write this command: -``` - write_data 1 128 200 200 40 BLUE - ``` +Now, we should see on the ping subscriber our fake ping along with the board pings: -To receive a data in the subscriber, you need to write this command: ``` -request_data 1 128 1 +user@user:~$ ros2 topic echo /microROS/ping +stamp: + sec: 0 + nanosec: 0 +frame_id: fake_ping +--- +stamp: + sec: 305 + nanosec: 973000000 +frame_id: '451230256_1085377743' +--- +stamp: + sec: 310 + nanosec: 957000000 +frame_id: '2084670932_1085377743' +--- ``` -You can find more detailed information on this page: -https://micro-xrce-dds.readthedocs.io/en/latest/index.html - -Important note: For each client that you want to run, you need to run an agent in PC. -For example: -We have the STM32L1 as publisher, so we need to check the serial port number of the Micro XRCE-DDS serial interface and run an Agent in the PC. -Then, we have the Olimex as subscriber, so we need to follow the same steps as with the STM32L1 board. - +And in the pong subscriber, we should see the board's answer to our fake ping: -## How to use micro-ROS demo {#micro-ROS-demo-Olimex} - -In this demo, we will use the alpha version of micro-ROS for NuttX running under the Olimex-STM32-E407 board. -With board running this demo we could create a ROS 2 publisher or a ROS 2 subscriber. -The publisher creates and publishes as a topic a progressive count of integers (From 0 to 1000). -The subscriber subscribes to that topic and shows the value of the number published. - -This demo is a little bit different as the other demos because we need to follow another path to configure it. -We need to download the docker files of micro-ROS, executing the next command: -`git clone -b features/micro-ros https://github.com/micro-ROS/docker` -(Note: This repository might change of location) - -Now it's necessary to build the docker file, so type the next command: -`docker build -t microros_stm32f4 .` -If everything goes right, you should run this command to start the docker: -`docker build -t microros_stm32f4 ` - -At this point it only left to upload the precompile firmware to the board, typing the next commands: -`cd nuttx` -`openocd -f interface/ftdi/olimex-arm-usb-tiny-h.cfg -f target/stm32f4x.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x08000000"` - -Once the firmware is ready and uploaded, you need to connect the miniUSB cable to the USB-OTG1 and connect the serial cable(TTL232) to USART3 with the next pinout: -- `USART3 TX` -> `TTL232 RX` -- `USART3 RX` -> `TTL232 TX` -- `GND Board` -> `TTL232 GND` - -And it should look like this: - -![image](imgs/olimex_uxd.jpg) - -Now the board it's ready. -Connect the serial cable (TTL232) to the computer and check which is the number of the serial port. - -Note: We need to install previously the micro-ROS agent. So you can follow the next guide to install it: -https://github.com/micro-ROS/micro-ROS-doc/blob/master/docs/install_and_run.md - -## Run a publisher: - -First you need to execute the **micro-ROS Agent** in your computer using the next command: ``` -cd ~/agent_ws/install/uros_agent/lib/uros_agent/ -./uros_agent serial -``` - -Once you execute it should look like this: - -![image](imgs/microros_agent.png) - -Now execute the publisher app in the Olimex board, typing `publisher`, and should send a new value every 100mS. And will look like this: - -**Agent** - -![image](imgs/microros_agentattach.png) - -**Board publisher** - -![image](imgs/microros_pub.png) - -Finally, if you type in a console `ros2 topic list`, you will be able to see the topic like in the image: - -![image](imgs/microros_ros2.png) - -## Run a publisher: - - -To run this example, you should follow the same steps as in the previous (Run a publisher), instead of run the `publisher` app, you should run `subscriber` app. - -If the publisher is running properly, you should see this on the board: - -![image](imgs/microros_sub.png) - -So as a summary: -- With this demo, you can run a publisher or subscriber in the Olimex Board. -- You need to run an agent for each publisher or subscriber that you want to run. -- You can create a ROS 2 subscriber in the PC and receive the topic. -- The topic that sends this example is an integer that goes from 0 to 1000. +user@user:~$ ros2 topic echo /microROS/pong +stamp: + sec: 0 + nanosec: 0 +frame_id: fake_ping +--- +``` \ No newline at end of file diff --git a/_docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_ethernet.jpg b/_docs/tutorials/advanced/nuttx/tcp_echo/images/olimex_ethernet.jpg similarity index 100% rename from _docs/tutorials/advanced/nuttx/nuttx_getting_started/imgs/olimex_ethernet.jpg rename to _docs/tutorials/advanced/nuttx/tcp_echo/images/olimex_ethernet.jpg diff --git a/_docs/tutorials/advanced/nuttx/tcp_echo/index.md b/_docs/tutorials/advanced/nuttx/tcp_echo/index.md new file mode 100644 index 00000000..443bbfb8 --- /dev/null +++ b/_docs/tutorials/advanced/nuttx/tcp_echo/index.md @@ -0,0 +1,152 @@ +--- +title: TCP echo server +permalink: /docs/tutorials/advanced/nuttx/tcp_echo/ +--- + +| RTOS | Board Compatible | +|:-----:|:-----------------:| +| NuttX | Olimex-STM32-E407 | + +In this tutorial, we will see how to use a TCP echo server on NuttX, to test a basic TCP server. TCP (Transmission Control Protocol) is a connection-oriented protocol, and a connection between client and server is established (passive open) before data can be sent. + +## Hardware requirements: +- [Olimex-STM32-E407 board](https://www.olimex.com/Products/ARM/ST/STM32-E407/open-source-hardware) +- [JTAG Flasher device](https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY/) +- Ethernet Cable. +- Mini USB cable. + + +## Create the firmware + +For this tutorial we're going to execute the following configuration in the Micro-ROS build system: +```bash +ros2 run micro_ros_setup create_firmware_ws.sh nuttx olimex-stm32-e407 +ros2 run micro_ros_setup configure_firmware.sh tcpecho +``` + +Once the board is configured, we need to build it by typing the command: +```bash +ros2 run micro_ros_setup build_firmware.sh +``` + +If the compilation succeds, it should return this output: +```bash +CP: nuttx.hex +CP: nuttx.bin +``` + +## Flash the firmware +Once the firmware is ready, you need to do the following connections: +- Connect the JTAG flasher device to the JTAG port. +- Connect the mini-USB port to the USB-OTG2 port. +- Connect the ethernet cable to the ethernet socket. + +The board should look like this: +![](images/olimex_ethernet.jpg) + +Now flash the board by typing the command: +```bash +ros2 run micro_ros_setup flash_firmware.sh +``` + +This should return this output once the process is finished: +```bash +wrote 49152 bytes from file nuttx.bin in 6.279262s (7.644 KiB/s) +Info : Listening on port 6666 for tcl connections +Info : Listening on port 4444 for telnet connections +``` +## Use the TCP echo server + +### NuttX side + +Now you need to open the NSH console of NuttX. To do so, follow these steps: + +- Push the reset button. The green LED will turn on to say that it is working properly. +- Look for the device by typing ``dmesg`` on the console. This should return something like this: +```bash +[20614.570781] usb 1-2: new full-speed USB device number 7 using xhci_hcd +[20614.724366] usb 1-2: New USB device found, idVendor=0525, idProduct=a4a7, bcdDevice= 1.01 +[20614.724372] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[20614.724375] usb 1-2: Product: CDC/ACM Serial +[20614.724378] usb 1-2: Manufacturer: NuttX +[20614.724381] usb 1-2: SerialNumber: 0 +[20614.745693] cdc_acm 1-2:1.0: ttyACM0: USB ACM device +[20614.746274] usbcore: registered new interface driver cdc_acm +[20614.746277] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters +``` +- In this example the device is the ``ttyACM0``. +- Open this port with your serial communication app. There are different serial communication applications, but in this tutorial we're going to use [minicom](https://linux.die.net/man/1/minicom). Type the next command to execute it. +```bash +sudo minicom -D /dev/ttyACM0 +``` + +Once the port is open, **you need to push two times the Enter key** and the next menu should pop up: + +```bash +NuttShell (NSH) +nsh> ? +help usage: help [-v] [] + + [ cd echo hexdump mb nslookup sh umount + ? cp exec ifconfig mkdir ps sleep unset + arp cmp exit ifdown mh pwd test usleep + basename dirname false ifup mount rm time xd + break dd free kill mv rmdir true + cat df help ls mw set uname + +Builtin Apps: + tcpecho +nsh> +``` +In the following step we will check the IP of the Olimex-STM32-E407 board. To do so you need to execute the commands below: +- Mount the PROC fyle system: +``` +mount -t procfs /proc +``` +- Execute ifconfig to see the network data: +``` +ifconfig +``` + +This will return as an output: + +```bash +nsh> mount -t procfs /proc +nsh> ifconfig +eth0 Link encap:Ethernet HWaddr 00:e0:de:ad:be:ef at UP + inet addr:192.168.1.130 DRaddr:192.168.1.1 Mask:255.255.255.0 + + IPv4 UDP ICMP +Received 0005 0005 0000 +Dropped 0000 0000 0000 + IPv4 VHL: 0000 Frg: 0000 + Checksum 0000 0000 ---- + Type 0000 ---- 0000 +Sent 0003 0003 0000 +nsh> + +``` +As you can see, the IP address of the ``eth0`` is :192.168.1.130. This is the IP of the board. + +**Note**: If you received an incorrect IP or 0 value on the field inet addr, you need to execute the next commands: +``` +ifdown eth0 +ifup eth0 +``` + +The board is now connected to the network and ready to execute the TCP echo server. To execute the application, just type ``tcpecho`` and it should output: + +```bash +nsh> tcpecho +Start TCP echo server +``` +## PC side + +Open a new console to run a TCP client. Connect it to the port 80 of the NuttX board. For this example we are using ``netcat``. Here you can see an example: + +```bash +netcat 192.168.1.130 80 +hello micro-ROS! +hello micro-ROS! +``` +When you write something on the TCP client, if everything goes fine, it should receive the same message that you send. diff --git a/_docs/tutorials/advanced/nuttx/udp_echo/images/olimex_ethernet.jpg b/_docs/tutorials/advanced/nuttx/udp_echo/images/olimex_ethernet.jpg new file mode 100644 index 00000000..fbbf64e4 Binary files /dev/null and b/_docs/tutorials/advanced/nuttx/udp_echo/images/olimex_ethernet.jpg differ diff --git a/_docs/tutorials/advanced/nuttx/udp_echo/index.md b/_docs/tutorials/advanced/nuttx/udp_echo/index.md new file mode 100644 index 00000000..53a0de7f --- /dev/null +++ b/_docs/tutorials/advanced/nuttx/udp_echo/index.md @@ -0,0 +1,161 @@ +--- +title: UDP echo server +permalink: /docs/tutorials/advanced/nuttx/udp_echo/ +--- + +| RTOS | Board Compatible | +|:-----:|:-----------------:| +| NuttX | Olimex-STM32-E407 | + +In this tutorial, we will see how to use a UDP echo server on NuttX, to test a basic UDP server. +UDP (User datagram protocol) is a connectionless protocol with a minimum protocol mechanism. This protocol is focused on time-sensitive applications for which is preferable to lose packages rather than having delayed packets. + +## Hardware requirements: +- [Olimex-STM32-E407 board](https://www.olimex.com/Products/ARM/ST/STM32-E407/open-source-hardware) +- [JTAG Flasher device](https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY/) +- Ethernet Cable. +- Mini USB cable. + + +## Create the firmware + +For this tutorial we're going to execute the following configuration in the Micro-ROS build system: +```bash +ros2 run micro_ros_setup create_firmware_ws.sh nuttx olimex-stm32-e407 +ros2 run micro_ros_setup configure_firmware.sh udpecho +``` + +Once the board is configured, we need to build it by typing the command: +```bash +ros2 run micro_ros_setup build_firmware.sh +``` + +If the compilation succeds, it should return this output: +```bash +CP: nuttx.hex +CP: nuttx.bin +``` + +## Flash the firmware +Once the firmware is ready, you need to do these connections: +- Connect the JTAG flasher device to the JTAG port. +- Connect the mini-USB port to the USB-OTG2 port. +- Connect the ethernet cable to the ethernet socket. + +The board should look like this: +![](images/olimex_ethernet.jpg) + +Now flash the board by typing the command: +```bash +ros2 run micro_ros_setup flash_firmware.sh +``` + +This should return this output once the process is finished: +```bash +wrote 49152 bytes from file nuttx.bin in 6.279262s (7.644 KiB/s) +Info : Listening on port 6666 for tcl connections +Info : Listening on port 4444 for telnet connections +``` + +## Use the UDP echo server + +### NuttX side + +Now you need to open the NSH console of NuttX. To do so, follow these steps: + +- Push the reset button. The green LED will turn on to say that it is working properly. +- Look for the device by typing ``dmesg`` on the console, this should return somenthing like this: +```bash +[20614.570781] usb 1-2: new full-speed USB device number 7 using xhci_hcd +[20614.724366] usb 1-2: New USB device found, idVendor=0525, idProduct=a4a7, bcdDevice= 1.01 +[20614.724372] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[20614.724375] usb 1-2: Product: CDC/ACM Serial +[20614.724378] usb 1-2: Manufacturer: NuttX +[20614.724381] usb 1-2: SerialNumber: 0 +[20614.745693] cdc_acm 1-2:1.0: ttyACM0: USB ACM device +[20614.746274] usbcore: registered new interface driver cdc_acm +[20614.746277] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters +``` +- In this example the device is the ``ttyACM0``. +- Open this port with your serial communication app. There are different serial communication applications, but in this tutorial we're going to use [minicom](https://linux.die.net/man/1/minicom). Type the next command to execute it. +```bash +sudo minicom -D /dev/ttyACM0 +``` + +Once the port is open, **you need to push two times the Enter key** and the following menu should pop up: + +```bash +NuttShell (NSH) +nsh> ? +help usage: help [-v] [] + + [ cd echo hexdump mb nslookup sh umount + ? cp exec ifconfig mkdir ps sleep unset + arp cmp exit ifdown mh pwd test usleep + basename dirname false ifup mount rm time xd + break dd free kill mv rmdir true + cat df help ls mw set uname + +Builtin Apps: + udpecho +nsh> +``` +In the next step we will check the IP of the Olimex-STM32-E407 board. To do so you need to execute the commands below: +- Mount the PROC fyle system: +``` +mount -t procfs /proc +``` +- Execute ifconfig to see the network data: +``` +ifconfig +``` + +This will output: + +```bash +nsh> mount -t procfs /proc +nsh> ifconfig +eth0 Link encap:Ethernet HWaddr 00:e0:de:ad:be:ef at UP + inet addr:192.168.1.130 DRaddr:192.168.1.1 Mask:255.255.255.0 + + IPv4 UDP ICMP +Received 0005 0005 0000 +Dropped 0000 0000 0000 + IPv4 VHL: 0000 Frg: 0000 + Checksum 0000 0000 ---- + Type 0000 ---- 0000 +Sent 0003 0003 0000 +nsh> + +``` +As you can see the IP address of the ``eth0`` is :192.168.1.130. This is the IP of the board. + +**Note**: If you received an incorrect IP or 0 value on the field inet addr, you need to execute the commands: +``` +ifdown eth0 +ifup eth0 +``` + +The board is now connected to the network and ready to execute the UDP echo server. To execute the application, just type ``udpecho`` and it should output: + +```bash +nsh> udpecho +server: 0. Receiving up 1024 bytes +``` +## PC side + +Open a new console and run a UDP client connected to the port 80 of the NuttX board. For this example we are using netcat, below you can see an example: + +```bash +netcat -u 192.168.1.130 80 +hello micro-ROS! +hello micro-ROS! +``` +When you write something in the UDP client, it should receive the same message and the next output should appear in NuttX: + +```bash +server: 0. Received 17 bytes from 192.168.1.132:53394 +client: 0. Sending 17 bytes +client: 0. Sent 17 bytes +server: 1. Receiving up 1024 bytes +```