micro_ros_setup icon indicating copy to clipboard operation
micro_ros_setup copied to clipboard

Support RTEMS

Open roncapat opened this issue 2 years ago • 31 comments

It would be interesting to use micro-ROS on RTEMS (The Real-Time Executive for Multiprocessor Systems).

It is an RTOS used in space applications. It offers POSIX interface. A simple and cheap SBC like a BeagleBone Black would be sufficient to make tests on hardware (but everything can be done also virtually).

For now, I do not have the time to try alone, Of course, if I ever find the time I will try on my own and share PRs if it's ok.

roncapat avatar Oct 09 '21 15:10 roncapat

I started to compile against an old RTEMS toolchain of mine, since it was ready on my PC.

rtems_toolchain.cmake

set(RTEMS_ROOT_PATH             "/mnt/sdb/rtems")
set(RTEMS_TOOLS_INSTALL_DIR     "${RTEMS_ROOT_PATH}/5")
set(RTEMS_TOOLS_BSP_LIB_DIR     "${RTEMS_ROOT_PATH}/5/sparc-rtems5/lib")
set(RTEMS_KERNEL_INSTALL_DIR    "${RTEMS_ROOT_PATH}/5/sparc-rtems5/erc32")
set(RTEMS_KERNEL_BSP_LIB_DIR    "${RTEMS_ROOT_PATH}/5/sparc-rtems5/erc32/lib")

set(ENV{PATH} "${RTEMS_TOOLS_INSTALL_DIR}/bin:$ENV{PATH}")
set(RTEMS_TOOLS_BSP_INCLUDE_DIR       "${RTEMS_ROOT_PATH}/5/sparc-rtems5/include")
set(RTEMS_KERNEL_BSP_INCLUDE_DIR      "${RTEMS_KERNEL_BSP_LIB_DIR}/include")
set(RTEMS_COMPILE_OPTIONS             "-B${RTEMS_KERNEL_BSP_LIB_DIR} -B${RTEMS_TOOLS_BSP_LIB_DIR} -specs bsp_specs -qrtems -mcpu=cypress")

set(CMAKE_SYSTEM_NAME         Generic)
set(CMAKE_SYSTEM_PROCESSOR    sparc)

set(CMAKE_C_COMPILER "sparc-rtems5-gcc")
set(CMAKE_CXX_COMPILER "sparc-rtems5-g++")

include_directories(BEFORE ${RTEMS_TOOLS_BSP_INCLUDE_DIR}                         
                           ${RTEMS_KERNEL_BSP_INCLUDE_DIR})

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

rtems.colcon.meta

{
    "names": {
        "tracetools": {
            "cmake-args": [
                "-DTRACETOOLS_DISABLED=ON",
                "-DTRACETOOLS_STATUS_CHECKING_TOOL=OFF"
            ]
        },
        "rosidl_typesupport": {
            "cmake-args": [
                "-DROSIDL_TYPESUPPORT_SINGLE_TYPESUPPORT=ON"
            ]
        },
        "rcl": {
            "cmake-args": [
                "-DBUILD_TESTING=OFF",
                "-DRCL_COMMAND_LINE_ENABLED=OFF",
                "-DRCL_LOGGING_ENABLED=OFF"
            ]
        }, 
        "rcutils": {
            "cmake-args": [
                "-DENABLE_TESTING=OFF",
                "-DRCUTILS_NO_FILESYSTEM=ON",
                "-DRCUTILS_NO_THREAD_SUPPORT=ON",
                "-DRCUTILS_AVOID_DYNAMIC_ALLOCATION=ON"
            ]
        },
        "microxrcedds_client": {
            "cmake-args": [
                "-DUCLIENT_PIC=OFF",
                "-DUCLIENT_PLATFORM_POSIX=ON",
                "-DUCLIENT_PROFILE_UDP=OFF",
                "-DUCLIENT_PROFILE_TCP=OFF",
                "-DUCLIENT_PROFILE_DISCOVERY=OFF",
                "-DUCLIENT_PROFILE_SERIAL=ON",
                "-DUCLIENT_PROFILE_STREAM_FRAMING=ON",
                "-DUCLIENT_PROFILE_CUSTOM_TRANSPORT=OFF"
            ]
        },
        "rmw_microxrcedds": {
            "cmake-args": [
                "-DRMW_UXRCE_MAX_NODES=1",
                "-DRMW_UXRCE_MAX_PUBLISHERS=1",
                "-DRMW_UXRCE_MAX_SUBSCRIPTIONS=1",
                "-DRMW_UXRCE_MAX_SERVICES=1",
                "-DRMW_UXRCE_MAX_CLIENTS=1",
                "-DRMW_UXRCE_MAX_HISTORY=4",
                "-DRMW_UXRCE_TRANSPORT=serial"
            ]
        }
    }
}

