Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: HardFault на операциях с double
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
dimka76
Компилятор Sourcery G++ Lite 2010q1-188.

Ядро Cortex-M3.

При попытке выполнить операции с данными типа double контроллер вылетает в HardFault Exaption. Таже сама программа скомпилированая IAR работает нормально.

Ключи компиляции
Код
CFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES)
LDFLAGS = -Wl,--gc-sections,-Map=$@.map,-cref,-u,Reset_Handler -T link.ld


Подскажите в чем может быть причина возникновения исключительной ситуации?
klen
на вскидку приходит мысль только о том что линкер неправильную либу libgcc прикручивает... хотя без даблов то работает. попробуйте мою сборку, если эффект тотже будет - помогу найти косяг.
AHTOXA
У меня на прошлой сборке (arm-2009q1-161-arm-none-eabi) и на сборках от klen-a с плавучкой порядок, нормально работает.
arm-2010q1-188 скачал, но ещё не пробовал.
dimka76
Цитата(klen @ Sep 16 2010, 20:18) *
на вскидку приходит мысль только о том что линкер неправильную либу libgcc прикручивает... хотя без даблов то работает. попробуйте мою сборку, если эффект тотже будет - помогу найти косяг.


Попробовал с вашей, тоже вылетает в эксепшен.

Вот мой тестовый проектик.

Нажмите для просмотра прикрепленного файла


Цитата(AHTOXA @ Sep 16 2010, 21:02) *
У меня на прошлой сборке (arm-2009q1-161-arm-none-eabi) и на сборках от klen-a с плавучкой порядок, нормально работает.
arm-2010q1-188 скачал, но ещё не пробовал.


Можно примерчик какой-нибудь.
klen
а со стеком все впорядке,? плавющая запятая реализована програмно и функции могут требовать много стека.
dimka76
Цитата(klen @ Sep 18 2010, 18:45) *
а со стеком все впорядке,? плавющая запятая реализована програмно и функции могут требовать много стека.


Я вот тоже грешу на стек. Скачал LPCXpresso, она вроде как ориентирована на NXP. Скомпилил ей, и все заработало. Насколько я правильно понял (из makefile) там свои библиотеки используются.
У LPC1311, на котором я экспериментирую, мало ОЗУ, вот наверное и проблемы со стеком, хотя я почти всю ОЗУ под стек отдал.
klen
Цитата(dimka76 @ Sep 20 2010, 09:29) *
Я вот тоже грешу на стек. Скачал LPCXpresso, она вроде как ориентирована на NXP. Скомпилил ей, и все заработало. Насколько я правильно понял (из makefile) там свои библиотеки используются.
У LPC1311, на котором я экспериментирую, мало ОЗУ, вот наверное и проблемы со стеком, хотя я почти всю ОЗУ под стек отдал.


дайте исходник функции с Вашими вычислениями, я сажу какой глубины стек она дернет.
dimka76
Цитата(klen @ Sep 20 2010, 13:33) *
дайте исходник функции с Вашими вычислениями, я сажу какой глубины стек она дернет.


Я чуть выше выкладывал свой проектик, но могу и повторить
Код
int16_t calc_TC_temp( uint32_t from_adc )
{
    double  emf = 1.0;
    double  res = 0;
    int16_t  j;

    double  volt = (0.0005) * ((double)from_adc);

   for(j=0;j < 10;j++)
    {
        res += emf * koeff[j];
        emf *= volt;
    }
    return (int16_t)res;
}

_Pasha
Дима, в пылу предположений забыл спросить, нет ли какой-то бяки, связанной с плавучим умножением на нуль?
dimka76
Цитата(_Pasha @ Sep 20 2010, 20:20) *
Дима, в пылу предположений забыл спросить, нет ли какой-то бяки, связанной с плавучим умножением на нуль?


Exeption возникает уже на строчки
Код
double  volt = (0.0005) * ((double)from_adc);


А здесь нет умножения на ноль. В качестве аргумента функции я ноль не передавал.
IgorKossak
QUOTE (_Pasha @ Sep 20 2010, 19:20) *
Дима, в пылу предположений забыл спросить, нет ли какой-то бяки, связанной с плавучим умножением на нуль?

Результатом должен быть нуль безо всякого исключения.
klen
глубина стека потребная для вызова вашей функции - 20 байтов, прогнал на всех значениях для входного параметра, у меня все работает.

