cancel
Showing results for 
Search instead for 
Did you mean: 

FreeRTOS Memory Overlap

Daniel_E
Associate

Good day.

I have encountered a strange situation and I am asking for your help in explaining it. A Google search did not provide me with answers, perhaps I was searching incorrectly. I am using CubeIDE v1.16.0, STM32F411CEU6, FreeRTOS CMSIS_V2.

have a variable DS18B20 sensors[SENSOR_NUMBER]; with the following structure:

 

 

typedef struct DS18B20
{
    uint8_t status;
    uint8_t serialN[DS18B20_SER_NUM_LEN];
    uint8_t T_LSB;
    uint8_t T_MSB;
    uint8_t TH;
    uint8_t TL;
    uint8_t configReg;
    float temp;
    char place[10];
} DS18B20;

 

 

The variable is declared in the main.c file, where the initialization of the DS18B20 sensor also takes place. As a result, in "Live Expressions" I see that the data is successfully placed into the sensors[] array. For FreeRTOS, the TOTAL_HEAP_SIZE parameter is set to 51200 bytes, and the heap management scheme is heap_4. There are 4 tasks declared: defaultTask - 128 words, Task_LED - 128 words (LED blinking), Task_List - 128 words (output in SWV vTaskList(buffer)) - all of this works well. However, as soon as I add another task, the data in the elements of the sensors[] array start changing chaotically after initialization.

By trying to disable various sections of the code, I found that the SWV print function: 

 

 

freertos.c:
void Task_List(void *argument)
{
  /* USER CODE BEGIN task_list */
  /* Infinite loop */
  for(;;)
  {
    Print_TaskList();
    osDelay(500);
  }
  /* USER CODE END task_list */
}
main.c:
char buffer[128];
void Print_TaskList()
{
    printf("Task Name\tState\tPriority\tStack\tNumber\n");
    printf("-----------------------------------------------------\n");
    vTaskList(buffer);
    printf("%s\n", buffer);
    size_t freeHeapSize = xPortGetFreeHeapSize();
    size_t minEverFreeHeapSize = xPortGetMinimumEverFreeHeapSize();
    printf("-----------------------------------------------------\n");
    printf("free heap = %u\tmin free heap = %u\n", freeHeapSize, minEverFreeHeapSize);
}

 

 

 uses the variable char buffer[128]; declared in the main.c file, which somehow, in a way I do not understand, encroaches on the memory area of the sensors[] array. 

The next step was to declare the variable char buffer[128] inside the Print_TaskList() function. This led to an error after one cycle of this function (I see the result of vTaskList() once) and a call to the Error_Handler(void) function. Increasing the stack for the thread to 512 words did not resolve the issue. The only thing that fixed the situation was declaring the variable char buffer[128] with the static keyword inside the Print_TaskList() function.

What could be the reason for memory overlap?

Why does declaring the variable char buffer[128] inside the function (as I understand, inside the thread stack) lead to an error after one cycle, even though the thread is allocated a stack size of 512 words?

Why does declaring static char buffer[128]; (as I understand, in static memory outside the thread stack) allow the program to work correctly?

Please help me understand what is happening.

1 ACCEPTED SOLUTION

Accepted Solutions

vTaskList() prints a TON of stuff to the buffer that you pass to it.  Most likely WAY more the 128 bytes worth.  And you have NO control over that because there is no "max length" parameter to give to vTaskList().  The answer is to either make your buffer much much larger (but may still overflow if you add more tasks), or don't use vTaskList().

Hint - don't use vTaskList.

You can roll your own using uxTaskGetNumberOfTasks() and usTaskGetSystemState() (which is essentially what vTaslkList() does), and this guarantee you never overflow any buffers.

View solution in original post

4 REPLIES 4
Daniel_E
Associate

upd: 

I have now moved the declaration of the variable char buffer[128] back to the main.c file, and the issue described above has not recurred. I am concerned that, since the reason for this behavior is not clear to me, I might encounter this problem again.

Could this be some kind of bug in FreeRTOS or the compiler?

vTaskList() prints a TON of stuff to the buffer that you pass to it.  Most likely WAY more the 128 bytes worth.  And you have NO control over that because there is no "max length" parameter to give to vTaskList().  The answer is to either make your buffer much much larger (but may still overflow if you add more tasks), or don't use vTaskList().

Hint - don't use vTaskList.

You can roll your own using uxTaskGetNumberOfTasks() and usTaskGetSystemState() (which is essentially what vTaslkList() does), and this guarantee you never overflow any buffers.

Daniel_E
Associate

Thank you for your response.

Am I correct in understanding that by passing a reference to my character buffer, the vTaskList() function sequentially fills bytes in RAM without size control, thereby exceeding the declared byte array and corrupting data belonging to other variables?