In my ros2_workspace:

ros2 run micro_ros_setup create_firmware_ws.sh generate_lib
ros2 run micro_ros_setup build_firmware.sh $(pwd)/src/micro_ros_setup/config/generate_lib/generic/rtems_toolchain.cmake $(pwd)/src/micro_ros_setup/config/generate_lib/generic/rtems-colcon.meta

Compilation goes on without critical failures. I met only a bug in:

mcu_ws/uros/rmw_microxrcedds/rmw_microxrcedds_c/src/memory.c

where #include <memory.h> should be substituted with #include "memory.h" to let the compiler use:

mcu_ws/uros/rmw_microxrcedds/rmw_microxrcedds_c/src/memory.h instead of something else in the include path.

roncapat avatar Oct 09 '21 17:10 roncapat

A lot of warnings though. This one occurs at every package.

CMake Warning at /mnt/sdb/microros_ws/firmware/mcu_ws/install/share/rcutils/cmake/ament_cmake_export_libraries-extras.cmake:116 (message):
  Package 'rcutils' exports library 'dl' which couldn't be found

This annoying warning can be suppressed by commenting out the following line:

ament_export_libraries(${PROJECT_NAME} ${CMAKE_DL_LIBS})

in firmware/mcu_ws/uros/rcutils/CMakeLists.txt

roncapat avatar Oct 09 '21 17:10 roncapat

Is there a list of all the definitions in colcon.meta?

roncapat avatar Oct 09 '21 17:10 roncapat

I discovered that no matter if in your custom toolchain you add a line such:

set(CMAKE_DL_LIBS "-lrtemscpu") # contains dlopen() family of symbols in RTEMS 

the rcutils CMake will always have dl as ${CMAKE_DL_LIBS}. Like if the override would not work correctly.

roncapat avatar Oct 10 '21 10:10 roncapat

Some updates:

rtems-toolchain.cmake

set(RTEMS_ROOT_PATH             "/mnt/sdb/rtems")
set(RTEMS_TOOLS_INSTALL_DIR     "${RTEMS_ROOT_PATH}/5")
set(RTEMS_TOOLS_BSP_LIB_DIR     "${RTEMS_ROOT_PATH}/5/arm-rtems5/lib")
set(RTEMS_KERNEL_INSTALL_DIR    "${RTEMS_ROOT_PATH}/5/arm-rtems5/beagleboneblack")
set(RTEMS_KERNEL_BSP_LIB_DIR    "${RTEMS_ROOT_PATH}/5/arm-rtems5/beagleboneblack/lib")

set(ENV{PATH} "${RTEMS_TOOLS_INSTALL_DIR}/bin:$ENV{PATH}")
set(RTEMS_TOOLS_BSP_INCLUDE_DIR       "${RTEMS_ROOT_PATH}/5/arm-rtems5/include")
set(RTEMS_KERNEL_BSP_INCLUDE_DIR      "${RTEMS_KERNEL_BSP_LIB_DIR}/include")
set(RTEMS_COMPILE_OPTIONS             "-B${RTEMS_KERNEL_BSP_LIB_DIR} -B${RTEMS_TOOLS_BSP_LIB_DIR} -specs bsp_specs -qrtems -mcpu=cortex-a8")

