Перейти к содержанию
    

LPC2103+FreeRTOS

Всем привет.

Засунул FreeRTOS в LPC2103. Первый раз не пришлось придумывать и обосновывать зачем я вставляю ОС в контроллер. Всетаки в природе попадаются такие задачи для микроконтроллеров... :)

Протрахался два дня c одной проблемкой. Была проблема с выделением памяти при инициализации задач и очередей. Вернее при выделении проблем не было - функция malloc исправно выдает указатели и тд. Но при некоторых вызовах, например

pbRes = xQueueSend(qhTwi_0_SignaledQueue, &pbTmp , portMAX_DELAY );

возвращался вместо результата 1 или 0 число позначение равное адресам попадавшим в кучу, стеки режимов процессора и тд. Тоест есть похоже чтото на чтото залазило. После такой ситуации есессено PAbort или DAbort.

Прикол в том что допишеш строку кода в какомнибудь любом модуле - работает, допишеш еще - глючит, и все в таком духе, закономерности поведения я не уловил.

Разгодать причину не получилось (стеки заведомо больше задавались чем нада - проверял ручным счетом, также при ручном выделении стало все работать безошибочно без изменения размеров). Поэтому взял попробывал ручное управление кучей а malloc из libc от CrossWork был послан нах, освобождение памяти мне не требуется, поэтому ручное выделение както проше, меньше жрет и так сказать я тут все регулирую.

 

Где проблема? я чето не понял как чтото работает или всетаки malloc у CrossWork кривой. Локально задачка решена, но не дает покоя вопрос ПОЧЕМУ? вдруг это почему вылезет потом в другом месте.

Изменено пользователем klen

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прикол в том что допишеш строку кода в какомнибудь любом модуле - работает, допишеш еще - глючит, и все в таком духе, закономерности поведения я не уловил.

 

Может проблема в необходимости сделать clean и пересобрать проект при изменениях в коде, сам вчера час потратил на поиск ошибки, стал вырубаться таймер 0, причем тоже как то нелинейно, в разные моменты времени, хотя все остальное работало. Оказалось что CW как то криво перекомпилировал изменения и после пересборки стало все отлично работать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Где проблема?

Несколько сумбурно все изложено :-(. Собственно не совсем понятно из чего сделан вывод о проблеме именно с malloc(). Что такое "ручное выделение"?

Воообще-то я широко пользуюсь менеджером памяти по мотивам FreeRTOSсовского heap_2.c - изменено только статическое назначение размера heap - под heap выделяется вся оставшаяся память.

Может все проще? И нужно пользоваться, например, xQueueSendFromISR в том конкретном случае или

какая-то другая "промашка"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может все проще? И нужно пользоваться, например, xQueueSendFromISR в том конкретном случае или

какая-то другая "промашка"?

Вы издеваетесь? :biggrin: это я про xQueueSendFromISR/xQueueSend.

Почему именно malloc ? а как тогда обяснить что при при heap_3.c (тоесть malloc из libc) проглюкавыет, а с heap_2.c работает как часики.

Я имел ввиду под ручным все то что не heap_3.c, тоесть не использует malloc из libc и соответственно секцию .heap . Заработало стабильно как раз после heap_2.c + немного напильником.

А как вы автоматом размер ручной кучи(остаток озу) в исходнике берете?

 

2_RRaptor

А это ИДЕЯ!! Ведь и вправду если хоть гдето в объектниках сохраняется константа-указатель на начало кучи то перекомпиляция другого модуля автоматом все двигает по озу, и получается каша, но с другой стороны этого вроде как не бывает - все абсолютные адреса после компиляния в линкере вычислюется и подставляются . Есть вариант что CW проглюкивает при генерации линковочного скрипта (относительно кучи) опятьже при не полной соборке. Поскольку при "ручном" выделении куча в понимании линкера уэже не секция кучи а просто данные-массив байт, то и глюков нет/другие

 

Еще вопрос до кучи.

Как правильно сказать компиллеру/линкеру GCC в CW засунуть функцию в ОЗУ.

... *Foo(...) __attribute__ ((section(".data_run"))) ;

... *Foo(...)

{....}

помогает, она размещается в ОЗУ, но код в ней кривой как коленвал.

И еще, допустим я засунул функцию в ОЗУ, но она дергает вызовы счета float, как указать чтоб из не моей библы конкретные только конкретные вызовы тоже в ОЗУ положить?

Изменено пользователем klen

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы издеваетесь? :biggrin: это я про xQueueSendFromISR/xQueueSend.

Нет, конечно! Всякое бывает :-(.

Заработало стабильно как раз после heap_2.c + немного напильником.

А как вы автоматом размер ручной кучи(остаток озу) в исходнике берете?

Последним (предпоследим) в списке линковки сегментов лежит HEAP_RTOS размером (произвольное значение для гарантии наличия хоть какой-то памяти для старта) в килобайт. Все от его начала до конца памяти - отдается менеджеру. Точнее не до конца а до начала прилинкованного в конец сегмента XXX_STACK размером 32 байта который используется для Abort/Undefined стеков и для IAP.

Все выглядит для IARа так:

void prvHeapInit()
{
//zlt[
total_heap_rtos = (ulong)(__segment_begin( "XXX_STACK")) - (ulong)(__segment_begin( "HEAP_RTOS")) + 1;
//]zlt
xBlockLink *pxFirstFreeBlock;

    /* xStart is used to hold a pointer to the first item in the list of free */
    /* blocks.  The void cast is used to prevent compiler warnings. */
//zlt[
//    xStart.pxNextFreeBlock = ( void * ) xHeap.ucHeap;
    xStart.pxNextFreeBlock = (xBlockLink *) __segment_begin( "HEAP_RTOS" );
//]zlt
    xStart.xBlockSize = ( size_t ) 0;

    /* xEnd is used to mark the end of the list of free blocks. */
//zlt[
//    xEnd.xBlockSize = configTOTAL_HEAP_SIZE;
    xEnd.xBlockSize = total_heap_rtos;
//]zlt
    xEnd.pxNextFreeBlock = NULL;

    /* To start with there is a single free block that is sized to take up the
    entire heap space. */
//zlt[
//    pxFirstFreeBlock = ( void * ) xHeap.ucHeap;
//    pxFirstFreeBlock->xBlockSize = configTOTAL_HEAP_SIZE;

    pxFirstFreeBlock = xStart.pxNextFreeBlock;        // Start of HEAP
    pxFirstFreeBlock->xBlockSize = total_heap_rtos;
//]zlt
    pxFirstFreeBlock->pxNextFreeBlock = &xEnd;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я огарчен. Глюк о котором я говорил выше не связан с кучей. Компилятор раз от раза генерит разный код в месте от выхода из функции и засовывания результата в локальную переменную. Ваще ничего не пойму :( В случае кривой кодогенерации стабильно кладет по адресу результата (окальная переменная) значение первого аргумента функции...., если переменная глобальная то проблем вроде не возникает. Внутри вызванной функции до самого выхода наверх все нормально - результат правильрый, после выхода из нее девки интересно плясать начинают.

Это ваще чево?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Глюк о котором я говорил выше не связан с кучей.

Что, в общем и следовало ожидать.

Это ваще чево?

Пробуйте спокойно локализовывать. Грабли номер 'раз', когда "ничего не понятно" обычно называются stack. Во FreeRTOS есть простеький механизм оценки обьема стека рельно используемого задачами.

Увеличте рамеры в разы и воспользуйтесь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Во FreeRTOS есть простеький механизм оценки обьема стека рельно используемого задачами.

Увеличте рамеры в разы и воспользуйтесь.

Че за механизм оценки использования глубины стека? ну очень хочется чтоб это было так что стеков не хватает... но все перерыл и калькулятором и отладчиком в самую глубокую функцию гглядя на SP. Пока на стеки пинать не приходится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Че за механизм оценки использования глубины стека?

 

Смотрите на:

prvListTaskWithinSingleList( ) -> usTaskCheckFreeStackSpace( )

 

Я в принципе у себя контроль переписывал, но больше из эстетических соображений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2_zltigo

 

А Вы еще быстрые синалы не дописали к FreeRTOS ? а то через очереди медленновата задачки синхронизировать - очередь сообщений для синхронизации дороговато будет.

думаю вот как покрасивее сигнальчики добавит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А Вы еще быстрые синалы не дописали к FreeRTOS ?

По крупному в ядре, пока ничего не делал - так, побольше удобств, warnigs поубирал, информации о состоянии системы, ARM mode, источник тактировки переключаемый на внешний, наворотики с idle task .....

Необходимости не было. Там где все быстро, хитро и узкоспециализировано - делалась своя системка в задаче. К осени будет проектик - надо будет крепко думать и над развитием ядра.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...