ESP32 xQueue, how to copy struct (memory) efficiently ?

toying around with this idea..

/*

https://forum.arduino.cc/t/esp32-xqueue-how-to-copy-struct-memory-efficiently/1393342

*/


#define BLOCK_SIZE 512
#define SD_QUEUE_SIZE 16 // maybe only 8

typedef struct {
  uint8_t  command;
  uint16_t len;
  uint8_t* block;
} SdBlock;

QueueHandle_t SdQ;

uint8_t SomeData[100];

void setup() {
  Serial.begin(115200);

  SdQ = xQueueCreate(SD_QUEUE_SIZE, sizeof(SdBlock));
  if ( SdQ != NULL )
  {
    xTaskCreate( vSdTask, "SD", 1000, NULL, 2, NULL );
  }
  else
  {
    /* The queue could not be created. */
    Serial.println("queue create failed..");
  }

  Serial.println("Ready..");

}

void loop() {


  if (Serial.available()) {
    switch (Serial.read()) {
      case '0': OpenFile("file.txt"); break;
      case '1': CloseFile(); break;
      case '2': WriteBlock((uint8_t*)&SomeData, sizeof(SomeData)); break;
    }
  }
  yield();
}



static void vSdTask( void *pvParameters )
{
  char CurrFileName[14];
  SdBlock RecBlock;
  BaseType_t xStatus;
  const TickType_t xTicksToWait = pdMS_TO_TICKS( 100 );

  for ( ;; )
  {
    xStatus = xQueueReceive( SdQ, &RecBlock, xTicksToWait );
    if ( xStatus == pdPASS )
    {
      switch (RecBlock.command) {
        case 0: //open file
          if (RecBlock.len < 14) {
            strcpy(CurrFileName, (char*)RecBlock.block);
            Serial.print("Opening File:"); Serial.println(CurrFileName);
          }
          break;
        case 1: //close file
          Serial.println("Closing File"); Serial.println(CurrFileName);
          break;
        case 2: //write block
          Serial.print("Writing block size:");
          Serial.println(RecBlock.len);
          break;

      }

      if (RecBlock.len > 0) {
        free(RecBlock.block);
        RecBlock.len = 0;
      }
    }
    else
    {
      vTaskDelay(1);
    }
    yield();
  }
}




bool OpenFile(char* filename) {
  BaseType_t qStatus;
  const TickType_t xTicksToWait = pdMS_TO_TICKS( 100 );
  SdBlock qBlock;
  bool ret = true;
  if (strlen(filename) > 0) {
    qBlock.block = (uint8_t*)malloc(strlen(filename) + 1);
    strcpy((char*)qBlock.block, filename);
    qBlock.command = 0;
    qBlock.len = strlen(filename);
    qStatus = xQueueSend(SdQ, &qBlock, xTicksToWait);
    if (qStatus != pdPASS) {
      Serial.println("OF:Send to Q failed..");
      free(qBlock.block);
      ret = false;
    }
  } else ret = false;
  return ret;
}

bool CloseFile() {
  BaseType_t qStatus;
  const TickType_t xTicksToWait = pdMS_TO_TICKS( 100 );
  SdBlock qBlock;
  bool ret = true;
  qBlock.command = 1;
  qBlock.len = 0;
  qStatus = xQueueSend(SdQ, &qBlock, xTicksToWait);
  if (qStatus != pdPASS) {
    Serial.println("CF:Send to Q failed..");
    ret = false;
  }
  return ret;
}


bool WriteBlock(uint8_t* buf, uint16_t len) {
  BaseType_t qStatus;
  const TickType_t xTicksToWait = pdMS_TO_TICKS( 100 );
  SdBlock qBlock;
  bool ret = true;
  if (len > 0) {
    qBlock.block = (uint8_t*)malloc(len);
    memcpy (qBlock.block, buf, len);
  }
  qBlock.len = len;
  qBlock.command = 2;
  qStatus = xQueueSend(SdQ, &qBlock, xTicksToWait);
  if (qStatus != pdPASS) {
    Serial.println("WB:Send to Q failed..");
    if (len > 0) free(qBlock.block);
    ret = false;
  }
  return ret;
}

fun stuff.. ~q

1 Like