Error when code splited to multiple Tabs (FreeRtos Arduino IDE 2.1)

Hi to all and happy new year

I wanted to play with FreeRtos and an Esp32.
I like when i am written my code to split it in multiple Tabs (one tab for "global variables", an other one for "setup" , an other for "Loop" etc)

i have this code that when i compile it like it is (in one only tab) everything is ok

// TWAI - CANBUs
#include "driver/twai.h"
// Pins used to connect to CAN bus transceiver:
#define RX_PIN 26
#define TX_PIN 25
// Intervall:
#define POLLING_RATE_MS 1000
static bool driver_installed = false;
String texto;

///??////////////////////////////////////////////////////////////////////


TaskHandle_t Task_OneTask;
TaskHandle_t Task_TWAI;
TaskHandle_t Task_ThirdTask;





void setup() {
  // put your setup code here, to run once:


  Serial.begin(115200);


  ///////////////////////////////////////////////////////////////////////
  // TWAI
  // Initialize configuration structures using macro initializers
  twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_LISTEN_ONLY);
  twai_timing_config_t t_config = TWAI_TIMING_CONFIG_125KBITS();  //Look in the api-reference for other speed sets.
  twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
  // Install TWAI driver
  if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
    Serial.println("Driver installed");
  } else {
    Serial.println("Failed to install driver");
    return;
  }
  // Start TWAI driver
  if (twai_start() == ESP_OK) {
    Serial.println("Driver started");
  } else {
    Serial.println("Failed to start driver");
    return;
  }
  // Reconfigure alerts to detect frame receive, Bus-Off error and RX queue full states
  uint32_t alerts_to_enable = TWAI_ALERT_RX_DATA | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL;
  if (twai_reconfigure_alerts(alerts_to_enable, NULL) == ESP_OK) {
    Serial.println("CAN Alerts reconfigured");
  } else {
    Serial.println("Failed to reconfigure alerts");
    return;
  }
  // TWAI driver is now successfully installed and started
  driver_installed = true;

  ///////////////////////////////////////////////////////////////////////
  // Free RTOS
  xTaskCreate(
    TaskOneTask,     // Task function.
    "Task OneTask",  // name of task.
    1024,            // Stack size of task
    NULL,            // parameter of the task
    1,               // priority of the task
    &Task_OneTask    // Task handle to keep track of created task
  );                 // pin task to core 0
  delay(100);
 
  xTaskCreate(
    TaskTWAI,     // Task function.
    "Task TWAI",  // name of task.
    1024,         // Stack size of task
    NULL,         // parameter of the 7
    1,            // priority of the task
    &Task_TWAI    // Task handle to keep track of created task
  );              // pin task to core 0
  delay(100);

  xTaskCreate(
    TaskThirdTask,     // Task function.
    "Task ThirdTask",  // name of task.
    1024,              // Stack size of task
    NULL,              // parameter of the task
    1,                 // priority of the task
    &Task_ThirdTask    // Task handle to keep track of created task
  );                   // pin task to core 0
  delay(100);
}



static void handle_rx_message(twai_message_t& message) {
  // Process received message
  if (message.extd) {
    Serial.println("Message is in Extended Format");
  } else {
    Serial.println("Message is in Standard Format");
  }
  Serial.printf("ID: %x\nByte:", message.identifier);
  if (!(message.rtr)) {
    for (int i = 0; i < message.data_length_code; i++) {
      Serial.printf(" %d = %02x,", i, message.data[i]);
    }
    Serial.println("");
  }

  // WORKING
  if (message.identifier == 0x20) {
    // working also and with 02  instead of  0x02
    if (message.data[1] == 0x02){ 
      Serial.println("Message received , everything OK !!  ");
    }
    
  }
}




void loop() {
  // put your main code here, to run repeatedly:
}






void TaskOneTask(void* parameter) {
  Serial.print("Task1 is running on core ");
  Serial.println(xPortGetCoreID());

  for (;;) {
    Serial.println("OneTask ");
    delay(200);
  }
}


void TaskTWAI(void* parameter) {
  Serial.print("Task1 is running on core ");
  Serial.println(xPortGetCoreID());

  for (;;) {
    Serial.println("TWAI ");
    if (!driver_installed) {
      // Driver not installed
      delay(1000);
      return;
    }
    // Check if alert happened
    uint32_t alerts_triggered;
    twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(POLLING_RATE_MS));
    twai_status_info_t twaistatus;
    twai_get_status_info(&twaistatus);

    // Handle alerts
    if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
      Serial.println("Alert: TWAI controller has become error passive.");
    }
    if (alerts_triggered & TWAI_ALERT_BUS_ERROR) {
      Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.");
      Serial.printf("Bus error count: %d\n", twaistatus.bus_error_count);
    }
    if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) {
      Serial.println("Alert: The RX queue is full causing a received frame to be lost.");
      Serial.printf("RX buffered: %d\t", twaistatus.msgs_to_rx);
      Serial.printf("RX missed: %d\t", twaistatus.rx_missed_count);
      Serial.printf("RX overrun %d\n", twaistatus.rx_overrun_count);
    }

    // Check if message is received
    if (alerts_triggered & TWAI_ALERT_RX_DATA) {
      // One or more messages received. Handle all.
      twai_message_t message;
      while (twai_receive(&message, 0) == ESP_OK) {
        handle_rx_message(message);
      }
    }
  }
}








void TaskThirdTask(void* parameter) {
  Serial.print("Task1 is running on core ");
  Serial.println(xPortGetCoreID());

  for (;;) {
    Serial.println("ThirdTask ");
    delay(200);
  }
}

If i split it to multiple Tabs i am getting an error

error: variable or field 'handle_rx_message' declared void
static void handle_rx_message(twai_message_t& message) {
^~~~~~~~~~~~~~

and

Compilation error: variable or field 'handle_rx_message' declared void

The problem is the : static void handle_rx_message(twai_message_t& message)

if i keep the global variables , setup and static void handle_rx_message(twai_message_t& message) in the same first Tab then i can split my remain code to other tabs

Any suggestion about what i am doing wrong when i split my code? am i missing any parammeters that have to use when i split my code?

Thanks in advance

It's impossible to know without seeing the code that's causing the errors.

I have upload the code... in what code are you refering?

The problem is just when i place the "voids" in diferent Tabs . (Arduino IDE just make then different ino files for each Tab )

So nothing is different in the code as the one i have uploaded all ready..

First, they are not "voids". They are functions, 'void' simply specifies that the function does not return a value.

Since the problem comes after you separate the code into different tabs, it seems logical that you should post the contents of the individual tabs as separate code blocks.

the arduino ide just save the code to separate .ino files with the name of the Tabs and has just only the Function code (everything you have placed in the Tab) nothing more nothing less

But if that helps it is not a problem to upload the file codes as separate

TEST_FREERTOS_TWAI.ino

// TWAI - CANBUs
#include "driver/twai.h"
// Pins used to connect to CAN bus transceiver:
#define RX_PIN 26
#define TX_PIN 25
// Intervall:
#define POLLING_RATE_MS 1000
static bool driver_installed = false;
String texto;

///??////////////////////////////////////////////////////////////////////


TaskHandle_t Task_OneTask;
TaskHandle_t Task_TWAI;
TaskHandle_t Task_ThirdTask;

01.ino

void setup() {
  // put your setup code here, to run once:


  Serial.begin(115200);


  ///////////////////////////////////////////////////////////////////////
  // TWAI
  // Initialize configuration structures using macro initializers
  twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_LISTEN_ONLY);
  twai_timing_config_t t_config = TWAI_TIMING_CONFIG_125KBITS();  //Look in the api-reference for other speed sets.
  twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
  // Install TWAI driver
  if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
    Serial.println("Driver installed");
  } else {
    Serial.println("Failed to install driver");
    return;
  }
  // Start TWAI driver
  if (twai_start() == ESP_OK) {
    Serial.println("Driver started");
  } else {
    Serial.println("Failed to start driver");
    return;
  }
  // Reconfigure alerts to detect frame receive, Bus-Off error and RX queue full states
  uint32_t alerts_to_enable = TWAI_ALERT_RX_DATA | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL;
  if (twai_reconfigure_alerts(alerts_to_enable, NULL) == ESP_OK) {
    Serial.println("CAN Alerts reconfigured");
  } else {
    Serial.println("Failed to reconfigure alerts");
    return;
  }
  // TWAI driver is now successfully installed and started
  driver_installed = true;

  ///////////////////////////////////////////////////////////////////////
  // Free RTOS
  xTaskCreate(
    TaskOneTask,     // Task function.
    "Task OneTask",  // name of task.
    1024,            // Stack size of task
    NULL,            // parameter of the task
    1,               // priority of the task
    &Task_OneTask    // Task handle to keep track of created task
  );                 // pin task to core 0
  delay(100);
 
  xTaskCreate(
    TaskTWAI,     // Task function.
    "Task TWAI",  // name of task.
    1024,         // Stack size of task
    NULL,         // parameter of the 7
    1,            // priority of the task
    &Task_TWAI    // Task handle to keep track of created task
  );              // pin task to core 0
  delay(100);

  xTaskCreate(
    TaskThirdTask,     // Task function.
    "Task ThirdTask",  // name of task.
    1024,              // Stack size of task
    NULL,              // parameter of the task
    1,                 // priority of the task
    &Task_ThirdTask    // Task handle to keep track of created task
  );                   // pin task to core 0
  delay(100);
}



static void handle_rx_message(twai_message_t& message) {
  // Process received message
  if (message.extd) {
    Serial.println("Message is in Extended Format");
  } else {
    Serial.println("Message is in Standard Format");
  }
  Serial.printf("ID: %x\nByte:", message.identifier);
  if (!(message.rtr)) {
    for (int i = 0; i < message.data_length_code; i++) {
      Serial.printf(" %d = %02x,", i, message.data[i]);
    }
    Serial.println("");
  }

  // WORKING
  if (message.identifier == 0x20) {
    // working also and with 02  instead of  0x02
    if (message.data[1] == 0x02){ 
      Serial.println("Message received , everything OK !!  ");
    }
    
  }
}

02.ino

void loop() {
  // put your main code here, to run repeatedly:
}

03.ino

void TaskOneTask(void* parameter) {
  Serial.print("Task1 is running on core ");
  Serial.println(xPortGetCoreID());

  for (;;) {
    Serial.println("OneTask ");
    delay(200);
  }
}

04.ino

void TaskTWAI(void* parameter) {
  Serial.print("Task1 is running on core ");
  Serial.println(xPortGetCoreID());

  for (;;) {
    Serial.println("TWAI ");
    if (!driver_installed) {
      // Driver not installed
      delay(1000);
      return;
    }
    // Check if alert happened
    uint32_t alerts_triggered;
    twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(POLLING_RATE_MS));
    twai_status_info_t twaistatus;
    twai_get_status_info(&twaistatus);

    // Handle alerts
    if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
      Serial.println("Alert: TWAI controller has become error passive.");
    }
    if (alerts_triggered & TWAI_ALERT_BUS_ERROR) {
      Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.");
      Serial.printf("Bus error count: %d\n", twaistatus.bus_error_count);
    }
    if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) {
      Serial.println("Alert: The RX queue is full causing a received frame to be lost.");
      Serial.printf("RX buffered: %d\t", twaistatus.msgs_to_rx);
      Serial.printf("RX missed: %d\t", twaistatus.rx_missed_count);
      Serial.printf("RX overrun %d\n", twaistatus.rx_overrun_count);
    }

    // Check if message is received
    if (alerts_triggered & TWAI_ALERT_RX_DATA) {
      // One or more messages received. Handle all.
      twai_message_t message;
      while (twai_receive(&message, 0) == ESP_OK) {
        handle_rx_message(message);
      }
    }
  }
}

05.ino

void TaskThirdTask(void* parameter) {
  Serial.print("Task1 is running on core ");
  Serial.println(xPortGetCoreID());

  for (;;) {
    Serial.println("ThirdTask ");
    delay(200);
  }
}

Ahhhhh .... so you're using the brain-dead "Arduino Method" of breaking a project into multiple files. I had assumed that you were using the method of proper .h / .cpp files.

That combined with the equally brain-dead Arduino auto-generation of function prototypes is what's causing the problem. Try adding your own function prototype for 'handle_rx_message()' to "TEST_FREERTOS_TWAI.ino":

// TWAI - CANBUs
#include "driver/twai.h"
// Pins used to connect to CAN bus transceiver:
#define RX_PIN 26
#define TX_PIN 25
// Intervall:
#define POLLING_RATE_MS 1000
static bool driver_installed = false;
String texto;

///??////////////////////////////////////////////////////////////////////

static void handle_rx_message(twai_message_t& message);

TaskHandle_t Task_OneTask;
TaskHandle_t Task_TWAI;
TaskHandle_t Task_ThirdTask;

By the way, why did you declare the function 'handle_rx_message()' as "static"????

1 Like

Thanks for the Help
No i am not familiar yet with the proper method but hope after some time that will be more capable to code start using the proper method

i would be very glad if my coding skills where at the level of the code is written in the function

handle_rx_message()

it is from the embedded example of the ESP32 for can-bus (twai) so i am not sure why the used the static

Thanks again to clarify me what was wrong

I guess "proper" is subjective. I'd say it's the method used by experienced programmers working on larger projects that benefit from modularity. See My Post #5 in this Thread for a basic guide.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.