set(CMAKE_SYSTEM_NAME         Generic)
set(CMAKE_SYSTEM_PROCESSOR    arm)

set(CMAKE_C_COMPILER "arm-rtems5-gcc")
set(CMAKE_CXX_COMPILER "arm-rtems5-g++")
set(CMAKE_DL_LIBS "-lrtemscpu")

set(CMAKE_CXX_FLAGS "${RTEMS_COMPILE_OPTIONS} -g -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable")
set(CMAKE_C_FLAGS "${RTEMS_COMPILE_OPTIONS} -g -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable")

include_directories(BEFORE ${RTEMS_TOOLS_BSP_INCLUDE_DIR}                         
                           ${RTEMS_KERNEL_BSP_INCLUDE_DIR})

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

rtems-colcon.meta

{
    "names": {
        "tracetools": {
            "cmake-args": [
                "-DTRACETOOLS_DISABLED=ON",
                "-DTRACETOOLS_STATUS_CHECKING_TOOL=OFF"
            ]
        },
        "rosidl_typesupport": {
            "cmake-args": [
                "-DROSIDL_TYPESUPPORT_SINGLE_TYPESUPPORT=ON"
            ]
        },
        "rcl": {
            "cmake-args": [
                "-DBUILD_TESTING=OFF",
                "-DRCL_COMMAND_LINE_ENABLED=OFF",
                "-DRCL_LOGGING_ENABLED=OFF"
            ]
        }, 
        "rcutils": {
            "cmake-args": [
                "-DENABLE_TESTING=OFF",
                "-DRCUTILS_NO_FILESYSTEM=ON",
                "-DRCUTILS_NO_THREAD_SUPPORT=OFF",
                "-DRCUTILS_AVOID_DYNAMIC_ALLOCATION=ON"
            ]
        },
        "microxrcedds_client": {
            "cmake-args": [
                "-DUCLIENT_PIC=OFF",
                "-DUCLIENT_PLATFORM_POSIX=ON",
                "-DUCLIENT_PROFILE_UDP=OFF",
                "-DUCLIENT_PROFILE_TCP=OFF",
                "-DUCLIENT_PROFILE_DISCOVERY=OFF",
                "-DUCLIENT_PROFILE_SERIAL=ON",
                "-DUCLIENT_PROFILE_STREAM_FRAMING=ON",
                "-DUCLIENT_PROFILE_CUSTOM_TRANSPORT=OFF"
            ]
        },
        "rmw_microxrcedds": {
            "cmake-args": [
                "-DRMW_UXRCE_MAX_NODES=1",
                "-DRMW_UXRCE_MAX_PUBLISHERS=1",
                "-DRMW_UXRCE_MAX_SUBSCRIPTIONS=1",
                "-DRMW_UXRCE_MAX_SERVICES=1",
                "-DRMW_UXRCE_MAX_CLIENTS=1",
                "-DRMW_UXRCE_MAX_HISTORY=4",
                "-DRMW_UXRCE_TRANSPORT=serial"
            ]
        }
    }
}

I commented out:

ament_export_libraries(${PROJECT_NAME} ${CMAKE_DL_LIBS})

in rcutils/CMakeLists.txt and suppressed in the toolchain some unused variable warnings to reduce the noise at the bare minimum. Of course those warnings should be later addressed in the various project by correct code tweaks, but this is not the scope of my work now.

Here is the only notable warning/error popping out of my build step:

--- stderr: micro_ros_utilities                                                                                      
/mnt/sdb/microros_ws/firmware/mcu_ws/uros/micro_ros_utilities/src/type_utilities.c: In function 'print_type_info':
/mnt/sdb/microros_ws/firmware/mcu_ws/uros/micro_ros_utilities/src/type_utilities.c:93:5: warning: implicit declaration of function 'snprintf' [-Wimplicit-function-declaration]
     snprintf(
     ^~~~~~~~
/mnt/sdb/microros_ws/firmware/mcu_ws/uros/micro_ros_utilities/src/type_utilities.c:93:5: warning: incompatible implicit declaration of built-in function 'snprintf'
/mnt/sdb/microros_ws/firmware/mcu_ws/uros/micro_ros_utilities/src/type_utilities.c:93:5: note: include '<stdio.h>' or provide a declaration of 'snprintf'
/mnt/sdb/microros_ws/firmware/mcu_ws/uros/micro_ros_utilities/src/type_utilities.c:94:74: warning: format '%ld' expects argument of type 'long int', but argument 8 has type 'size_t {aka const unsigned int}' [-Wformat=]
       buffer, sizeof(buffer), "%sIntrospection for %s/%s - %d members, %ld B\n",
                                                                        ~~^
                                                                        %d
/mnt/sdb/microros_ws/firmware/mcu_ws/uros/micro_ros_utilities/src/type_utilities.c:99:7:
       members->size_of_
       ~~~~~~~~~~~~~~~~~                                                   
/mnt/sdb/microros_ws/firmware/mcu_ws/uros/micro_ros_utilities/src/type_utilities.c:115:5: warning: incompatible implicit declaration of built-in function 'snprintf'
     snprintf(
     ^~~~~~~~
/mnt/sdb/microros_ws/firmware/mcu_ws/uros/micro_ros_utilities/src/type_utilities.c:115:5: note: include '<stdio.h>' or provide a declaration of 'snprintf'
---

roncapat avatar Oct 10 '21 11:10 roncapat

I opended some PRs to fix the warnings.

Next step is waiting to retrieve my Beaglebone Black (which now I don't have with me, but it will be again sometime in the following weeks) and start some tests.

roncapat avatar Oct 10 '21 11:10 roncapat

TODOs (suggestions welcomed):

  • [ ] build a sample application with micro-ros targeting RTEMS BeagleBone Black
  • [ ] deploy the application
  • [ ] get RTEMS boot correctly
  • [ ] tune rtems-colcon.meta
  • [ ] ensure everything works

In particular, one doubt of mine is how to specify which serial/network port to use on the board to the micro-ros library.

Hoping it is somewhere in the documentation. If anyone can pinpoint me, it would be awesome.

roncapat avatar Oct 10 '21 11:10 roncapat

Are there any tests which don't require networking and just check basic services to start with? And I would recommend trying arm/zynq on qemu first. If you need a example RTEMS configuration and initialization that sets things up and then calls main(), just ask and I'll email it to you privately

joelsherrill avatar Oct 11 '21 00:10 joelsherrill

I believe the basic setup could be a RTEMS application with 1 task and 1 micro-ROS publisher. Yes, I need to check if with my pre-existing setup I can already run a RTEMS-only demo in qemu, just to be sure that everything works before start breaking stuff.

roncapat avatar Oct 11 '21 07:10 roncapat

In parallel with making myself a new RTEMS environment (with the goal to execute some default tests in the emulator before starting to add micro-ROS in the mix), I'm reading more about micro-ROS.

I have some questions in my mind, but the first one is: do you believe or know wether it will be necessary to write some specific code to adapt to this RTOS, or everything shoud work out of the box because the target RTOS is a POSIX system? Do you have a list of steps for things to check?

EDIT: let me rephrase that: using generate_lib, is there any target-specific source code implementation needed to support micro-ROS, or I just need to use its API as normal when writing a task of my RTOS image?

roncapat avatar Oct 11 '21 09:10 roncapat

I tried to dig in the source code, following the source of an example: https://github.com/micro-ROS/freertos_apps/blob/foxy/apps/ping_pong/app.c and for what I've seen up to now, it's all about allocation and initialisation of structures until the rclc_executor_spin_some() is called. In an RTEMS application. Since micro-ROS seems to not open autonomously other threads/tasks/processes, but you must explicitly spin the executor in foreground in a task you write and schedule, I think the effort to get to aminimal demo like the ping-pong one should not be very high and aside for the task, maybe no target-specific code for the adaptation of micro-ROS onto RTEMS should be needed.

roncapat avatar Oct 11 '21 10:10 roncapat

I have some questions in my mind, but the first one is: do you believe or know wether it will be necessary to write some specific code to adapt to this RTOS, or everything shoud work out of the box because the target RTOS is a POSIX system? Do you have a list of steps for things to check?

I can't tell if this is a micro-ROS or RTEMS question. I can't imagine ROS needs anything from POSIX that RTEMS does not have. We have this guide in our documentation set (https://docs.rtems.org/branches/master/posix-compliance/index.html) which details how RTEMS aligns against various C and POSIX based standards.

EDIT: let me rephrase that: using generate_lib, is there any target-specific source code implementation needed to support micro-ROS, or I just need to use its API as normal when writing a task of my RTOS image?

If a package has a POSIX port which is geared to embedded environments (e.g. doesn't use fork/exec, graphics, etc.), then it often just compiles for RTEMS. The issues that must be addressed are RTEMS initialization and configuration and possibly contents of the initial filesystem.

joelsherrill avatar Oct 11 '21 13:10 joelsherrill

Thank you @joelsherrill for your answers! Yes, I followed the source code pointed and used by the demo but never found fork/exec. When I have time, I'll also do a keyword based research around the codebase just as an additional check.

roncapat avatar Oct 11 '21 16:10 roncapat

Hello everyone, finally I got a clean RTEMS 5.1 erc32 BSP (sparc) built on my PC. All standard tests ran in the simulator, so I was ready to start fiddling with microROS in a RTEMS app.

A year ago, I wrote this simple CMake template fort RTEMS. I made it compile for erc32 and run with the simulator. Everything OK.

Now I started porting the ping-pong microROS app. Here is the source pingpongport_1.zip.

I started copy-pasting some code from freeRTOS ping-pong example and up to now, the compiler errors are:

[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /mnt/sdb/rtems_master/workspace/microROS/build --config Debug --target all -j 10 --
[build] [1/1 100% :: 0.132] Linking CXX executable HELLO
[build] FAILED: HELLO 
[build] : && /mnt/sdb/rtems_master/rtems/5/bin/sparc-rtems5-g++  -B/mnt/sdb/rtems_master/rtems/5/sparc-rtems5/erc32/lib -B/mnt/sdb/rtems_master/rtems/5/sparc-rtems5/lib -specs bsp_specs -qrtems -mcpu=cypress -g   CMakeFiles/HELLO.dir/example.cpp.obj  -o HELLO -L/mnt/sdb/microros_ws/firmware/build -lmicroros && :
[build] /mnt/sdb/rtems_master/rtems/5/lib/gcc/sparc-rtems5/7.5.0/../../../../sparc-rtems5/bin/ld: /mnt/sdb/microros_ws/firmware/build/libmicroros.a(libmicrocdr-array.c.obj): in function `ucdr_serialize_array_uint16_t':
[build] /mnt/sdb/microros_ws/firmware/mcu_ws/eProsima/Micro-CDR/src/c/types/array.c:176: undefined reference to `_GLOBAL_OFFSET_TABLE_'
[build] /mnt/sdb/rtems_master/rtems/5/lib/gcc/sparc-rtems5/7.5.0/../../../../sparc-rtems5/bin/ld: /mnt/sdb/microros_ws/firmware/mcu_ws/eProsima/Micro-CDR/src/c/types/array.c:176: undefined reference to `_GLOBAL_OFFSET_TABLE_'
[build] /mnt/sdb/rtems_master/rtems/5/lib/gcc/sparc-rtems5/7.5.0/../../../../sparc-rtems5/bin/ld: /mnt/sdb/microros_ws/firmware/build/libmicroros.a(libmicrocdr-array.c.obj): in function `ucdr_serialize_array_uint32_t':
[build] /mnt/sdb/microros_ws/firmware/mcu_ws/eProsima/Micro-CDR/src/c/types/array.c:177: undefined reference to `_GLOBAL_OFFSET_TABLE_'
[build] /mnt/sdb/rtems_master/rtems/5/lib/gcc/sparc-rtems5/7.5.0/../../../../sparc-rtems5/bin/ld: /mnt/sdb/microros_ws/firmware/mcu_ws/eProsima/Micro-CDR/src/c/types/array.c:177: undefined reference to `_GLOBAL_OFFSET_TABLE_'
[build] /mnt/sdb/rtems_master/rtems/5/lib/gcc/sparc-rtems5/7.5.0/../../../../sparc-rtems5/bin/ld: /mnt/sdb/microros_ws/firmware/build/libmicroros.a(libmicrocdr-array.c.obj): in function `ucdr_serialize_array_uint64_t':
[build] /mnt/sdb/microros_ws/firmware/mcu_ws/eProsima/Micro-CDR/src/c/types/array.c:178: undefined reference to `_GLOBAL_OFFSET_TABLE_'
[build] /mnt/sdb/rtems_master/rtems/5/lib/gcc/sparc-rtems5/7.5.0/../../../../sparc-rtems5/bin/ld: /mnt/sdb/microros_ws/firmware/build/libmicroros.a(libmicrocdr-array.c.obj):/mnt/sdb/microros_ws/firmware/mcu_ws/eProsima/Micro-CDR/src/c/types/array.c:178: more undefined references to `_GLOBAL_OFFSET_TABLE_' follow
[build] /mnt/sdb/rtems_master/rtems/5/lib/gcc/sparc-rtems5/7.5.0/../../../../sparc-rtems5/bin/ld: /mnt/sdb/microros_ws/firmware/build/libmicroros.a(libmicroxrcedds_client-serial_transport_posix.c.obj): in function `uxr_read_serial_data_platform':
[build] /mnt/sdb/microros_ws/firmware/mcu_ws/eProsima/Micro-XRCE-DDS-Client/src/c/profile/transport/serial/serial_transport_posix.c:64: undefined reference to `poll'
[build] collect2: error: ld returned 1 exit status
[build] ninja: build stopped: subcommand failed.
[build] Build finished with exit code 1

In practice, two problems up to now:

  • undefined reference to `GLOBAL_OFFSET_TABLE'
  • undefined reference to `poll'

I suspect the second one is related to the simulator not having a serial port implemented, so I may fix it changing microROS build configuration to use network instead of serial port. But the first issue is the most critical IMHO, and I don't know how to proceed. Any help?

roncapat avatar Oct 17 '21 10:10 roncapat

Seems that adding to rtems-colcon.meta the following:

"microcdr": {
            "cmake-args": [
                "-DUCDR_PIC=OFF"
            ]
        },

solved the GLOBAL_OFFSET_TABLE problem. Now I have the issue with the unimpemented poll for serial ports in erc32 architecture (sounds to me this is the core of the issue) and going on adding other code of the ping-pong demo to my RTEMS app until everything can be tested and demonstrated.

roncapat avatar Oct 17 '21 17:10 roncapat

Seems that RTEMS deliberately does not support poll() call.

https://docs.rtems.org/branches/master/posix-compliance/posix-compliance.html

https://docs.rtems.org/releases/rtems-docs-4.11.1/bsp-howto/console.html

RTEMS relies on termios. I need to investigate how to maybe offer an alternative to the POSIX implementation Micro-XRCE-DDS-Client/src/c/profile/transport/serial/serial_transport_posix.c

roncapat avatar Oct 17 '21 20:10 roncapat

Another round of updates:

I read the sources and found that for now the simplest way to get to a minimal demo is to use UDP transport with the UCLIENT_PLATFORM_POSIX_POLL flag set. There is a dedicated UDB transport implementation for POSIX platforms without poll(). This is not entirely true for TCP and SERIAL transports, but I'll dig into that later. Here is my current toolchain, Colcon meta, ping-pong source and build script.

microros_build_conf_2.zip pingpongport_2.zip

It builds. Now the "hard" part is to test it.

roncapat avatar Oct 19 '21 08:10 roncapat

Are there any tests which don't require networking and just check basic services to start with? And I would recommend trying arm/zynq on qemu first. If you need a example RTEMS configuration and initialization that sets things up and then calls main(), just ask and I'll email it to you privately

Can you give me some help about what you are saying?

  • a sample app source code
  • a sample qemu command to run the example

Is qemu helpful for testing also tcp/udp and uarts? Is it possible? Do you have some demo code for interface configuration?

roncapat avatar Oct 19 '21 10:10 roncapat

Email me at joel AT rtems dot org and I will email you back a quick start network example for zynq qemu that should help you. If you don't initialize the network stack, then there is no networking.

joelsherrill avatar Oct 19 '21 13:10 joelsherrill

This branch (https://github.com/roncapat/Micro-XRCE-DDS-Client/tree/foxy) adds a TCP/UDP implementation suitable for RTEMS. It is a clean POSIX using select() call instead of poll(). I will not open a PR until I see it run on RTEMS and not only build correctly.

roncapat avatar Oct 19 '21 19:10 roncapat

@joelsherrill I wrote to you by email but sadly no response... Today I set up my beaglebone black and now I'm stuck at the same point of setting up networking. Could you send me the example at [email protected] ? It would be very helpful for me.

roncapat avatar Nov 07 '21 21:11 roncapat

@roncapat Not sure what happened. I don't see any email from you about this. But I went ahead and sent it. Poke me if you don't get it.

joelsherrill avatar Nov 07 '21 22:11 joelsherrill

Thank you so much! Hope to share some project updates before Christmas :)

roncapat avatar Nov 07 '21 22:11 roncapat

Working again on the subject.

This time I'm here to share a build issue related to glibc 2.46.

On my system (Ubuntu 20.04) I have sb-set-builder failing with the following, uninformative last line: UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 78: ordinal not in range(128) Adding --log /path/to/logfile to the command line helps to get insights on what happened:

CC       libgio_2_0_la-gdbuserror.lo
../../glib-2.46.2/gio/gdbusauth.c: In function ‘_g_dbus_auth_run_server’:
../../glib-2.46.2/gio/gdbusauth.c:1295:11: error: ‘%s’ directive argument is null [-Werror=format-overflow=]
 1295 |           debug_print ("SERVER: WaitingForBegin, read '%s'", line);
      |           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  CC       libgio_2_0_la-gdbusconnection.lo
  CC       libgio_2_0_la-gdbusmessage.lo
  CC       libgio_2_0_la-gdbusnameowning.lo
cc1: some warnings being treated as errors
make[4]: *** [Makefile:3624: libgio_2_0_la-gdbusauth.lo] Errore 1
make[4]: *** Attesa per i processi non terminati....
../../glib-2.46.2/gio/gdbusmessage.c: In function ‘g_dbus_message_to_blob’:
../../glib-2.46.2/gio/gdbusmessage.c:2698:30: error: ‘%s’ directive argument is null [-Werror=format-overflow=]
 2698 |       tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors

On the internet, I found only this reference to a simple patch to use whenever host GCC is version 9. However, I have GCC 8 as host compiler and GCC 7.5 as ARM compiler from RSB tools.

I tried to apply manually the patch to the source files and rebuild but files are probably being overwritten. Anyone has the solution to trigger a sb-set-builder rebuild without overwriting source files?

EDIT: more readable patch but not directly applicable.

Patches can be added to the build process in file rtems-source-builder/bare/config/devel/glib-2.46.2-1.cfg. I'll try to produce and apply a suitable patch.

EDIT 2: SOLVED This Diff Gist has been crafted by me to solve the compilation issues.

In rtems-source-builder/bare/config/devel/glib-2.46.2-1.cfg just add the line

%patch add glib https://gist.githubusercontent.com/roncapat/34eb82ece80ac26fd290a50dc7e85219/raw/247750ad17c31b26ef31af909fbcac05e57f71bd/glibc_2.46-2.1_rtems_5_rsb.patch

after the last %patch or %hash directive and then re-run the sb-set-builder

roncapat avatar Nov 13 '21 14:11 roncapat

Another error while trying to build devel/qemu4:

/usr/bin/ld: linux-user/syscall.o: in function `do_syscall1':
/mnt/sdb/rtems-work/rtems-source-builder/bare/build/qemu-4.1.0-x86_64-linux-gnu-1/qemu-4.1.0/linux-user/syscall.c:7660: undefined reference to `stime'

the proper fix should be this one. Trying to follow the same patching logic of the glibc problem.

EDIT: SOLVED This Diff Gist has been crafted by me to solve the compilation issues.

In rtems-source-builder/bare/config/devel/qemu4-git-1.cfg just add the line

%patch add qemu https://gist.githubusercontent.com/roncapat/34eb82ece80ac26fd290a50dc7e85219/raw/9445c0a954e92d3323596c51b1958c7be38b1cb4/qemu_4.10_rtems_5_rsb.patch

after the last %patch or %hash directive and then re-run the sb-set-builder

EDIT 2: The patches are being reviewed by RTEMS developers. https://devel.rtems.org/ticket/4561 https://lists.rtems.org/pipermail/devel/2021-December/070090.html

roncapat avatar Nov 13 '21 16:11 roncapat

@joelsherrill I think I got to a good point. The task passes all allocations for the DDS, and now the application fails to establish a qemu-outgoing TCP connection to my local host. In fact, the connect() call fails and I receive no handshake on host side. Do you have hints on how to configure gateway or other parameters for outgoing connections from RTEMS app in qemu?

roncapat avatar Nov 14 '21 01:11 roncapat

connect() from RTEMS QEMU guest tries to connect to microROS Agent on the TCP host port 8888. (127.0.0.1:8888) but returns EADDRNOTAVAIL, when using QEMU SLIRP which by default should allow outgoing packets to 127.0.0.1. RTEMS is configured to use DHCP, as Joel told me to do in his tutorial.

Any suggestions about how to proceed?

roncapat avatar Nov 14 '21 11:11 roncapat

Aaaand: IT WORKS!

PingPong example ran successfully on my machine after a very long weekend.

First of all, before forgetting it forever, here is what I found useful to set a tap network between host and qemu:

# For Network Bridging/TAP
# Set permissions of tun device
chown root.users /dev/net/tun 
chmod g+rw /dev/net/tun

#Add a bridge, add eth0
brctl addbr br0
ifconfig eth0 0.0.0.0 promisc
brctl addif br0 eth0
dhclient br0

# Create tap0
tunctl -t tap0 -u username #replace username by your username

# Enable tap0
brctl addif br0 tap0
ifconfig tap0 up

I used qemu from rtems-libbsd. My current command line is:

qemu-system-arm \
-no-reboot \
-serial null -serial mon:stdio \
-net tap,ifname=

tap0 -net nic,model=cadence_gem,macaddr=0e:b0:ba:5e:ba:11 \
-nographic \
-M xilinx-zynq-a9 -m 256M \
-kernel <<<RTEMS exe file>>>

For now, the application connects to the host and set ups correctly all publishers and subscribers. The timer ticks every 2 secs and published a ping message, but unfortunately I can't see it while ros2 topic echo /microROS/ping.

EDIT: the communication works for the first 4 PINGs. After them, seems like the timer is called but the actual publication of the message is not happening anymore.

microros_build_conf_3.zip pingpongport_3.zip

roncapat avatar Nov 14 '21 17:11 roncapat

Solved the bug. It was an issue on host->target communication, where the custom code for the DDS failed to poll presence of incoming data. Seems I was not resetting the FD_SET prior to calling select(). Now that everything works well, I do some cleanups and open a PR for the DDS Client.

roncapat avatar Nov 14 '21 18:11 roncapat

If possible, I'd keep this Issue open. Since support was merged, now the next step would be to find a way to add scripting support for RTEMS build in this repo. When I will have more time I'll give it a try.

roncapat avatar Nov 15 '21 12:11 roncapat