Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Менеджер динамической памяти в IAR
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Andy Mozzhevilov
Функции malloc, free, realloc, calloc реализованы в стандартной библиотеке, чтобы ими пользоваться включаем stdlib.h:
Код
#include <stdlib.h>

void main (void)
{
    void * pSlon;

    pSlon = malloc(1000);
}

Вопрос: как, не внося изменения в системный stdlib.h, объяснить IAR-у чтобы он использовал мою реализацию функий malloc, free, realloc, calloc взамен библиотечных? То есть чтобы исходник выглядел так же, как и выше, но реализация функций была заменена?
Есть какой-то кошерный способ это сделать?
HARMHARM
Я вообще-то не очень разбирался, но есть два метода:
1) Наглый:
#include <stdlib.h>

void *myMalloc(size_t size) {
// log
return malloc(size);
}

void myFree(void *ptr) {
// log
free(ptr);
}

#define malloc(size) myMalloc(size)
#define free(ptr) myFree(ptr)

2) Правильный:
Можно почитать в главе "Overriding library modules" в ARM® IAR C/C++ Compiler Reference Guide. Суть в подключении своих функций, они должны в командной строке линкера быть перед библиотечными. Вы же cstartup стандартный заменяете?
Сергей Борщ
Цитата(Andy Mozzhevilov @ Apr 21 2009, 17:58) *
Вопрос: как, не внося изменения в системный stdlib.h, объяснить IAR-у чтобы он использовал мою реализацию функий malloc, free, realloc, calloc взамен библиотечных?
Насколько я понимаю - просто написать свои функции с такими же именами. Они будут подлинковываться взамен библиотечных, точно так же как подлинковываются putchar(), __write()
Andy Mozzhevilov
Цитата(Сергей Борщ @ Apr 21 2009, 19:48) *
Насколько я понимаю - просто написать свои функции с такими же именами. Они будут подлинковываться взамен библиотечных, точно так же как подлинковываются putchar(), __write()

там не все так просто.
В stdlib malloc определяется как:
Код
#ifndef _NO_DEFINITIONS_IN_HEADER_FILES
#ifndef _DO_NOT_INLINE_MALLOC

#pragma inline
void * malloc(size_t _S)
{
  return _GLUE(__DEF_PTR_MEM__,_malloc(_S));

}

#endif /* _DO_NOT_INLINE_MALLOC */
#endif /* _NO_DEFINITIONS_IN_HEADER_FILES */

После препроцессора из stdlib.h получается:
Код
__intrinsic void * malloc(size_t);

...

__intrinsic void __data * __data_malloc(__data_size_t);


#pragma inline
void * malloc(size_t _S)
{
  return __data_malloc(_S);
}

В листинге получается:
Код
    133              pSlon = malloc(1000);
   \   00000004   64409FE5           LDR      R4,??main_0     ;; pSlon
   \   00000008   FA0FA0E3           MOV      R0,#+1000
   \   0000000C   ........           BL       __data_malloc
   \   00000010   000084E5           STR      R0,[R4, #+0]


я так понимаю, можно как-то рулить определениями _NO_DEFINITIONS_IN_HEADER_FILES и/или _DO_NOT_INLINE_MALLOC , в которые завернуты определения функций менеджера динамической памяти в stdlib.h, но вопрос - как сделать кошерно? В документации пока не нашел.




Цитата(HARMHARM @ Apr 21 2009, 19:36) *
Я вообще-то не очень разбирался, но есть два метода:
1) Наглый:
...
#define malloc(size) myMalloc(size)
#define free(ptr) myFree(ptr)

это не так, как хотелось бы.

Цитата
2) Правильный:
Можно почитать в главе "Overriding library modules" в ARM® IAR C/C++ Compiler Reference Guide. Суть в подключении своих функций, они должны в командной строке линкера быть перед библиотечными.

Завтра попробую еще почитать, сегодня уже голова плохо работает.
Цитата
Вы же cstartup стандартный заменяете?

Нет, зачем? Мне функциональности low_level_init() более чем достаточно.
HARMHARM
Цитата(Andy Mozzhevilov @ Apr 21 2009, 22:41) *
...
я так понимаю, можно как-то рулить определениями _NO_DEFINITIONS_IN_HEADER_FILES и/или _DO_NOT_INLINE_MALLOC , в которые завернуты определения функций менеджера динамической памяти в stdlib.h, но вопрос - как сделать кошерно? В документации пока не нашел.

Это уже кишочки писателей библиотеки, кажется так глубоко нырять не потребуется...
Цитата
Нет, зачем? Мне функциональности low_level_init() более чем достаточно.

По сути то же самое. В библиотеке есть low_level_init(), там заглушка...
Andy Mozzhevilov
Цитата(Сергей Борщ @ Apr 21 2009, 19:48) *
Насколько я понимаю - просто написать свои функции с такими же именами. Они будут подлинковываться взамен библиотечных, точно так же как подлинковываются putchar(), __write()


"The library files that you can override with your own versions are located in the arm\src\lib directory"
Функции менеджера памяти сюда не входят sad.gif


Цитата(HARMHARM @ Apr 22 2009, 00:02) *
Это уже кишочки писателей библиотеки, кажется так глубоко нырять не потребуется...

Вот и мне не хотелось бы.

Цитата
По сути то же самое. В библиотеке есть low_level_init(), там заглушка...

Не совсем. Функции менеджера памяти судя по всему не входят в список переопределяемых поверх стандартных.
Можно их через "customized library" ввести наверняка, но это то, чем совсем не хотелось бы заниматься. И я не уверен, что это даже выйдет, поскольку потребует наличия исходников библиотек.
_Pasha
Цитата(HARMHARM @ Apr 21 2009, 18:36) *
есть два метода:
1) Наглый:
#define malloc(size) myMalloc(size)
#define free(ptr) myFree(ptr)


Пользуюсь без зазрения совести именно таким методом. Для облагораживания добавлены варнинги про то, что мол куча самописная.
Сергей Борщ
Цитата(Andy Mozzhevilov @ Apr 21 2009, 22:41) *
Код
#pragma inline
void * malloc(size_t _S)
{
  return __data_malloc(_S);
}
значит надо подменить __data_malloc(). Попробовал в 4.30А - получилось:
Код
file1.cpp:
#include    <stdlib.h>
extern "C" void * __data_malloc(size_t size)
{
    return (void *)0x123;
}
file2.cpp:
#include    <stdlib.h>

void * Temp;
_C_LIB_DECL
#pragma language=extended
#pragma location="ICODE"
int __low_level_init(void)
{
    Temp = malloc(5);

Посмотрел список модулей в библиотеке при помощи xlib (xlib.exe -c "LIST-ENTRIES dl4tptinl8n.r79 "):
Код
       1.  Lib  ?low_level_init
             Ent   __low_level_init
....
     125.  Lib  ?free
             Ent   _Instansiator_free
             Ent   __data_free
             Ent   free
...
     177.  Lib  ?malloc
             Ent   ?init?tab?DATA_Z
             Ent   _Instansiator_malloc
             Ent   __data_Aldata
             Ent   __data_malloc
             Ent   malloc
Никаких намеков на то, что могут быть "подменяемые" и "неподменяемые" функции.
Andy Mozzhevilov
Цитата(Сергей Борщ @ Apr 22 2009, 11:53) *
значит надо подменить __data_malloc(). Попробовал в 4.30А - получилось:

Я в данный момент пользуюсь 5.11.
Тот код, что я приводил был для него.
Для 5.20 и 5.30 при абсолютно тех же ключах компилятора получается:
Код
   \   000002A8   040096E5           LDR      R0,[R6, #+4]
   \   000002AC   080090E5           LDR      R0,[R0, #+8]
   \   000002B0   00008DE5           STR      R0,[SP, #+0]
   \   000002B4   6400A0E3           MOV      R0,#+100
   \   000002B8   ........           BL       malloc

То есть тут уже нужно подменять malloc. Нужно хотя бы просто попробовать сделать подмену, на предмет выйдет или нет.
Но, например, в 5.xx дефолтовые вектора прерываний объявлены как:
Код
        MODULE  ?vectortrap

        PUBWEAK Undefined_Handler

        SECTION .text:CODE:NOROOT:REORDER(2)
        ARM
Undefined_Handler:
        B .
...

PUBWEAK is similar to PUBLIC except that it allows the same symbol to be defined several times. Only one of those definitions will be used by ILINK. If a module containing a PUBLIC definition of a symbol is linked with one or more modules containing PUBWEAK definitions of the same symbol, ILINK will use the PUBLIC definition.

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