1

Good day to everyone,

I am currently working on project using ATmega2560. I want to use threading, that is why I decided to use FreeRTOS. However, I cannot make one thread to work fine, so that I start writing second one. So, I have following code:

#include <stdlib.h>
#include <avr/wdt.h>
#include <Arduino_FreeRTOS.h>
#include <semphr.h>

void setup()
{
    pinMode(car_state_pin, INPUT);
    pinMode(battery_pin, INPUT);

    Serial.begin(9600);
    Serial2.begin(9600);
    Serial3.begin(9600);

    watchdogSetup(); //setup WD for 8 secs

    Serial.println("Create Tasks");

    Serial.flush();
    Serial2.flush();
    Serial3.flush();

    xTaskCreate(collect_data, (const portCHAR *) "GPS_Collect_Data", 128, NULL, 1, NULL);

    //collect_data(NULL);
}    

And I have function collect_data which should run as thread:

void collect_data(void *pvParameters)
{

    (void)pvParameters;
    uint8_t len;
    char *tmp;

    for (;;)
    {
        millis_delay(2000);

        if (digitalRead(car_state_pin) == HIGH)
        {

            Serial.println("Collecting Data");
            tmp = (char *) calloc(50, sizeof(char));

            do
            {
                wdt_reset();
                len = gps_get_data(tmp);            
                Serial.println("Len < 15!");
                millis_delay(100);
            } while (strlen(tmp) < 15);


            /* Add imei and state of the car into the data string */
            len += sprintf(tmp + len, "%s,%d,%d", imei, digitalRead(car_state_pin), digitalRead(battery_pin));
            tmp[len] = 0;

#ifdef DEBUG
            Serial.print("TMP IS: ");
            Serial.println(tmp);

            Serial.print("Len is: ");
            Serial.println(len);
#endif

            free(tmp);
        }
    }
}

The problem is, this current code does not work properly, it resets automatically after printing "Collecting Data" and it just repeats forever (So output is:

Creating Tasks
Collecting Data
Creating Tasks
Collecting Data

and so on). However, when I comment xTaskCreate and do normal function call (uncomment the last line of setup), it works perfect. Can there be any reason, why thread wouldn't work as normal function call? I guessed maybe because of stacksize, but I've increased it and still no result.

  • What is `wdt_reset()` supposed to do? – Sim Son Dec 22 '19 at 14:33
  • @SimSon The watchdog handling is activated for RTOS and you have to ensure that it is triggered in between the watchdog time interval (here 8 sec ?). If these triggers do not occur, the MCU assumes a hanging interrupt and resets the MCU. I'm more concerned about the cmalloc without a free. – Peter Paul Kiefer Dec 22 '19 at 15:22
  • You use cmalloc without freeing the memory. The task needs memory. The greater the stack is, the more memory is used by the task, the less memory you can allocate. If you use more stack memory there is not enough memory for the second malloc. Why do you allocate the buffer in the loop? If you need it, be sure to free the tmp variable after usage. Use a smaller stack size. You only need space for the task frame and the local variables. – Peter Paul Kiefer Dec 22 '19 at 15:27
  • @PeterPaulKiefer ahh, I remember. Thanks for reminding! – Sim Son Dec 22 '19 at 17:49
  • @PeterPaulKiefer thanks for your answer. However, decreasing stack size and free-ing tmp did not change anything. Again, function call works fine, however, thread fails. I already made changes to the code snippet – Miradil Zeynalli Dec 23 '19 at 08:54

0 Answers0