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

 
 
 
Reply to this topicStart new topic
> STM32F100 и проблемы с FPU, Не понятно как настроить FPU
Evgeniy Lipunov
сообщение Apr 24 2014, 04:36
Сообщение #1





Группа: Новичок
Сообщений: 5
Регистрация: 1-07-08
Из: Челябинск
Пользователь №: 38 668



Добрый день уважаемые форумчане.

Разбираюсь с STM32F100RB, а именно с STM32VLDISCOVERY. Воспользовался портом RTOS взятым тут: https://bitbucket.org/KilleRMill/stm32f107vc_freertos_gcc
Использую Eclipse. импортировал проект, к уарту прикрутил 1-wire DS18B20, попробовал сделать несколько задач, синхронизацию между ними - все шикарно, все работает как нужно.

Как только коснулся использования float, встал и не могу третий день сдвинуться с места.
К примеру, хотел сохранить полученное значение температуры следующим образом:
Код
float temp;
uint8_t scratchpad[9];
...
temp = *(int16_t*)(scratchpad) / 16.0;
...

вроде все просто и понятно. Но при заливке и попытке отладки, программа перестает работать.

однако, если сделать так
Код
float temp,tempmul=16.0;
uint8_t scratchpad[9];
...
temp = *(int16_t*)(scratchpad) / tempmul;
...


то все работает.
Странно, подумал я, и забил на некоторое время.
Дальше больше - выяснилось, что при попытке сравнить две переменные типа float я получаю практически идентичный эффект:
Код
float f1=2.0,f2=3.0;
...
if (f1>f2) vTaskDelay(100); // либо любое другое действие, не важно
...

