0
votes

I am using heap_1 memory allocation. There is an initialization task Task_ini, from which 2 tasks Task_1 and Task_2 are launched. Then I delete Task_ini. At some point in time from Task_1 I need to create a new task Task_3. How can I create Task_3 in the FreeRTOS heap in place of Task_ini which has already been deleted by that time, knowing only its TaskHandle_t?

int main(void){
  xTaskCreate(Task_ini, "Task_ini", configMINIMAL_STACK_SIZE, NULL, 1, &htask_ini);
  vTaskStartScheduler();    
  for(;;);
}
void Task_ini(void *pParams){   
  xTaskCreate(Task_function, "Task_1", configMINIMAL_STACK_SIZE, &param1, 1, &htask1);
  xTaskCreate(Task_function, "Task_2", configMINIMAL_STACK_SIZE, &param2, 1, &htask2);
  vTaskDelete(NULL);
}
void Task_function(void *pParams){
  for(;;){
    //task code
    //...
    //end task code
    if(create == true){
      create = false;
//Here I need to create a task at the address where the "Task_ini" task was.
//My code creates a task in a new heap section, and if there is no space it will cause a memory allocation error.
      xTaskCreate(Task_function, "Task_3", configMINIMAL_STACK_SIZE, &param3, 1, &htask3);
    }
  }
}
1

1 Answers

3
votes

The main idea of heap_1 is that you can't free memory. It is simply not capable of doing so. If you want to delete tasks, you need to use other heap_n methods. Even in that case, you should let the kernel to do its job: It's kernels job to manage memory for FreeRTOS objects, not yours.

Actually, deleting tasks isn't considered as a good practice in general. Unless you are really low on heap space, you can simply suspend the task. In this way, you can wake it up again without any cost in case its services are required again.

It's true that an init task will become useless after the system initialization. But there is a well known solution for your init task problem: It can evolve into another task after it completes the initialization sequence. For example, Task_ini can create only Task_2, and instead of creating a Task_1, it can do the Task_1's job itself.

Update:

It's kernels job to manage memory for FreeRTOS objects, not yours.

Actually, FreeRTOS allows you to manage the memory manually, if you prefer to do so. There are static versions of object creation functions, like xTaskCreateStatic(). When using these static versions, you pass two statically allocated buffers to the function for the task stack and the task control block (TCB). Then you will literally be able to place one task onto another (provided that it's deleted). To be able to use these functions, configSUPPORT_STATIC_ALLOCATION must be defined as 1.

But I suggest you to avoid manual memory management unless you have a specific reason to do so.