Nefel 2024-03-29 11:31 采纳率: 0%
浏览 107

请问如何解决在使用VSCode插件Platform编译ESP32时出现的错误

在使用VSCode插件Platform编译ESP32时出现错误

错误详情:

assert failed: xQueueGenericSend queue.c:832 (pxQueue->pcHead != ((void *)0) || pxQueue->u.xSemaphore.xMutexHolder == ((void *)0) || pxQueue->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle())

Backtrace: 0x40083721:0x3ffd2d40 0x4008be6d:0x3ffd2d60 0x40091815:0x3ffd2d80 0x4008c922:0x3ffd2eb0 0x40143be9:0x3ffd2ef0 0x4014322b:0x3ffd2f10 0x400d48b2:0x3ffd2f30 0x400d521d:0x3ffd2f90 0x400d6cea:0x3ffd2ff0 0x4015389d:0x3ffd3020 0x401538c2:0x3ffd3040 0x400db17e:0x3ffd3060 0x400d3065:0x3ffd3080 0x400d31f6:0x3ffd30b0

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-03-29 11:31
    关注

    引自免费微信小程序:皆我百晓生

    在VSCode插件Platform编译ESP32的过程中,如果出现assert failed: xQueueGenericSend queue.c:832 (pxQueue->pcHead != ((void *)0) || pxQueue->u.xSemaphore.xMutexHolder == ((void *)0) || pxQueue->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle())错误,这通常是因为pxQueue结构体可能没有正确的初始化或包含必要的字段。

    下面是关于这个问题的一些解决方案:

    1. 检查并初始化pxQueue:

      • 首先,确保pxQueue结构体被正确地定义且包含了必要的字段,例如pxQueue头指针、pxQueue的元素(每个元素可能是一个双向队列)以及pxQueue->u.xSemaphore结构体,这个结构体用于控制队列状态和处理任务。
      // 初始化pxQueue结构体
      let pxQueue = {
        pcHead: null,
        u: { /* 应包含必要的pxQueue结构字段 */ },
        xSemaphore: {}
      };
      
      • 如果pxQueue中存在空指针,你可能需要删除它并重新初始化,这样pxQueue头指针将指向一个非空对象。
      if (!pxQueue || pxQueue.pcHead === null) {
        pxQueue = {
          pcHead: null,
          u: { /* 应包含必要的pxQueue结构字段 */ },
          xSemaphore: {}
        };
      }
      
    2. 检查并初始化pxQueue中的特定字段:

      • pxQueue->u.xSemaphore结构体中,务必检查xSemaphoreHoldCount字段是否设置为非零值。xSemaphoreHoldCount用于跟踪处于就绪队列中的工作任务的数量,并在xSemaphore库或其他第三方工具(如Apache libxSemaphore)提供等待任务超时的通知。
      if (!pxQueue.u.xSemaphore.xSemaphoreHoldCount) {
        throw new Error('xSemaphoreHoldCount must be non-zero for pxQueue');
      }
      
      • pxQueue->u.xSemaphore.xSemaphoreHoldCount为负数,这意味着任务队列中不存在任何待执行的任务,因此需要更新头指针指向空位置以使pxQueue->u.xSemaphore属性适应实际的工作流。
      pxQueue.u.xSemaphore.xSemaphoreHoldCount = 0;
      pxQueue.u.xSemaphore.xSemaphore = xTaskCreate(NULL, NULL, NULL, NULL, NULL);
      
    3. 清除和重新创建任务队列:

      • 删除当前未处理的任务,并尝试重新创建一个空的任务队列,这样新的任务将自动填充空位并进入就绪队列。
      pxQueue.packets = [];
      while (!pxQueue.packets.length) {
        pxQueue.packets.push({ /* 应包含任务描述信息 */ });
        pxQueue.packets.shift();
      }
      
      // 创建一个新的空任务队列
      let taskQueue = xQueueCreate(&pxQueue.u.xSemaphore, 1);
      
      // 启动新的任务队列
      xTaskSetPriority(taskQueue, kTaskPriorityNormal); // Set the priority to normal
      xTaskCreate(&pxQueue.packets[0].task, "task", taskQueue, kCpuCoreNumberFirst, NULL, NULL);
      
      • 使用xQueueCreate()函数从pxQueue.u.xSemaphore结构体中创建一个新的任务队列,并指定一个负载因子(kCpuCoreNumberFirst表示CPU核心数量的第一位)。xQueueCreate()函数将返回一个指向新任务队列的指针。
    4. 检测任务队列大小和状态:

      • 当启动新任务队列后,使用isTaskInWaiting()方法检查当前任务队列的状态。这个方法会返回一个布尔值,表示任务队列是否在就绪状态(即任务列表为空),并且可以根据具体的需求进行异常处理,例如向日志文件打印错误消息或重置定时器等。
      function isTaskInWaiting() {
        return pxQueue.packets.length > 0 && !pxQueue.packets.some(function(packet) {
          return packet.taskState !== kTaskRunning && packet.timeRemaining > 0; // Check whether task is in running state and has remaining time
        });
      }
      
      if (isTaskInWaiting()) {
        console.error("Task is currently in waiting state");
      } else {
        // If task is not in waiting state, clear the pending tasks and start a new one
        pxQueue.packets.forEach((packet) => {
          pxQueue.packets.shift();
        });
      
        // Start a new empty task queue
        taskQueue = xQueueCreate(&pxQueue.u.xSemaphore, 1);
        // ... (Continuation for completing the task queue)
      }
      
      • 遍历所有待处理的任务,如果发现某个任务已成功完成并达到等待条件,可以通过调用cancelPendingTasks()方法移除该任务并从队列中移除,从而释放资源并清理临时数据。
      pxQueue.packets.forEach((packet) => {
        if (packet.taskState === kTaskFinished && packet.timeRemaining <= 0) {
          // Remove the task from the queue and release its resources
          pxQueue.packets.shift();
          pxQueue.packets.splice(pxQueue.packets.indexOf(packet), 1);
          // Clear any temporary data associated with this task
          delete pxQueue.packets[packet.id];
          // ... (Continuation for cleaning up the task queue)
        }
      });
      
    5. 添加和更新驱动程序到平台库:

      • 通过platform-driver-sdk命令行工具更新esp-idfesp-gpio驱动程序到符合Platform插件要求的新版本,以便与pxQueue交互。
      # Update ESP-IDF or ESP-GPIO drivers to Platform library version
      platform_driver_update("//tools/platform-driver-sdk.esp-idf", "new-version")
      
      • 确保pxQueue引用正确的驱动程序依赖,通常是最新版本的esp-idf库文件名。例如,如果你正在使用的是esp-idf-v5.7.0, 需要更新驱动程序到drivers/xtensa/v5.7.0/xsoc Esp-idf-xsoc-prog.a

        // Update esp-idf v5.7.0
        platform_driver_update("//tools/platform-driver-sdk.esp-idf", "v5.7.0")
        
      • 重启vscode服务或应用以应用上述操作,然后再次尝试编译ESP32代码。

      • 对于esp-gpio驱动程序,更新其源码或依赖项到符合Platform插件要求的新版本,然后重新编译代码:

        # Update esp-gpio driver to Platform library version
        platform_driver_update("//tools/platform-driver-sdk.esp-gpio", "new-version")
        
      • 将更改后的驱动程序替换现有的配置文件或platform.json文件,比如platform.json文件路径:.../platforms/{project-name}/platform.json

    6. 检查并修复跨进程通信:

      • pxQueue结构体内维护pxQueueTaskMap对象,用于跟踪不同进程中完成的任务及其上下文。此对象的键是标识符(用于唯一区分同一任务的不同实例),值是一个字典,包含该任务所属进程的进程ID(xTaskProcessID)、创建任务的时间戳(created_at)、任务状态(task_state)以及任务的剩余时间(time_remaining)等信息。
      let pxQueueTaskMap = {};
      pxQueueTaskMap["id"] = { /* ... */}
      
      • 更新pxQueueTaskMap对象的同步方法,确保在各个进程间正确更新任务状态和恢复它们的工作流。例如,在onXXXUpdated事件处理器中:

        function onWorkerStart(xTaskProcessId, created_at, task_state, time_remaining) {
          if (!pxQueueTaskMap[xTaskProcessId]) {
            pxQueueTaskMap[xTaskProcessId] = { /* ... */}
          }
        
          const packet = { ...pxQueueTaskMap[xTaskProcessId], ...packet }; // Copy the updated payload
        
          if (task_state !== "running") {
            // Remove the completed task from the queue and update its status
            pxQueue.packets.splice(pxQueue.packets.indexOf(packet), 1);
            pxQueue.packets[packet.id].taskState = "finished"; // Change the task's status to "finished"
            pxQueue.packets[packet.id].timeRemaining -= time_remaining;
        
            // Try again after finishing the current task
            window.setTimeout(() => {
              try {
                isTaskInWaiting();
              } catch (error) {
                console.error(`Error during task reconfiguration for ${created_at} due to ` + error.message);
              }
            }, 0);
          } else {
            // The task is already in running state, so simply mark it as finished
            pxQueue.packets[packet.id].taskState = "finished";
          }
        }
        
      • 运行platformDriverUpdate()命令以加载新的驱动程序版本并更新pxQueueTaskMap对象。

    7. 调试和诊断:

      • 逐步执行代码,逐个检查各个步骤,看是否存在潜在的
    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 3月29日