Как мы можем уменьшить чрезмерное использование оперативной памяти этим ядром

Rogerclark
Пт 18 ноября 2016 г. 22:14
Ребята,

Рик заметил, что использование RAM этого ядра очень высокое. Пустой набросок берет 9 тыс. ОЗУ против Либмапл. Использует 2K.

Основной причиной этого, по -видимому, являются массивы данных в ОЗУ, большая часть которых является статичной и не должна быть там

Я начал исправить часть этого, рассмотрев код PWM, который имел массив всех контактов с PWM, которые должны хранить данные Hal Timhandle, но также включали определения PIN / порта, которые не изменяются, как а также настройку данных, которые не меняются.

Ветвь WIP https: // github.com/stm32duino/arduino_c ... 1/дерево/WIP Имеет это исправление, которое вдвое увеличивает количество оперативной памяти для конфигурации ШИМ (и сохраняет чуть менее 1K)

Но, исследуя эту проблему, я заметил, что такие вещи
PinDescription g_intPinConfigured[MAX_DIGITAL_IOS];

Стивестронг
Сб 19 ноября 2016 г. 8:32 утра
Rogerclark написал: В этом случае это не должно быть множеством страхов, это должно быть множеством указателей на структуры

Даниэфф
Сб 19 ноября 2016 г. 8:42 утра
Я сделал .Карта анализатор: http: // danieleff.com/stm32/map_analizer ... Uepill.карта
Вы можете загрузить .Карты файлов из каталога сборки, и он будет отображать размеры объектов. Я поместил там несколько примеров.
Преимущество стандартного ARM-None-Eabi-NM заключается в том, что это также показывает исходный файл, который был включен объект.
РЕДАКТИРОВАТЬ: Я имею в виду, что я сделал это так, чтобы использование RAM можно было проанализировать.

Rogerclark
Сб 19 ноября 2016 г. 8:54 утра
Спасибо @danieleff

КСТАТИ.

Я понял, что g_intpinconfigured [pin] = g_apindescription; действительно делает Memcpy на структуре

Стивестронг
Сб 19 ноября 2016 г. 8:58 утра
HM, у меня есть ощущение, что создатель этого кода поступает из мира ПК, где размер оперативной памяти никогда не является проблемой.
Глядя на карту от Danieleff (хорошая функция, спасибо!) кажется, что структура analog_config_str g_analog_config[NB_ANALOG_CHANNELS]

Rogerclark
Сб 19 ноября 2016 г., 9:14
Да. Я согласен, что разработчики, похоже, не рассматривали использование RAM

На самом деле эта структура имеет 1 член Timhandle, который должен быть в оперативной памяти (см. Тот же файл в филиале WIP)

Я думаю, что член DAC также должен быть в RAM

Стивестронг
Сб 19 ноября 2016 г., 9:33 утра
Я понимаю, что ты имеешь в виду, ты прав.
Вы имеете в виду "Dacinstance" или "DacChannel"? Или оба?
Один мог сделать отдельные структуры, одна часть во флэш -ной, другая в ОЗУ? Я думаю, что это уже обсуждалось.

Rogerclark
Сб 19 ноября 2016 г., 9:51
Стивестронг написал:Я понимаю, что ты имеешь в виду, ты прав.

Один мог сделать отдельные структуры, одна часть во флэш -ной, другая в ОЗУ? Я думаю, что это уже обсуждалось.

Стивестронг
Сб 19 ноября 2016 г., 9:57 утра
Выглядит очень красиво :)
В том же контексте я вижу огромный потенциал сбережений оперативной памяти в USB -материалах, например, сокращение размера данных UIN32 на UINT8 по функциям USB_CFGTYPEDEF.
Уменьшение количества конечные точки от 15 до 7 Также было бы неплохо, я не думаю, что все конечные точки будут использоваться одновременно в любом приложении.

Rogerclark
Сб 19 ноября 2016 г. 10:44
Стивестронг написал:Выглядит очень красиво :)
В том же контексте я вижу огромный потенциал сбережений оперативной памяти в USB -материалах, например, сокращение размера данных UIN32 на UINT8 по функциям USB_CFGTYPEDEF.
Уменьшение количества конечные точки от 15 до 7 Также было бы неплохо, я не думаю, что все конечные точки будут использоваться одновременно в любом приложении.

Rogerclark
Сб 19 ноября 2016 г., 10:51
КСТАТИ. У меня есть 2 проблемы с различными проблемами с использованием RAM

https: // github.com/stm32duino/arduino_c ... /проблемы/27

https: // github.com/stm32duino/arduino_c ... /проблемы/23

@danieleff указал на некоторые другие проблемы (в другой проблеме), которые были бы исправлены, если мы внесем изменения для улучшения использования ОЗУ