я уже думаю что у вас проблемы не с флотами а с иницализацией в crt коде
до кучи покажите ключи оптимизации, вдруг вы умудрились воткнуть ему аппраратную плавучку...
dimka76
Цитата(klen @ Sep 21 2010, 15:38) *
глубина стека потребная для вызова вашей функции - 20 байтов, прогнал на всех значениях для входного параметра, у меня все работает.

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



Код
OPTIMIZATION = -Os
CFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) -DSTM32F10X_MD
LDFLAGS = -Wl,--gc-sections,-Map=$@.map,-cref,-u,Reset_Handler -T STM32.ld

#-------------------------------------------------------------------------------
#        Rules
#-------------------------------------------------------------------------------

all: clean gccversion $(BIN) $(OBJ) flash

$(BIN) $(OBJ):
    mkdir $@

define RULES
C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))

$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
    $(CC) $(LDFLAGS) -o $(OUTPUT).elf $$^
    $(OBJCOPY) -O binary $(OUTPUT).elf $(OUTPUT).bin
    $(OBJDUMP) -h -z -S $(OUTPUT).elf > $(OUTPUT).lss
    $(SIZE) $$^ $(OUTPUT).elf

$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
    $(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<

$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
    $(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<


crt код это sturtup ?

Если да, то вот его фрагменты

Код
.............................
#define STACK_SIZE       0x00000100      /*!< Stack size (in Words)           */
__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];

...............................

__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) =
{
  /*----------Core Exceptions-------------------------------------------------*/
  (void *)&pulStack[STACK_SIZE-1],     /*!< The initial stack pointer         */
  Reset_Handler,                /*!< Reset Handler        

.................................................................

void Default_Reset_Handler(void)
{
  /* Initialize data and bss */
  unsigned long *pulSrc, *pulDest;

  /* Copy the data segment initializers from flash to SRAM */
  pulSrc = &_sidata;

  for(pulDest = &_sdata; pulDest < &_edata; )
  {
    *(pulDest++) = *(pulSrc++);
  }

  /* Zero fill the bss segment.  This is done with inline assembly since this
     will clear the value of pulDest if it is not kept in a register. */
  __asm("  ldr     r0, =_sbss\n"
        "  ldr     r1, =_ebss\n"
        "  mov     r2, #0\n"
        "  .thumb_func\n"
        "zero_loop:\n"
        "    cmp     r0, r1\n"
        "    it      lt\n"
        "    strlt   r2, [r0], #4\n"
        "    blt     zero_loop");

  /* Setup the microcontroller system. */
  SystemInit();  // Настройка PLL

  /* Call the application's entry point.*/
  main();
}


Вот как описана секция .co_stack

Код
/* stack section */
    .co_stack (NOLOAD):
    {
        . = ALIGN(8);
        *(.co_stack .co_stack.*)
    } > ram


klen
на первый взгляд нет косяков, ошибка видимо смешная и тривиальноая, поэтому хрег найдеш smile.gif
GetSmart
Разве под отладчиком нельзя найти место "сваливания"?
dimka76
Цитата(klen @ Sep 21 2010, 15:38) *
глубина стека потребная для вызова вашей функции - 20 байтов, прогнал на всех значениях для входного параметра, у меня все работает.


Вы на каком контроллере пробовали ? В железе или в симуляторе?


Цитата(GetSmart @ Sep 22 2010, 08:28) *
Разве под отладчиком нельзя найти место "сваливания"?


Нету у меня отладчика crying.gif

Да и как я писал выше, тот же проект собранный в IAR замечательно работает.
klen
Цитата(dimka76 @ Sep 22 2010, 08:30) *
Вы на каком контроллере пробовали ? В железе или в симуляторе?

проверял на stm32f103
от контроллера целевой код независит - ядро одно и библиотеки одни, разница только в инициализации микросхемы
dimka76
Цитата(klen @ Sep 22 2010, 14:03) *
проверял на stm32f103
от контроллера целевой код независит - ядро одно и библиотеки одни, разница только в инициализации микросхемы


А можно на ваш пример посмотреть?
Особенно интересуют startup, скрипт линкера и makefile.

можно на почту dimka76<собака>rambler.ru
dimka76
Удалось решить проблему.

Собрал свой проектик в Keil, настроил Keil на GCC компилятор. Скомпилировал и все заработало.
Посмотрел какие ключи компилятора и линкера генерит Keil.
Вставил их в свой makefile и порядок.

Вот исходный фрагмент моего makefile
Код
OPTIMIZATION = -Os
CFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) -DSTM32F10X_MD
LDFLAGS = -Wl,--gc-sections,-Map=$@.map,-cref,-u,Reset_Handler -T STM32.ld


