Search code examples
c++arduinointerrupt

Arduino, code hangs in weird way when a function is invoked


I have the following code behaving in a weird way, when I make a method call

#include <TimerOne.h>
#include <cppQueue.h>
#include <Arduino.h>

typedef struct Diagnostic {
String entityName;
uint16_t pin;
} Diag;
// Global setup
cppQueue q(sizeof(Diag *), 10, FIFO, false);
int ctr = 0;
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
}

// Add to queue

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(2000);                       // wait for a second
  Serial.println("After high");
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second

  // Critical Section

  Diag d;
  Serial.println("String assignment");
  d.entityName = "Front Door";
  d.pin = LED_BUILTIN;
  d_ptr = &d;
  Serial.println("Enqueuing one");
  q.push(&d);
  Serial.println("Enqueued one");
  Serial.println(freeMemory());
  //q.pop(&d);
  //Serial.println("Dequeued one" + d.entityName);
  DequeueIsr();
  //Serial.println("Atomic block");
  //Serial.println(q.getCount());

  //Serial.println("Loop end");
}

 void DequeueIsr() {
   Diag di;

   if (!q.isEmpty())
   {
      Serial.println("Queue not empty");
      q.pop(&di);
      Serial.println("Dequeued one" + di.entityName);
      Serial.println(freeMemory());
   }   
 }

Whenever I try to pop my object in the DequeueIsr function, the code hangs after 2 or 3 iterations, there is no output on the serial monitor after that. If I just copy the code in the Dequeue method and run it in the main loop it works, it doesn't get stuck. Also this happens when I work with strings, if I remove the entityName field from Diag, it works inside the method. Am I missing something crucial ?

What I really wanted to do was, dequeue the queue using an interrupt method using the TimerOne library. I have removed all timer related code and even a simple method call isn't working.


Solution

  • It looks like cppQueue copies objects using memcpy so it only works with trivially copyable objects, String is not trivially copyable so your code has undefined behaviour