Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Подключение libc (из состава arm-kgp-eabi) на STM32
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
gba
Пытаюсь подключить стандартную библиотеку к проекту для STM32. Использую Eclipse + тулчейн от KGP.

Насколько я понимаю, линкер должен выдать мне десяток сообщений о том, что не найдены системные вызовы типа sbrk, read, write и т.д., но ничего подобного не происходит все компилится на ура. Однако при попытке вызова printf() проц вываливается в HardFault. Если я правильно понимаю это может происходить из-за проблем с адресацией(?). Т.е., например, указатель указывает на область данных?

Параметры компиляции:

Код
CROSS_COMPILE    = arm-kgp-eabi-
CC                = $(CROSS_COMPILE)gcc
LD                = $(CROSS_COMPILE)gcc
AR                = $(CROSS_COMPILE)ar
AS                = $(CROSS_COMPILE)as
CP                = $(CROSS_COMPILE)objcopy
OD                = $(CROSS_COMPILE)objdump
OPENOCD            = openocd

CCFLAGS    = -std=c99 -I./ -c -fno-common -O0 -g -mcpu=cortex-m3 -mthumb -DSTM32F10X_HD -DUSE_FULL_ASSERT -DUSE_STDPERIPH_DRIVER
ARFLAGS = -rcs
LDFLAGS    = -Tstm32_flash.ld -nostartfiles -nostdlib -L../lib
CPFLAGS    = -Obinary
ODFLAGS    = -S


В чем может быть косяк?

PS Могу выложить Makefile целиком, если необходимо
AHTOXA
Цитата(gba @ Feb 17 2011, 11:18) *
Могу выложить Makefile целиком, если необходимо

Выкладывайте конечно. И stm32_flash.ld тоже.
gba
Вот... Тот кусок, что в первом посте и есть options.mk, который подключается ниже

Код
include ../options.mk

# NOTICE:    reflash.cfg utilizes file main.bin,
#             thus when changing $BIN make corresponding changes in reflash.cfg  

# final binary (put it in the root directory)
BIN            = main.bin

# add library parts to be compiled
LIB_OPT        = misc.c
LIB_OPT        += stm32f10x_rcc.c
LIB_OPT        += stm32f10x_gpio.c
LIB_OPT        += stm32f10x_tim.c
LIB_OPT        += stm32f10x_usart.c
LIB_OPT        += stm32f10x_dma.c
LIB_OPT        += stm32f10x_spi.c

VPATH        = ../lib

#TARGET        = STM32F10X_HD

# sources and objects directories
SRC_DIR        = ./src
OBJ_DIR        = ./obj

