FreeRTOS timer never getting into callback function

Hello! I'm trying out FreeRTOS on ESP32 and I wrote this code:

Service.h

#ifndef Service_H
#define Service_H

#include <Arduino.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"

class Service 
{
    public:
        Service(const char* ServiceName, uint32_t TickRate);
        void ServiceInit();
        void DoWork();
        void Stop();
        static void vTimerCallback(TimerHandle_t TimerHandle);
        TimerHandle_t gWorkTimer;
    private:
        uint32_t gTickRate;
        const char* gServiceName;
};

#endif

Service.cpp

#include "Service.h"

Service::Service(const char* ServiceName, uint32_t TickRate)
{
    this->gTickRate = TickRate;
    this->gServiceName = ServiceName;
}

void Service::ServiceInit()
{
    Serial.println("init");
    this->gWorkTimer = xTimerCreate(this->gServiceName, pdMS_TO_TICKS(this->gTickRate), pdTRUE, (void*)0, &vTimerCallback);
}

void Service::DoWork()
{

}

void Service::Stop()
{

}

void Service::vTimerCallback(TimerHandle_t TimerHandle)
{
    Serial.println("...");
}

Main.ino:

#include "Service.h"

void setup() {
  Serial.begin(115200);
  Serial.println("setup");
  Service* s = new Service("dummy", 2000);
  s->ServiceInit();

  while(1) {}
}

void loop() {
}

When it runs, timer never gets to vTimerCallback function ("..." never gets printed):

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13864
load:0x40080400,len:3608
entry 0x400805f0
setup
init

Does someone know what could be wrong?

Best regards,
Luka

Never print in an interrupt service routine. Instead set a global flag variable, declared volatile, and check the flag in the main loop.

It is not an ISR timer, but a software one.
Can you please try to help me with the problem?
I think that the problem is because I have it in a class. For an example, this code works for me and it looks very similar:

Check that you have included codes in the .cpp file to start the timer.

My Output:

13:06:47.336 -> ...
13:06:49.321 -> ...
13:06:51.326 -> ...

So, my code works for you?

How do I choose the timer to generate ticks?
Also, I thought xTimerCreate starts the timer by itself, can you please paste that part of the code?
Even better, could you paste the whole code?

Thank you,
Luka

1. You insert the following codes at the appropriate place of your .cpp file:

if (gWorkTimer != NULL) 
 {
   // Start the timer
   xTimerStart(gWorkTimer, 0);   
 }

2. xTimerCreate() Function
In FreeRTOS, the xTimerCreate() function is used to create a software timer. FreeRTOS is a real-time operating system (RTOS) that allows you to build embedded and real-time systems with tasks, queues, and timers. Software timers are a feature of FreeRTOS that allow you to execute code at specified intervals or after a certain amount of time has passed. Here is the basic syntax for the xTimerCreate() function:

TimerHandle_t xTimerCreate(const char *pcTimerName, TickType_t xTimerPeriodInTicks, UBaseType_t uxAutoReload, void *pvTimerID, TimerCallbackFunction_t pxCallbackFunction);

pcTimerName: This is a pointer to a string that provides a human-readable name for the timer. It's for debugging and identification purposes.

xTimerPeriodInTicks: This parameter specifies the timer period in ticks. A tick in FreeRTOS is the unit of time used by the scheduler. The actual duration of a tick depends on the configuration of FreeRTOS but is typically in milliseconds. The timer will expire and trigger its callback function after this number of ticks has passed.

uxAutoReload: This is a flag (either pdTRUE or pdFALSE) that determines whether the timer is an auto-reload timer. If set to pdTRUE, the timer will automatically restart itself after it expires, and the callback function will be called periodically. If set to pdFALSE, the timer will expire only once, and you'll need to manually restart it if you want it to run again.

pvTimerID: This is a pointer to a user-defined data structure or value that can be associated with the timer. It allows you to pass additional information to the timer callback function.

pxCallbackFunction: This is a pointer to the function that will be called when the timer expires. The callback function should have a specific signature and can perform the desired task or action when the timer triggers.

3. xStartTimer() Function:
The xTimerStart() function is part of the FreeRTOS real-time operating system and is used to start a software timer that was previously created using xTimerCreate(). Software timers in FreeRTOS are used for executing tasks or calling callback functions at specific intervals or after a certain amount of time has passed. Here is the basic syntax for the xTimerStart() function:

BaseType_t xTimerStart(TimerHandle_t xTimer, TickType_t xTicksToWait);

xTimer: This is the handle to the timer that you want to start. You obtain this handle when you create a timer using xTimerCreate().

xTicksToWait: This parameter specifies the amount of time, in ticks, that the function should wait before starting the timer. If you want to start the timer immediately, you can set this parameter to zero (0).

1 Like

Ohhh, I knew it was something stupid.
Thank you a lot!

It was not a stupid job from your side. We have been learning slowly the FreeRTOS using ESP32; so, making one or more mistakes are quite normal.

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