<?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[使用Micro-ROS报错]]></title><description><![CDATA[<p dir="auto">使用CubeMX+IDE开发<br />
下面是我freertos的Default代码</p>
<pre><code>void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */

  // 0. 上电自检打印
  printf("\r\n[SYSTEM] Power On.\r\n");
  printf("[SYSTEM] Stack Size: %d bytes\r\n", (int)(3000 * 4));

  // 1. 初始化底层 (串口/内存)
  printf("[Init] Connecting to Agent...\r\n");
  while(Micro_ROS_Patch_Init(&amp;huart3) != 1)
  {
      printf("[Error] Patch Init Failed.\r\n");
      osDelay(500);
  }

  // 2. 初始化分配器
  allocator = rcl_get_default_allocator();

  // 3. 握手连接 Agent
  rcl_ret_t rc_support = rclc_support_init(&amp;support, 0, NULL, &amp;allocator);
  while (rc_support != RCL_RET_OK)
  {
      printf("."); // 打印点点表示正在连接
      HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0); // 快闪板载LED
      osDelay(200);
      // 重试
      rc_support = rclc_support_init(&amp;support, 0, NULL, &amp;allocator);
  }
  printf("\r\n[Init] Agent Connected! (rc=%d)\r\n", (int)rc_support);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // 灭灯

  // 4. 创建节点
  rclc_node_init_default(&amp;node, "stm32_led_node", "", &amp;support);

  // 5. 创建订阅者 (Reliable)
  rcl_ret_t rc_sub = rclc_subscription_init_default(
      &amp;subscriber,
      &amp;node,
      ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, String),
      "led_control"
  );
  if (rc_sub != RCL_RET_OK) {
      printf("[Fatal] Sub Init Failed: %d\r\n", (int)rc_sub);
      for(;;) osDelay(100);
  }

  // 6. 配置消息内存
  std_msgs__msg__String__init(&amp;sub_msg);
  sub_msg.data.data = msg_buffer;
  sub_msg.data.capacity = sizeof(msg_buffer);
  sub_msg.data.size = 0;

  // 7. 初始化执行器
  rcl_ret_t rc_exec = rclc_executor_init(&amp;executor, &amp;support.context, 4, &amp;allocator);
  if (rc_exec != RCL_RET_OK) {
      printf("[Fatal] Executor Init Failed: %d\r\n", (int)rc_exec);
      for(;;) osDelay(100);
  }

  // 8. 添加订阅者
  rcl_ret_t rc_add = rclc_executor_add_subscription(
        &amp;executor,
        &amp;subscriber,
        &amp;sub_msg,
        &amp;Led_Control_Callback,
        ON_NEW_DATA
    );
  if (rc_add != RCL_RET_OK) {
      printf("[Fatal] Add Sub Failed: %d\r\n", (int)rc_add);
      for(;;) osDelay(100);
  }

  printf("[Init] System Ready. Entering Loop...\r\n");

  // ==========================================================
  // 主循环
  // ==========================================================
  for(;;)
  {
      // Spin
      rcl_ret_t rc = rclc_executor_spin_some(&amp;executor, RCL_MS_TO_NS(100));

      if (rc == RCL_RET_OK) {
          // 正常: 收到消息处理完毕
          // printf("OK "); // 刷屏太快，建议屏蔽
      }
      else if (rc == RCL_RET_TIMEOUT) {
          // 正常: 没有消息
      }
      else {
          // 🔴 真正的运行时错误捕获
          printf("[Error] Spin: %d\r\n", (int)rc);

          osDelay(100);
      }

      osDelay(10);
  }
  /* USER CODE END StartDefaultTask */
}
</code></pre>
<p dir="auto">之后报错，下面是报错日志</p>
<pre><code>[Init] Agent Connected! (rc=0)
[Init] System Ready. Entering Loop...
[Error] Spin: 900
[Error] Spin: 900
[Error] Spin: 900
[Error] Spin: 900
[Error] Spin: 900
[Error] Spin: 900
[Error] Spin: 900
</code></pre>
]]></description><link>https://fishros.org.cn/forum/topic/4663/使用micro-ros报错</link><generator>RSS for Node</generator><lastBuildDate>Wed, 26 Aug 2026 15:13:53 GMT</lastBuildDate><atom:link href="https://fishros.org.cn/forum/topic/4663.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 04 Dec 2025 07:30:56 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to 使用Micro-ROS报错 on Thu, 04 Dec 2025 08:01:26 GMT]]></title><description><![CDATA[<p dir="auto">问题解决了，源头出在一个补丁函数：</p>
<pre><code>void * microros_reallocate(void * pointer, size_t size, void * state){
  return NULL; // 静态策略下通常不使用 realloc
}
</code></pre>
<p dir="auto">简单来说，就是micro-ROS 试图申请或调整内存时，需要用到这个函数，而我的函数直接返回了NULL值，导致了micro-ROS 无法调整内存<br />
为此，求助LLM，对函数做出以下修改:</p>
<pre><code>void * microros_reallocate(void * pointer, size_t size, void * state){
  // 情况 1: 如果指针为空，这就相当于 malloc (这是 Micro-ROS 初始化最常用的情况)
  if (pointer == NULL) {
    return pvPortMalloc(size);
  }

  // 情况 2: 如果大小为 0，这就相当于 free
  if (size == 0) {
    vPortFree(pointer);
    return NULL;
  }

  // 情况 3: 真正的 realloc (调整大小)
  // 由于 FreeRTOS 的 heap_4 不支持 realloc，我们需要手动“搬家”
  // ⚠️ 警告：我们不知道旧数据块的大小，这是一个风险点。
  // 但 Micro-ROS 通常用它是为了扩大数组。
  // 这里的策略是：申请新内存 -&gt; 假定旧数据有效 -&gt; 释放旧内存
  
  void * new_ptr = pvPortMalloc(size);
  if (new_ptr != NULL) {
      // 这里的拷贝长度是个玄学，因为我们不知道旧块有多大。
      // 但对于 wait_set 这种结构，通常是安全的，或者我们可以只拷贝一部分。
      // 为了安全起见，我们假设旧数据也很重要，拷贝 size 长度 (可能会读越界，但在 RAM 连续的 MCU 上通常没事)
      // 更安全的做法是引入记录内存大小的机制，但太复杂。
      // 这里采用最简单的“能跑就行”策略：
      memcpy(new_ptr, pointer, size); // 注意：如果 size &lt; old_size，会截断；如果 size &gt; old_size，可能会读到垃圾数据
      vPortFree(pointer);
  }
  return new_ptr;
}
</code></pre>
<p dir="auto">重新编译烧录，问题解决</p>
]]></description><link>https://fishros.org.cn/forum/post/19319</link><guid isPermaLink="true">https://fishros.org.cn/forum/post/19319</guid><dc:creator><![CDATA[winstonmanapple]]></dc:creator><pubDate>Thu, 04 Dec 2025 08:01:26 GMT</pubDate></item></channel></rss>