Alexey75 0 21 декабря, 2006 Опубликовано 21 декабря, 2006 · Жалоба Пишу программу для LPC2214 с внешней SRAM, разместил область стека во внуреннем ОЗУ, а кучу во внешнем, но при использовании функций динамического выделения памяти прога зависает. Как оказалось проблема в том что куча находится выше указателя стека и из-за этого выдается ошибка ENOMEM. После поисков в internet и в документации к Newlib, стало ясно что надо написать другой вариант фунции sbrk, но при этом возникли вопросы: 1. как называть новую переопределяемую функцию (в разных местах ее называют как sbrk, _sbrk, _sbrk_r, может еще как-нибудь) 2. как пристроить эту новую функцию, чтобы она заменила существующую библиотечную и линкер бы не ругался Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 21 декабря, 2006 Опубликовано 21 декабря, 2006 · Жалоба Как оказалось проблема в том что куча находится выше указателя стека и из-за этого выдается ошибка ENOMEM. Абсолютно все равно где находится стек. Что-то у Вас с причиной другое совсем. И какое отношение sbrk() к описанной проблеме при попытке динамического выделения памяти вообще имеет. А как Вы вообще представляете реаллокацию памяти на контроллерах класса ARM7? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexey75 0 21 декабря, 2006 Опубликовано 21 декабря, 2006 · Жалоба Как оказалось проблема в том что куча находится выше указателя стека и из-за этого выдается ошибка ENOMEM. Абсолютно все равно где находится стек. Что-то у Вас с причиной другое совсем. Я делал пошаговое выполнение, так вот в функции _sbrk проверяется, чтобы выделяемая область памяти не попадала на стек: caddr_t _sbrk (int incr) { extern char end asm ("end"); /* Defined by the linker. */ static char * heap_end; char * prev_heap_end; if (heap_end == NULL) heap_end = & end; prev_heap_end = heap_end; if (heap_end + incr > stack_ptr) { /* Some of the libstdc++-v3 tests rely upon detecting out of memory errors, so do not abort here. */ #if 0 extern void abort (void); _write (1, "_sbrk: Heap and stack collision\n", 32); abort (); #else errno = ENOMEM; return (caddr_t) -1; #endif } heap_end += incr; return (caddr_t) prev_heap_end; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 21 декабря, 2006 Опубликовано 21 декабря, 2006 · Жалоба Я делал пошаговое выполнение, так вот в функции _sbrk Для начала Вы написали следующее: при использовании функций динамического выделения памяти прога зависает. Между написанным и неработоспособностью некой _sbrk() - изменяющей размер хипа и не имеющей, отношения к привычному системному вызову sbrk() есть разница. А есть-ли вообще необходимость на ходу менять размер heap? Что там за границей у Вас находится? "Ничего"? Так отдайте сразу все под heap. 2. как пристроить эту новую функцию, чтобы она заменила существующую библиотечную и линкер бы не ругался Ну а если желаете создать иллюзию изменения - то просто напишите свою выкинув контроль и она будет молча использоваться вместо библиотечной. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexey75 0 21 декабря, 2006 Опубликовано 21 декабря, 2006 (изменено) · Жалоба Я видимо не совсем ясно выразился, когда задавал вопрос. Вобщем то у меня нет желания делать какие-то навороты по управлению памятью. Проблема возникает когда я размещаю стек во внутренней памяти LPC2214, а heap во внешней (большего размера). Если разместить heap ниже стека то все работает нормально, уже проверил. Просто хотелось бы чтобы стек находился в быстрой внутренней памяти, но там мало места, чтобы размещать там и heap. По большому счету я понял что делать, у меня просто не получилось сделать так, чтобы при компиляции вместо библиотечной функции использовалась измененная мной функция. Изменено 21 декабря, 2006 пользователем Alexey75 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 21 декабря, 2006 Опубликовано 21 декабря, 2006 · Жалоба Вобщем то у меня нет желания делать какие-то навороты по управлению памятью. Проблема возникает когда я размещаю стек во внутренней памяти LPC2214, а heap во внешней (большего размера). Если разместить heap ниже стека то все работает нормально, уже проверил. Просто хотелось бы чтобы стек находился в быстрой внутренней памяти, но там мало места, чтобы размещать там и heap. Все пожелания абсолютно логичны. Проблема не понятна, ибо _sbrk() это уже перераспледеление размера heap. Или они ее и для инициализации размера (я не в курсе) heap используют? В общем если так, то просто выкиньте "контроль" и поместите результат в свой проект. По большому счету я понял что делать, у меня просто не получилось сделать так, чтобы при компиляции вместо библиотечной функции использовалась измененная мной функция. Даже затрудняюсь предположить, что можно сделать "не так" :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexey75 0 21 декабря, 2006 Опубликовано 21 декабря, 2006 · Жалоба По большому счету я понял что делать, у меня просто не получилось сделать так, чтобы при компиляции вместо библиотечной функции использовалась измененная мной функция. Даже затрудняюсь предположить, что можно сделать "не так" :( Не хотелось бы задавать глупые вопросы, но как сделать, чтобы компилятор не обращал внимание на существование библиотечной функции, а брал бы новый вариант функции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 21 декабря, 2006 Опубликовано 21 декабря, 2006 · Жалоба но как сделать, чтобы компилятор не обращал внимание на существование библиотечной функции, а брал бы новый вариант функции. Третий раз пишу - написать свою одноименную и все. Не представляю, по каким причинам сие может не сработать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexey75 0 21 декабря, 2006 Опубликовано 21 декабря, 2006 · Жалоба но как сделать, чтобы компилятор не обращал внимание на существование библиотечной функции, а брал бы новый вариант функции. Третий раз пишу - написать свою одноименную и все. Не представляю, по каким причинам сие может не сработать. С третьего раза я понял о чем вы говорите :) , буду разбираться с компилятором Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 21 декабря, 2006 Опубликовано 21 декабря, 2006 · Жалоба С третьего раза я понял о чем вы говорите :) , буду разбираться с компиляторомЕсли файл в котором будете определять функцию компилится в режиме C++, то надо функцию объявить с extern "C", иначе она получит другое "С++ное" внутреннее имя и, соответственно, не заменит библиотечную. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 21 декабря, 2006 Опубликовано 21 декабря, 2006 · Жалоба Если файл в котором будете определять функцию компилится в режиме C++, то надо функцию объявить с extern "C", иначе она получит другое "С++ное" внутреннее имя и, соответственно, не заменит библиотечную. А что производители компиляторов уже начали писать библиотечные хидеры без extern "С" :)? Хотя конечно если не включить готовый хидер и наплевать на вопли об отсутствии прототипа, то добиться вышеописанного можно :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SergeyDDD 0 21 декабря, 2006 Опубликовано 21 декабря, 2006 · Жалоба Когда идет инициализация стеков и кучи, внешняя память не подключена к процессору. На сколько я помню, кроме контроллера внешней памяти еще необходимо соответственно настраивать совмещенные с шиной памяти порты. Может в этом проблема Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexey75 0 22 декабря, 2006 Опубликовано 22 декабря, 2006 (изменено) · Жалоба Проблема решилась, когда я подменил не функцию _sbrk, а функцию _sbrk_r, файл _sbrk_r.c был взят из newlib-lpc_rel_5a. В результате линкер перестал ругаться, что встретил два определения функции и нормально подменил библиотечную функцию. Изменено 22 декабря, 2006 пользователем Alexey75 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 22 декабря, 2006 Опубликовано 22 декабря, 2006 · Жалоба А что производители компиляторов уже начали писать библиотечные хидеры без extern "С" :)? Хотя конечно если не включить готовый хидер и наплевать на вопли об отсутствии прототипа, то добиться вышеописанного можно :( В некоторых случаях совсем необязательно включать хидер, ибо определение функции является и объявлением. Например я постоянно использую свое определение extern "C" __low_level_init(), но при этом никакой дополнительный хидер в main.cpp не включаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 22 декабря, 2006 Опубликовано 22 декабря, 2006 · Жалоба Например я постоянно использую свое определение extern "C" __low_level_init(), но при этом никакой дополнительный хидер в main.cpp не включаю. __low_level_init() не есть библиотечная функция а просто IARовский прибамбас, посему вполне логично для него отсутствует прототип в библиотечных хидерах и IAR выдает просто болванку в которой все в одном флаконе с хидером. Описывать-же "свои" прототипы для стандартных библиотечных функций есть безобразие. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться