Best practice for Memory management and RTOS tasks
Best practice for Memory management and RTOS tasks
Hi everyone,
I am writing an app that is highly dependent on the big objects/classes stored in the external PS-RAM.
Since I can't have the classes as a static variable so I need to find the best way to pass-in the object.
my first thought was to make a static pointer pointing to the class in the PS-RAM and then use inside the TaskFunction or it would be much best if I pass the pointer to the object when creating the TaskHandle (xTaskCreatePinnedToCore)?
thanks,
I am writing an app that is highly dependent on the big objects/classes stored in the external PS-RAM.
Since I can't have the classes as a static variable so I need to find the best way to pass-in the object.
my first thought was to make a static pointer pointing to the class in the PS-RAM and then use inside the TaskFunction or it would be much best if I pass the pointer to the object when creating the TaskHandle (xTaskCreatePinnedToCore)?
thanks,
Re: Best practice for Memory management and RTOS tasks
https://www.freertos.org/xTaskCreateStatic.html
To use this function you have to enable option in menuconfig (i am not sure if it is still possible).
https://github.com/espressif/esp-idf/issues/6264
To use this function you have to enable option in menuconfig (i am not sure if it is still possible).
https://github.com/espressif/esp-idf/issues/6264
Re: Best practice for Memory management and RTOS tasks
@chegewarta thanks for your reply.
If I understood correctly, the xTaskCreateStatic is storing on top of the stack.
in my case, I can store Task on the internal heap but it needs to have access to the data stored on external ps-ram.
If I understood correctly, the xTaskCreateStatic is storing on top of the stack.
in my case, I can store Task on the internal heap but it needs to have access to the data stored on external ps-ram.
Re: Best practice for Memory management and RTOS tasks
xTaskCreate and xTaskCreatePinnedToCore are allocating stack from internal memory. We also have xTaskCreateStatic, which is using stack passed by programmer and can be created in both, internal memory and PSRAM.
Example:
Example:
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include <stdio.h>
- #define STACK_SIZE 200
- StaticTask_t xTaskBuffer;
- StackType_t *xStack;
- void test_task(void*p)
- {
- while(1)
- {
- vTaskDelay(100);
- }
- }
- void app_main(void)
- {
- xStack = (uint8_t*)heap_caps_calloc(1, 10*1024, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT | MALLOC_CAP_32BIT);
- xTaskCreateStatic(test_task, "test", 10*1024, NULL, 6, xStack, &xTaskBuffer);
- }
Re: Best practice for Memory management and RTOS tasks
@chegewarta thanks for your message. Now everything looks more clear.
So, as I said I need to have access to a non-static variable (big_class here) inside the task function.
Not having the task stored in the psram.
I thought the following code might work without using the internal heap.
The other solution I was thinking of is something like this.
So, as I said I need to have access to a non-static variable (big_class here) inside the task function.
Not having the task stored in the psram.
I thought the following code might work without using the internal heap.
Code: Select all
volatile BigClass* big_class = (BigClass*)ps_calloc(1, sizeof(BigClass));
void test_function(void*p)
{
while(1)
{
BigClass* local_big_class= (BigClass*)p;
local_big_class->doSomthing();
vTaskDelay(100);
}
}
void setup(void)
{
xTaskCreatePinnedToCore(test_function, "test", 1024, (void *)&big_class , 6, NULL, 1);
}
Code: Select all
static BigClass* big_class_ptr;
BigClass* big_class = (BigClass*)ps_calloc(1, sizeof(BigClass));
void test_function(void*p)
{
while(1)
{
//big_class->doSomthing();
big_class_ptr->doSomthing();
vTaskDelay(100);
}
}
void setup(void)
{
big_class_ptr = big_class;
xTaskCreatePinnedToCore(test_function, "test", 1024, NULL, 6, NULL, 1);
}
Re: Best practice for Memory management and RTOS tasks
1. Sorry, i missed the fact you are using arduino
2. I am not C++ expert, but as far as i know you cant use code like this, because instantiating class object in C++ is more than just allocating memory
3. You can try code like this, which will create instance of class on task stack (im not 100% sure about it):
As you can see task stack is allocated from PSRAM, not internal memory and can be very big (100kB in example).
4. Another idea i have, because i dont know your code, especially BigClass, but i am assuming it is using some arrays, can be using variable in class as a pointers and in constructor allocate memory for such big variables with ps_malloc. This is option i would start with.
2. I am not C++ expert, but as far as i know you cant use code like this, because instantiating class object in C++ is more than just allocating memory
Code: Select all
volatile BigClass* big_class = (BigClass*)ps_calloc(1, sizeof(BigClass));
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include <stdio.h>
- #define STACK_SIZE 200
- StaticTask_t xTaskBuffer;
- StackType_t *xStack;
- void test_task(void*p)
- {
- BigClass* big_class = new BigClass(); // instantiate object in task stack, but i am not 100% sure
- while(1)
- {
- local_big_class->doSomthing();
- vTaskDelay(100);
- }
- }
- void setup() {
- // put your setup code here, to run once:
- xStack = (uint8_t*)heap_caps_calloc(1, 100*1024, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT | MALLOC_CAP_32BIT);
- xTaskCreateStatic(test_task, "test", 100*1024, NULL, 1, xStack, &xTaskBuffer);
- }
- void loop() {
- // put your main code here, to run repeatedly:
- }
4. Another idea i have, because i dont know your code, especially BigClass, but i am assuming it is using some arrays, can be using variable in class as a pointers and in constructor allocate memory for such big variables with ps_malloc. This is option i would start with.
Re: Best practice for Memory management and RTOS tasks
Thanks for pointing out the problems. I don't claim any good skills in c++ just want to get things done.
I am also a bit puzzled about how new would work in this context. not very certain if it calls ps_malloc or malloc! This can also be true in a class with members initialize by new!
Truly, the class is supposed to be instantiated in setup/app_main and I need to keep it alive outside of test_task. So, I should pass it in the test_task (as far as I can imagine).
I am also a bit puzzled about how new would work in this context. not very certain if it calls ps_malloc or malloc! This can also be true in a class with members initialize by new!
Truly, the class is supposed to be instantiated in setup/app_main and I need to keep it alive outside of test_task. So, I should pass it in the test_task (as far as I can imagine).
Re: Best practice for Memory management and RTOS tasks
That is not that big issue. What you can do is to adapt code i posted earlier, delete setup/loop task and use new task as if it would be a setup and loop, but like i mentioned earlier in point 4, better way would be to refactor class and allocate all bigger variables in constructor from PSRAM. Usual there is few ways to achieve the same result, all depends on skills and preference.reza_neam wrote: Truly, the class is supposed to be instantiated in setup/app_main and I need to keep it alive outside of test_task. So, I should pass it in the test_task (as far as I can imagine).
Re: Best practice for Memory management and RTOS tasks
Many Thanks for your help, I got the idea.
I definitely delete setup and loop after setting up queues and tasks.
I definitely delete setup and loop after setting up queues and tasks.
Who is online
Users browsing this forum: No registered users and 101 guests