micro_ros_setup
micro_ros_setup copied to clipboard
Support RTEMS
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.
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.
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
Is there a list of all the definitions in colcon.meta?
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.
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'
---
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.
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.
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
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.
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?
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.
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.
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.
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?
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.
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
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.
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?
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.
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.
@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 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.
Thank you so much! Hope to share some project updates before Christmas :)
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
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
@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?
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?
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.
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.
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.