а вот с исправлениями из Keil

Код
CFLAGS = -c -mcpu=cortex-m3 -mthumb -Wall -gdwarf-2 -Os -mapcs-frame
CFLAGS += $(INCLUDES)
CFLAGS += -Wall

LDFLAGS = -T link.ld -mcpu=cortex-m3 -mthumb -nostartfiles -Wl,-Map=.map -lm
_Pasha
Цитата(dimka76 @ Sep 24 2010, 13:56) *
Код
LDFLAGS = ... -nostartfiles... -lm

1.У Вас что, стартап собственный?
2. lm - линкует математику, при чем тут плавучка? smile3046.gif
dimka76
Цитата(_Pasha @ Sep 24 2010, 15:39) *
1.У Вас что, стартап собственный?
2. lm - линкует математику, при чем тут плавучка? smile3046.gif


Да, собственный StartUp.

А плавучка разве не математика.
Это целые для регистров могут быть использованы, а плавучка исключительно для математики.

Может тут еще сыграло роль указание для линкера -mcpu=cortex-m3 -mthumb

Я больше с ключами не игрался, заработало и хорошо )))
klen
-mcpu=cortex-m3 -mthumb

это никак не могло сыграть, во первых эти ключи одинаковые и там и там, во вторых если убрать -mthumb вы вообще кода не полуцчите - компиллер скажет что М3 не поддерживает арм32 интсрукции только тумб.


а вот -nostartfiles должен быть в обязательном порядке, для каждого ядра нада настраивать crt код индивидуельно, еще символы в скрипте линкера коррелируют этим кодом. а если подлинковать непонятно что в качестве crt кода - это то что лежит в пакете по умолчанию то получиш ЧТОТО. если не добавлять -nostartfiles то прилинкуется crt0.o вместо Вашего кода

както мы это незаметили. попробуйте убрать -nostartfiles, должно получится глюк как прежде. даю прогноз 56% smile.gif

PS: компиллер как обычно - не виноват
dimka76
Цитата(klen @ Sep 24 2010, 16:45) *
а вот -nostartfiles должен быть в обязательном порядке, для каждого ядра нада настраивать crt код индивидуельно, еще символы в скрипте линкера коррелируют этим кодом. а если подлинковать непонятно что в качестве crt кода - это то что лежит в пакете по умолчанию то получиш ЧТОТО. если не добавлять -nostartfiles то прилинкуется crt0.o вместо Вашего кода

както мы это незаметили. попробуйте убрать -nostartfiles, должно получится глюк как прежде. даю прогноз 56% smile.gif

PS: компиллер как обычно - не виноват


Возможно. Но до того как я добавил этот ключ и не использовал double все работало и прерывания и глубина вызовов была в несколько функций с аргументами, т.е. я хочу сказать, что стек не рушился. А как появились double, то начались Exaption.

Как нибудь еще попробую поиграться с -nostartfiles и -lm.
MrYuran
Цитата(dimka76 @ Sep 24 2010, 16:01) *
А плавучка разве не математика.
Это целые для регистров могут быть использованы, а плавучка исключительно для математики.

плавучка сама по себе, а математика - это синусы-логарифмы и дробные степени
dimka76
Поэкспериментировав с ключиками линкера выяснил, что определяющими являются ключи -mcpu=cortex-m3 -mthumb.
Без них на операциях с double попадает в HardFault.
klen
Цитата(dimka76 @ Sep 25 2010, 07:47) *
Поэкспериментировав с ключиками линкера выяснил, что определяющими являются ключи -mcpu=cortex-m3 -mthumb.
Без них на операциях с double попадает в HardFault.


бред какойто, я лично никакой прямой связи между выбором набора инстркций CPU и библиотечными функцийями арифметики не вижу. ошибка в другом. если вы скомпилируете код без -mcpu=cortex-m3 -mthumb то кортекс-м3 вы этот код вообще не можете использовать - он в вылетит в эксепшен потому что не сможет исполнить первую инструкцию не Tumb2. но я такой случай даже не расматривал - это тривиально: козлу капусту кормим а не телячие маслы для волка.
dimka76
Цитата(klen @ Sep 25 2010, 10:39) *
бред какойто, .....


Может и бред, но у меня так получилось.

Если вам интересно докопаться до истины, то можете взглянуть на мой изначальный проект, в котором у меня все кроме double работало и который я выкладывал здесь
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.