реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> stm32 gcc lib printf улетает в HardFault_Handler, Не получается запустить printf улетает в HardFault_Handler
marka
сообщение Nov 26 2015, 20:16
Сообщение #1





Группа: Участник
Сообщений: 11
Регистрация: 26-11-15
Пользователь №: 89 481



Здравствуйте.

Суть проблемы...

Пытаюсь вызвать стандартный printf из stdio и после вызова вылетает в HardFault_Handler.

Запускал отладчик смотрел на каком месте падает...
На строчке ldrh r2, [r1, #12]

Код
        862 [1]    in ../../../../../../newlib/libc/stdio/vfprintf.c
0x8003934  <+0x0034>        51 46        mov    r1, r10
0x8003936  <+0x0036>        8a 89        ldrh    r2, [r1, #12]


Есть подозрения что что-то с линковкой (адреса путаются)... или флаги линковщику особенные нужно скармливать...

Да! Заранее конечно подготовил мин. набор функция для библиотеки _write, _read и другие. Линковка проходит нормально, не ругается это точно.

Хочу узнать ваши предположения. Может кто сталкивался с такой проблемой...

Кусок из makefile, то что касается линковщика:

Код
LD     =arm-none-eabi-ld

LIB_B       =/usr/lib/arm-none-eabi/newlib/armv6-m/
LIB_GCC =/usr/lib/gcc/arm-none-eabi/4.8.2/armv6-m/
LIB_OP    =-L$(LIB_B) -lc -lg -L$(LIB_GCC) -lgcc
LINKOP   =-T link.ld

AFOBJ= \
    startup_stm32f0xx.o \
    user_io.o \
    main.o \
    phisic.o

$(LD) $(AFOBJ)  $(LINKOP) $(LIB_OP) -o $(PBIN)$(NAMEPROJ).elf


Вот скрипт линкера (самописный):
CODE
MEMORY
{
FLASH(RX) : ORIGIN = 0x08000000, LENGTH = 64K
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 8K
}

_Min_Heap_Size =1; /* required amount of heap */

SECTIONS
{
.isr_vector : ALIGN(4)
{
_start_isr_vector = .;
KEEP(*(.isr_vector))
_end_isr_vector = .;
. = 0xc8 - _end_isr_vector + ALIGN(2);
KEEP(*(.loop))
} > FLASH = 0xff

.text : ALIGN(4)
{
_start_text = .;
*(.text)
*(.text*)
KEEP(*(.data_flash))
_end_text = .;
} > FLASH

.rodata : ALIGN(4)
{
_start_rodata = .;
*(.rodata)
*(.rodata*)
_end_rodata = .;
} > RAM AT > FLASH

.data : ALIGN(4)
{
_start_data = .;
*(.data)
*(.data*)
_end_data = .;
} > RAM AT > FLASH

.bss : ALIGN(4)
{
_start_bss = .;
*(.bss)
*(.bss*)
_end_bss = .;
} > RAM

.heap :
{
. = ALIGN(4);
PROVIDE(end = .);
KEEP(*(.heap))

. = . + _Min_Heap_Size;
} > RAM
}

_size_rodata = SIZEOF(.rodata);
_size_data = SIZEOF(.data);
_size_bss = SIZEOF(.bss);

_start_rodata_copi = _end_text;
_start_data_copi = _end_text + _size_rodata;
_start_bss_copi = _end_text + _size_rodata + _size_data;


Сообщение отредактировал IgorKossak - Nov 27 2015, 08:42
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
Go to the top of the page
 
+Quote Post
slavokhire5
сообщение Nov 26 2015, 22:43
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 31-03-14
Из: Харьков
Пользователь №: 81 165



Вероятно проблемы с не выровнянным доступом. В f0 серии этого нельзя делать. Падает на инструкции загрузки полуслова. Если пытаетесь взять полуслово с не четного адреса, то это и есть ваша проблема)
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Nov 27 2015, 01:45
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Какое содержимое регистров r1, r10 и r2?
Go to the top of the page
 
+Quote Post
marka
сообщение Nov 27 2015, 08:20
Сообщение #4





Группа: Участник
Сообщений: 11
Регистрация: 26-11-15
Пользователь №: 89 481



Большое спасибо что откликнулись)

Цитата(slavokhire5 @ Nov 27 2015, 01:43) *
Вероятно проблемы с не выровнянным доступом. В f0 серии этого нельзя делать. Падает на инструкции загрузки полуслова. Если пытаетесь взять полуслово с не четного адреса, то это и есть ваша проблема)


Цитата(Tarbal @ Nov 27 2015, 04:45) *
Какое содержимое регистров r1, r10 и r2?



Да, вы правы. младший бит установлен. Подскажите как это исправить ? Может в скрипте линкера я не правильно применяю ALIGN(4) ?

Код
        862 [1]    in ../../../../../../newlib/libc/stdio/vfprintf.c
0x800392c  <+0x0034>        51 46        mov    r1, r10         // r1 = 0x80000c9 r10 = 0x80000c9
0x800392e  <+0x0036>        8a 89        ldrh    r2, [r1, #12]


Спасибо.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 27 2015, 09:50
Сообщение #5


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Стек должен быть выровнен на 8 байт. Проверьте это.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
marka
сообщение Nov 27 2015, 10:08
Сообщение #6





Группа: Участник
Сообщений: 11
Регистрация: 26-11-15
Пользователь №: 89 481



Цитата(AHTOXA @ Nov 27 2015, 13:50) *
Стек должен быть выровнен на 8 байт. Проверьте это.


Я только инициализирую указатель стека (0x20001FFF). Как еще можно его выровнять ?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 27 2015, 11:13
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(marka @ Nov 27 2015, 13:08) *
Я только инициализирую указатель стека (0x20001FFF).
Как давно 0x20001FFF стало кратным 8? Вам надо инициализировать числом 0x20002000


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
marka
сообщение Nov 27 2015, 16:24
Сообщение #8





Группа: Участник
Сообщений: 11
Регистрация: 26-11-15
Пользователь №: 89 481



Цитата(Сергей Борщ @ Nov 27 2015, 14:13) *
Как давно 0x20001FFF стало кратным 8? Вам надо инициализировать числом 0x20002000


Сделал. Не помогло.

Проверил отдельно загрузку полуслова... все работает.
В чем еще может быть дело ?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 27 2015, 17:40
Сообщение #9


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Осей никаких не используете?
Ну и покажите, наконец, код.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
marka
сообщение Nov 27 2015, 18:11
Сообщение #10





Группа: Участник
Сообщений: 11
Регистрация: 26-11-15
Пользователь №: 89 481



Цитата(AHTOXA @ Nov 27 2015, 20:40) *
Осей никаких не используете?
Ну и покажите, наконец, код.


Оси нет. Вот исходники ....Прикрепленный файл  f051r8_test_printf.rar ( 950.65 килобайт ) Кол-во скачиваний: 32


Уже все перепробовал sad.gif

Сейчас поставил затычку -lnosys для отладки. Если уходит в HardFault_Handler то зажигает светодиод.
Go to the top of the page
 
+Quote Post
marka
сообщение Nov 28 2015, 14:15
Сообщение #11





Группа: Участник
Сообщений: 11
Регистрация: 26-11-15
Пользователь №: 89 481



Цитата(marka @ Nov 27 2015, 21:11) *
Оси нет. Вот исходники ....Прикрепленный файл  f051r8_test_printf.rar ( 950.65 килобайт ) Кол-во скачиваний: 32


Уже все перепробовал sad.gif

Сейчас поставил затычку -lnosys для отладки. Если уходит в HardFault_Handler то зажигает светодиод.


Что подскажите ?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 28 2015, 17:00
Сообщение #12


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Да непонятно.
Куда у вас должен выводить текст printf? Откуда выделяется память для кучи?
Почему вы вручную указываете пути к библиотекам?
Что делает вот эта строчка в линкерном скрипте:
Код
        . = 0xc8 - _end_isr_vector + ALIGN(2);

?
Что-то странное вы наворотили с bss_init(), я не понял идеи. Очень вероятно, что вылетает не из printf, a отсюда:
Код
void bss_init()
{
    void *p = 0x00;
    while(p++ != pEndIN) *((uint8_t *)pStartIN++) = 0x00;
}


Советую вам взять какой-нибудь готовый пример, и допилить его под свои нужды. Например, тот, что я выкладывал здесь.

ЗЫ. Кстати, для вашего контроллера с 64К флеша и 8К ОЗУ gcc-шный printf - довольно жирное решение.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
marka
сообщение Nov 28 2015, 17:45
Сообщение #13





Группа: Участник
Сообщений: 11
Регистрация: 26-11-15
Пользователь №: 89 481



Цитата(AHTOXA @ Nov 28 2015, 20:00) *
Да непонятно.
Куда у вас должен выводить текст printf? Откуда выделяется память для кучи?
Почему вы вручную указываете пути к библиотекам?


Перед началом теста printf делал заглушки _write, _read и остальные (из вышей ссылки (находил раньше когда гуглил)) sm.gif
Но до них вызов даже не доходил, сразу падала уже... после вызова printf где то в глубине...
Ну а потом просто решил линковать -lnosys.

Да, malloc работает корректно с -lnosys Нужно было только end в скрипте линкера дописать.

Выделении памяти от end после bss

Код
    .heap :
    {
        . = ALIGN(4);
        PROVIDE(end = .);
        KEEP(*(.heap))
        . = . + _Min_Heap_Size;
        . = ALIGN(4);
    } > RAM


Цитата(AHTOXA @ Nov 28 2015, 20:00) *
Что делает вот эта строчка в линкерном скрипте:
Код
        . = 0xc8 - _end_isr_vector + ALIGN(2);

?


Да, это я эксперименты ставил sm.gif нужно убрать.

Цитата(AHTOXA @ Nov 28 2015, 20:00) *
Что-то странное вы наворотили с bss_init(), я не понял идеи. Очень вероятно, что вылетает не из printf, a отсюда:
Код
void bss_init()
{
    void *p = 0x00;
    while(p++ != pEndIN) *((uint8_t *)pStartIN++) = 0x00;
}


Ну тот просто заполнение нулями от pStartIN до заранее подсчитанного размера секции bss.

Это все работает отлично. Проблем нет. Не где не падает до применения printf. Как только вызываю printf то усе sm.gif упала.

Цитата(AHTOXA @ Nov 28 2015, 20:00) *
ЗЫ. Кстати, для вашего контроллера с 64К флеша и 8К ОЗУ gcc-шный printf - довольно жирное решение.


Да, возможно. Но это просто тест printf.
Go to the top of the page
 
+Quote Post
marka
сообщение Nov 28 2015, 21:32
Сообщение #14





Группа: Участник
Сообщений: 11
Регистрация: 26-11-15
Пользователь №: 89 481



Проблема решена sm.gif
А дело вот в чем было...
В скрипт линкера нужно было добавить секцию:
Код
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        . = ALIGN(8);
        __exidx_end = .;
    } > FLASH


