Colocación del montón de FreeRTOS en la sección CCMRAM para STM32

Al desarrollar un dispositivo basado en STM32F407, me enfrenté al problema de la falta de RAM. El propósito del dispositivo en sí no es importante, pero es importante que el código original fue escrito para un sistema de escritorio y solo necesitaba ser transferido a un microcontrolador que ejecute FreeRTOS. Y dado que el código fuente se escribió en C ++ y ni siquiera se planteó la cuestión de ahorrar RAM, surgió el problema correspondiente.



Realmente no quería involucrarme en la optimización del código y al mismo tiempo agregar problemas para encontrar nuevos errores. Por lo tanto, se recordó oportunamente que esta versión del microcontrolador tiene un segmento RAM adicional de 64K (CCM SRAM) a bordo, que no se ha utilizado de ninguna manera ahora. Eureka - ¡aquí está, la solución!



Pero, lamentablemente, todo resultó no ser tan sencillo.





Resultados de búsqueda de una solución lista para usar



La documentación oficial de CCMRAM proporciona ejemplos para colocar código ejecutable, una pila o variables individuales en él.



La búsqueda en los foros arrojó varios enlaces a diferentes formas de usar CCMRAM, pero desafortunadamente, todas eran variaciones diferentes de las formas que se describen en la documentación oficial. Y todos ellos requirieron revisar el código fuente para agregar atributos al declarar cada función o variable.



Para GCC, en mi caso, algo como esto:



__attribute__((section(".ccmram")));
      
      





Además, algunas variables tienen un valor predeterminado, que requiere modificar el cargador de arranque para que cuando se inicie el firmware, dichas variables se copien en un área separada para las variables inicializadas o puestas a cero.



Bueno, la dificultad final fueron las limitaciones de CCMRAM en sí. Se cuelga de un bus separado al que DMA no tiene acceso, y se planeó utilizar el acceso directo a la memoria de manera muy activa.



En otras palabras, al resolver un problema, uno podría agregar accidentalmente un montón de otros y profundizar en la depuración para encontrar los errores introducidos.



Afortunadamente, logramos encontrar una solución simple por parte de FreeRTOS.



El tamaño del montón era menor que el tamaño del segmento RAM de CCM y la decisión fue evidente: mover el montón a esta partición.



Y logramos hacer esto con cambios mínimos en el código.



  1. Se agrega una nueva sección al archivo ld (en mi caso STM32F407VGTX_FLASH.ld):



    .ccmram :
     {
       . = ALIGN(8);
       . = . + _Min_Heap_Size;
       . = ALIGN(8);
     } >CCMRAM
          
          



  2. En la sección "._user_heap_stack" se comenta o elimina una línea



    /*    . = . + _Min_Heap_Size; */
          
          





    Las líneas con _Min_Heap_Size son necesarias para que el vinculador emita advertencias en caso de que el tamaño de RAM sea insuficiente.
  3. Se agrega una sola variable al cuerpo del programa.



    uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__((section(".ccmram")));
          
          



  4. Y al construir un proyecto, se agrega una definición de preprocesador



    configAPPLICATION_ALLOCATED_HEAP=1
          
          





Como resultado, ¡un montón de FreeRTOS en CCM SRAM con un número mínimo de ediciones en el código fuente!



All Articles