diff --git a/.gitignore b/.gitignore index 7f40370..e74d266 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ Makefile *.s *.ld build -.vscode \ No newline at end of file +.vscode +libmicroros \ No newline at end of file diff --git a/README.md b/README.md index 30f5ec7..fd21d6b 100644 --- a/README.md +++ b/README.md @@ -18,38 +18,32 @@ C_SOURCES := $(filter-out Middlewares/Third_Party/FreeRTOS/Source/portable/MemMa ####################################### # micro-ROS addons ####################################### -LDFLAGS += microros_component/libmicroros.a -C_INCLUDES += -Imicroros_component/microros_include +LDFLAGS += microros_static_library/libmicroros/libmicroros.a +C_INCLUDES += -Imicroros_static_library/libmicroros/microros_include # Add micro-ROS utils -C_SOURCES += microros_component/custom_memory_manager.c -C_SOURCES += microros_component/microros_allocators.c -C_SOURCES += microros_component/microros_time.c +C_SOURCES += extra_sources/custom_memory_manager.c +C_SOURCES += extra_sources/microros_allocators.c +C_SOURCES += extra_sources/microros_time.c # Set here the custom transport implementation -C_SOURCES += microros_component/microros_transports/dma_transport.c +C_SOURCES += extra_sources/microros_transports/dma_transport.c print_cflags: @echo $(CFLAGS) ``` -6. Go to `microros_component` and execute the static library generation tool. Compiler flags will retrieved automatically from your `Makefile` and user will be prompted to check if they are correct. +6. Execute the static library generation tool. Compiler flags will retrieved automatically from your `Makefile` and user will be prompted to check if they are correct. - ```bash -cd microros_component -docker pull microros/micro_ros_cubemx_builder:foxy -docker run -it --rm -v $(pwd)/../:/microros_library microros/micro_ros_cubemx_builder:foxy +docker pull microros/micro_ros_static_library_builder:foxy +docker run -it --rm -v $(pwd):/project microros/micro_ros_static_library_builder:foxy cd .. ``` -7. Modify your `main.c` to use micro-ROS. An example application can be found in `sample_main.c`. -8. Continue your usual workflow building your project and flashing the binary: +1. Modify your `main.c` to use micro-ROS. An example application can be found in `sample_main.c`. +2. Continue your usual workflow building your project and flashing the binary: ```bash make -j$(nproc) @@ -83,16 +77,25 @@ Note that folders added to `microros_component/extra_packages` and entries added micro-ROS precompiled library can be used in an SMT32CubeIDE but SMT32CubeIMX should be used for generating it. Once you have followed the steps in this first section: -1. Add micro-ROS include directory. In `Project -> Settings -> C/C++ Build -> Settings -> MCU GCC Compiler -> Include paths` add `microros_component/include` -2. Add the micro-ROS precompiled library. In `Project -> Settings -> C/C++ Build -> Settings -> MCU GCC Linker -> Libraries` - - add `microros_component` in `Library search path (-L)` +1. Clone this repo in your project +2. Go to `Project -> Settings -> C/C++ Build -> Settings -> Build Steps Tab` and in `Pre-build steps` add: + +```bash +docker pull microros/micro_ros_static_library_builder:foxy && docker run --rm -v ${workspace_loc:/${ProjName}}:/project --env MICROROS_LIBRARY_FOLDER=micro_ros_stm32cubemx_utils/microros_static_library_ide microros/micro_ros_static_library_builder:foxy +``` + +3. Add micro-ROS include directory. In `Project -> Settings -> C/C++ Build -> Settings -> Tool Settings Tab -> MCU GCC Compiler -> Include paths` add `micro_ros_stm32cubemx_utils/microros_static_library_ide/libmicroros/include` +4. Add the micro-ROS precompiled library. In `Project -> Settings -> C/C++ Build -> Settings -> MCU GCC Linker -> Libraries` + - add `micro_ros_stm32cubemx_utils/microros_static_library_ide/libmicroros` in `Library search path (-L)` - add `microros` in `Libraries (-l)` -3. Add the following source code files to your project: - - `microros_component/microros_time.c` - - `microros_component/microros_allocators.c` - - `microros_component/microros_custom_memory_manager.c` - - `microros_component/microros_transports/dma_transport.c` or your transport selection. -4. Build and run your project +5. Add the following source code files to your project, dragging them to source folder: + - `extra_sources/microros_time.c` + - `extra_sources/microros_allocators.c` + - `extra_sources/custom_memory_manager.c` + - `extra_sources/microros_transports/dma_transport.c` or your transport selection. +6. Make sure that if you are using FreeRTOS, the micro-ROS task **has more than 10 kB of stack**: [Detail](.images/Set_freertos_stack.jpg) +7. Configure the transport interface on the STM32CubeMX project, check the [Transport configuration](#Transport-configuration) section for instructions on the custom transports provided. +8. Build and run your project ## Purpose of the Project diff --git a/microros_component/custom_memory_manager.c b/extra_sources/custom_memory_manager.c similarity index 100% rename from microros_component/custom_memory_manager.c rename to extra_sources/custom_memory_manager.c diff --git a/microros_component/microros_allocators.c b/extra_sources/microros_allocators.c similarity index 94% rename from microros_component/microros_allocators.c rename to extra_sources/microros_allocators.c index 9b984af..aaf7a17 100644 --- a/microros_component/microros_allocators.c +++ b/extra_sources/microros_allocators.c @@ -5,6 +5,8 @@ int absoluteUsedMemory = 0; int usedMemory = 0; +void *pvPortMallocMicroROS( size_t xWantedSize ); +void vPortFreeMicroROS( void *pv ); void *pvPortReallocMicroROS( void *pv, size_t xWantedSize ); size_t getBlockSize( void *pv ); void *pvPortCallocMicroROS( size_t num, size_t xWantedSize ); diff --git a/microros_component/microros_time.c b/extra_sources/microros_time.c similarity index 100% rename from microros_component/microros_time.c rename to extra_sources/microros_time.c diff --git a/microros_component/microros_transports/dma_transport.c b/extra_sources/microros_transports/dma_transport.c similarity index 100% rename from microros_component/microros_transports/dma_transport.c rename to extra_sources/microros_transports/dma_transport.c diff --git a/microros_component/microros_transports/it_transport.c b/extra_sources/microros_transports/it_transport.c similarity index 100% rename from microros_component/microros_transports/it_transport.c rename to extra_sources/microros_transports/it_transport.c diff --git a/microros_component/.gitignore b/microros_component/.gitignore deleted file mode 100644 index 3747a73..0000000 --- a/microros_component/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -libmicroros.a -microros_include -built_packages -available_ros2_types \ No newline at end of file diff --git a/microros_component/Dockerfile b/microros_component/Dockerfile deleted file mode 100644 index cd58e3e..0000000 --- a/microros_component/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM ros:foxy - -RUN mkdir -p uros_ws -WORKDIR uros_ws -RUN git clone https://github.com/micro-ROS/micro-ros-build.git src/micro-ros-build \ - && . /opt/ros/$ROS_DISTRO/setup.sh \ - && apt update \ - && apt install -y python3-pip wget clang-format pyflakes3 python3-mypy python3-pytest-mock gperf ros-foxy-osrf-testing-tools-cpp python3-lttng ros-foxy-mimick-vendor ros-foxy-rmw-cyclonedds-cpp python3-babeltrace \ - && apt install -y gcc-arm-none-eabi \ - && rosdep update \ - && rosdep install --from-paths src --ignore-src -y \ - && colcon build \ - && . install/local_setup.sh \ - && rm -rf log/ build/ src/* \ - && rm -rf /var/lib/apt/lists/* - -COPY ./library_generation.sh /library_generation.sh - -ENTRYPOINT ["/library_generation.sh"] \ No newline at end of file diff --git a/microros_component/colcon.meta b/microros_static_library/library_generation/colcon.meta similarity index 100% rename from microros_component/colcon.meta rename to microros_static_library/library_generation/colcon.meta diff --git a/microros_component/extra_packages/extra_packages.repos b/microros_static_library/library_generation/extra_packages/extra_packages.repos similarity index 100% rename from microros_component/extra_packages/extra_packages.repos rename to microros_static_library/library_generation/extra_packages/extra_packages.repos diff --git a/microros_component/library_generation.sh b/microros_static_library/library_generation/library_generation.sh similarity index 56% rename from microros_component/library_generation.sh rename to microros_static_library/library_generation/library_generation.sh index 52333b1..d170bc2 100755 --- a/microros_component/library_generation.sh +++ b/microros_static_library/library_generation/library_generation.sh @@ -4,6 +4,7 @@ set -e ######## Init ######## apt update +apt install -y gcc-arm-none-eabi cd /uros_ws @@ -23,14 +24,14 @@ pushd firmware/mcu_ws > /dev/null # Import user defined packages mkdir extra_packages pushd extra_packages > /dev/null - cp -R /microros_library/microros_component/extra_packages/* . + cp -R /project/microros_static_library/library_generation/extra_packages/* . vcs import --input extra_packages.repos popd > /dev/null popd > /dev/null ######## Trying to retrieve CFLAGS ######## -pushd /microros_library > /dev/null +pushd /project > /dev/null export RET_CFLAGS=$(make print_cflags) RET_CODE=$? @@ -50,27 +51,29 @@ if [ $RET_CODE = "0" ]; then fi else echo "Please read README.md to update your Makefile" + exit 1; fi popd > /dev/null ######## Build ######## export TOOLCHAIN_PREFIX=/usr/bin/arm-none-eabi- -ros2 run micro_ros_setup build_firmware.sh /microros_library/microros_component/toolchain.cmake /microros_library/microros_component/colcon.meta +ros2 run micro_ros_setup build_firmware.sh /project/microros_static_library/library_generation/toolchain.cmake /project/microros_static_library/library_generation/colcon.meta find firmware/build/include/ -name "*.c" -delete -rm -rf /microros_library/microros_component/microros_include -mkdir /microros_library/microros_component/microros_include -cp -R firmware/build/include/* /microros_library/microros_component/microros_include/ -cp -R firmware/build/libmicroros.a /microros_library/microros_component/libmicroros.a +rm -rf /project/microros_static_library/libmicroros +mkdir -p /project/microros_static_library/libmicroros/microros_include +cp -R firmware/build/include/* /project/microros_static_library/libmicroros/microros_include/ +cp -R firmware/build/libmicroros.a /project/microros_static_library/libmicroros/libmicroros.a ######## Generate extra files ######## -find firmware/mcu_ws/ros2 \( -name "*.srv" -o -name "*.msg" -o -name "*.action" \) | awk -F"/" '{print $(NF-2)"/"$NF}' > /microros_library/microros_component/available_ros2_types -find firmware/mcu_ws/extra_packages \( -name "*.srv" -o -name "*.msg" -o -name "*.action" \) | awk -F"/" '{print $(NF-2)"/"$NF}' >> /microros_library/microros_component/available_ros2_types +find firmware/mcu_ws/ros2 \( -name "*.srv" -o -name "*.msg" -o -name "*.action" \) | awk -F"/" '{print $(NF-2)"/"$NF}' > /project/microros_static_library/libmicroros/available_ros2_types +find firmware/mcu_ws/extra_packages \( -name "*.srv" -o -name "*.msg" -o -name "*.action" \) | awk -F"/" '{print $(NF-2)"/"$NF}' >> /project/microros_static_library/libmicroros/available_ros2_types cd firmware -echo "" > /microros_library/microros_component/built_packages -for f in $(find $(pwd) -name .git -type d); do pushd $f > /dev/null; echo $(git config --get remote.origin.url) $(git rev-parse HEAD) >> /microros_library/microros_component/built_packages; popd > /dev/null; done; +echo "" > /project/microros_static_library/libmicroros/built_packages +for f in $(find $(pwd) -name .git -type d); do pushd $f > /dev/null; echo $(git config --get remote.origin.url) $(git rev-parse HEAD) >> /project/microros_static_library/libmicroros/built_packages; popd > /dev/null; done; ######## Fix permissions ######## -sudo chmod -R 777 /microros_library/microros_component/microros_include/ -sudo chmod -R 777 /microros_library/microros_component/libmicroros.a \ No newline at end of file +sudo chmod -R 777 /project/microros_static_library/libmicroros/libmicroros/ +sudo chmod -R 777 /project/microros_static_library/libmicroros/libmicroros/include/ +sudo chmod -R 777 /project/microros_static_library/libmicroros/libmicroros/libmicroros.a \ No newline at end of file diff --git a/microros_component/toolchain.cmake b/microros_static_library/library_generation/toolchain.cmake similarity index 100% rename from microros_component/toolchain.cmake rename to microros_static_library/library_generation/toolchain.cmake diff --git a/microros_static_library_ide/library_generation/colcon.meta b/microros_static_library_ide/library_generation/colcon.meta new file mode 100755 index 0000000..5bb8eff --- /dev/null +++ b/microros_static_library_ide/library_generation/colcon.meta @@ -0,0 +1,53 @@ +{ + "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_NO_64_ATOMIC=ON", + "-DRCUTILS_AVOID_DYNAMIC_ALLOCATION=ON" + ] + }, + "microxrcedds_client": { + "cmake-args": [ + "-DUCLIENT_PIC=OFF", + "-DUCLIENT_PROFILE_UDP=OFF", + "-DUCLIENT_PROFILE_TCP=OFF", + "-DUCLIENT_PROFILE_DISCOVERY=OFF", + "-DUCLIENT_PROFILE_SERIAL=OFF", + "-UCLIENT_PROFILE_STREAM_FRAMING=ON", + "-DUCLIENT_PROFILE_CUSTOM_TRANSPORT=ON" + ] + }, + "rmw_microxrcedds": { + "cmake-args": [ + "-DRMW_UXRCE_MAX_NODES=1", + "-DRMW_UXRCE_MAX_PUBLISHERS=10", + "-DRMW_UXRCE_MAX_SUBSCRIPTIONS=5", + "-DRMW_UXRCE_MAX_SERVICES=1", + "-DRMW_UXRCE_MAX_CLIENTS=1", + "-DRMW_UXRCE_MAX_HISTORY=4", + "-DRMW_UXRCE_TRANSPORT=custom" + ] + } + } +} diff --git a/microros_static_library_ide/library_generation/extra_packages/extra_packages.repos b/microros_static_library_ide/library_generation/extra_packages/extra_packages.repos new file mode 100755 index 0000000..7ce2b93 --- /dev/null +++ b/microros_static_library_ide/library_generation/extra_packages/extra_packages.repos @@ -0,0 +1,5 @@ +repositories: + control_msgs: + type: git + url: https://github.com/ros-controls/control_msgs + version: foxy-devel \ No newline at end of file diff --git a/microros_static_library_ide/library_generation/extract_flags.py b/microros_static_library_ide/library_generation/extract_flags.py new file mode 100644 index 0000000..070dd06 --- /dev/null +++ b/microros_static_library_ide/library_generation/extract_flags.py @@ -0,0 +1,21 @@ +import sys + +text = sys.stdin.read().replace('\n', ' ').split(' ') + +mcpu = [x for x in text if x.startswith("-mcpu")] +mfpu = [x for x in text if x.startswith("-mfpu")] +mfloatabi = [x for x in text if x.startswith("-mfloat-abi")] +mthumb = [x for x in text if x.startswith("-mthumb")] +optimization = [x for x in text if x.startswith("-O")] + +out = "-ffunction-sections -fdata-sections" +if len(mcpu) and len(mfpu) and len(mfloatabi): + out = out + " " + mcpu[0] + " " + mfpu[0] + " " + mfloatabi[0] + if len(mthumb): + out = out + " " + mthumb[0] + if len(optimization): + out = out + " " + optimization[0] + print(out) + sys.exit(0) +else: + sys.exit(1) diff --git a/microros_static_library_ide/library_generation/library_generation.sh b/microros_static_library_ide/library_generation/library_generation.sh new file mode 100755 index 0000000..27a3702 --- /dev/null +++ b/microros_static_library_ide/library_generation/library_generation.sh @@ -0,0 +1,75 @@ +#!/bin/bash +set -e + +export BASE_PATH=/project/micro_ros_stm32cubemx_utils/microros_static_library_ide + +######## Check existing library ######## +if [ -f "$BASE_PATH/libmicroros/libmicroros.a" ]; then + echo "micro-ROS library found. Skipping..." + echo "Delete micro_ros_stm32cubemx_utils/microros_static_library_ide/libmicroros/ for rebuild." + exit 0 +fi +######## Trying to retrieve CFLAGS ######## +export RET_CFLAGS=$(find /project -type f -name *.mk -exec cat {} \; | python3 $BASE_PATH/library_generation/extract_flags.py) +RET_CODE=$? + +if [ $RET_CODE = "0" ]; then + echo "Found CFLAGS:" + echo "-------------" + echo $RET_CFLAGS + echo "-------------" +else + echo "Error retrieving croscompiler flags" + exit 1; +fi + +######## Init ######## +apt update +apt install -y gcc-arm-none-eabi + +cd /uros_ws + +source /opt/ros/$ROS_DISTRO/setup.bash +source install/local_setup.bash + +ros2 run micro_ros_setup create_firmware_ws.sh generate_lib + +######## Adding extra packages ######## +pushd firmware/mcu_ws > /dev/null + + # Workaround: Copy just tf2_msgs + git clone -b foxy https://github.com/ros2/geometry2 + cp -R geometry2/tf2_msgs ros2/tf2_msgs + rm -rf geometry2 + + # Import user defined packages + mkdir extra_packages + pushd extra_packages > /dev/null + cp -R $BASE_PATH/library_generation/extra_packages/* . + vcs import --input extra_packages.repos + popd > /dev/null + +popd > /dev/null + +######## Build ######## +export TOOLCHAIN_PREFIX=/usr/bin/arm-none-eabi- +ros2 run micro_ros_setup build_firmware.sh $BASE_PATH/library_generation/toolchain.cmake $BASE_PATH/library_generation/colcon.meta + +find firmware/build/include/ -name "*.c" -delete +rm -rf $BASE_PATH/libmicroros +mkdir -p $BASE_PATH/libmicroros/include +cp -R firmware/build/include/* $BASE_PATH/libmicroros/include/ +cp -R firmware/build/libmicroros.a $BASE_PATH/libmicroros/libmicroros.a + +######## Generate extra files ######## +find firmware/mcu_ws/ros2 \( -name "*.srv" -o -name "*.msg" -o -name "*.action" \) | awk -F"/" '{print $(NF-2)"/"$NF}' > $BASE_PATH/libmicroros/available_ros2_types +find firmware/mcu_ws/extra_packages \( -name "*.srv" -o -name "*.msg" -o -name "*.action" \) | awk -F"/" '{print $(NF-2)"/"$NF}' >> $BASE_PATH/libmicroros/available_ros2_types + +cd firmware +echo "" > $BASE_PATH/libmicroros/built_packages +for f in $(find $(pwd) -name .git -type d); do pushd $f > /dev/null; echo $(git config --get remote.origin.url) $(git rev-parse HEAD) >> $BASE_PATH/libmicroros/built_packages; popd > /dev/null; done; + +######## Fix permissions ######## +sudo chmod -R 777 $BASE_PATH/libmicroros/ +sudo chmod -R 777 $BASE_PATH/libmicroros/include/ +sudo chmod -R 777 $BASE_PATH/libmicroros/libmicroros.a \ No newline at end of file diff --git a/microros_static_library_ide/library_generation/toolchain.cmake b/microros_static_library_ide/library_generation/toolchain.cmake new file mode 100755 index 0000000..731fe18 --- /dev/null +++ b/microros_static_library_ide/library_generation/toolchain.cmake @@ -0,0 +1,17 @@ +SET(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_CROSSCOMPILING 1) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_C_COMPILER $ENV{TOOLCHAIN_PREFIX}gcc) +set(CMAKE_CXX_COMPILER $ENV{TOOLCHAIN_PREFIX}g++) + +SET(CMAKE_C_COMPILER_WORKS 1 CACHE INTERNAL "") +SET(CMAKE_CXX_COMPILER_WORKS 1 CACHE INTERNAL "") + +set(FLAGS $ENV{RET_CFLAGS} CACHE STRING "" FORCE) +set(MICROROSFLAGS "-DCLOCK_MONOTONIC=0 -D'__attribute__(x)='" CACHE STRING "" FORCE) + +set(CMAKE_C_FLAGS_INIT "-std=c11 ${FLAGS} ${MICROROSFLAGS} " CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS_INIT "-std=c++14 ${FLAGS} -fno-rtti ${MICROROSFLAGS} " CACHE STRING "" FORCE) + +set(__BIG_ENDIAN__ 0)