Creating Circular Buffer lib

Thanks, I had tried that before but my syntax was incorrect.

It works now :slight_smile:

Thank you everyone for your help.

For anyone interested, below is the code:

//#include <malloc.h>
#include "datastructures.h"

queue testqueue; //create queue
char currenttask;
char addtask;
char resettask = 1;

void setup() {
  queueInit(&testqueue, 8);
  addtask = 'a';
  queueAdd(&testqueue, &addtask);
  
  Serial.begin(9600);
}

void loop() {
  
  if (!queueIsEmpty(&testqueue)){
    queueGetTask(&testqueue, &currenttask);
    queueExecuteTask(&testqueue, &currenttask);
  }
  
  addtask = 'b';
  
  if (queueIsFull(&testqueue)) queueFree(&testqueue);
  else queueAddFront(&testqueue, &addtask); 
 
  if (!queueIsEmpty(&testqueue)){
    queueGetTask(&testqueue, &currenttask);
    queueExecuteTask(&testqueue, &currenttask);
  }
  
  // As an alternative to checking !queueIsEmpty before get & execute next task,
  // we can assume something went wrong if the queue is empty at the end of the
  // main loop, so we can add a 'reset' task to the queue to be executed next.
  // This implies that tasks must add themselves or another task upon completion.
  if (queueIsEmpty(&testqueue)) queueAdd(&testqueue, &resettask);
  
}


/******************************************************************/
/*                    Task Queue functions                        */
/******************************************************************/

void queueInit(queue *q, int size) {
  q->size = size;
  q->head = 0;
  q->count = 0;
  q->tasks = (char *)calloc(q->size, sizeof(char)); }

void queueFree(queue *q) {
  free(q->tasks); }

int queueIsFull(queue *q) {
  return q->count == q->size; }
 
int queueIsEmpty(queue *q) {
  return q->count == 0; }
    
int queueDuplicateExists(queue *q, char *task) {
  for (int i=0; i < q->count; i++) {  //loop is skipped if queue is empty
    if (*task == q->tasks[i]) return 1; } //true 
  return 0; } //false
 
// Since nothing is returned, app must check if !queueIsFull() before attempting to add task
// otherwise it cannot know if Add was successful
void queueAdd(queue *q, char *task) {
  if (queueDuplicateExists(q, task)) return;
  if (queueIsFull(q)) return;   
  else {
      int tail = (q->head + q->count) % q->size;
      q->tasks[tail] = *task;
      ++ q->count; } }

void queueAddFront(queue *q, char *task) {
  if (queueDuplicateExists(q, task)) return;
  if (queueIsFull(q)) return;   
  else {
      q->tasks[(q->head - 1) % q->size] = *task; 
      q->head -- % q->size;
      ++ q->count; } }
 
// App must ensure !queueIsEmpty() first!!
void queueGetTask(queue *q, char *task) {
    *task = q->tasks[q->head];
    q->head = (q->head + 1) % q->size;
    -- q->count; }

void queueExecuteTask(queue *q, char *task) {
 
  switch (*task) {
    case 'a':
    Serial.println("function 'a' was called");
    case 'b':
    Serial.println("function 'b' was called");
    
    case 127:
    queueAdd(q, &resettask); // special reset task to be added in case queue is unexpectedly empty at end of main loop
                             // e.g. set char resettask = 'a' to start from that function again    
  }

  
}


/* function that returns free Ram on the device
int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}
*/