Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: GCC Ворос по malloc
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
doomer#gp
Как заставить malloc выделять память в Ext SRAM /SDRAM, в то время как указатель на стек загружена вершина внутреннего SRAM. Разделения стеков на kernel и user mode нету. Если никак то придется надо сделать принудительную реализацию различных стеков, огранизовав вызов "системных" функции через SWI. Хотелось бы иметь быстрый стек и динамичексую память из внешней.
doomer#gp
Да, наверное, самому придестя реализовывать объект MemoryPool
scum
Цитата(doomer#gp @ Apr 20 2006, 13:07) *
Да, наверное, самому придестя реализовывать объект MemoryPool

Если надо стек в локальной памяти и кучу во внешней, то в чем проблема-то? Или надо две кучи? Вы же в курсе что динамическая память не выделяется на стеке. А то из первого сообщения складывается ложное впечатление.
makc
Цитата(doomer#gp @ Apr 20 2006, 09:50) *
Как заставить malloc выделять память в Ext SRAM /SDRAM, в то время как указатель на стек загружена вершина внутреннего SRAM. Разделения стеков на kernel и user mode нету. Если никак то придется надо сделать принудительную реализацию различных стеков, огранизовав вызов "системных" функции через SWI. Хотелось бы иметь быстрый стек и динамичексую память из внешней.


Если Вы возьмете malloc и компанию из newlib, то для его работы придется определить свою функцию sbrk( ... ), которая и возвращает указатель на память по запросу. Какой это будет указатель, это уже ваше дело. glibc ведет себя подобным же образом, если мне не изменяет память. Так что проблемы использования стандартного malloc'a я лично не вижу.
doomer#gp
Про sbrk(), _sbrk_r() я в курсе. Не совсем коррктно сформулировал вопрос. Но это не позволяет создавать кучу динамически. Заниматся переинициализацией stdlib с целью выполнения sbrk() каждый раз - путь через ж...., а тем более если надо несколько куч в разных адресных пространствах вот в этом то и загвостка.
makc
Цитата(doomer#gp @ Apr 20 2006, 21:01) *
Про sbrk(), _sbrk_r() я в курсе. Не совсем коррктно сформулировал вопрос. Но это не позволяет создавать кучу динамически. Заниматся переинициализацией stdlib с целью выполнения sbrk() каждый раз - путь через ж...., а тем более если надо несколько куч в разных адресных пространствах вот в этом то и загвостка.


Вы меня совсем запутали - как и для чего Вам нужно создавать кучу динамически? И если Вам нужно несколько разных куч, то как Вы предполагаете их различать при использовании malloc.

Мое видение проблемы таково - если у Вас есть память в нескольких адресных пространствах, то Вы легко можете реализовать sbrk, который будет знать о размере каждого из адресных пространств и начаная с первого адресного пространства при его исчерпании переходить следующее и наоборот. Это вполне можно реализовать и получить общую кучу, склеенную из памяти в нескольких адресных пространствах (из нескольких маленьких кучек smile.gif ).
doomer#gp
Благодарю за ответы, вопрос решен.
makc
Цитата(doomer#gp @ Apr 21 2006, 06:37) *
Благодарю за ответы, вопрос решен.


На чем душа успокоилась? smile.gif
doomer#gp
"Успокоился" на том, что придется писать собственный аллокатор.
А вот почему. Аллокатор в GCC не подерживает работу с MMU. В идеале должна получиться библиотечка, в которой можно будет переопределить подпрограммы работы с MMU для разных процов.
А пока мне был нужен аллокатор который мог бы работать с множеством куч. Это обусловлено тем, что выделяя небольшие кучи получим рост производительности аллокатора на обработке дефрагментации.
Пока реализовывается следующим набором функций

MEM_HANDLE* MmHeapAlloc(MEM_DESCR* pDescr );
unsigned char* MmProcessHeapSpace(MEM_HANDLE* pMemHandle,int nbytes);
unsigned char* MmAlloc(MEM_HANDLE* pMemHandle,int nbytes);
unsigned char* MmRelloc(MEM_HANDLE* pMemHandle,int nbytes);
void MmFree(unsigned char* pMem,MEM_HANDLE* pMemHandle);

Ну вообщем появлестя еще один идентификатор блока памяти - его хендл.

А с GCC у меня возникли некоторые проблемы. У меня версия 4.0.2 с newlibc. Там надо определить свой _sbrk_r(reentrant*,...). Я его написал как и описано в мануалах. Исполняю код и вижу функция вызвалась 2 раза внутри malloc(), и malloc выдает zero pointer. Проверил все - никак не вылечивается.
Глянул код - все библиотечные функции скомпилены в Thumb-е. В каком режиме _sbrk_r() не компиль результат тот-же.
makc
Цитата(doomer#gp @ Apr 24 2006, 21:34) *
"Успокоился" на том, что придется писать собственный аллокатор.
А вот почему. Аллокатор в GCC не подерживает работу с MMU. В идеале должна получиться библиотечка, в которой можно будет переопределить подпрограммы работы с MMU для разных процов.
А пока мне был нужен аллокатор который мог бы работать с множеством куч. Это обусловлено тем, что выделяя небольшие кучи получим рост производительности аллокатора на обработке дефрагментации.
Пока реализовывается следующим набором функций

MEM_HANDLE* MmHeapAlloc(MEM_DESCR* pDescr );
unsigned char* MmProcessHeapSpace(MEM_HANDLE* pMemHandle,int nbytes);
unsigned char* MmAlloc(MEM_HANDLE* pMemHandle,int nbytes);
unsigned char* MmRelloc(MEM_HANDLE* pMemHandle,int nbytes);
void MmFree(unsigned char* pMem,MEM_HANDLE* pMemHandle);

Ну вообщем появлестя еще один идентификатор блока памяти - его хендл.


Фактически Вы пытаетесь реализовать VMM, который в большинстве случаев реализуется в ОС.
Кстати, посмотрите еще на mmaloc. Может поможет...

Цитата
А с GCC у меня возникли некоторые проблемы. У меня версия 4.0.2 с newlibc. Там надо определить свой _sbrk_r(reentrant*,...). Я его написал как и описано в мануалах. Исполняю код и вижу функция вызвалась 2 раза внутри malloc(), и malloc выдает zero pointer. Проверил все - никак не вылечивается.
Глянул код - все библиотечные функции скомпилены в Thumb-е. В каком режиме _sbrk_r() не компиль результат тот-же.


Если мне не изменяет память, то определять нужно просто caddr_t sbrk(int nbytes); а reentrant определяется через него:

Код
void *
_DEFUN (_sbrk_r, (ptr, incr),
     struct _reent *ptr _AND
     ptrdiff_t incr)
{
  char *ret;
  void *_sbrk(ptrdiff_t);

  errno = 0;
  if ((ret = (char *)(_sbrk (incr))) == (void *) -1 && errno != 0)
    ptr->_errno = errno;
  return ret;
}
doomer#gp
Если определяю только sbrk(), то ликуется неправильно, не поддерживает thumb-interworking.
И соответственно неправильно вызывается.

Пробовал скомпилить sbrk() и заглушку зля malloc в Thumb-е, не помогает.

А если определять _sbrk_r (обе функции),то компилится нормально, но malloc возвращает NULL.



arm-elf-gcc -mthumb -mcpu=arm7tdmi-s -mthumb-interwork -I. -gdwarf-2 -DROM_RUN -Os -Wall -Wcast-align -Wcast-qual -Wimplicit -fPIC -Wpointer-arith -Wswitch -Wredundant-decls -Wreturn-type -Wshadow -Wunused -Wa,-adhlns=crt0.lst -MD -MP -MF .dep/main.elf.d crt0.o uartISR.o armVIC.o sysTime.o shed.o hal.o main.o flash.o uart.o modem.o ppp.o syscalls.o --output main.elf -nostartfiles -Wl,-Map=main.map,--cref -lc -lnewlib-lpc -lm -lc -lgcc -lstdc++ -TLPC2129-ROM.ld
c:\winarm\bin\..\lib\gcc\arm-elf\4.0.2\..\..\..\..\arm-elf\bin\ld.exe: Warning: c:/winarm/bin/../lib/gcc/arm-elf/4.0.2\libnewlib-lpc.a(_sbrk_r.o) does not support interworking, whereas main.elf does
c:\winarm\bin\..\lib\gcc\arm-elf\4.0.2\..\..\..\..\arm-elf\bin\ld.exe: c:/winarm/bin/../lib/gcc/arm-elf/4.0.2\libnewlib-lpc.a(_sbrk_r.o)(_sbrk_r): warning: interworking not enabled.
first occurrence: c:/winarm/bin/../lib/gcc/arm-elf/4.0.2/../../../../arm-elf/lib/thumb/interwork\libc.a(mallocr.o): thumb call to arm
c:/winarm/bin/../lib/gcc/arm-elf/4.0.2/../../../../arm-elf/lib/thumb/interwork\libc.a(mallocr.o): In function `_malloc_r':mallocr.c:(.text+0x25a): warning: internal error: dangerous error
c:\winarm\bin\..\lib\gcc\arm-elf\4.0.2\..\..\..\..\arm-elf\bin\ld.exe: c:/winarm/bin/../lib/gcc/arm-elf/4.0.2\libnewlib-lpc.a(_sbrk_r.o)(_sbrk_r): warning: interworking not enabled.
first occurrence: c:/winarm/bin/../lib/gcc/arm-elf/4.0.2/../../../../arm-elf/lib/thumb/interwork\libc.a(mallocr.o): thumb call to arm
:mallocr.c:(.text+0x3c4): warning: internal error: dangerous error
c:\winarm\bin\..\lib\gcc\arm-elf\4.0.2\..\..\..\..\arm-elf\bin\ld.exe: c:/winarm/bin/../lib/gcc/arm-elf/4.0.2\libnewlib-lpc.a(_sbrk_r.o)(_sbrk_r): warning: interworking not enabled.
first occurrence: c:/winarm/bin/../lib/gcc/arm-elf/4.0.2/../../../../arm-elf/lib/thumb/interwork\libc.a(freer.o): thumb call to arm
c:/winarm/bin/../lib/gcc/arm-elf/4.0.2/../../../../arm-elf/lib/thumb/interwork\libc.a(freer.o): In function `_malloc_trim_r':mallocr.c:(.text+0x2c): warning: internal error: dangerous error
c:\winarm\bin\..\lib\gcc\arm-elf\4.0.2\..\..\..\..\arm-elf\bin\ld.exe: c:/winarm/bin/../lib/gcc/arm-elf/4.0.2\libnewlib-lpc.a(_sbrk_r.o)(_sbrk_r): warning: interworking not enabled.
first occurrence: c:/winarm/bin/../lib/gcc/arm-elf/4.0.2/../../../../arm-elf/lib/thumb/interwork\libc.a(freer.o): thumb call to arm
:mallocr.c:(.text+0x4a): warning: internal error: dangerous error
c:\winarm\bin\..\lib\gcc\arm-elf\4.0.2\..\..\..\..\arm-elf\bin\ld.exe: c:/winarm/bin/../lib/gcc/arm-elf/4.0.2\libnewlib-lpc.a(_sbrk_r.o)(_sbrk_r): warning: interworking not enabled.
first occurrence: c:/winarm/bin/../lib/gcc/arm-elf/4.0.2/../../../../arm-elf/lib/thumb/interwork\libc.a(freer.o): thumb call to arm
makc
Нужно посмотреть, как были собраны библиотеки с помощью arm-elf-objdump.
Разобравшись с этим, можно будет задать правильные ключи для компиляции и линковки или пересобрать либы. Но "на вскидку" могу предложить попробовать вместо -mthumb задать что-то вроде -mcpu=arm7tdmi
doomer#gp
У меня задана MCU = arm7tdmi-s
THUMB_IW = -mthumb-interwork

В Makefile складывается куча опций для каждого режима компиляции. Но во все всходит $(MCU) и $(THUMB_IW). Попробую разобраться с lib-ами.

makс, а Вы не в курсе как указать чтобы в asm-листингах константы были hex, а не decimal ?
makc
Цитата(doomer#gp @ Apr 25 2006, 08:14) *
makс, а Вы не в курсе как указать чтобы в asm-листингах константы были hex, а не decimal ?


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