Для чего она нужна... еще не знаю. Может вы знаете ?

И данные для копирования (инициализация секций rodata, data, bss) нужно уже брать с адреса __exidx_end.
Вот полный скрипт линкера:
CODE
MEMORY
{
FLASH(RX) : ORIGIN = 0x08000000, LENGTH = 64K
RAM(RWX) : ORIGIN = 0x20000000, LENGTH = 8K
}

__ram_end = 0x20000000 + 8K;

/*
.text — скомпилированный машинный код;
.rodata — аналог .data для неизменяемых данных;
.data — глобальные и статические переменные;
.bss — глобальные и статические переменные, которые при старте содержат нулевое значение.

.comment — информация о версии компилятора;
.ARM.attributes — ARM-специфичные атрибуты файла.
*/

_Min_Heap_Size =1; /* required amount of heap */

SECTIONS
{
.isr_vector :
{
. = ALIGN(4);
_start_isr_vector = .;
KEEP(*(.isr_vector))
_end_isr_vector = .;
. = ALIGN(4);
_start_loop = .;
KEEP(*(.loop))
. = ALIGN(4);
_end_loop = .;
} > FLASH = 0xff

.text :
{
. = ALIGN(4);
_start_text = .;
*(.text)
*(.text*)
. = ALIGN(4);
_start_data_flash = .;
KEEP(*(.data_flash))
. = ALIGN(8);
_end_data_flash = .;
_end_text = .;

} > FLASH

.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
. = ALIGN(8);
__exidx_end = .;
} > FLASH

.rodata :
{
. = ALIGN(4);
_start_rodata = .;
*(.rodata)
*(.rodata*)
. = ALIGN(4);
_end_rodata = .;
} > RAM AT > FLASH

.data :
{
. = ALIGN(4);
_start_data = .;
*(.data)
*(.data*)
. = ALIGN(4);
_end_data = .;
} > RAM AT > FLASH

.bss :
{
. = ALIGN(4);
_start_bss = .;
*(.bss)
*(.bss*)
. = ALIGN(4);
_end_bss = .;
} > RAM

.heap :
{
. = ALIGN(4);
_start_heap = .;
PROVIDE(end = .);
KEEP(*(.heap))
. = . + _Min_Heap_Size;
. = ALIGN(4);
_end_heap = .;
} > RAM
}

_size_rodata = SIZEOF(.rodata);
_size_data = SIZEOF(.data);
_size_bss = SIZEOF(.bss);

_start_rodata_copi = __exidx_end;
_start_data_copi = __exidx_end + _size_rodata;
_start_bss_copi = __exidx_end + _size_rodata + _size_data;


Теперь камушек не падает sm.gif

Сообщение отредактировал IgorKossak - Nov 29 2015, 18:28
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 28 2015, 22:00
Сообщение #15


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



.rodata класть в ОЗУ не нужно.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 07:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01496 секунд с 7
ELECTRONIX ©2004-2016