ESP32:任务之间的共享变量

问题描述 投票:0回答:0

我想在 ESP32 上实现生产者/消费者任务。为此,有两个任务:第一个任务通过 I2C 读取输入并将其存储在队列中;第二个任务从队列中获取值。虽然,生产者持续提供数据,因此不能被搁置,同时消费者任务相对较慢,包括文件管理。 出于这个原因,我有两个队列,因此在消费者从其中一个队列获取值期间,消费者填充另一个队列。为此,我打算实现一种信号量,为他们应该使用的队列任务提供信息。

在执行过程中,收到以下错误信息:

ELF file SHA256: f835c00085624c05

Rebooting...
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13104
load:0x40080400,len:3036
entry 0x400805e4

assert failed: xQueueGenericSend queue.c:820 (pxQueue)


Backtrace: 0x40083585:0x3ffb4d80 0x400890c9:0x3ffb4da0 0x4008e10d:0x3ffb4dc0 0x400898ce:0x3ffb4ef0 0x400d1444:0x3ffb4f30

这里是相关代码:

#include <Arduino.h>
#include "esp_task_wdt.h"

TaskHandle_t Task1_f;
TaskHandle_t Task2_f;
void Task1code( void * pvParameters );
void Task2code( void * pvParameters );
static volatile QueueHandle_t queue;

enum semaphore_t {INSENDING, INRECEIVING, IDLE};
static volatile semaphore_t queue_semaphore;

void setup() {
  xTaskCreatePinnedToCore(
    Task1code,                /* Task function. */
    "Task1 - producer",       /* name of task. */
    10000,                    /* Stack size of task */
    NULL,                     /* parameter of the task */
    1,                        /* priority of the task */
    &Task1_f,                 /* Task handle to keep track of created task */
    0);                       /* pin task to core 0 */                  

  xTaskCreatePinnedToCore(
    Task2code,                /* Task function. */
    "Task2 - consumer",       /* name of task. */
    10000,                    /* Stack size of task */
    NULL,                     /* parameter of the task */
    2,                        /* priority of the task */
    &Task2_f,                 /* Task handle to keep track of created task */
    1);                       /* pin task to core 1 */  

  queue = xQueueCreate(256, sizeof(uint8_t));
  queue_semaphore = INSENDING;

  Serial.begin(115200);
  while(!Serial);
}


void Task1code( void * pvParameters ){
  uint8_t l_counter = 0;
  Serial.printf("%s running on core %d\n", "Task1code", xPortGetCoreID());
  
  for(;;){    

    if(l_counter<100){
      xQueueSend(queue, &l_counter, portMAX_DELAY);
      l_counter++;
    }else if(queue_semaphore==INSENDING){
      queue_semaphore=INRECEIVING;
    }else if(queue_semaphore==IDLE){
      queue_semaphore=INSENDING;
      l_counter=0;
    }

    esp_task_wdt_reset();

    delay(5000);
  }
}

void Task2code( void * pvParameters ){
  uint8_t l_counter = 0;

  Serial.printf("%s running on core %d\n", "Task2code", xPortGetCoreID());

  for(;;){
    if(queue_semaphore==INRECEIVING){
       while(uxQueueSpacesAvailable(queue)!=256){
         xQueueReceive(queue, &l_counter, portMAX_DELAY);
         //...
       }

      queue_semaphore=IDLE;
    }

    esp_task_wdt_reset();

    delay(3000);
  }
}

void loop() {
  vTaskDelete(NULL);
}

注:代码经过简化

我不确定 FreeRTOS 二进制信号量或互斥量是否可以解决问题,因为生产者任务无法暂停。

multithreading esp32 producer-consumer
© www.soinside.com 2019 - 2024. All rights reserved.