STM32系列MICROROS环境配置(更新 使用cmake管理)
-
更新:更加自由的构建STM32 Microros静态库的方法(适用于linux X86 arm64本文只讲述x86,arm64流程一致,不过需要将arm64系统中的编译器补全部分库即可)
一.使用 micro_ros_setup 生成Microros静态链接库
Ubuntu x86环境:前提 ,需要下载交叉编译器,若已安装可以跳过
sudo apt-get install -y gcc-arm-none-eabi
下面为从创建工作空间到生成静态库的所有命令,一步一步运行即可:
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_setup.git src/micro_ros_setup #若不能使用rosdep,可以使用rosdepc rosdep update && rosdep install --from-paths src --ignore-src -y colcon build source install/local_setup.bash ros2 run micro_ros_setup create_firmware_ws.sh generate_lib generic
到此,基础构建完成目录如上图所示,但还需要配置两个配置文件 toolchain.cmake和colcon.meta才能生成静态链接库
toolchain.cmake配置如下set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_CROSSCOMPILING 1) set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) # SET HERE THE PATH TO YOUR C99 AND C++ COMPILERS # 在这里添加编译器路径 set(PIX arm-none-eabi-) set(CMAKE_C_COMPILER ${PIX}gcc) set(CMAKE_CXX_COMPILER ${PIX}g++) set(CMAKE_C_COMPILER_WORKS 1 CACHE INTERNAL "") set(CMAKE_CXX_COMPILER_WORKS 1 CACHE INTERNAL "") # SET HERE YOUR BUILDING FLAGS set(FLAGS "-O2 -ffunction-sections -fdata-sections -fno-exceptions -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -nostdlib -mthumb --param max-inline-insns-single=500 -D'RCUTILS_LOG_MIN_SEVERITY=RCUTILS_LOG_MIN_SEVERITY_NONE'" CACHE STRING "" FORCE) #-mcpu=cortex-m3 改成 -mcpu=cortex-m7 这里根据stm32内核更替 # 加入 mfpu=fpv5-d16 -mfloat-abi=hard 支持硬件浮点编译 这里根据stm32内核更替 set(CMAKE_C_FLAGS_INIT "-std=c11 ${FLAGS} -DCLOCK_MONOTONIC=0 -D'__attribute__(x)='" CACHE STRING "" FORCE) set(CMAKE_CXX_FLAGS_INIT "-std=c++11 ${FLAGS} -fno-rtti -DCLOCK_MONOTONIC=0 -D'__attribute__(x)='" CACHE STRING "" FORCE) set(__BIG_ENDIAN__ 0)
注意:在toolchain.cmake中的
-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
部分最好根据生成的工程中cmake配置文件保持一致,此配置对stm32同意系列生效(一般同一系列内核保持一致,例如F1系列内核为M3,F4系列内核为M4)如下图所示colcon.meta配置如下,此配置摘抄自 micro_ros_stm32cubemx_utils 配置文件如下图所示路径
{ "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" ] } } }
上述两个文件(toolchain.cmake colcon.meta)放入如下图所示的路径中
~/uros_ws/firmware/mcu_ws
最后编译静态库ros2 run micro_ros_setup build_firmware.sh $(pwd)/firmware/mcu_ws/toolchain.cmake $(pwd)/firmware/mcu_ws/colcon.meta
最后生成文件在firmware/build目录下,如下图所示
将inclue目录和静态库文件移植到stm32工程文件中即可使用二.使用静态库文件
STM32方面配置可参考我上篇文章进行配置STM32配置流程只需注意最后生成工程选择cmake即可(cubemx可能需要更新到最新才有此选项)
在STM32 CMakeLists.txt文件中需要加入以下内容
编译C文件- custom_memory_manager.c
- microros_allocators.c
- microros_time.c
- microros_transports/dma_transport.c
如下图所示
set(extera_source ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/Src/custom_memory_manager.c ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/Src/microros_allocators.c ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/Src/microros_time.c ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/Src/microros_transports/dma_transport.c )
并在如下图位置加入即可
添加静态库文件- libmicroros.a
set(THIRD_PARTY_LIB "${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/lib/libmicroros.a")
并在如下图位置加入即可
cmake内容如下,但由于该工程有其他库内容,读者只需看个模板即可,具体内容还是根据读者工程目录进行修改
cmake_minimum_required(VERSION 3.22) # # This file is generated only once, # and is not re-generated if converter is called multiple times. # # User is free to modify the file as much as necessary # # Setup compiler settings set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS ON) # Define the build type if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Debug") endif() # Set the project name set(CMAKE_PROJECT_NAME MicroROSF4_Cmake) # Include toolchain file include("cmake/gcc-arm-none-eabi.cmake") # Enable compile command to ease indexing with e.g. clangd set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) # Core project settings project(${CMAKE_PROJECT_NAME}) message("Build type: " ${CMAKE_BUILD_TYPE}) # Enable CMake support for ASM and C languages enable_language(C ASM) # Create an executable object type add_executable(${CMAKE_PROJECT_NAME}) # Add STM32CubeMX generated sources add_subdirectory(cmake/stm32cubemx) # Link directories setup target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE # Add user defined library search paths ) # # 3rd-party lib start # # set(THIRD_PARTY_LIB "${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/lib/libmicroros.a") set(extera_source_control ${PROJECT_SOURCE_DIR}/Third-party/control/Src/control.c ${PROJECT_SOURCE_DIR}/Third-party/control/Src/Encoder.c ${PROJECT_SOURCE_DIR}/Third-party/oled/Src/I2C_Fun.c ${PROJECT_SOURCE_DIR}/Third-party/imu/Src/ICM20948.c ${PROJECT_SOURCE_DIR}/Third-party/oled/Src/oled.c ${PROJECT_SOURCE_DIR}/Third-party/delay/Src/Delay.c ${PROJECT_SOURCE_DIR}/Third-party/robot_sys/Src/sys_struct.c ${PROJECT_SOURCE_DIR}/Third-party/MadgwickAHRS/Src/MadgwickAHRS.c ) set(extera_source ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/Src/custom_memory_manager.c ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/Src/microros_allocators.c ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/Src/microros_time.c ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/Src/microros_transports/dma_transport.c ) message(STATUS "dir is = ${PROJECT_SOURCE_DIR}") add_library(LibMicroros_app ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microrosapp/Src/microrosclass_agent.cpp ) target_include_directories(LibMicroros_app PRIVATE ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/Inc/microros_include ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microrosapp/Inc ) target_sources(LibMicroros_app PRIVATE # Add user sources here ${extera_source} Third-party/Lib_Microrosapp/Src/microros_class.cpp ) target_link_libraries(LibMicroros_app PRIVATE stm32cubemx ${THIRD_PARTY_LIB} ) # # 3rd-party lib end # # # Add sources to executable target_sources(${CMAKE_PROJECT_NAME} PRIVATE # Add user sources here ${extera_source} ${extera_source_control} ) # Add include paths target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE # Add user defined include paths ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microros/Inc/microros_include ${PROJECT_SOURCE_DIR}/Third-party/Lib_Microrosapp/Inc ${PROJECT_SOURCE_DIR}/Third-party/MadgwickAHRS/Inc ${PROJECT_SOURCE_DIR}/Third-party/control/Inc ${PROJECT_SOURCE_DIR}/Third-party/oled/Inc ${PROJECT_SOURCE_DIR}/Third-party/imu/Inc ${PROJECT_SOURCE_DIR}/Third-party/robot_sys/Inc ${PROJECT_SOURCE_DIR}/Third-party/delay/Inc ) # Add project symbols (macros) target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE # Add user defined symbols ) # Add linked libraries target_link_libraries(${CMAKE_PROJECT_NAME} stm32cubemx # Add user defined libraries LibMicroros_app # 自己生成的静态库 ${THIRD_PARTY_LIB} # 第三方静态库 )
剩下的内容可以查看我上一章节内容,主要是microros agent的构建与使用AGENT使用