просто вставив это в код программы, я получаю "кирпич".
На сколько я понял, иногда перестают работать прерывания (при этом в задачах freeRTOS'a жизнь вертится), иногда все встает непонятным образом.

Перепробовал кучу комбинаций -mfpu=XXXX -msoft-float -mfloat-abi=ХХХХ без видимого эффекта.

Для меня вообще не понятная проблема. Прошу помощи.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 24 2014, 05:28
Сообщение #2


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

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



У STM32F1xx нет FPU, поэтому все комбинации -mfpu=xxx -msoft-float -mfloat-abi=xxx не имеют смысла. Я никогда не указывал для m3 ничего кроме -mcpu=cortex-m3 -mthumb, и вся плавучка прекрасно работала. Скорее всего проблема в чём-то другом. Например, в размерах стеков.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
kan35
сообщение Apr 24 2014, 05:57
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Возможно, что проблема в стеке, его не хватке.
Go to the top of the page
 
+Quote Post
Evgeniy Lipunov
сообщение Apr 24 2014, 07:07
Сообщение #4





Группа: Новичок
Сообщений: 5
Регистрация: 1-07-08
Из: Челябинск
Пользователь №: 38 668



Проверил догадку про стек следующим образом:
Код
float flo1 = 3.2, flo2 = 2.3, flo3 = 2.22;

int main(void) {
  if (flo1>=flo2) flo3 = flo2 / flo1;
  vFreeRTOSInitAll();
  xTaskCreate( vTaskReadTemperature,
  ....
...


т.е. добавил сравнение/вычисление в самое начало программы еще ДО инициализации RTOS, результат тот же - прерывания не работают (конкретно говорю о прерываниях USART1/3_IRQ)
похоже дело не в стеке..

Забыл отметить, тулчайн GNU Tools for ARM Embedded Processors 4.8 (Отсюда)

Мейк тут:
Код
#
#       !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!!  
#
################################################################################
##############
#
# On command line:
#
# make all = Create project
#
# make clean = Clean project files.
#
# To rebuild project do "make clean" and "make all".
#
# Included originally in the yagarto projects. Original Author : Michael Fischer
# Modified to suit our purposes by Hussam Al-Hertani
# Use at your own risk!!!!!

# Define project name and Ram/Flash mode here
PROJECT        = STM32_FreeRTOS
RUN_FROM_FLASH = 1

################################################################################
##############
# Start of default section
#

TRGT = arm-none-eabi-
CC   = $(TRGT)gcc
CP   = $(TRGT)objcopy
AS   = $(TRGT)gcc -x assembler-with-cpp
HEX  = $(CP) -O ihex
BIN  = $(CP) -O binary -S
MCU  = cortex-m3
LINKERFILE = stm32f100rb.ld

# List all default C defines here, like -D_DEBUG=1
DDEFS = -DSTM32F10X_MD_VL -DUSE_STDPERIPH_DRIVER
# List all default ASM defines here, like -D_DEBUG=1
DADEFS =

# List all default directories to look for include files here
DINCDIR =

# List the default directory to look for the libraries here
DLIBDIR =

# List all default libraries here
DLIBS =

#
# End of default section
################################################################################
##############

################################################################################
##############
# Start of user section
#

# List all user C define here, like -D_DEBUG=1
UDEFS =

# Define ASM defines here
UADEFS =

# List C source files here
LIBSDIR    = .
CORELIBDIR = $(LIBSDIR)\CMSIS
STMSPDDIR    = $(LIBSDIR)\StdPeripheralDriver
STMSPSRCDDIR = $(STMSPDDIR)\src
STMSPINCDDIR = $(STMSPDDIR)\inc
FREERTOS = .\FreeRTOS
FREERTOSSRC = $(FREERTOS)\Source
FREERTOSSRCINC = $(FREERTOSSRC)\include
FREERTOSSRCPORT = $(FREERTOSSRC)\portable
OUTDIR = .\out
LINKER = .\linker
$(shell mkdir $(OUTDIR))

## Source Code
SRC  = .\src\main.c

#SRC += .\src\stm32f10x_it.c
SRC += $(CORELIBDIR)\system_stm32f10x.c
SRC += $(CORELIBDIR)\startup_stm32f10x_md_vl.c
## used parts of the STM-Library
SRC += $(STMSPSRCDDIR)\stm32f10x_rcc.c
SRC += $(STMSPSRCDDIR)\stm32f10x_gpio.c
SRC += $(STMSPSRCDDIR)\misc.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_adc.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_bkp.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_can.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_cec.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_crc.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_dac.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_dbgmcu.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_dma.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_exti.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_flash.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_fsmc.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_i2c.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_iwdg.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_pwr.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_rtc.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_sdio.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_spi.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_tim.c
SRC += $(STMSPSRCDDIR)\stm32f10x_usart.c
#SRC += $(STMSPSRCDDIR)\stm32f10x_wwdg.c
##FreeRTOS source files here
SRC += $(FREERTOSSRC)\list.c
SRC += $(FREERTOSSRC)\queue.c
SRC += $(FREERTOSSRC)\tasks.c
SRC += $(FREERTOSSRC)\timers.c
#SRC += $(FREERTOSSRCPORT)\heap_1.c
SRC += $(FREERTOSSRCPORT)\heap_2.c
SRC += $(FREERTOSSRCPORT)\port.c



# List ASM source files here
# ASRC = $(DEVDIR)\startup_stm32f10x_md_vl.S

# List all user directories here
UINCDIR = $(CORELIBDIR) \
          $(STMSPINCDDIR) \
          $(FREERTOS) \
          $(FREERTOSSRCINC) \
          $(FREERTOSSRCPORT) \
          .\inc    
# List the user directory to look for the libraries here
ULIBDIR =

# List all user libraries here
ULIBS =

# Define optimisation level here
OPT = -Os

#
# End of user defines
################################################################################
##############
#
# Define linker script file here
#
ifeq ($(RUN_FROM_FLASH), 0)
LDSCRIPT = $(LINKER)\$(LINKERFILE)
FULL_PRJ = $(OUTDIR)\$(PROJECT)_ram
else
LDSCRIPT = .\linker\$(LINKERFILE)
FULL_PRJ = $(OUTDIR)\$(PROJECT)_rom
endif

INCDIR  = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR))
LIBDIR  = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR))

ifeq ($(RUN_FROM_FLASH), 0)
DEFS    = $(DDEFS) $(UDEFS) -DRUN_FROM_FLASH=0 -DVECT_TAB_SRAM
else
DEFS    = $(DDEFS) $(UDEFS) -DRUN_FROM_FLASH=1
endif

