<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[stm32移植microros]]></title><description><![CDATA[<h1>概述</h1>
<p dir="auto"><strong>本篇以<code>cubemx</code>模板构建<code>microros</code>代码，实现stm32F429IGT6运行简单例程。</strong></p>
<p dir="auto">官方学习网站：<a href="https://micro.ros.org/" target="_blank" rel="noopener noreferrer nofollow ugc">https://micro.ros.org/</a></p>
<h1>嵌入式端构建流程</h1>
<p dir="auto">以该仓库为教程：<a href="https://github.com/micro-ROS/micro_ros_stm32cubemx_utils" target="_blank" rel="noopener noreferrer nofollow ugc">https://github.com/micro-ROS/micro_ros_stm32cubemx_utils</a></p>
<p dir="auto"><strong>大致步骤：</strong></p>
<ul>
<li>
<p dir="auto">克隆仓库</p>
</li>
<li>
<p dir="auto">选择<code>sample_project.ioc</code>，在<code>cubemx</code>中打开并完善配置，生成<code>MakeFile</code>工程。</p>
</li>
<li>
<p dir="auto">修改<code>MakeFile</code>文件</p>
</li>
<li>
<p dir="auto">从Docker拉取镜像并构建生成静态库<code>libmicroros.a</code>及头文件。</p>
</li>
<li>
<p dir="auto">添加文件，添加例程代码，进行测试。</p>
</li>
</ul>
<h1>具体步骤</h1>
<h2>克隆仓库</h2>
<p dir="auto">无他，找寻个喜欢的位置，直接克隆即可。</p>
<p dir="auto"><strong>以下是克隆下的仓库，只需关注所框文件：</strong><br />
<img src="/forum/assets/uploads/files/1764682622434-df6b7dce-ec36-48a0-8286-fd877231a218-image-20251126223754318.png" alt="df6b7dce-ec36-48a0-8286-fd877231a218-image-20251126223754318.png" class=" img-fluid img-markdown" /></p>
<ul>
<li>
<p dir="auto"><code>extra_sources</code>:里面是<code>microros</code>框架针对STM32嵌入式平台提供的适配层和底层支持代码。</p>
</li>
<li>
<p dir="auto"><code>custom_memory_manager.c</code>:microros实际管理分配内存的代码，使用的是<code>freertosAPI</code>函数</p>
<ul>
<li><code>microros_allocators.c</code>:对<code>custom_memory_manager.c</code>的进一步封装</li>
<li><code>microros_time.c</code>:为 micro-ROS 客户端库提供精确的系统时间，使用的是<code>freertosAPI</code>函数</li>
<li><code>microros_transports</code>文件夹下的四个文件，是官方提供的物理传输层接口，分别通过串口+DMA,串口中断，<code>udp</code>,<code>usb</code>与电脑连接，从而实现板子和电脑上的数据传输。</li>
</ul>
</li>
<li>
<p dir="auto"><code>microros_static_library,microros_static_library_ide</code>是静态库构建的核心，为 Docker 容器提供所有必要的脚本和配置文件。最后生成的静态库就这这两个文件夹下面，以<code>cubemx</code>模板构建在前者文件夹，<code>IDE</code>则在后者。</p>
</li>
<li>
<p dir="auto"><code>sample_main.c,sample_main_udp.c,sample_main_embeddedrtps.c</code>三者都是得的例程，区别在传输协议上，前两个用的是<strong>micro-XRCE-DDS 协议</strong>，通过串口，网络与ROS节点通信，依赖<strong>micro-ROS Agent</strong> 充当中继；<code>embeddedrtps.c</code>则是<strong>直接在嵌入式设备上运行完整的 DDS/RTPS 协议栈</strong>，可直接与ROS节点通信，不依赖<strong>micro-ROS Agent</strong> ，延迟更低，但资源消耗太大。</p>
</li>
<li>
<p dir="auto"><code>sample_project.ioc</code>其实没啥用，就是正常的<code>cubemx</code>工程配置。</p>
</li>
</ul>
<h2>生成<code>MakeFile</code>工程</h2>
<p dir="auto">通过<code>cubemx</code>配置生成<code>MakeFile</code>工程。配置时只需注意串口，<code>DMA</code>,<code>FreeRTOS</code>，任务栈要给大，官方推荐3000。</p>
<h2>修改<code>MakeFile</code>文件</h2>
<p dir="auto"><code>MakeFile</code>文件在Docker编译生成静态库中很重要，Docker编译时会读取你工程中的<code>MakeFile</code>文件中关于**编译工具，选项的设置，**如编译器版本，是否使用硬件浮点等。默认是不用修改的。</p>
<h2>构建生成静态库</h2>
<pre><code>docker pull microros/micro_ros_static_library_builder:kilted
docker run -it --rm -v $(pwd):/project --env MICROROS_LIBRARY_FOLDER=micro_ros_stm32cubemx_utils/microros_static_library microros/micro_ros_static_library_builder:kilted
</code></pre>
<p dir="auto">​    构建过程其实就这几行命令，注意选择自己需要的R版本，还有比较令人恼火的是，因为网络代理原因，拉取完镜像，<strong>构建编译时总是失败，原因是无法连接到<code>github</code></strong>。作者被折磨了好几天，也未能解决，在<code>linux</code>上构建编译时从未成功,几次成功的经历都是在WSL环境下实现的。注意Docker的代理需要手动配置，WSL2的也需要手动配置。希望读者不会遇到该问题，或读者能轻松解决。</p>
<p dir="auto"><img src="/forum/assets/uploads/files/1764682721269-53115e51-078d-46e6-baf1-61aa89a77b8d-image-20251127183437635.png" alt="53115e51-078d-46e6-baf1-61aa89a77b8d-image-20251127183437635.png" class=" img-fluid img-markdown" /> <img src="image-20251127183437635.png" alt="image-20251127183437635" class=" img-fluid img-markdown" /></p>
<p dir="auto">​    构建成功之后，我们会在<code>microros_static_library</code>文件夹中找到<code>libmicroros</code>文件夹，该文件夹就是生成的静态库等所需文件。</p>
<p dir="auto"><img src="/forum/assets/uploads/files/1764682741992-ee2aec3f-e5ec-4edb-a5c9-21e82580948a-image-20251127183757235-resized.png" alt="ee2aec3f-e5ec-4edb-a5c9-21e82580948a-image-20251127183757235.png" class=" img-fluid img-markdown" /> <img src="image-20251127183757235.png" alt="image-20251127183757235" class=" img-fluid img-markdown" /></p>
<ul>
<li><code>microros_include</code>文件夹是各种头文件。</li>
<li><code>libmicroros.a</code>就是静态库文件，里面包含了<code>microros</code>的函数具体实现，相当于它没有给我们.c源文件，而是把他们包含在了.a静态库中。优点是不用添加一堆文件，缺点万一有问题不能debug，因为你没有源码，并且消息类型变量不能自由定义。</li>
<li><code>available_ros2_types</code>这是<code>microros</code>可用的消息类型，由编译时生成。</li>
<li><code>built_packages</code>这个似乎是用于版本记录控制的，无需太关注。</li>
</ul>
<h2>添加例程，文件进行测试</h2>
<h3>添加文件</h3>
<p dir="auto">​    就五个文件（头文件除外）</p>
<ul>
<li>
<p dir="auto"><code>libmicroros.a</code></p>
</li>
<li>
<p dir="auto"><code>custom_memory_manager.c</code></p>
</li>
<li>
<p dir="auto"><code>microros_allocators.c</code></p>
</li>
<li>
<p dir="auto"><code>microros_time.c</code></p>
</li>
<li>
<p dir="auto"><code>dma_transport.c</code>:如果你不是用串口+DMA通信，改用符合的文件。</p>
</li>
</ul>
<h2>例程</h2>
<p dir="auto">参照<code>sample_main.c</code>，主要代码如下：</p>
<pre><code class="language-c">/* USER CODE BEGIN 4 */
bool cubemx_transport_open(struct uxrCustomTransport * transport);
bool cubemx_transport_close(struct uxrCustomTransport * transport);
size_t cubemx_transport_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
size_t cubemx_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);

void * microros_allocate(size_t size, void * state);
void microros_deallocate(void * pointer, void * state);
void * microros_reallocate(void * pointer, size_t size, void * state);
void * microros_zero_allocate(size_t number_of_elements, size_t size_of_element, void * state);
/* USER CODE END 4 */

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN 5 */

  // micro-ROS configuration

  rmw_uros_set_custom_transport(
    true,
    (void *) &amp;huart3,
    cubemx_transport_open,
    cubemx_transport_close,
    cubemx_transport_write,
    cubemx_transport_read);

  rcl_allocator_t freeRTOS_allocator = rcutils_get_zero_initialized_allocator();
  freeRTOS_allocator.allocate = microros_allocate;
  freeRTOS_allocator.deallocate = microros_deallocate;
  freeRTOS_allocator.reallocate = microros_reallocate;
  freeRTOS_allocator.zero_allocate =  microros_zero_allocate;

  if (!rcutils_set_default_allocator(&amp;freeRTOS_allocator)) {
      printf("Error on default allocators (line %d)\n", __LINE__); 
  }

  // micro-ROS app

  rcl_publisher_t publisher;
  std_msgs__msg__Int32 msg;
  rclc_support_t support;
  rcl_allocator_t allocator;
  rcl_node_t node;

  allocator = rcl_get_default_allocator();

  //create init_options
  rclc_support_init(&amp;support, 0, NULL, &amp;allocator);

  // create node
  rclc_node_init_default(&amp;node, "cubemx_node", "", &amp;support);

  // create publisher
  rclc_publisher_init_default(
    &amp;publisher,
    &amp;node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "cubemx_publisher");

  msg.data = 0;

  for(;;)
  {
    rcl_ret_t ret = rcl_publish(&amp;publisher, &amp;msg, NULL);
    if (ret != RCL_RET_OK)
    {
      printf("Error publishing (line %d)\n", __LINE__); 
    }
    
    msg.data++;
    osDelay(10);
  }
  /* USER CODE END 5 */
}
</code></pre>
<h1>代理端构建</h1>
<p dir="auto">​        如果通信协议选择使用的<strong>micro-XRCE-DDS 协议</strong>，在运行ROS2的主机上还需构建<code>microros_agent</code>,官方教程参照：<a href="https://github.com/micro-ROS/micro_ros_setup?tab=readme-ov-file%E3%80%82%E6%8C%89%E7%85%A7%E5%AE%98%E6%96%B9%E6%95%99%E7%A8%8B%E5%AE%8C%E6%95%B4%E6%B5%81%E7%A8%8B%E6%9E%84%E5%BB%BA%EF%BC%8C%E9%99%A4%E4%BA%86%E5%8F%AF%E9%85%8D%E7%BD%AE" target="_blank" rel="noopener noreferrer nofollow ugc">https://github.com/micro-ROS/micro_ros_setup?tab=readme-ov-file。按照官方教程完整流程构建，除了可配置</a><code>miccroros_agent</code>，**还可获得所有源码，如之前缺失的.c文件。**但文件层次比较复杂，需仔细研究一番。</p>
<p dir="auto">​    <strong>若只构建<code>microros_agent</code>:</strong></p>
<p dir="auto">只需参考运行<strong>Building，Building micro-ROS-Agent</strong>这两部分的命令代码。</p>
<p dir="auto"><img src="/forum/assets/uploads/files/1764682787264-1a7e02c9-d4ea-4507-8432-e87135e3e945-image-20251127204425923-resized.png" alt="1a7e02c9-d4ea-4507-8432-e87135e3e945-image-20251127204425923.png" class=" img-fluid img-markdown" /> <img src="image-20251127204425923.png" alt="image-20251127204425923" class=" img-fluid img-markdown" /></p>
<p dir="auto"><img src="/forum/assets/uploads/files/1764682823263-b20cac9c-52a9-4203-ab94-82267762caef-image-20251127205159697-resized.png" alt="b20cac9c-52a9-4203-ab94-82267762caef-image-20251127205159697.png" class=" img-fluid img-markdown" /> <img src="image-20251127205159697.png" alt="image-20251127205159697" class=" img-fluid img-markdown" /></p>
<h1>成果检验</h1>
<p dir="auto">最终效果：</p>
<p dir="auto"><img src="/forum/assets/uploads/files/1764682840479-2251c90a-7b80-4456-b966-e5fe74cf661f-image-20251127204943932.png" alt="2251c90a-7b80-4456-b966-e5fe74cf661f-image-20251127204943932.png" class=" img-fluid img-markdown" /> <img src="image-20251127204943932.png" alt="image-20251127204943932" class=" img-fluid img-markdown" /></p>
]]></description><link>https://fishros.org.cn/forum/topic/4659/stm32移植microros</link><generator>RSS for Node</generator><lastBuildDate>Wed, 26 Aug 2026 15:13:51 GMT</lastBuildDate><atom:link href="https://fishros.org.cn/forum/topic/4659.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 02 Dec 2025 13:43:14 GMT</pubDate><ttl>60</ttl></channel></rss>