Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Получить адресс возврата на cortex
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Dron_Gus
Пилю менеджер кучи от zltigo. Решил добавить пару сервисных функций для отладки. В частности хочу знать, откуда был вызов на выделение памяти. Для этого как-то нужно выдернуть содержимое регистра LR. В асме не силен. Так что все потуги пока не увенчались успехом. Может кто подскажет обертку/функцию для получения LR?
aaarrr
Цитата(Dron_Gus @ Apr 23 2010, 18:00) *
Может кто подскажет обертку/функцию для получения LR?

Компилятор-то как зовут?
AHTOXA
Примерно вот так:
Код
inline __attribute__((__always_inline__)) uint32_t get_return_address()
{
    unsigned int ret;
    __asm__ __volatile__ ("mov %0, LR" : "=r"(ret) );
    return ret - 4;
}

void __attribute__((__noinline__)) print_calee(void)
{
    volatile uint32_t ret = get_return_address();
    uart << "called from \t"; uart.put_hex(ret);
}

void test1(void)
{
    print_calee();
}

void test2(void)
{
    print_calee();
}
zltigo
Цитата(Dron_Gus @ Apr 23 2010, 16:00) *
Пилю менеджер кучи от zltigo.

Вообще-то проще и уж точно удобнее для отладки, передавать уже готовый указатель на владельца, что и сделано через void *owner в функции void *malloc_z( heap_t *heap, size_t size, int type, void *owner );
При этом у меня владельцем обычно является указатель на TCB задачи. Хотя естественно, можно и хоть указатель на имя подставлять, хоть явно адрес вызывающей подпрограммы , а не вытаскивать его постфактум.
AHTOXA
Цитата(AHTOXA @ Apr 23 2010, 22:36) *
Примерно вот так:...

Вот так лучше:
Код
inline __attribute__((__always_inline__)) uint32_t get_return_address()
{
    unsigned int ret;
    __asm__ __volatile__ ("sub   %0, LR, #4" : "=r"(ret) );
    return ret;
}


Цитата(zltigo @ Apr 23 2010, 23:11) *
Вообще-то проще и уж точно удобнее для отладки, передавать уже готовый указатель на владельца


Если есть такая возможность, то конечно лучше так. Потому что адрес возврата может испортиться по ходу выполнения malloc (потому приходится его извлекать в самом начале), а параметр уж никуда не денется.
igorsk
Если компилятор от Keil/ARM, то есть интринсик __return_address().
xyzzy
Цитата(igorsk @ Apr 23 2010, 18:00) *
Если компилятор от Keil/ARM, то есть интринсик __return_address().


А если gcc, то __builtin_return_address(unsigned in level)
Dron_Gus
Спасибо всем! Компиляторы Keil и CrossWorks (GCC).
По поводу достаточности указателя на TCB задачи - не всегда достаточно. Во-первых у меня некоторое выделение происходит еще вне задач, потом и в задачах бывает по несколько вызовов. Поэтому найти "неправильный" вызов проще по адресу возврата.
zltigo
Цитата(Dron_Gus @ Apr 25 2010, 12:07) *
По поводу достаточности указателя на TCB задачи - не всегда достаточно.

Вообще-то были предложены и еще другие варианты. Можете вообще хоть указатель на имя файла и номер строки передавать.
Dron_Gus
Спасибо за помощь. Бага найдена.

З.Ы. Мало ли кому пригодиться: lwIP имеет свой heap, который несколько больше указанного в настройках MEM_SIZE. Это надо учитывать выделяя эту память malloc'ом.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.