ADEFS   = $(DADEFS) $(UADEFS)
OBJS  = $(ASRC:.S=.o) $(SRC:.c=.o)
LIBS    = $(DLIBS) $(ULIBS)
MCFLAGS = -mcpu=$(MCU)

ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -mthumb  -Wa,-amhls=$(<:.s=.lst) $(ADEFS)
CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb   -fomit-frame-pointer -Wall -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS)
#CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb   -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS)
LDFLAGS = $(MCFLAGS) -mthumb -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(FULL_PRJ).map,--cref,--no-warn-mismatch $(LIBDIR)

# Generate dependency information
CPFLAGS += -MD -MP -MF .dep\$(@F).d

#
# makefile rules
#

all: $(OBJS) $(FULL_PRJ).elf  $(FULL_PRJ).hex $(FULL_PRJ).bin
    $(TRGT)size $(FULL_PRJ).elf
#ifeq ($(RUN_FROM_FLASH), 0)
#    $(TRGT)size $(PROJECT)_ram.elf
#else
#    $(TRGT)size $(PROJECT)_rom.elf
#endif

%o: %c
    $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@

%o: %s
    $(AS) -c $(ASFLAGS) $< -o $@

%elf: $(OBJS)
    $(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $@

%hex: %elf
    $(HEX) $< $@
    
%bin: %elf
    $(BIN)  $< $@
    
clean:
    del $(OBJS)
    del $(FULL_PRJ).elf
    del $(FULL_PRJ).map
    del $(FULL_PRJ).hex
    del $(FULL_PRJ).bin
#    del $(SRC:.c=.c.bak)
    del $(SRC:.c=.lst)
#   del $(ASRC:.s=.s.bak)
#    del $(ASRC:.S=.lst)
    rmdir out /Q
    rmdir  .dep /S /Q
    
    
#
# Include the dependency files, should be the last of the makefile
#
#-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
#23-July-2012 /dev/null gives an error on Win 7 64-bit : Hussam
-include $(shell mkdir .dep) $(wildcard .dep/*)

# *** EOF ***


Сообщение отредактировал Evgeniy Lipunov - Apr 24 2014, 07:09
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 24 2014, 07:19
Сообщение #5


Гуру
******

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



А что там было с выравниванием стека на 8? Вроде бы как раз на плавающей точке и вылезало...


--------------------
На любой вопрос даю любой ответ
"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
Evgeniy Lipunov
сообщение Apr 24 2014, 08:27
Сообщение #6





Группа: Новичок
Сообщений: 5
Регистрация: 1-07-08
Из: Челябинск
Пользователь №: 38 668



Цитата(Сергей Борщ @ Apr 24 2014, 10:19) *
А что там было с выравниванием стека на 8? Вроде бы как раз на плавающей точке и вылезало...


в RTOS по умолчанию выравнивание по 8
portmacro.h
Код
...
/* Architecture specifics. */
#define portBYTE_ALIGNMENT            8
...


пробовал менять на 4 - ничего не меняется, при 2 и 1 вылетает в DefaultHandler

а вот как задать/узнать выравнивание при сборке, я увы не знаю...

или я не о том говорю?

Ставил брейки :
Код
if (flo1>=flo2) flo3 = flo2 / flo1;
080034a8:   ldr.w r8, [pc, #136]   ; 0x8003534 <main+144>
080034ac:   ldrd r4, r5, [r8]
080034b0:   ldrd r6, r7, [r8, #8]
080034b4:   mov r0, r4
080034b6:   mov r1, r5
080034b8:   mov r2, r6
080034ba:   mov r3, r7
080034bc:   bl 0x8003390 <__aeabi_dcmpge>
080034c0:   cbz r0, 0x80034d2 <main+46>
080034c2:   mov r0, r6
080034c4:   mov r1, r7
080034c6:   mov r2, r4
080034c8:   mov r3, r5
080034ca:   bl 0x80030d8 <__divdf3>
080034ce:   strd r0, r1, [r8, #16]
46         xTaskCreate(


в начале и в конце, стек-поинтер и там и там 0x2000041c <pulStack+976>, т.е. не изменяется. если убрать строку (в рабочем варианте) стек-поинтер = 0x2000042c <pulStack+992>

Сообщение отредактировал Evgeniy Lipunov - Apr 24 2014, 08:06
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 24 2014, 08:38
Сообщение #7


Гуру
******

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



Цитата(Evgeniy Lipunov @ Apr 24 2014, 11:27) *
0x2000041c <pulStack+976>
Этот адрес кратен 4 байтам, но не 8. Посмотрите в скрипте линкера (stm32f100rb.ld) резервирование памяти под стек, или покажите скрипт нам.


--------------------
На любой вопрос даю любой ответ
"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
Evgeniy Lipunov
сообщение Apr 24 2014, 08:47
Сообщение #8





Группа: Новичок
Сообщений: 5
Регистрация: 1-07-08
Из: Челябинск
Пользователь №: 38 668



Код
ENTRY(Reset_Handler)

MEMORY
{
  FLASH (rx)  : ORIGIN = 0x08000000, LENGTH = 128K
  RAM   (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
}

_estack = ORIGIN(RAM) + LENGTH(RAM);

MIN_HEAP_SIZE = 0;
MIN_STACK_SIZE = 256;

SECTIONS
{
  /* Interrupt vector table */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector))
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(4);
    /* Code */
    *(.text)
    *(.text*)
    /* Constants */
    *(.rodata)
    *(.rodata*)
    /* ARM->Thumb and Thumb->ARM glue code */
    *(.glue_7)
    *(.glue_7t)
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);
    _etext = .;
  } >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

  _sidata = .;

  /* Initialized data */
  .data : AT ( _sidata )
  {
    . = ALIGN(4);
    _sdata = .;   /* create a global symbol at data start */
    *(.data)
    *(.data*)

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

  /* Uninitialized data */
  . = 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

  /DISCARD/ :
  {
    libc.a(*)
    libm.a(*)
    libgcc.a(*)
  }
}


ALIGN(4)? =)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 24 2014, 09:33
Сообщение #9


Гуру
******

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



Цитата(Evgeniy Lipunov @ Apr 24 2014, 11:47) *
ALIGN(4)? =)

Ага
Код
    . = . + MIN_STACK_SIZE;
    . = ALIGN(4);
  } >RAM


Но я слабо помню, что за ошибка вылезала при невыравнивании на 8 и не уверен, что проблема в этом. Кстати, если кто-то напомнит суть проблемы с выравниванием на 8, буду благодарен


--------------------
На любой вопрос даю любой ответ
"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
shreck
сообщение Apr 24 2014, 09:48
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 327
Регистрация: 24-06-06
Из: Томск
Пользователь №: 18 328



Цитата(Сергей Борщ @ Apr 24 2014, 16:33) *
Но я слабо помню, что за ошибка вылезала при невыравнивании на 8 и не уверен, что проблема в этом. Кстати, если кто-то напомнит суть проблемы с выравниванием на 8, буду благодарен

printf при печати double глючит.
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Apr 24 2014, 09:56
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



В FreeRTOS если не ошибаюсь, стеки для задач выделялись через malloc, то есть в куче. Проверьте, используется ли у вас куча и выделена ли для неё память.
Go to the top of the page
 
+Quote Post
Evgeniy Lipunov
сообщение Apr 24 2014, 10:34
Сообщение #12





Группа: Новичок
Сообщений: 5
Регистрация: 1-07-08
Из: Челябинск
Пользователь №: 38 668



Цитата(andrewlekar @ Apr 24 2014, 12:56) *
В FreeRTOS если не ошибаюсь, стеки для задач выделялись через malloc, то есть в куче. Проверьте, используется ли у вас куча и выделена ли для неё память.


FreeRTOSConfig.h
Код
#define configMINIMAL_STACK_SIZE        ( ( unsigned short ) 64 )
#define configTOTAL_HEAP_SIZE            ( ( size_t ) ( 4 * 1024 ) )


heap_2.c
Код
/* Allocate the memory for the heap. */
static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];


Выделена. Используется heap_2 (там вроде были варианты, посмотрю в чем разница, попробую использовать другие менеджеры)

Проблема после изменения скрипта, к сожалению, не исчезла.

Попробовал ипользовать heap_1.c - никакой разницы, тот же эффект.

Вставлял
Код
if (flo1>=flo2) vTaskDelay(10);
после запуска шедулера (т.е. код никогда не будет выполнен) - тоже перестает работать. Ничего не понимаю...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th August 2025 - 22:24
Рейтинг@Mail.ru


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