BUG: RTOS library seems to be incompatible to rpcWiFi.h

There seems to be an issue when RTOS and rpcWiFi.h libraries are combined. The below code will run if you remove the rpcWiFI.h library which makes it very difficult to use WiFi and RTOS together.

//**************************************************************************
// FreeRtos on Samd21
// By Scott Briscoe
//

// Project is a simple example of how to get FreeRtos running on a SamD21 processor
// Project can be used as a template to build your projects off of as well
//**************************************************************************

#include <Seeed_Arduino_FreeRTOS.h>
#include <rpcWiFi.h>

//**************************************************************************
// Type Defines and Constants
//**************************************************************************

#define ERROR_LED_PIN 13 //Led Pin: Typical Arduino Board

#define ERROR_LED_LIGHTUP_STATE LOW // the state that makes the led light up on your board, either low or high

// Select the serial port the project should use and communicate over
// Sombe boards use SerialUSB, some use Serial
#define SERIAL SerialUSB
//#define SERIAL Serial

//**************************************************************************
// global variables
//**************************************************************************
TaskHandle_t Handle_aTask;
TaskHandle_t Handle_bTask;
TaskHandle_t Handle_monitorTask;

//**************************************************************************
// Can use these function for RTOS delays
// Takes into account procesor speed
//**************************************************************************
void myDelayUs(int us) {
vTaskDelay(us / portTICK_PERIOD_US);
}

void myDelayMsUntil(TickType_t* previousWakeTime, int ms) {
vTaskDelayUntil(previousWakeTime, (ms * 1000) / portTICK_PERIOD_US);
}

//*****************************************************************
// Create a thread that prints out A to the screen every two seconds
// this task will delete its self after printing out afew messages
//*****************************************************************
static void threadA(void* pvParameters) {

SERIAL.println("Thread A: Started");
for (int x = 0; x < 20; ++x) {
    SERIAL.print("A");
    delay(500);
}

// delete ourselves.
// Have to call this or the system crashes when you reach the end bracket and then get scheduled.
SERIAL.println("Thread A: Deleting");
vTaskDelete(NULL);

}

//*****************************************************************
// Create a thread that prints out B to the screen every second
// this task will run forever
//*****************************************************************
static void threadB(void* pvParameters) {
SERIAL.println(“Thread B: Started”);

while (1) {
    SERIAL.println("B");
    delay(2000);
}

}

//*****************************************************************
// Task will periodicallt print out useful information about the tasks running
// Is a useful tool to help figure out stack sizes being used
//*****************************************************************
void taskMonitor(void* pvParameters) {
int x;
int measurement;

SERIAL.println("Task Monitor: Started");

// run this task afew times before exiting forever
for (x = 0; x < 10; ++x) {

    SERIAL.println("");
    SERIAL.println("******************************");
    SERIAL.println("[Stacks Free Bytes Remaining] ");

    measurement = uxTaskGetStackHighWaterMark(Handle_aTask);
    SERIAL.print("Thread A: ");
    SERIAL.println(measurement);

    measurement = uxTaskGetStackHighWaterMark(Handle_bTask);
    SERIAL.print("Thread B: ");
    SERIAL.println(measurement);

    measurement = uxTaskGetStackHighWaterMark(Handle_monitorTask);
    SERIAL.print("Monitor Stack: ");
    SERIAL.println(measurement);

    SERIAL.println("******************************");

    delay(10000); // print every 10 seconds
}

// delete ourselves.
// Have to call this or the system crashes when you reach the end bracket and then get scheduled.
SERIAL.println("Task Monitor: Deleting");
vTaskDelete(NULL);

}

//*****************************************************************

void setup() {

SERIAL.begin(115200);

vNopDelayMS(1000); // prevents usb driver crash on startup, do not omit this
while (!SERIAL) ;  // Wait for serial terminal to open port before starting program

SERIAL.println("");
SERIAL.println("******************************");
SERIAL.println("        Program start         ");
SERIAL.println("******************************");

// Set the led the rtos will blink when we have a fatal rtos error
// RTOS also Needs to know if high/low is the state that turns on the led.
// Error Blink Codes:
//    3 blinks - Fatal Rtos Error, something bad happened. Think really hard about what you just changed.
//    2 blinks - Malloc Failed, Happens when you couldn't create a rtos object.
//               Probably ran out of heap.
//    1 blink  - Stack overflow, Task needs more bytes defined for its stack!
//               Use the taskMonitor thread to help gauge how much more you need
vSetErrorLed(ERROR_LED_PIN, ERROR_LED_LIGHTUP_STATE);

// Create the threads that will be managed by the rtos
// Sets the stack size and priority of each task
// Also initializes a handler pointer to each task, which are important to communicate with and retrieve info from tasks
xTaskCreate(threadA,     "Task A",       256, NULL, tskIDLE_PRIORITY + 3, &Handle_aTask);
xTaskCreate(threadB,     "Task B",       256, NULL, tskIDLE_PRIORITY + 2, &Handle_bTask);
xTaskCreate(taskMonitor, "Task Monitor", 256, NULL, tskIDLE_PRIORITY + 1, &Handle_monitorTask);

// Start the RTOS, this function will never return and will schedule the tasks.
vTaskStartScheduler();

}

//*****************************************************************
// This is now the rtos idle loop
// No rtos blocking functions allowed!
//*****************************************************************
void loop() {
// Optional commands, can comment/uncomment below
SERIAL.print("."); //print out dots in terminal, we only do this when the RTOS is in the idle state
vNopDelayMS(100);
}

//*****************************************************************

Hi @richard.seguin,

Could you delete vTaskStartScheduler(); ?

We have already called it in rpcUnified. You can check here:

Hope it helps.

Best Regards,
Lakshantha

Hi,

I made the change that you recommended, and now I see the “.” from the loop(), but I don’t see any tasks running.

Hi @richard.seguin,

It seems like if you delete the codes inside the void loop(), the tasks will start running.

We have updated the example here:

Best Regards,
Lakshantha

Hi,

i have the same pb here !
if i want to use FreeRTOS with rpcWIFI, my app doesn’t work… (hang at vTaskStartScheduler)
i tryed to remove it as recommended, but the task doesn’t start… and the loop is runnning…

how to combinate custom tasks and rpcWifi ? any example ?

Thank so much for help !

I have the same problem !! I delete vTaskStartScheduler() in Setup(), but program still stuck …

Any improvements here? Having same problem. Any attempt to use rpcWiFi and FreeRTOS results in hanged WIO terminal and I only able to upload anything to it after switching it to bootloader mode.

Any way to do this? I’m having the same problem, Wio Terminal stops working when the FreeRTOS tasks are created :slightly_frowning_face: