Advice: reduce memory usage

virviglaz wrote on Friday, June 23, 2017:

Hi everyone,

My problem is that I have a banch of tasks, they are creating each other and works fine as I expected. They are small and simple. But some of them needs to use RFID driver which immidietly increases heap size more than 2k! Basicaly, only one existing task can execute RFID related functions. Why should we copy the content of function to the RAM all the time. Why we can’t just keep it in flash? I do not have enought memory for that. The sequence works like that - one task creates another and immidietly delete themselve and release the memory. But before it is done, it still needs 2k of ram for new task which is also using have RFID driver requests. The way to optimise that is to create independent task for RFID driver and perform communication between tasks with messages of notifications. But it is a bit dirty - driver needs to use some handlers, which is a bit complicated to configure outside. So, in summary, I need to understand, if we do not require to have a multiple instance of one task, can we keep it in flash and not copy to ram?

Thanks in advance,
BR, Pavel

heinbali01 wrote on Friday, June 23, 2017:

Hi Pavel,

The way to optimise that is to create independent task for RFID driver and
perform communication between tasks with messages of notifications.

I agree very much. RFID drivers are quite complex and have some slow operations, it is good to isolate that in a dedicated task.

So, in summary, I need to understand, if we do not require to have a multiple
instance of one task, can we keep it in flash and not copy to ram?

I’m reading your text over and again, but things are not clear.

What CPU are you using?
What compilers?
Where did you get the software that you’re working with?
Or did you write it yourself?

Normally, in smaller MCU’s, RAM is scarce and the code runs directly from flash ( non-volatile memory ). You can use a compiler option that puts a individual function permanently in RAM. E.g. this can be a function that writes to flash.
Sometimes flash is very slow ( serial flash ), and then functions running from RAM will be faster.

Creating a task under FreeRTOS does not mean that you copy code to RAM. Creating a task means :

● creating a Task Control Block, information about the task ( hidden in task.c )
● creating a Task Stack
● passing the task to the scheduler

Normally the memories for the TCB’s and stack are allocated dynamically by calling pvPortMalloc(). But if you like you can declare space for a task and its stack space statically ( v9.0.0 ).

virviglaz wrote on Friday, June 23, 2017:

STM32F030CC, Keil 5.23 (why this is matters?..)

gettaskinfo
USART RX R 4 520 1
IDLE R 0 108 10
LED Handler B 1 30 6
Available B 2 2128 24
Temp ctrl B 1 94 7
Live Data B 2 368 26
Buzzer Task S 2 38 5
Lock Control S 1 20 8
LCD Handler S 3 168 3
DB Task S 1 166 2
Memory free: 10248

You see, that I still have 10k memory out of 28k dedicated to RTOS. But when I’m trying to create one more task with heap = 500, it returns ‘out of memory’ in vApplicationMallocFailedHook.

‘Available’ task should me small and simple. Only because of using RFID driver it becomes so big. Creating static task is not an option - the same memory will be just taken by compilier. I can’t get why having 10k of free memory I can’t start the task with 500 bytes heap.

heinbali01 wrote on Friday, June 23, 2017:

That looks like a problem that each one of us has to solve some times :slight_smile:

Think of combining activities from several tasks into a single task.Try to put each activity into a status machine.

I would normal have a single main task, and a few (2 or 3) helping tasks, such as the IP-task and some complex drivers ( e.g. a radion tuner, an MP3 player or a RFID device ).

virviglaz wrote on Friday, June 23, 2017:

If I will remove RFID driver from task it will consume less than 100 bytes of heap. That’s actualy the my question is. How to reduce memory usage? RFID driver should exist only in one instance. No point to keep it in RAM.

virviglaz wrote on Friday, June 23, 2017:

Problem solved. Dont trust vTaskList command. It shows not real heap size. Only already dedicated. Use this event to report if memory is low:
void vApplicationStackOverflowHook( TaskHandle_t xTask, signed char pcTaskName )
{
/
Stack overflow */
printf(“Task %s stack overflow!\n”, pcTaskName);
}

rtel wrote on Saturday, June 24, 2017:

Dont trust vTaskList command.

Can you please elaborate on that? If vTaskList is doing something other
than its documented behaviour we need to know so we can investigate.

heinbali01 wrote on Saturday, June 24, 2017:

void vApplicationStackOverflowHook( TaskHandle_t, signed char* )
{
/* Stack overflow */
printf("Task %s stack overflow!\n", pcTaskName);
}

You will use:

    #define configCHECK_FOR_STACK_OVERFLOW     2

It will catch stack overflows, but beware of two things:

your application might still crash, e.g. if you have a function that claims a big amount of stack space:

    void foo()
    {
    char buffer[ 65536 ];
        /* Program might still crash here. */
        sprintf( buffer, "Hello world" );
    }

And secondly, note that checking the free stack space may decrease performance. When releasing your software, you might want to disable it.

virviglaz wrote on Saturday, June 24, 2017:

Thanks, that I know. Currently I have a hard fault because of using sprintf with float value. But suppose I will handle that myself. I do not use static arrays. All memory usage done by heap_4.c

heinbali01 wrote on Saturday, June 24, 2017:

sprintf with float value

There have been many posts about the use of float / double. Most problems seem to be related with the alignment of the values. Maybe you could play / test with an explicit alignment.

Earlier you wrote:

Dont trust vTaskList command.
It shows not real heap size.
Only already dedicated.

Can you elaborate on those remarks? Like Richard said, when you think that some function doesn’t work properly, we’d like to know the what and the why.