Размещение кучи FreeRTOS в разделе CCMRAM для STM32

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

При разработке одного девайса на базе STM32F407 столкнулся с проблемой нехватки оперативной памяти. Назначение самого девайса не принципиально, но важно, что изначальный код писался для десктопной системы и его нужно было просто портировать на микроконтроллер под управлением FreeRTOS. А так как исходный код был написан на С++ и вопрос об экономии ОЗУ даже не стоял, то и вылезла соответствующая проблема.

Заниматься оптимизацией кода, одновременно добавляя себе проблем с поиском новых ошибок, очень не хотелось. Поэтому своевременно вспомнилось, что данная версия микроконтроллера имеет на борту дополнительный сегмент ОЗУ размером 64К (CCM SRAM), который сейчас никак не был задействован. Эврика — вот оно, решение!

Но к сожалению, все оказалось не так просто.



Результаты поиска готового решения


В официальной документации на CCMRAM приводятся примеры для размещения в ней исполняемого кода, стека или отдельных переменных.

Поиск по форумам выдал несколько ссылок на разные способы использования CCMRAM, но к сожалению, все они являлись разными вариациями тех способов, которые были описаны в официальной документации. И все они требовали перелопачивать исходный код для добавления атрибутов при объявлении каждой функции или переменной.

Для GCC, в моем случае, примерно вот так:
__attribute__((section(".ccmram")));


В добавок, некоторые переменные имеют значение по умолчанию, что потребует модифицировать загрузчик, чтобы такие переменные при старте копировались в отдельную область для инициализированных или обнуленных переменных.

Ну и финальной сложностью были ограничения самой CCMRAM. Она висит на отдельной шине к которой у DMA нет доступа, а прямой доступ к памяти планировалось использовать очень активно.

Другими словами, решая одну проблему, можно было нечаянно добавить ворох других, и зарыться в отладку для поиска привнесенных багов.

К счастью, удалось найти простое решение со стороны FreeRTOS.


Размер кучи был меньше размера сегмента CCM RAM и решение напрашивалось само-собой — переместить кучу в данный раздел.

И это удалось сделать минимальными правками кода.

  1. В ld файле (в моем случае STM32F407VGTX_FLASH.ld) добавляется новая секция:
    .ccmram :
     {
       . = ALIGN(8);
       . = . + _Min_Heap_Size;
       . = ALIGN(8);
     } >CCMRAM

  2. В секции « ._user_heap_stack » комментируется или удаляется строка
    /*    . = . + _Min_Heap_Size; */

    Строки с _Min_Heap_Size требуются для выдачи предупреждений линковщиком в случае недостатка размера ОЗУ.
  3. В теле программы добавляется единственная переменная
    uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__((section(".ccmram")));

  4. А при сборке проекта добавляется препроцессорное определение
    configAPPLICATION_ALLOCATED_HEAP=1



В результате — куча FreeRTOS в CCM SRAM с минимальным количеством правок в исходном коде!
Источник: https://habr.com/ru/company/timeweb/blog/546670/


Интересные статьи

Интересные статьи

В этой статье мы расскажем, как оптимизировать крупный проект в «Битрикс24» и увеличить его производительность в 3 раза, изменяя настройки MySQL и режим питания CPU. Дано Корпоративн...
Всем привет!  В предыдущей части я остановился на том, что мои ракеты удачно взлетели и приземлились, а на одной даже был установлен альтиметр. В этой статье я и расскажу о т...
Всем привет! Не так давно на работе в рамках тестирования нового бизнес-процесса мне понадобилась возможность авторизации под разными пользователями. Переход в соответствующий р...
Проблема обратной совместимости, вероятнее всего, будет всегда. В области разработки электроники порой приходится поддерживать устройства 30-летней давности (а иногда и старше). В таких аппарат...
Привет, Хабр! Данный пост посвящён DIY разработке Ethernet-RS485 шлюза. Цель данного шлюза – обеспечение централизованного управления нодами Mysensors со стороны контроллера умного дома. Недавн...