Dynamic memory allocation for pvParameter structs?

Hello, this question is about dynamic memory allocation for pvParameter structs.

So far I can allocate a static struct, use it as the pvParameter in xTimerCreate, and cast / access it in the timer callback function successfully, which is very nice indeed. Now I’m at the point where I realize I need to dynamically allocate these structs, because for example if I have something like “ulExecutionCount” from code example 14, each task will need a separate struct in memory to track that.

Searching around I found one solution on these forums which I’m still mulling over, and a post on the esp32 boards (see below)

My initial reaction is to custom build / search for a struct memory pool mechanism. Sound reasonable? Is there a “best practice” solution for this? Maybe the freertos gods can share their wisdom :slight_smile: ty!

(I would directly link these, but as a new user I can’t )
For the related post on here see “xTaskCreate and memory storing pvParameters”
For the esp32 post, search for “Correct way to pass struct as an xTaskCreate parameter?”

Maybe I get you wrong… but pvParameter can be anything or point to anything you want. It’s just a handle of user/application specific data and is not touched by FreeRTOS. It’s up to you how it’s interpreted.
It can be a simple integer value like 42 casted to void* or a pointer to a dynamically allocated struct or something else.
There are a few restrictions like don’t use main stack data for task parameters on Cortex-M MCUs because main stack is reused as ISR stack by FreeRTOS.
Also be careful regarding the lifetime/scope of data given as pointer e.g. when using (task) stack data.

@hs2 yes totally agree. I forgot to mention that I need to store more than just one value.

^^ Yes! That’s my question. How to manage the lifetime of the pointers. Do you have any concrete advice for that?

Still grinding on this, I’m using ESP32 so I’m going to have a look at using the espressif ring buffer implementation for this purpose.

Well, you could use heap memory using pvPortMalloc/Free which is simple and thread safe or a custom (fixed block) allocator like a ring buffer. The latter has the benefit that you can limit the amount of items to allocate but the minor drawback that you’ve to implement it and make it thread safe :wink: Even though that shouldn’t be too complicated.
Or if you’re using C++ you could use std::stack, pre-fill it with (malloc’d) buffers and wrap pop and push with a mutex or simply vTaskSuspend/ResumeAll to make it thread safe.

@hs2 Sounds amazing! Do you have any sample C or C++ code you can share implementing such things?

Sorry, I’ve nothing ready to share. But why not just starting with simple and ready to use pvPortMalloc/Free and maybe optimize later if really needed ?
If you deal with timer parameters resp. timer IDs the number of timers is limited anyway and therefore the number of parameter/ID allocations can’t go wild.
Be careful to avoid memory leaks e.g. when canceling a timer freeing up the timer ID.

I kept reading the docs and realized that rtos queues are exactly what I was looking for. Surprised someone here didn’t slap me silly with that right away hahah :rofl:

Still going with this. Turns out I still needed dynamic memory allocation for auto-reload timer pvParameters which I’m creating after I pull an event of the queue.

For now i’m using this:

To make it safe across tasks, I surrounded it with a mutex. Something like this:

// Critical Section
xSemaphoreTake(xMutex, portMAX_DELAY);
{
    xNewEvent = pEventPool.new_object();
}
xSemaphoreGive(xMutex);

You question about dynamic allocation is not very clear. Are you trying to do something like this:

typedef struct MyData
{
    uint32_t data1;
    uint32_t data2;
} MyData_t;

void vTimerCallback( TimerHandle_t xExpiredTimer )
{
    MyData_t * dynamicallyAllocatedStruct;

    dynamicallyAllocatedStruct = ( MyData_t * ) pvTimerGetTimerID( xExpiredTimer );

    /* Use dynamicallyAllocatedStruct here. */
}

void app( void )
{
    TimeHandle_t xTimerHandle;
    MyData_t * dynamicallyAllocatedStruct;

    /* Dynamically allocate MyData_t. */
    dynamicallyAllocatedStruct = ( MyData_t * ) pvPortMalloc( sizeof( MyData_t ) );
    configASSERT( dynamicallyAllocatedStruct != NULL );

    xTimerHandle = xTimerCreate( "Timer",
                                 pdMS_TO_TICKS( 1000 ),
                                 pdTRUE, /* Auto-reload. */
                                 ( void * ) dynamicallyAllocatedStruct,
                                 vTimerCallback );
}

2 Likes

@aggarg hey wow, finally some real code. TYSM For posting this!! I really appreciate it.

Yes, this answers the question.

Now I didn’t want to “roll my own” memory allocation routines as been there done that years ago, and many days scratching head with crashing programs, and i’m not the sharpest tool in the shed :sweat_smile: so yea, I prefer using a library for this type of thing.

I am currently using bitshifter’s objectpool posted above with success. I had to update my esp-idf framework for posix_memalign support on ESP32, but once I did that, works like a treat :slight_smile:

e.g. in platformio.ini:

[env:esp32dev]
platform = espressif32 @ 6.6.0

Cheers