Re: Dacinstance

На самом деле он не использовался нигде, вероятно, поскольку у Nucleo F103RB нет DAC

Мы должны переместить его в его собственный массив, как я сделал для Тимхандл, но этот массив необходим только для F103RC или лучше

И....

Повторное использование структуры PindeScription (в оперативной памяти) во многих местах, где 90% структуры должны быть статичными или нет вообще, также необходимо исправить ;-(-(

Grumpyoldpizza
Сб 19 ноября 2016 г. 18:33
Просто быстро попробовал Bareminimum.INO на Nucleo-L432KC с сердечником STM32L4 (не ядро ​​STM). Это то, что я получаю:
text data bss dec hex filename 5872 8 576 6456 1938 BareMinimum.ino.elf

Rogerclark
Сб 19 ноября 2016 г. 18:44
Проблема, по -видимому, заключается в статически выделенных массивах для обработки всех возможных пин -штифтов.

Обычно я знаю, что Malloc () обычно не используется из -за фрагментации памяти, но я думаю, что из -за того, как HAL нуждаются Каждая штифта по мере необходимости.
Но не звоните бесплатно () PIN PWM_STOP (), потому что в некоторых случаях это может привести к тому, что что -то напоминает утечка памяти.

Это было бы не хуже текущего кода, и будет означать, что если вы не используете ШИМ, он сэкономит более 1K.

Я не смотрел на другие свиньи памяти, но, надеюсь, что -то подобное может быть сделано с ними.

Рик Кимбалл
Сб 19 ноября 2016 г., 19:26
То, как Arduino IDE вычисляет использование RAM, и то, как сценарий линкера пытается предупредить вас о низком использовании памяти, находится в конфликте. На самом деле есть 1536 байтов оперативной памяти, которые линкер «распределяет» на кучу и стек. Тем не менее, подход линкера на самом деле не отражает, сколько кучи или оперативной памяти используется. Arduino IDE знает, сколько оперативной памяти у платы/чипа есть, и будет сообщать о низких проблемах с памятью с предупреждением о стабильности. Однако ни один подход не является точным.

Вы, вероятно, могли бы изменить часть сценария линкера здесь с: /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(4); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(4); } >RAM

Rogerclark
Сб 19 ноября 2016 г., 19:46
Спасибо, Рик,

Линкерный материал находится вне моей базы знаний ;-)

Rogerclark
Сб 19 ноября 2016 г., 22:02
Я обновил филиал WIP, чтобы Malloc Timhandle, когда она фактически используется.

я.e У меня есть массив указателей, которые должны быть инициализированы до 0 (NULL)
TIM_HandleTypeDef *g_analog_timer_config[NB_ANALOG_CHANNELS]={};

Rogerclark
Солнце 20 ноября 2016 г., 3:01
Рик Кимбалл написал:То, как Arduino IDE вычисляет использование RAM, и то, как сценарий линкера пытается предупредить вас о низком использовании памяти, находится в конфликте. На самом деле есть 1536 байтов оперативной памяти, которые линкер «распределяет» на кучу и стек. Тем не менее, подход линкера на самом деле не отражает, сколько кучи или оперативной памяти используется. Arduino IDE знает, сколько оперативной памяти у платы/чипа есть, и будет сообщать о низких проблемах с памятью с предупреждением о стабильности. Однако ни один подход не является точным.

Вы, вероятно, могли бы изменить часть сценария линкера здесь с: /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(4); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(4); } >RAM

Даниэфф
Солнце 20 ноября 2016 г. 8:21
Стивестронг написал:Rogerclark написал: В этом случае это не должно быть множеством страхов, это должно быть множеством указателей на структуры

Rogerclark
Солнце 20 ноября 2016 г. 20:56
Стивестронг написал:Выглядит очень красиво :)
В том же контексте я вижу огромный потенциал сбережений оперативной памяти в USB -материалах, например, сокращение размера данных UIN32 на UINT8 по функциям USB_CFGTYPEDEF.
Уменьшение количества конечные точки от 15 до 7 Также было бы неплохо, я не думаю, что все конечные точки будут использоваться одновременно в любом приложении.

Wi6labs
Ср 23 ноября 2016 г. 11:18
Rogerclark написал:Рик Кимбалл написал:То, как Arduino IDE вычисляет использование RAM, и то, как сценарий линкера пытается предупредить вас о низком использовании памяти, находится в конфликте. На самом деле есть 1536 байтов оперативной памяти, которые линкер «распределяет» на кучу и стек. Тем не менее, подход линкера на самом деле не отражает, сколько кучи или оперативной памяти используется. Arduino IDE знает, сколько оперативной памяти у платы/чипа есть, и будет сообщать о низких проблемах с памятью с предупреждением о стабильности. Однако ни один подход не является точным.

Вы, вероятно, могли бы изменить часть сценария линкера здесь с: /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(4); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(4); } >RAM

Даниэфф
Ср 23 ноября 2016 г. 12:38
Он заменяет, если кто -то хочет иметь предупреждение или ошибку, когда осталась слишком низкая память для стека+куча.
Ардуино делает предупреждение (на 75% ОЗУ) и _user_Heap_stack оставляет ОЗУ, делая его ошибкой.

Таким образом, в настоящее время (без модификации) оба действуют.

*РЕДАКТИРОВАТЬ: Мое предложение состоит в том, чтобы считать стек необходимым, все программы используют его, поэтому зарезервируйте его (Оставлять ". = . + _Min_stack_size; "Inside"._user_heap_stack: "), в то время как куча не является важной, большинство программ не будут использовать его, и оставит Arduino Warning (Удалять ". = . + _Min_Heap_size; "от"._user_heap_stack: ")

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

Рик Кимбалл
Ср 23 ноября 2016 г. 14:09
Как я упоминал в своем предыдущем посте, ни один метод на самом деле не является точным. Используя произвольные значения в сценарии LD, вы просто делаете предположения о том, сколько кучи и стека Arduino может на самом деле использовать. Тем не менее, позволить arduino ide предупредить вас своей произвольной низкой отметиной водой не лучше. Arduino, кажется, использует параметр двигателя сборки 75% ОЗУ (сборка.warn_data_percentage = 75). Таким образом, для 20K STM32F103C8 он даст вам предупреждение о стабильности, когда у вас остается менее 5120 байтов. Это даже более консервативно, чем байты 1536 года, зарезервированные LDSCIPT.

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

-рик

Grumpyoldpizza
Ср 23 ноября 2016 г. 14:51
Рик Кимбалл написал:Как я упоминал в своем предыдущем посте, ни один метод на самом деле не является точным. Используя произвольные значения в сценарии LD, вы просто делаете предположения о том, сколько кучи и стека Arduino может на самом деле использовать. Тем не менее, позволить arduino ide предупредить вас своей произвольной низкой отметиной водой не лучше. Arduino, кажется, использует параметр двигателя сборки 75% ОЗУ (сборка.warn_data_percentage = 75). Таким образом, для 20K STM32F103C8 он даст вам предупреждение о стабильности, когда у вас остается менее 5120 байтов. Это даже более консервативно, чем байты 1536 года, зарезервированные LDSCIPT.

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

-рик

Рик Кимбалл
Ср 23 ноября 2016 г., 15:40
Grumpyoldpizza написал:[
Может быть интересно использовать аналогичную схему, которую использует ARM для CMSIS (startup_cm4.S и GCC_ARM.LD ниже). По сути, вы можете определить __heap_size как аргумент времени компиляции (и __stack_size). Если вы переполняете минимальное требование (в конце концов .данные/.Данные BSS были выделены), линкер вынесет ошибку.

Grumpyoldpizza
Ср 23 ноября 2016 г. 18:34
Рик Кимбалл написал:Grumpyoldpizza написал:[
Может быть интересно использовать аналогичную схему, которую использует ARM для CMSIS (startup_cm4.S и GCC_ARM.LD ниже). По сути, вы можете определить __heap_size как аргумент времени компиляции (и __stack_size). Если вы переполняете минимальное требование (в конце концов .данные/.Данные BSS были выделены), линкер вынесет ошибку.

Рик Кимбалл
Ср 23 ноября 2016 г. 18:38
Вы действительно хотите контролировать это на уровне эскизов, а не на уровне доски.

Скажи, я создаю большой массив в стеке
void somefunction(void) { char mybuffer[8192]; while (1) { .. do somethign with the buffer... } }

Rogerclark
Чт 24 ноября 2016 г., 7:11 утра
ммм.

Похоже, мне нужно вернуть это изменение, пока пыль не оседает

Wi6labs
Чт 24 ноября 2016 г., 9:14
Мы предпочитаем сохранить базу предупреждения на реальном использовании оперативной памяти для пользователя. Мы согласны с тем, что Arduino должен дать решение для изменения этого уровня (75% слишком низкий).
Уменьшите стек и кучу под текущей стоимостью рискованно (мы сделали некоторые тесты во время разработки).
Может быть, на данный момент нет решения.

Rogerclark
Чт 24 ноября 2016 г., 10:28
Я вернул изменение всех файлов линкера, которые я изменил в репо F1

Примечание.
Все недавние изменения связаны только с филиалом WIP (работа в процессе) и не должны влиять на любого, кто загружает Master Repo Zip

Maple Bootloader 2.0