FormatCft 0 17 октября, 2008 Опубликовано 17 октября, 2008 · Жалоба Тестировал 2.4.2. Включил в свой проект и погонял свое устройство день. Все работало, как и с прежним аллокатором BGET (тоже известная вещь), т.е. никаких проблем замечено не было. Подключил я этот алокатор. Вылетает в dabort_hamdler при входе в макрос EXTRACT_BLOCK_HDR(b, tlsf, fl, sl); Использую CW. Может уже разбирались с этой проблемой? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 17 октября, 2008 Опубликовано 17 октября, 2008 · Жалоба И излишества всякие, нехорошие ... Думал просто oткомментировать немного и выложить heap manager для FreeRTOS, но получается, что сначала нужно описывать почему он сделан именно так :(. Попробую: 1. Хотелось иметь возможность получения списков свободных и занятых блоков памяти во время консольной отладки. 2. Хотелось иметь признак для чего блок памяти используется системой (TCB/Stack, Очередь,...) 3. Хотелось иметь возможность знать какая задача породила тот или иной блок - самое простое, при запросе блока сохранять адрес TCB. 4. Обязательна возможность использовать с менеджером разрозненные блоки памяти в едином списке. И наоборот - использовать несколько независимо управляемых блоков памяти (например, если эти блоки памяти имеют разное назначение/свойства, или для ручной борьбы с дефрагментацией ) 5. Особые навороты с для ускорения поиска свободных блоков типа "испанского варианта" не нужны, поскольку - основная масса блоков памяти под задачи, очереди и прочее выделяется "навсегда" и естественно выделение начинается с них; - относительно родной реализации FreeRTOS под задачу и очередь у меня выделяется по одному блоку памяти TCB+Stack и QCB+Queue вместо отдельных. - в результате в реальности занимаются/освобождаются обычно 2-3-5-ну чуть больше блоков и найти подходящий по размеру проще и быстрее простым перебором из свободных. 6. Борьба с дефрагментацией: - склеивание соседних свободных блоков в один; - прежде всего поиск свободного блока равного размеру запрашиваемого - на самом деле достаточно не редкий вариант, особенно, если чуть приложить к этому усилия. Как строим: 1. Один общий связанный список, или отдельные для свободных и занятых. Использую один общий. Решающая причина - простой механизм склейки свободных блоков. При этом недостатки такого подхода нивелирутся тем, что ввиду (п.5) дефрагментация только в хвосте списка и длинна списка для поиска свободного эффективно сокращается использованием всего одного дополнительного указателя на первый свободный блок в общем списке. 2. На MCB выделено достаточно много памяти - 16 байт. Для максимально кастрированного варианта типа родных heap_*.с и с ограничением на размеры выделяемого блока можно было и в 4 байта уложиться, но см. "хотелки". Без особого напряга можно было в 12 байт уложиться, но тем неменее исходя из того, что например, для ARM стека выравнивание на 8 байт надо.... Пусть будет на данный момент 16 байт. typedef union type_size { unsigned long size; struct { unsigned long xlen:24; unsigned long type:8; }; }type_size; // Memory Control Block (MCB) typedef struct heap_mcb { struct heap_mcb *next; // Указатель на следующий MCB // mcb.next последнего MCM всегда указывает на // первый MCB. struct heap_mcb *prev; // Указатель на предыдущий MCB. // Для первого MCB этот указатель указывает // сам на себя. union type_size ts; // Размер блока памяти и тип блока void *ow; // ТСВ Владельца блока памяти // Собственно контролируемый блок памяти расположен сразу за MCB } heap_mcb; // Структура-описатель HEAP (тип-структура t_heap) typedef struct heap_t { // Указатель на начало heap (первый MCB) struct heap_mcb *start; // Указатель на первый свободный MCB struct heap_mcb *freem; // RAW размер HEAP unsigned long hsize; } heap_t; Осталось откомментировать и выложить исходники. Завтра... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 18 октября, 2008 Опубликовано 18 октября, 2008 · Жалоба Оптимально-простой в соответствии с ранее изложенными принципами менеджер памяти. Подгибать, немного по месту, естественно, надо. Инициализация у меня, например, в одном из применений выглядит примерно так: #pragma segment="HEAP_RTOS" #pragma segment="XXX_STACK" void init_system_heap( int add_ram_id ) { system_heap.start = (heap_mcb *)(__segment_begin( "HEAP_RTOS")); system_heap.freem = (heap_mcb *)(__segment_begin( "HEAP_RTOS")); system_heap.hsize = (ulong)(__segment_begin( "XXX_STACK")) - (ulong)(__segment_begin( "HEAP_RTOS")) + 1; heapinit( &system_heap ); if( add_ram_id == 2148 ) // LPC2148 USB Memory as General prupose RAM heapadd( &system_heap, (void *)0x7FD00000, 0x2000 ); } Для стандартной FreeRTOS можно для начала обертки сделать #define pvPortMalloc( size ) malloc_z( &system_heap, (size), MARK_SYSTEM, NULL ) #define vPortFree( ptr ) free_z( &system_heap, (ptr) ) MEM.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
FormatCft 0 18 октября, 2008 Опубликовано 18 октября, 2008 · Жалоба Спасибо! ! ! Щас будем прикручивать :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Terminator 0 12 ноября, 2008 Опубликовано 12 ноября, 2008 · Жалоба Прикрутил к FreeRTOS TLSF ~3kB RAM уходит на таблицу. Не нашёл описания на кучу дефайнов в tlsf.c, походу минимальный выделяемый блок 128 байт. freertos_tlsf.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 17 апреля, 2010 Опубликовано 17 апреля, 2010 · Жалоба Сергей Борщ нашел потенциально суровый баг при освобождении памяти, если используются несколько пулов памяти. Архив с исправлениями в приложении. MEM2.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dron_Gus 2 21 апреля, 2010 Опубликовано 21 апреля, 2010 · Жалоба Спасибо за исходники. Пошел подтачивать под ansi. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex B._ 0 22 апреля, 2010 Опубликовано 22 апреля, 2010 · Жалоба Первый выделенный блок не освобождается. Наверное перекрестную проверку нужно изменить с xptr = tptr->prev; if( ( xptr->next != tptr )||( mem_ptr < heap->start ) ) { xTaskResumeScheduler(); return; } на xptr = tptr->prev; if ( ((xptr != tptr) && ( xptr->next != tptr )) || ( mem_ptr < (void*)heap->start ) ) { xTaskResumeScheduler(); return; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 22 апреля, 2010 Опубликовано 22 апреля, 2010 · Жалоба Первый выделенный блок не освобождается. Типа да, это тоже были особенности использования в системе, которая имеет как минимум одну idle задачу, которая занимает минимум один блок. Если это не так, то добавить этот код надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex B._ 0 22 апреля, 2010 Опубликовано 22 апреля, 2010 · Жалоба Типа да, это тоже были особенности использования в системе, которая имеет как минимум одну idle задачу, которая занимает минимум один блок. Да это понятно. Спасибо за исходники. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
wave48 0 15 июля, 2013 Опубликовано 15 июля, 2013 · Жалоба Исходники аллокатора от zltigo оказались очень полезными. Их, правда, пришлось почти полностью переписать, но идея, положенная в основу самая правильная. В результате получилась heap, которая при размере в 15 килобайт устойчиво держится в системе FreeRTOS, lwip (полный) и FatFS. Heap_mang.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 16 июля, 2013 Опубликовано 16 июля, 2013 · Жалоба Раз уж подняли тему. Модулей диагностики (хотя б печать занятых/свободных блоков) для штатных heap2/heap4 никто не делал? Вроде б очень нужная вещь для отладки, но найти я не смог. Или все внешние прикручивают? Странно это... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
wave48 0 17 июля, 2013 Опубликовано 17 июля, 2013 · Жалоба Вот это и было одной из причин использовать собственный аллокатор. На моей плате хеапы из дистрибутива FReeRTOS увеличивали размер кучи после просмотра двух-трех страниц lwipa и чтения пары килобайт из конфигурационных файлов. Оказалось что они почти не следят за освободившимися блоками, не умеют их объединять. Системный malloc приводил к таким же результатам - ему требовался большой стек. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MiG-3 0 4 декабря, 2014 Опубликовано 4 декабря, 2014 · Жалоба Добрый день, коллеги! Хочется более точно понять как и откуда выделяется память во FreeRTOS и особенности функционирования отдельных выделяльщиков. Проект в IARe, в конфигурации линковщика есть параметр "heap". Так ли я понимаю, что при использовании heap_1.c, heap_2.c, heap_4.c для оси выделяется динамическая память размером "configTOTAL_HEAP_SIZE". Вопрос 1. Откуда она выделяется? Т.е. "configTOTAL_HEAP_SIZE" это часть "heap" или "configTOTAL_HEAP_SIZE" - это память, забираемая плюсом к "heap"? Т.е. сколько мне остается на переменные проекта :-) Вопрос 2. Для heap_3.c размер кучи - это "heap" линковщика? Вопрос 3. В последних версиях FreeRTOS heap_4.c (heap_5.c) имеет все равно проблемы с фрагментацией? Вопрос 4. Если память выделяется динамически на этапе старта - инита оси, стеков и пр., а в дальнейшем изменения задач, мутексов и динамически выделяемых данных не предвидится, то есть ли смысл париться альтернативным кодом аллокаторов? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 8 декабря, 2014 Опубликовано 8 декабря, 2014 · Жалоба Так ли я понимаю, что при использовании heap_1.c, heap_2.c, heap_4.c для оси выделяется динамическая память размером "configTOTAL_HEAP_SIZE". Не понял что значит "для оси выделяется динамическая память"? configTOTAL_HEAP_SIZE задает объем памяти, доступный через pvPortMalloc. Память с его помощью выделяет сама ОС, и он же может использоваться в пользовательском коде... Вопрос 1. Откуда она выделяется? Т.е. "configTOTAL_HEAP_SIZE" это часть "heap" или "configTOTAL_HEAP_SIZE" - это память, забираемая плюсом к "heap"? Т.е. сколько мне остается на переменные проекта :-) Есть массив размера configTOTAL_HEAP_SIZE, из него память и выделяется. Вопрос 2. Для heap_3.c размер кучи - это "heap" линковщика? void *pvPortMalloc( size_t xWantedSize ) { void *pvReturn; vTaskSuspendAll(); { pvReturn = malloc( xWantedSize ); } xTaskResumeAll(); return pvReturn; } КО подсказывает, что да :) Вопрос 3. В последних версиях FreeRTOS heap_4.c (heap_5.c) имеет все равно проблемы с фрагментацией? Я сижу на 7.4.0, на моих применениях полет нормальный. heap_4 выполняет склейку соседних блоков памяти при освобождении. Вопрос 4. Если память выделяется динамически на этапе старта - инита оси, стеков и пр., а в дальнейшем изменения задач, мутексов и динамически выделяемых данных не предвидится, то есть ли смысл париться альтернативным кодом аллокаторов? Используй heap_1 да и все. Она не освобождает память, поэтому реализация простая и очень быстрая... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться