Qual o footprint de memória do FreeRTOS?

- por Sergio Prado

Categorias: FreeRTOS Tags: , ,

Esta é uma pergunta frequente. E a resposta depende de diversos fatores, incluindo a configuração do FreeRTOS, o compilador utilizado, a plataforma de hardware e as características da sua aplicação.

freertos

Segundo o FAQ oficial do projeto, o uso de flash pode variar de 5KB a 10KB, e o uso de RAM do escalonador gira em torno de 250 bytes. Claro que não estão inclusos aqui a memória RAM alocada para cada componente criado pela aplicação (tarefa, queue, semáforo, timer, etc).

Mas nada melhor do que tirar nossas próprias conclusões, não é verdade? :)

Fiz alguns testes utilizando o kit de desenvolvimento FRDM-KL46Z, um ARM Cortex-M0 de 48MHz com 256KB de flash e 32KB de SRAM.

Criei um projeto para compilar uma aplicação enxuta com o FreeRTOS, utilizando um toolchain baseado no GCC mantido pelo próprio pessoal da ARM.

O projeto é composto por uma aplicação simples com duas tarefas (80 words de stack alocados para cada tarefa) e 12KB alocados para o heap do FreeRTOS. O projeto está disponível no Github, para quem quiser dar uma olhada.

O resultado final foi este:

$ arm-none-eabi-size main.elf
   text	   data	    bss	    dec	    hex	filename
   6804	     24	  13544	  20372	   4f94	main.elf

Em resumo, a aplicação irá consumir 6804 bytes de flash e 13568 (13544 + 24) bytes de RAM. Mas que parte deste consumo de memória vem do FreeRTOS?

Para responder esta pergunta, podemos dar uma olhada no mapa de símbolos gerado pelo compilador.

Vamos primeiro analisar o tamanho do código do FreeRTOS:

$ cat main.map | grep ".text"
[...]
 *(.text .text.* .gnu.linkonce.t.*)
 .text          0x00000410      0x130 main.o
 .text          0x00000540       0x68 startup.o
 .text          0x000005a8      0x150 freertos/list.o
 .text          0x000006f8     0x12b4 freertos/tasks.o
                0x00000cf0                vTaskSwitchContext
 .text          0x000019ac      0x1f4 freertos/portable/MemMang/heap_2.o
 .text          0x00001ba0      0x204 freertos/portable/GCC/ARM_CM0/port.o

Podemos medir o tamanho do código do FreeRTOS, e consequentemente seu consumo de memória flash, somando individualmente o tamanho da região .text de cada arquivo-fonte do FreeRTOS, totalizando 6140 bytes na listagem acima.

Já o consumo de RAM está dividido nas seções .data (variáveis inicializadas) e .bss (variáveis não-inicializadas).

Veja no comando abaixo que são consumidos pelo FreeRTOS apenas 8 bytes na seção de variáveis inicializadas.

$ cat main.map | grep ".data"
[...]
 *(.data .data.*)
 .data          0x1fffe000        0x4 freertos/portable/MemMang/heap_2.o
 .data          0x1fffe004        0x4 freertos/portable/GCC/ARM_CM0/port.o

Já na seção de variáveis não-inicializadas, são consumidos 212 bytes pelo escalonador (tasks.o) e 12308 bytes pela implementação de alocação de memória utilizada no projeto de exemplo (heap_2.o).

$ *(.bss .bss.*)
[...]
 .bss           0x1fffe008       0xd4 freertos/tasks.o
 .bss           0x1fffe0dc     0x3014 freertos/portable/MemMang/heap_2.o

A implementação de alocação de memória consume bastante RAM porque ela pré-aloca um buffer de 12KB para a região de heap do FreeRTOS. Esta região será utilizada para a criação dos componentes da aplicação (tarefa, queue, semáforo, etc) e pode ser alterada conforme a necessidade através da variável configTOTAL_HEAP_SIZE no FreeRTOSConfig.h.

Sem considerar o buffer pré-alocado para o heap do FreeRTOS, temos um consumo de flash de 6140 bytes e um consumo de RAM de 220 bytes (212 + 8), valores bem próximos aos documentados no FAQ do projeto.

Claro que, para cada componente criado pela aplicação (tarefa, queue, semáforo, etc) mais memória RAM será utilizada. Por exemplo, a estrutura que armazena informações sobre as tarefas (TCB ou Task Control Block) possui um tamanho típico de 80 bytes, e para criar uma tarefa com 100 bytes de stack, serão alocados 180 bytes do heap do FreeRTOS.

Na prática, estes são valores típicos que podem depender das características da plataforma de hardware, do compilador (incluindo as flags de compilação utilizadas), configuração do FreeRTOS e dos componentes do kernel criados pela aplicação.

Conclusão? O FreeRTOS é realmente um kernel bastante enxuto e eficiente com relação ao consumo de memória RAM e flash.

A não ser que você tenha em mãos um microcontrolador de 8 bits com 2K de flash e 256 bytes de RAM, falta de memória não deve ser uma desculpa para você não utilizá-lo, principalmente pelas diversas vantagens trazidas pelo uso de um kernel de tempo real. De acordo? :)

Have fun!

Sergio Prado

  • Eder

    Legal este post Sérgio!

    Será que o footprint ainda é o mesmo para a última versão, visto este artigo ser de 2015? Talvez esses valores tenham mudado… não é?

    Vlw!

    • Olá Eder!

      Teria que medir novamente, mas possivelmente é bem parecido, porque a grande maioria dos novos recursos adicionados ao FreeRTOS nos dois últimos anos podem ser desabilitados no FreeRTOSConfig.h.

      Um abraço!

      • Eder

        Obrigado pela resposta Sergio.

        Aguardo novidades sobre FreeRTOS Amazon ;)

Navegue
Creative Commons Este trabalho de Sergio Prado é licenciado pelo
Creative Commons BY-NC-SA 3.0.