# list of sources in SRC_DIR directory
SRC            = $(wildcard $(SRC_DIR)/*.c)
# remove directory part from the list of sources
SRC_PLAIN    = $(notdir $(SRC))

# list of objects in OBJ_DIR directory
OBJ            = $(patsubst %, $(OBJ_DIR)/%, $(SRC_PLAIN:.c=.o))

# main output file
MAIN_OUT    = $(patsubst %, $(OBJ_DIR)/%, $(patsubst %.bin, %.out, $(notdir $(BIN))))
# disassembly of the main output object
LIST_OUT    = $(MAIN_OUT:.out=.list)
# memory map file
MAP_OUT        = $(MAIN_OUT:.out=.map)

# include CMSIS library paths
CCFLAGS        += -I../lib/libcmsis -I../lib/libstdperiph/inc
# generate map file
LDFLAGS        += -Wl,-Map='$(MAP_OUT)',--cref,--gc-sections


all: $(BIN)

$(BIN): $(MAIN_OUT)
    @echo "--------------- copying ---------------"
    $(CP) $(CPFLAGS) $(MAIN_OUT) $(BIN)
    $(OD) $(ODFLAGS) $(MAIN_OUT) > $(LIST_OUT)
    
$(MAIN_OUT): $(OBJ) libs
    @echo "--------------- linking ---------------"
    $(LD) $(LDFLAGS) -o $(MAIN_OUT) $(OBJ) -lstdperiph -lc -lgcc
    
libs:
    @echo "--------------- making libraries ------"
    make all -C ../lib LIB_OPT='$(LIB_OPT)'
    
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
    @echo "--------------- compiling -------------"
    $(CC) $(CCFLAGS) -c $< -o $@
    
clean:
    @echo "--------------- cleaning --------------"
    make clean -C ../lib
    rm -f $(OBJ) $(MAIN_OUT) $(BIN) $(LIST_OUT) $(MAP_OUT)
    
reflash: $(BIN)
    @echo "--------------- programming flash -----"
    $(OPENOCD) -f armusbocd.cfg -f reflash.cfg


stm32_flash.ld
Код
/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = 0x20010000;    /* end of 64K RAM */

/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0;      /* required amount of heap  */
_Min_Stack_Size = 0x200; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 512K
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 64K
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH


   .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
    .ARM : {
    __exidx_start = .;
      *(.ARM.exidx*)
      __exidx_end = .;
    } >FLASH

  .ARM.attributes : { *(.ARM.attributes) } > FLASH

  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH
  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >FLASH
  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(.fini_array*))
    KEEP (*(SORT(.fini_array.*)))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >FLASH

  /* used by the startup to initialize data */
  _sidata = .;

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data : AT ( _sidata )
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM

  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM

  PROVIDE ( end = _ebss );
  PROVIDE ( _end = _ebss );

  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(4);
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(4);
  } >RAM

  /* MEMORY_bank1 section, code must be located here explicitly            */
  /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
  .memory_b1_text :
  {
    *(.mb1text)        /* .mb1text sections (code) */
    *(.mb1text*)       /* .mb1text* sections (code)  */
    *(.mb1rodata)      /* read-only data (constants) */
    *(.mb1rodata*)
  } >MEMORY_B1

  /* Remove debug information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }
}


Пробовал скрипт для линкера из соседней ветки, на который Вы дали ссылку, но один фиг... На всякий случай еще прикладываю .map файл. Похоже на то, что линкер находит реализацию системных вызовов в самой libc. Это так во всех тулчейнах или это особенность KGP?
AHTOXA
Хм. Странно. Вроде нормально всё. Я самые свежие kgp ещё не пробовал.
Вот, попробуйте вот этот проект собрать: Нажмите для просмотра прикрепленного файла
gba
Проект собирается, правда заливать не пробовал... Но в любом случае, в проекте вроде printf() не используется.

Попробовал добавить вызов printf() в main(), при сборке выдает следующее:

Код
--- compiling ./src/main.c...
--- linking...
e:/_distr/stm32/kgp_arm_eabi/bin/../lib/gcc/arm-kgp-eabi/4.6.0/../../../../arm-kgp-eabi/lib/thumb/cortex-m3\libc.a(lib_a-syscalls.o): In function `_sbrk':
/opt/home/arm-kgp-eabi/newlib/arm-kgp-eabi/thumb/cortex-m3/newlib/libc/sys/arm/../../../../../../../../../src/./newlib/newlib/libc/sys/arm/syscalls.c:506: undefined reference to `end'
collect2: ld returned 1 exit status
make.EXE: *** [exe/hello-stm32.elf] Error 1

Похоже системные вызовы откуда-то цепляются все-таки.
AHTOXA
Цитата(gba @ Feb 17 2011, 19:50) *
Проект собирается, правда заливать не пробовал... Но в любом случае, в проекте вроде printf() не используется.

Пардон, я не то вложилsm.gif Сейчас исправлюсь...
Цитата(gba @ Feb 17 2011, 19:50) *
Похоже системные вызовы откуда-то цепляются все-таки.

Попробуйте с Sourcery G++ Lite, может и правда что-то не то с этим свежим kgp. (Если так, то надо отписать в теме про kgp)

Вот, теперь точно с printf: Нажмите для просмотра прикрепленного файла
Проверил с Sourcery G++, работает.
gba
Да, с Code Sourcery эффект есть. Выкинул файл syscalls.c и получил то, что ждал от KGP:

Код
Ошибка в синтаксисе команды.
--- compiling ./src/main.c...
--- compiling ./src/rs1.c...
--- compiling ./src/base/startup.c...
--- compiling ./src/base/sysinit.c...
--- compiling ../lib/CMSIS/core_cm3.c...
--- compiling ../lib/CMSIS/system_stm32f10x.c...
--- linking...
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb2\libc.a(lib_a-sbrkr.o):
In function `_sbrk_r':
sbrkr.c:(.text+0x12): undefined reference to `_sbrk'
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb2\libc.a(lib_a-writer.o)
: In function `_write_r':
writer.c:(.text+0x16): undefined reference to `_write'
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb2\libc.a(lib_a-closer.o)
: In function `_close_r':
closer.c:(.text+0x12): undefined reference to `_close'
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb2\libc.a(lib_a-fstatr.o)
: In function `_fstat_r':
fstatr.c:(.text+0x14): undefined reference to `_fstat'
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb2\libc.a(lib_a-isattyr.o
): In function `_isatty_r':
isattyr.c:(.text+0x12): undefined reference to `_isatty'
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb2\libc.a(lib_a-lseekr.o)
: In function `_lseek_r':
lseekr.c:(.text+0x16): undefined reference to `_lseek'
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb2\libc.a(lib_a-readr.o):
In function `_read_r':
readr.c:(.text+0x16): undefined reference to `_read'
collect2: ld returned 1 exit status
make.EXE: *** [exe/hello-stm32-printf.elf] Error 1


Единственное, что выскочила какая-то "Ошибка в синтаксисе команды.", но на процесс вроде не повлияло.

Видимо что-то в сборке KGP действительно не так, сейчас отпишусь в теме.

Спасибо за помощь sm.gif
gba
Оказалось не все так радужно. При попытке вызова printf() проц все равно вываливается в HardFault. Скрипт для линкера тот же, что и выше, только добавлены указатели _heap и _eheap (использовал Ваш syscalls.c). Интересно то, что из main'а printf() вызывается по адресу 0x800db74, а когда вываливается в обработчик HardFault, то в регистре lr находится 0xfffffff9

Вот, что в дизассемблере
Код
283           printf("New DBGU initialized!\n");
08000e2c:   movw r0, #31864; 0x7c78
08000e30:   movt r0, #2049 ; 0x801
08000e34:   blx 0x800db74 <puts>


Забыл сказать - собираю при помощи Code Sourcery
timm
Слаб я в армах, но:
Цитата(gba @ Feb 17 2011, 10:36) *
Код
$(MAIN_OUT): $(OBJ) libs
    @echo "--------------- linking ---------------"
    $(LD) $(LDFLAGS) -o $(MAIN_OUT) $(OBJ) -lstdperiph -lc -lgcc

libc === -lc
Цитата
Код
LDFLAGS    = -Tstm32_flash.ld -nostartfiles -nostdlib -L../lib

Это не совсем то. Попоробуйте
СFLAGS+= -ffreestanding

И, конечно, sbrk, write и не относятся к libc.
AHTOXA
Цитата(gba @ Feb 24 2011, 15:44) *
При попытке вызова printf() проц все равно вываливается в HardFault.

А мой пример?
И ещё уточните - какой codesourcery? arm-none-eabi-?
gba
timm, честно говоря, не понял, что Вас смутило с libc...

Я хочу использовать libc и подключаю ее через параметр -lc, верно?

sbrk() - да, к libc напрямую не относится, но функции, которые сидят в libc, например, malloc() используют эту и остальные функции, насколько я понимаю

По поводу параметра -ffreestanding я ничего не понял - в доках написано, что он включает -fno-buitin, а еще он что-то делает или нет?

AHTOXA, Ваш пример наконец-то запустил через дебаггер. Как-то оно странно работает. Сначала я не мог поймать точку входа (она по дефолту либо с ноля, либо с начала .text, если ENTRY не используется?). В любом случае оно в Reset_Handler() не попадало... Поставил принудительно ENTRY(Reset_Handler) в скрипте линкера... Дальше оно начало падать на строке инициализации ctor'ов. Закоментил, т.к. С++ не использую, но теперь оно падает в самом начале копирования флеша в оперативу... То есть, где-то косяк при линковке?

Под "падает" я имею в виду, что вылетает в Default_Handler(), скорее всего HardFault срабатывает...

PS Компилирую с arm-none-eabi-
AHTOXA
Цитата(gba @ Feb 25 2011, 20:23) *
AHTOXA, Ваш пример наконец-то запустил через дебаггер.

А просто, без дебаггера, не пробовали? Это точно работающий пример, я его проверил в железе.
Цитата(gba @ Feb 25 2011, 20:23) *
вылетает в Default_Handler(), скорее всего HardFault срабатывает...

Чудеса, чесслово. То есть, вы ничего не меняли в моём примере, использовали приложенные к нему скрипт и makefile, и вылетает? Удивительно.
А попробуйте без printf - будет работать?
gba
Цитата(AHTOXA @ Feb 25 2011, 20:59) *
А просто, без дебаггера, не пробовали? Это точно работающий пример, я его проверил в железе.

Точно - он, гад.

Чудеса - это не то слово - каким-то образом подменяются даже указатели _sdata и _edata, соответственно никакая инициализация не проходит. Сначала в _edata вообще 0x0 было, потом включил обратно оптимизацию -O2, стало больше на правду похоже, но все равно _edata указывал чуть раньше чем реальный конец секции, а в _sdata вообще что-то не релевантное.

Как же тогда отлаживать? Или светодиоды и printf'ы?


Спасибо за очередную наводку. Попробую теперь разобраться со своим кодом.
AHTOXA
Я редко пользуюсь отладчиком, но когда пробовал, всё работало нормально. Запускалось, брякалось на main(), ходило по шагам, показывало переменные.
А вы плагин "Zylin Embedded CDT" -- поставили? А то без него в Helios почему-то перестала получаться отладка.

ЗЫ. К модераторам просьба - перенести тему в "GNU/OpenSource средства разработки для avr/arm/mips". Ибо тематика соответствует, и может ещё кто-нибудь что-то подскажет.
gba
Цитата(AHTOXA @ Feb 25 2011, 22:21) *
Я редко пользуюсь отладчиком, но когда пробовал, всё работало нормально. Запускалось, брякалось на main(), ходило по шагам, показывало переменные.
А вы плагин "Zylin Embedded CDT" -- поставили? А то без него в Helios почему-то перестала получаться отладка.

Странность в том, что у меня отладчик до этого работал, останавливался где надо и т.д., я поэтому на него и не думал... А вот с Вашим проектом почему-то не захотел работать нормально, вернее, он точно также работает, но вот память портится.

Плагин Zylin не пробовал, начинал с STM32 возится по статье klen'а, в ней предлагается использовать родной эклипсовский "GDB Hardware Debugging Plug-in" (правда его оказалось не легко найти в репозиториях, он где-то глубоко зарыт). Насколько я понимаю, он вобрал в себя части плагина "Zylin Embedded CDT".
KnightIgor
Цитата(gba @ Feb 17 2011, 07:18) *
Пытаюсь подключить стандартную библиотеку к проекту для STM32. Использую Eclipse + тулчейн от KGP.

Насколько я понимаю, линкер должен выдать мне десяток сообщений о том, что не найдены системные вызовы типа sbrk, read, write и т.д., но ничего подобного не происходит все компилится на ура. Однако при попытке вызова printf() проц вываливается в HardFault. Если я правильно понимаю это может происходить из-за проблем с адресацией(?). Т.е., например, указатель указывает на область данных?


А куда printf() будет выводить? Наверное, через UART. Но стандартные библиотеки не могут знать особенностей железа в смысле как отправить символ через железо процессора. Как это у Вас решено?
gba
Цитата(KnightIgor @ Feb 26 2011, 15:11) *
А куда printf() будет выводить? Наверное, через UART. Но стандартные библиотеки не могут знать особенностей железа в смысле как отправить символ через железо процессора. Как это у Вас решено?

А вот для этого как раз и необходима своя реализация системных вызовов (system calls) - sbrk(), write(), read() и т.д. Вообще говоря необходима реализация минимального набора системных вызовов, половина из которых может быть просто заглушками. Если же даже заглушек не будет, то при линковке линкер выдаст ошибки. В системный вызов write() можно запихнуть вызов функции, которая выводит символ через UART, а реализацию этой функции можно разместить в модуле программы, где происходит работа с железом.

Пример описанного выше давал AHTOXA здесь
KnightIgor
Цитата(gba @ Feb 26 2011, 14:51) *
А вот для этого как раз и необходима своя реализация системных вызовов (system calls) - sbrk(), write(), read() и т.д. Вообще говоря необходима реализация минимального набора системных вызовов, половина из которых может быть просто заглушками. Если же даже заглушек не будет, то при линковке линкер выдаст ошибки. В системный вызов write() можно запихнуть вызов функции, которая выводит символ через UART, а реализацию этой функции можно разместить в модуле программы, где происходит работа с железом.
Пример описанного выше давал AHTOXA здесь

Это все правильно. И Вы сделали соответствующую реализацию? Может быть в ней причина вылета в Hardware Fault?
gba
Цитата(KnightIgor @ Feb 26 2011, 18:06) *
Это все правильно. И Вы сделали соответствующую реализацию? Может быть в ней причина вылета в Hardware Fault?

Реализацию взял из работающего проекта, который выложил АНТОХА. При вызове printf() в моем проекте, проц сразу же вываливается в HardFault, в sbrk() вообще не заходит - пробовал и через дебаггер смотреть и светодиодом моргать без дебаггера. Сейчас пытаюсь вкурить как размотать стек, чтобы точно определить какая команда провоцирует HardFault. Пользуюсь методом, предложенным здесь. Но получаю какую-то ерунду:

Код
stacked_r0    0x2000085c    
stacked_r1    0x2000085c    
stacked_r2    0x20000864    
stacked_r3    0x20000864    
stacked_r12    0x2000086c    
stacked_lr    0x2000086c    
stacked_pc    0x20000874    
stacked_psr    0x20000874

Обработчик HardFault'а (взят по ссылке выше):

Код
void HardFault_Handler(){
    // start of user stack
    extern unsigned int _susrstack;

    unsigned int stacked_r0;
    unsigned int stacked_r1;
    unsigned int stacked_r2;
    unsigned int stacked_r3;
    unsigned int stacked_r12;
    unsigned int stacked_lr;
    unsigned int stacked_pc;
    unsigned int stacked_psr;
    u32* hardfault_args = (u32*) _susrstack;

    __asm(
    "TST LR, #4 \n"
    "ITE EQ \n"
    "MRSEQ R0, MSP \n"
    "MRSNE R0, PSP \n");

    stacked_r0 = ((unsigned long) hardfault_args[0]);
    stacked_r1 = ((unsigned long) hardfault_args[1]);
    stacked_r2 = ((unsigned long) hardfault_args[2]);
    stacked_r3 = ((unsigned long) hardfault_args[3]);

    stacked_r12 = ((unsigned long) hardfault_args[4]);
    stacked_lr = ((unsigned long) hardfault_args[5]);
    stacked_pc = ((unsigned long) hardfault_args[6]);
    stacked_psr = ((unsigned long) hardfault_args[7]);

    while(1){}
}

Из моих изменений здесь только указатель на стек. Может в этом и косяк?
AHTOXA
Вот за это я и не люблю отладчики. Они зачастую сбивают с мысли. При возникновении проблемы, человек с отладчиком, вместо того, чтобы сесть и подумать, в чём может быть проблема, сразу же лезет отлаживаться.
У вас есть работающий пример, сравните со своим, найдите отличия. Или возьмите его за основу и добавляйте что надо понемножку. Отладочная выдача там уже работает. А вы уже столько времени воюете с отладчиком.
Ну да ладно, это я так, поворчал простоsm.gif
Насчёт HardFault. Вот тут я постил рабочий пример, может поможет.
gba
Можно не любить калькулятор, но он тем не менее ускоряет работу sm.gif Честно говоря, я первый раз сталкиваюсь с таким глюкаловом при отладке. Хотя может это специфика отладки железок?

Спасибо за работающий обработчик HardFault. К сожалению он ясности не добавил, вот что в регистрах:
Код
        r0 = 0x08018238
        r1 = 0x000000FF
        r2 = 0x00000001
        r3 = 0x200008F0
        r12 = 0xFFEFFBFF
        lr = 0x08000829
        pc = 0x0800128C
        psr = 0x21000000

По адресу 0x0800128C вызов printf():
Код
287           printf("New DBGU enabled %d!\n", 0xff);
08001280:   movw r0, #33336; 0x8238
08001284:   movt r0, #2049 ; 0x801
08001288:   mov.w r1, #255 ; 0xff
0800128c:   blx 0x800e050 <printf>

Соответственно по адресу 0x0800e050 printf() и лежит:
Код
          printf:
0800e050:   push {r0, r1, r2, r3}
0800e054:   push {lr}              ; (str lr, [sp, #-4]!)
0800e058:   ldr r3, [pc, #44]      ; 0x800e08c <printf+60>
0800e05c:   sub sp, sp, #12
0800e060:   ldr r0, [r3]
0800e064:   add r12, sp, #20
0800e068:   ldr r1, [r0, #8]
0800e06c:   ldr r2, [sp, #16]
0800e070:   mov r3, r12
0800e074:   str r12, [sp, #4]
0800e078:   bl 0x800e1a4 <_vfprintf_r>
... ... ...

Принципиальных отличий с Вашим примером не смог пока найти... пробовал даже подсовывать в свой проект Ваши sysinit.c и syscalls.c толку ноль. Скрипт линкера тоже такой же. Единственное, что может еще отличаться это Standard Peripheral Library - я качал где-то месяц назад с сайта ST.
AHTOXA
Цитата(gba @ Feb 28 2011, 12:08) *
Можно не любить калькулятор, но он тем не менее ускоряет работу sm.gif

Посчитать 2+2 быстрее в умеsm.gif
Цитата(gba @ Feb 28 2011, 12:08) *
Код
0800128c:   blx 0x800e050 <printf>

Меня смутило blx. Насколько я понимаю, это вызов с переключением режима. Причём, поскольку операнд имеет сброшенный нулевой бит, то переключение в ARM-моде, которого в кортексах нет. Вот и HardFault... Вы случаем не потеряли ключик -mthumb или что-то типа того?
gba
Цитата(AHTOXA @ Feb 28 2011, 12:08) *
Меня смутило blx. Насколько я понимаю, это вызов с переключением режима. Причём, поскольку операнд имеет сброшенный нулевой бит, то переключение в ARM-моде, которого в кортексах нет. Вот и HardFault... Вы случаем не потеряли ключик -mthumb или что-то типа того?

Это фейл... Я думал архитектуру только компилятору надо указывать, а оказывается еще и линкеру. Спасибо в очередной раз!

PS Всегда всем говорил, что программить надо начинать с ассемблера, а сам до армового ассемблера так и не добрался
AHTOXA
Да ерунда всё это. Нормальный процесс начального вхождения. Дальше всё легче пойдёт.
ЗЫ. Ассемблер для АРМ я тоже не знаю, так, читаю со словарём sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.