Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: malloc и компания
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Terminator
В демке FreeRTOS для sam7 есть три модели распределения памяти:
  1. выделение без освобождения
  2. выделение с освобождением, но без объединения мелких свободных блоков в большой
  3. использование библиотечных malloc, free

Взял за основу демку для sam7. С второй моделью всё работает, а вот с третьей нет, OS крутит задачу idle и всё sad.gif

Смотрел пошаговое выполнение, все выделения памяти выполняются вроде правильно.
Куда копать?

"Среда"
arm-elf-gcc (GCC) 4.1.2
GNU ld version 2.17
newlib-1.15.0
_dem
а malloc/free "обернуты" в выключение/включение шедулера задач ?
Terminator
Цитата(_dem @ Oct 10 2007, 15:06) *
а malloc/free "обернуты" в выключение/включение шедулера задач ?

Конечно.
В "оригинале" было SuspendAll и потом ResumeAll.
Я подумал что при таком раскладе задача, попросившая память, после SuspedAll остановится и с ней все остальные.
Поменял на ENTER_CRITICAL, EXIT_CRITICAL.

Всё равно не работает. До замены тоже не работало.
zltigo
Цитата(Terminator @ Oct 10 2007, 11:17) *
В "оригинале" было SuspendAll и потом ResumeAll.
Я подумал что при таком раскладе задача, попросившая память, после SuspedAll остановится и с ней все остальные.

Задача, естественно, не "останавливается" - останавливается шедулер, просто название системных вызовов крайне не удачное - на самом деле это vTaskSuspendScheduler(). Во SafeRTOS они имеют нормальные названия, а во FreeRTOS Автор оставил дурацкие.
Цитата
Всё равно не работает. До замены тоже не работало.

Собственно там вариантов никаих и нет - банально на работает штатный malloc() - начните раззборки с его прямого вызова.
Terminator
Цитата(zltigo @ Oct 10 2007, 15:30) *
Собственно там вариантов никаих и нет - банально на работает штатный malloc() - начните раззборки с его прямого вызова.

Вызов прямее некуда.
Код
void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn;

    portENTER_CRITICAL();
    //vTaskSuspendAll();
    {
        pvReturn = malloc( xWantedSize );
    }
    //xTaskResumeAll();
    portEXIT_CRITICAL();

    return pvReturn;
}


Всё ещё не догоняю куда копать smile3046.gif
Dron_Gus
При запуске задач используется все тот же malloc. Если крутится только idle, значит больше задач нет. Значит при их запуске (например) не выделилось нужного места под стек и т.д. Копайте в сторону настроек кучи. А заодно проверьте, что возвращает xTaskCreate. Я для этого использую такую конструкцию

__inline signed portBASE_TYPE _xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask )
{
portBASE_TYPE result;
result = xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask );
if ( result != pdPASS )
printf("%s coud not be created\r\n", pcName);
#ifdef DEBUG
else
printf("%s started\r\n", pcName);
#endif
return result;
}
Terminator
Цитата(Dron_Gus @ Oct 10 2007, 17:16) *
При запуске задач используется все тот же malloc. Если крутится только idle, значит больше задач нет.

Задачи есть. Если сменить модель выделения памяти на другую, то всё работает.
Цитата
Значит при их запуске (например) не выделилось нужного места под стек и т.д. Копайте в сторону настроек кучи. А заодно проверьте, что возвращает xTaskCreate. Я для этого использую такую конструкцию
...

Пошаговое выполнение смотрел, память выделяется. В случае библиотечных malloc free, никаких настроек кучи нету, только линкер должен определить где кончается занятая память. Я проверял, выделение начинается сразу после последней глобальной переменной.

Походу никто с такой проблемой не сталкивался ...

Придётся выделять память большими одинаковыми кусками.
zltigo
Цитата(Terminator @ Oct 11 2007, 06:07) *
память выделяется....

Что-то в ваших словах не сходится - если память выделяется, то никаких причин не работать нет.
Цитата
Походу никто с такой проблемой не сталкивался ...

Не приходило в голову использовать какой-то непонятно реализованный "штатный" malloc(). Пользую свой менеджер использующий всю свободную память, немножко борющийся с дефрагментацией и знающий владельца блока.
Terminator
Цитата(zltigo @ Oct 11 2007, 15:13) *
Что-то в ваших словах не сходится - если память выделяется, то никаких причин не работать нет.

Это точно wacko.gif
Цитата
Не приходило в голову использовать какой-то непонятно реализованный "штатный" malloc().

В доке к newlib он описан.
Цитата
Пользую свой менеджер использующий всю свободную память, немножко борющийся с дефрагментацией и знающий владельца блока.

Не поделитесь? cheers.gif
zltigo
Цитата(Terminator @ Oct 11 2007, 11:24) *
В доке к newlib он описан.

Тогда читайте. Прежде всего гляньте наличие выравнивания выделенного блока хотя-бы на 4 байта.
Цитата
Не поделитесь? cheers.gif

Впрямую он Вам всеравно не подойдет, ибо местами сильно завязан на операционку, которая в свою очередь местами заметно переписана.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.