klen 1 18 августа, 2006 Опубликовано 18 августа, 2006 (изменено) · Жалоба Всем привет. Засунул FreeRTOS в LPC2103. Первый раз не пришлось придумывать и обосновывать зачем я вставляю ОС в контроллер. Всетаки в природе попадаются такие задачи для микроконтроллеров... :) Протрахался два дня c одной проблемкой. Была проблема с выделением памяти при инициализации задач и очередей. Вернее при выделении проблем не было - функция malloc исправно выдает указатели и тд. Но при некоторых вызовах, например pbRes = xQueueSend(qhTwi_0_SignaledQueue, &pbTmp , portMAX_DELAY ); возвращался вместо результата 1 или 0 число позначение равное адресам попадавшим в кучу, стеки режимов процессора и тд. Тоест есть похоже чтото на чтото залазило. После такой ситуации есессено PAbort или DAbort. Прикол в том что допишеш строку кода в какомнибудь любом модуле - работает, допишеш еще - глючит, и все в таком духе, закономерности поведения я не уловил. Разгодать причину не получилось (стеки заведомо больше задавались чем нада - проверял ручным счетом, также при ручном выделении стало все работать безошибочно без изменения размеров). Поэтому взял попробывал ручное управление кучей а malloc из libc от CrossWork был послан нах, освобождение памяти мне не требуется, поэтому ручное выделение както проше, меньше жрет и так сказать я тут все регулирую. Где проблема? я чето не понял как чтото работает или всетаки malloc у CrossWork кривой. Локально задачка решена, но не дает покоя вопрос ПОЧЕМУ? вдруг это почему вылезет потом в другом месте. Изменено 18 августа, 2006 пользователем klen Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RRaptor 0 18 августа, 2006 Опубликовано 18 августа, 2006 · Жалоба Прикол в том что допишеш строку кода в какомнибудь любом модуле - работает, допишеш еще - глючит, и все в таком духе, закономерности поведения я не уловил. Может проблема в необходимости сделать clean и пересобрать проект при изменениях в коде, сам вчера час потратил на поиск ошибки, стал вырубаться таймер 0, причем тоже как то нелинейно, в разные моменты времени, хотя все остальное работало. Оказалось что CW как то криво перекомпилировал изменения и после пересборки стало все отлично работать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 18 августа, 2006 Опубликовано 18 августа, 2006 · Жалоба Где проблема? Несколько сумбурно все изложено :-(. Собственно не совсем понятно из чего сделан вывод о проблеме именно с malloc(). Что такое "ручное выделение"? Воообще-то я широко пользуюсь менеджером памяти по мотивам FreeRTOSсовского heap_2.c - изменено только статическое назначение размера heap - под heap выделяется вся оставшаяся память. Может все проще? И нужно пользоваться, например, xQueueSendFromISR в том конкретном случае или какая-то другая "промашка"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 18 августа, 2006 Опубликовано 18 августа, 2006 (изменено) · Жалоба Может все проще? И нужно пользоваться, например, xQueueSendFromISR в том конкретном случае или какая-то другая "промашка"? Вы издеваетесь? это я про 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, как указать чтоб из не моей библы конкретные только конкретные вызовы тоже в ОЗУ положить? Изменено 18 августа, 2006 пользователем klen Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 18 августа, 2006 Опубликовано 18 августа, 2006 · Жалоба Вы издеваетесь? это я про 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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 18 августа, 2006 Опубликовано 18 августа, 2006 · Жалоба Я огарчен. Глюк о котором я говорил выше не связан с кучей. Компилятор раз от раза генерит разный код в месте от выхода из функции и засовывания результата в локальную переменную. Ваще ничего не пойму :( В случае кривой кодогенерации стабильно кладет по адресу результата (окальная переменная) значение первого аргумента функции...., если переменная глобальная то проблем вроде не возникает. Внутри вызванной функции до самого выхода наверх все нормально - результат правильрый, после выхода из нее девки интересно плясать начинают. Это ваще чево? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 18 августа, 2006 Опубликовано 18 августа, 2006 · Жалоба Глюк о котором я говорил выше не связан с кучей. Что, в общем и следовало ожидать. Это ваще чево? Пробуйте спокойно локализовывать. Грабли номер 'раз', когда "ничего не понятно" обычно называются stack. Во FreeRTOS есть простеький механизм оценки обьема стека рельно используемого задачами. Увеличте рамеры в разы и воспользуйтесь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 18 августа, 2006 Опубликовано 18 августа, 2006 · Жалоба Во FreeRTOS есть простеький механизм оценки обьема стека рельно используемого задачами. Увеличте рамеры в разы и воспользуйтесь. Че за механизм оценки использования глубины стека? ну очень хочется чтоб это было так что стеков не хватает... но все перерыл и калькулятором и отладчиком в самую глубокую функцию гглядя на SP. Пока на стеки пинать не приходится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 18 августа, 2006 Опубликовано 18 августа, 2006 · Жалоба Че за механизм оценки использования глубины стека? Смотрите на: prvListTaskWithinSingleList( ) -> usTaskCheckFreeStackSpace( ) Я в принципе у себя контроль переписывал, но больше из эстетических соображений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 19 августа, 2006 Опубликовано 19 августа, 2006 · Жалоба 2_zltigo А Вы еще быстрые синалы не дописали к FreeRTOS ? а то через очереди медленновата задачки синхронизировать - очередь сообщений для синхронизации дороговато будет. думаю вот как покрасивее сигнальчики добавит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 19 августа, 2006 Опубликовано 19 августа, 2006 · Жалоба А Вы еще быстрые синалы не дописали к FreeRTOS ? По крупному в ядре, пока ничего не делал - так, побольше удобств, warnigs поубирал, информации о состоянии системы, ARM mode, источник тактировки переключаемый на внешний, наворотики с idle task ..... Необходимости не было. Там где все быстро, хитро и узкоспециализировано - делалась своя системка в задаче. К осени будет проектик - надо будет крепко думать и над развитием ядра. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться