FreeRTOS on WiFi MKR 1010

Hello, I am having an issue with the Arduino WiFi MKR 1010 board running FreeRTOS. The board just quits working when I upload a sketch that contains a xTaskCreate function.

Here is the quick summary. I have the built in LED blink really fast until a serial connection is made. When I include FreeRTOS_SAMD21 and don't call xTaskCreate, I can see the LED blink really fast, I then make a serial connection and everyone's happy.

As soon as I uncomment xTaskCreate when I upload the image, I don't see that built in LED blink really fast anymore, it's just frozen. I don't see the Arduino board on any COMS port. Anyone has any idea what is going on? I have to press the power button twice to get it to show up in the COMS list again.

I am now seeing different behavior. If I just include FreeRTOS_SAMD21 then it freezes and I don't get the blinking LED and the Arduino board doesn't show up in the COMS list. I can't believe that it is corrupt or running out of RAM.

I wouldn't jump to that conclusion.

The tricky thing about the boards with native USB functionality like your board is that the USB code that creates the CDC serial port is running on the same ATSAMD21G18 microcontroller as your sketch. This means your sketch code can break the USB code, or stop it from running. When that happens, it no longer presents a port.

This can be unexpected to those who previously mainly worked with the boards like Uno and Mega that have a dedicated USB chip that can never be affected by the sketch code.

In some cases this could be the normal and expected result from your code. The most common example is putting the microcontroller to sleep to save power: if the microcontroller is sleeping, it can't also be running the code that creates the CDC serial port, so the port will only be available while the microcontroller is awake. A simple example of a sketch that will make the board's port disappear by putting it to sleep:

#include <ArduinoLowPower.h>
void setup() {
  LowPower.sleep();
}
void loop() {}

Another example would be where you had an application where the CDC or even entire USB stack was not needed or wanted and so bypassed or disabled that lower level USB code that is normally compiled into your sketch program. For example:

// Override core library's main()
int main() {
  return 0;
}

Another:

void setup() {
  noInterrupts();
}
void loop() {}

It also might happen unintentionally when a bug in your program causes the chip to not be able to run the USB stack. That could be unintentionally causing one of the conditions I mentioned above, or just a pure bug, such as:

void setup() {
  volatile byte foo = 1 / 0;  // The variable must be volatile to prevent it from being optimized out.
}
void loop() {}

I realize that none of what I have written provides an answer about what is happening with your sketch. My hope was that a general overview of what can cause these symptoms can be useful for anyone who owns one of these boards. I don't have any experience with FreeRTOS. Hopefully the other forum members can provide more specific assistance.

Hi @matikitorch

As @in0 says, the Arduino loop() function also checks the COM so that the board can automatically upload new sketches. However, in the SAMD21 port of FreeRTOS the loop() function also acts as the idle task that executes whenever all other tasks are in the blocked state.

If you create a FreeRTOS task at a higher priority than the idle task and this task doesn't block, the idle task will never be given the opportunity to run and consequently the Arduino sketch can't service the COM port. In this instance, automatic uploads will fail.

If you insert some form of blocking delay in your task, it should give enough slack in the system for the idle task to run and thereby allow the sketch to operate as normal. Just add the FreeRTOS delay function vTaskDelay() to your task, this will cause it to block for the specified time allowing the loop() function to run.

For example to add a 100ms delay:

vTaskDelay(pdMS_TO_TICKS(100));

Thank you for your responses. While that definitely helps understand the system, I am not sure that that's what I'm experiencing. This morning I went at it again, trying to use the FreeRTOS library in the Arduino IDE and it kind of just worked this time. I played with a few configurations in the FreeRTOSConfig file, that's all, can't remember exactly which ones I changed, but I basically removed a few features that I knew I wasn't going to use.

This does make sense that it could be a USB stack problem, but the FreeRTOS portion of my code (xTaskCreate and vTaskStartScheduler) doesn't get executed until a serial connection is made. The very first line in setup is waiting for a serial connection and blinking the built in light. Can something in the compilation cause the Arduino to crash/freeze?

What I am seeing though, that this is very inconsistent. I was able to run 2 tasks, but then when I added a 3rd, everything crashed again. I went back to 2 and now that doesn't even work.

This freeRTOS code that crashes when three tasks are ran, is it secret?

I'm not a WiFi MKR 101 person, have not used one but I've been using freeRTOS for a number of years and know a thing or two.

``
xTaskCreatePinnedToCore( MQTTkeepalive, "MQTTkeepalive", 15000, NULL, 5, NULL, 1 );
xTaskCreatePinnedToCore( fparseMQTT, "fparseMQTT", 10000, NULL, 5, NULL, 1 ); // assign all to core 1, WiFi in use.
xTaskCreatePinnedToCore( fReadBattery, "fReadBattery", 4000, NULL, 3, NULL, 1 );
xTaskCreatePinnedToCore( fReadCurrent, "fReadCurrent", 4000, NULL, 3, NULL, 1 );
xTaskCreatePinnedToCore( fWindDirection, "fWindDirection", 10000, NULL, 4, NULL, 1 );
xTaskCreatePinnedToCore( fAnemometer, "fAnemometer", 10000, NULL, 4, NULL, 1 );
xTaskCreatePinnedToCore( fRainFall, "fRainFall", 10000, NULL, 4, NULL, 1 );
xTaskCreatePinnedToCore( fmqttWatchDog, "fmqttWatchDog", 3000, NULL, 3, NULL, 1 ); // assign all to core 1

Hi @matikitorch

As @Idahowalker says, at this stage it probably easiest to just post your code. At least we'll then be able to see where the problem might lie.