kan35 7 24 ноября, 2023 Опубликовано 24 ноября, 2023 (изменено) · Жалоба Доброго дня всем! Использую порт для PIC18, и все вроде бы хорошо, но подобрался уже к лимиту по ОЗУ. И решил свободную heap часть уменьшить до 0. У меня простейшая модель памяти heap_1 и по ходу дела я не выделяю новые объемы, а только в самом начале приложения. И таким образом, я считал оставшийся свободные байты и вычел их из configTOTAL_HEAP_SIZE. Почему то при свободном нуле байт - он не заработал в принципе. Оставляю ему пару сотен свободных байт - работает. Отлаживаться крайне неудобно на PIC18, тыкаюсь-тыкаюсь и все равно не могу избавиться от свободной памяти. Ведь прерывания использую стек задач? И вообще это нормально дойти до 0 незанятой памяти? Я уже крутил стеками задач, я переставлял местами задачи, чтобы в heap они выделали память в разной очередности, чтобы понять, что именно даёт сбой. Ни на что не влияет, только нужна свободная память ему... Изменено 24 ноября, 2023 пользователем kan35 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 226 24 ноября, 2023 Опубликовано 24 ноября, 2023 · Жалоба 17 минут назад, kan35 сказал: У меня простейшая модель памяти heap_1 и по ходу дела я не выделяю новые объемы, а только в самом начале приложения. Зачем тогда вообще куча нужна? "подобрался уже к лимиту по ОЗУ" и при этом впустую тратите память на ненужную кучу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 24 ноября, 2023 Опубликовано 24 ноября, 2023 · Жалоба 50 минут назад, kan35 сказал: И таким образом, я считал оставшийся свободные байты и вычел их из configTOTAL_HEAP_SIZE может посчитали неправильно? попробуйте вычитать меньше. А вообще, да: куча здесь и не нужна. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 24 ноября, 2023 Опубликовано 24 ноября, 2023 (изменено) · Жалоба 3 hours ago, jcxz said: Зачем тогда вообще куча нужна? "подобрался уже к лимиту по ОЗУ" и при этом впустую тратите память на ненужную кучу. Да, если честно, куча heap_1 это громко сказано, что это куча, с минимумом сервиса и перерасхода практически ноль. Для платформы PIC18 она удобна на самом деле. Я в ней аллоцирую массивы для работы, иначе в потоке я не могу сделать выделение переменных на более, чем около 100 байт... такая кривая архитектура, но пока приходится работать на нем. Но похоже я понял в чем дело, программный таймер вроде портил мне жизнь... увеличил стек под него, хотя там вообще никаких вычислений, но видимо прерывания выделяли область в его стеке больше, чем я думал. Оставляю свободной памяти 1 байт теперь и все нормально. Спасибо всем! Изменено 24 ноября, 2023 пользователем kan35 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
seniorandre 0 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба Я в последнее время перенастраиваю всё на статическую аллокацию и выключаю хип. Памяти экономится много, т.к. ее отжирает только стек который ты указываешь, а все хвостики на запас хипа твой бонус. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба 1 hour ago, seniorandre said: Я в последнее время перенастраиваю всё на статическую аллокацию и выключаю хип. Памяти экономится много, т.к. ее отжирает только стек который ты указываешь, а все хвостики на запас хипа твой бонус. heap_1 отжирает только 2 байта на свою работу: static size_t xNextFreeByte = ( size_t ) 0; И я готов потерять их 🙂 В моем случае контроллер с дурацким псевдо-постраничным доступом, который я, впрочем, победил, настроив оптимизацию, а именно отключив "banking optimizer". Но до этого я успел помучаться, так как линкер размещал переменные в алфавитном порядке и карту памяти было просто невозможно читать... И тогда было удобно пользоваться аллокатором фриртоса тем самым можно было легче контроллировать положение каждого стека и каждого массива, так как все они лежали именно в хронометрическом порядке по мере создания. К тому же как я написал выше, я не могу создать локальных переменных более, чем на ~100байт, это глупое ограничение архитектуры опять же. И аллокация хотя бы массивов - вполне удобный инструмент для данного случая, иначе была бы куча ненужных глобальных переменных... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 226 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба 2 часа назад, kan35 сказал: heap_1 отжирает только 2 байта на свою работу: А как происходит выделение блока памяти? Имхо: должен создаваться заголовок блока (занимающий несколько байт), в котором указан его размер и ещё какая-то инфа. Нужный для последующего освобождения блока (ведь куча не знает, что вы не собираетесь его освобождать). 1. Т.е. - на каждый выделенный блок тратится ещё место для заголовка. Чего нет при статическом распределении. 2. Плюс ещё расходы ОЗУ - на хранение указателя для каждого выделенного блока. Что также не нужно при статическом распределении. 3. Кроме того: Использование динамически выделенных блоков памяти должно увеличивать расход регистров, стека в целом по всему коду. И должно в замедлять работу программы в целом, делать программу более громоздкой. PS: Так что - лукавите. Общий проигрыш от использования дин.памяти вместо статической, должен быть существенным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 23 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба 57 minutes ago, jcxz said: Имхо: должен создаваться заголовок блока (занимающий несколько байт), в котором указан его размер и ещё какая-то инфа. Нужный для последующего освобождения блока (ведь куча не знает, что вы не собираетесь его освобождать). Во FreeRTOS несколько реализаций heap, разной степени примитивности. В этой освобождение блоков не предусмотрено. https://www.freertos.org/a00111.html 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 79 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба На PIC18, да RTOS? Смело 🙂 Вы просто не учитываете, что при динамическом выделении памяти вначале блока идет заголовок на несколько байт. Так же, каждая задача, очередь и тп имеет свой заголовок. В целом, раз вы не создаете/удаляете динамически объекты, то целесообразно перейти в статический режим распределения. Подробности - в мануале FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensions Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба 1 час назад, EdgeAligned сказал: Так же, каждая задача, очередь и тп имеет свой заголовок А это-то здесь причем? При статическом выделении они никуда не денутся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 79 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба Заголовки задач никуда не денутся, зато заголовки блоков выделенной памяти уберутся. Ну и сейчас на память боюсь ошибиться, но по-моему, при статическом создании задачи у нее заголовок занимает меньше места. Но это надо проверить, на память не помню. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 26 ноября, 2023 Опубликовано 26 ноября, 2023 · Жалоба 17 часов назад, EdgeAligned сказал: Но это надо проверить, на память не помню. проверил) в типе tskTCB есть такое: tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ #endif но только когда используется и статическое и динамическое выделение совместно. Собственно, это поле для того и служит чтобы определить, каким образом был выделен контрол блок (заголовок, если правильно вас понял). В конрол-блоках очередей (семафоры, мьютексы) - такая же история Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 14 декабря, 2023 Опубликовано 14 декабря, 2023 · Жалоба On 11/25/2023 at 10:59 PM, EdgeAligned said: Заголовки задач никуда не денутся, зато заголовки блоков выделенной памяти уберутся. Ну и сейчас на память боюсь ошибиться, но по-моему, при статическом создании задачи у нее заголовок занимает меньше места. Но это надо проверить, на память не помню. Как уже обсуждали, это heap_1 , который не имеет такой функции и потому не может высвобождать память, так что все нормально, потерь тут нет. On 11/25/2023 at 7:31 PM, EdgeAligned said: На PIC18, да RTOS? Смело 🙂 Глаза боятся))) Сначала ожидал, что контроллер будет ср..ть кирпичами и это будет ощущаться, но оказалось, что при 1мс такте у нас имеется 12000 операций на каждый тик времени, и этого оказалось достаточно, чтобы ОС не перегрузила проц собой. При желании время можно и загрубить. Если хотите отзыв про PIC18+FreeRTOS, сообщаю - работает отлично, я крайне удовлетворен)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan1 17 26 января Опубликовано 26 января · Жалоба В 14.12.2023 в 14:35, kan35 сказал: Глаза боятся))) Сначала ожидал, что контроллер будет ср..ть кирпичами и это будет ощущаться, но оказалось, что при 1мс такте у нас имеется 12000 операций на каждый тик времени, и этого оказалось достаточно, чтобы ОС не перегрузила проц собой. При желании время можно и загрубить. Кстати, про системный тик: Практически все пользователи (и я тоже) оставляют этот параметр по умолчанию. Но мало кому дествительно нужно каждую миллисекунду запускать планировщик, это чисто психологический параметр (О! одна миллисекунда! круто!). В реальности эту величину можно и поменять, например увеличить, чтобы меньше ресурсов жралось на пустое переключение задач. Например, в очень шустром ESP32 (тактовая 240 МГц) по умолчанию тик выбран 10 миллисекунд, и это не мешает его езернетам и вайфаям- все делается через прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 40 27 января Опубликовано 27 января · Жалоба 16 hours ago, Ruslan1 said: и это не мешает его езернетам и вайфаям- все делается через прерывания Или через yeild(). В таком случае размер тика становится не принципиальным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться