Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Флоаты в STM32F303

Пт фев 11, 2022 19:04:32

Не могу добиться работы: уходит в хардфолт.
make линкует так:
Код:
/opt/bin/arm-none-eabi-gcc -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -D __ARM_ARCH_7M__ -specs=nano.specs -L../inc/ld  -Tstm32f303xB.ld -Wl,-Map=mk/usart1.map,--cref -Wl,--gc-sections -Wl,--print-memory-usage mk/hardware.o mk/main.o mk/usart.o mk/startup.o  -o mk/usart1.elf

В sysreset() в самом начале вызывается
Код:
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));


Может, у меня что-то неправильное в опциях линкера?

Если убираю операции с флоатами - работает, как только добавляю - хардфолт еще до отправки тестового сообщения через USART!..

Добавлено after 29 minutes 2 seconds:
Вместо hard написал: -mfloat-abi=soft
и оно заработало.
Но нафиг мне softfloat, если там аппаратный есть? Все-таки, не пойму никак, как мне аппаратные флоаты на F303 организовать?

Re: Флоаты в STM32F303

Пт фев 11, 2022 19:51:43

Стек выровнен на 8?

Re: Флоаты в STM32F303

Пт фев 11, 2022 20:12:45

Откуда ж мне знать?
В ld-скрипте все секции выравнены на 4.

Сделал выравнивание начала и конца всех секций на 8. Не помогло.

softfp, кстати, тоже не работает.

Re: Флоаты в STM32F303

Пт фев 11, 2022 22:03:11

IDE и отладчик? Не, не слышали.

Добавлено after 7 minutes 3 seconds:
А можно узнать зачем применён оператор |= ? Ну мне так, чисто поржать.

Re: Флоаты в STM32F303

Пт фев 11, 2022 22:11:33

Ура! Нашел решение: в стартапе я в reset_handler готовлю данные, а потом сразу вызываю main(). А уже оттуда вызываю все настройки. И тут-то нежданчик: оказывается, gcc выталкивал на стек флоаты в main() еще до инициализации FPU. Перенес инициализацию в reset_handler - заработало.

Добавлено after 1 minute 29 seconds:
IDE и отладчик? Не, не слышали.

Я пользуюсь IDE, отвали в туман! А вот gdb я не осилил, хоть в qt-creator есть даже "встроенная поддержка" его (правда, нафиг, если удобней в консоли?).
Правда, не вижу вообще, чем бы мне в данной ситуации помог отладчик! Он бы мне сказал, что флоаты выкинуты в стек еще до инициализации FPU?
А можно узнать зачем применён оператор |= ? Ну мне так, чисто поржать.

"Все написали и я написал" ☺
Да, исправил на =.

Добавлено after 2 minutes 28 seconds:
В общем, обработчик прерывания сброса у меня теперь вот такой:
Код:
void WEAK __attribute__ ((naked)) __attribute__ ((noreturn)) reset_handler(void){
  extern char _sdata;    // .data section start
  extern char _edata;    // .data section end
  extern char _sbss;     // .bss  section start
  extern char _ebss;     // .bss  section end
  extern char _ldata;    // .data load address

  char *dst = &_sdata;
  char *src = &_ldata;

  // enable 8-byte stack alignment to comply with AAPCS
  SCB->CCR |= 0x00000200;

  // copy initialized variables data
  while ( dst < &_edata ) { *dst++ = *src++; }

  // clear uninitialized variables
  for ( dst = &_sbss; dst < &_ebss; dst++ ) { *dst = 0; }

  /* FPU settings ----------*/
  #if (__FPU_PRESENT == 1)
    SCB->CPACR = 0x0f << 20 ;  /* set CP10 and CP11 Full Access */
    nop();
    __DSB();
    __ISB();
  #endif

  // call main
  main();

  // halt
  for(;;) {}
}


Добавлено after 2 minutes 52 seconds:
Теперь надо расширить свои сниппеты на вывод числа с плавающей точкой.

Re: Флоаты в STM32F303

Сб фев 12, 2022 00:20:53

в стартапе я в reset_handler готовлю данные, а потом сразу вызываю main(). А уже оттуда вызываю все настройки.
Сколько прошло с того времени как ты на SystemInit() выступал? Ну так получай, фашист, гранату. Нормальные люди вызывают SystemInit(), инициализируют в нём периферию, затем инициализируют сегменты данных и только потом в main идут. Причём, компилятор это всё заинлайнит сам и вызовов не будет.

gcc выталкивал на стек флоаты в main() еще до инициализации FPU.
Имеет право, переменные создаёт.

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

А вот gdb я не осилил, хоть в qt-creator есть даже "встроенная поддержка" его (правда, нафиг, если удобней в консоли?).
Так удобно, что не освоил.

Правда, не вижу вообще, чем бы мне в данной ситуации помог отладчик! Он бы мне сказал, что флоаты выкинуты в стек еще до инициализации FPU?
Конечно показал бы. На раз два.

В общем, обработчик прерывания сброса у меня теперь вот такой:
Дичь какая-то...
Код:
SCB->CCR |= 0x00000200;
Если хотя бы краем глаза заглянуть в Cortex-M4F Programmming Mnual, то обнаружится, что значение по ресету там как раз 0x00000200. Да даже просто в отладчике это видно.

Код:
    SCB->CPACR = 0x0f << 20 ;  /* set CP10 and CP11 Full Access */
    nop();
    __DSB();
    __ISB();
Я знаю кунг-фу, карате, джиу-джитсу и ещё много страшных слов. Нафига последние три команды тут? Ты хоть представляешь что они делают?

Код:
  for(;;) {}
Ты из main возвращаться решил? Зачем тогда говорил, что noreturn?

Re: Флоаты в STM32F303

Сб фев 12, 2022 01:42:21

Нафига последние три команды тут? Ты хоть представляешь что они делают?

Везде пишут, что синхронизация нужна, а то мало ли что-то зафигачится в стек…

Добавлено after 1 minute 29 seconds:
А еще у F303 есть 8кБ "особой" оперативки. Надо посмотреть, как люди ею пользуются — вдруг пригодится… Хотя, конечно, заполнить 40кБ оперативы — постараться надо, разве что с экранными буферами работать.

Добавлено after 2 minutes 28 seconds:
Я и вывод флоата в строку уже написал!.. Можно пользоваться.
Упс, там малость мусора осталось…

Re: Флоаты в STM32F303

Сб фев 12, 2022 08:28:24

Везде пишут, что синхронизация нужна, а то мало ли что-то зафигачится в стек…
Что плохого, если что-то, как ты говоришь, "зафигачится" в стек? До разрешения доступа к FPU туда могло уже столько всего "зафигачиться"... Ты всего лишь должен гарантировать отсутствие доступа к FPU до его разрешения. Откуда такой доступ может взяться? Первое - длина конвейера. Ну, при его размере в Cortex-M4F об этом даже говорить смешно. Второе - шалости оптимизатора компилятора. Они тоже не безграничны. Перенеси команду перед инициализацией сегментов данных и периферии. Ни один оптимизатор не вырвется за поток доступа к volatile сущностям, содержащимся в этом коде.

А еще у F303 есть 8кБ "особой" оперативки. Надо посмотреть, как люди ею пользуются — вдруг пригодится…
Самое простое - стек туда. Похоже, ты впервые с разными банками памяти сталкиваешься? На будущее - они могут быть, вообще говоря, выключеными и/или несконфигурированными. Код инициализации сегментов данных или переноса стека должен быть после их включения. Вызов SystemInit() делают в самом начале. Да даже просто тупить в циклах инициализации памяти на 16 МГц с выключенными кэшами и предвыборкой flash - банальная трата времени.

Re: Флоаты в STM32F303

Сб фев 12, 2022 09:58:10

Откуда ж мне знать?
А кто у вас пишет программу? Не Вы? Спросите у того, кто её пишет.

В ld-скрипте все секции выравнены на 4.

Сделал выравнивание начала и конца всех секций на 8. Не помогло.
С тем же успехом можно было протереть экран монитора.... :facepalm:
Вопрос был не про "выравнивание секций", а про выровненность SP во всех функциях, где идёт работа с float.

Re: Флоаты в STM32F303

Сб фев 12, 2022 10:37:08

jcxz, стек по дефолту выровнен на 8. VladislavS мне на это выше указал. Так что, не умничай!

Добавлено after 1 minute 21 second:
Самое простое - стек туда.

Хорошая идея, надо повозиться с ld-скриптом.

Re: Флоаты в STM32F303

Сб фев 12, 2022 11:28:53

Я и вывод флоата в строку уже написал!.. Можно пользоваться.

Помню когда AVI-crak форматирование для float написал я с ходу две ошибки нашел, в частности 0 неправильно выводился, а у тебя с нулем просто виснет :)

Re: Флоаты в STM32F303

Сб фев 12, 2022 13:12:41

Reflector, черт! Спасибо, вот это я лоханулся…
FIX:
Код:
if(x > 0.) while(x < 1.){ ...


Добавлено after 1 hour 29 minutes 54 seconds:
Кстати, зачем выравнивать стек на 8 байт, если флоаты 4-байтные?

Re: Флоаты в STM32F303

Сб фев 12, 2022 14:12:38

Может всё таки стоит Cortex-M4 Programming maual почитать? Найти там 64-битные регистры и команды их загрузки-выгрузки?

PS: Но мне кажется, что они будут примерно как LDM STM работать, требуя выравнивания по 4 байта.
Последний раз редактировалось VladislavS Сб фев 12, 2022 14:46:20, всего редактировалось 1 раз.

Re: Флоаты в STM32F303

Сб фев 12, 2022 14:20:47

jcxz, стек по дефолту выровнен на 8.
И где этот "дефолт" задаётся? Что значит "стек по дефолту"? Расскажите нам. Думаю многим будет любопытно узнать. :)))

Добавлено after 1 minute 48 seconds:
вот это я лоханулся…
FIX:
Код:
if(x > 0.) while(x < 1.){ ...
И какое отношение это имеет к float? Где тут float-ы?
double - вижу, float - нет. :dont_know:

Re: Флоаты в STM32F303

Сб фев 12, 2022 14:33:51

Вообще, в Cortex-M4 в указателе стека младшие два бита всегда 0, так что, он автоматом на 4 байта выровнен.

Код:
if(x > 0.) while(x < 1.){ ...
И какое отношение это имеет к float? Где тут float-ы?
double - вижу, float - нет. :dont_know:
Тссс!!! Он сейчас найдёт в GCC -fsingle-precision-constant и скажет, что double только в анале видел :)

Если честно, то я сомневаюсь в необходимости выравнивания стека по 8 байт. Можете примеры с проблемой привести? Да и не знаю я такого механизма для локальных автоматических переменных.

Re: Флоаты в STM32F303

Сб фев 12, 2022 15:02:43

Вообще, в Cortex-M4 в указателе стека младшие два бита всегда 0, так что, он автоматом на 4 байта выровнен.
Выравнивание на 8 - это не 2 бита, а 3.

Если честно, то я сомневаюсь в необходимости выравнивания стека по 8 байт. Можете примеры с проблемой привести? Да и не знаю я такого механизма для локальных автоматических переменных.
Если сомневаетесь - сделайте невыровненным и попробуйте активно поработать.
Я точно не помню где именно причина (возможно - внутри _Printf()), но она точно есть. Достаточно полистать сообщения на многих форумах, например electronix-е. Многие наступали на эти грабли.

Re: Флоаты в STM32F303

Сб фев 12, 2022 15:20:16

Он сейчас найдёт в GCC -fsingle-precision-constant и скажет, что double только в анале видел :)

О, ты прямо за меня можешь говорить! Я действительно этот ключ использую. А как же без него?

Re: Флоаты в STM32F303

Сб фев 12, 2022 15:22:53

Например вот: https://electronix.ru/forum/index.php?a ... nt-1474218
Даже если в коде вообще нет использования float/double, но CPU имеет FPU, то выравнивание на 8 всё равно крайне рекомендуется. Так как иногда компилятор может проводить оптимизацию копирований некоторых объектов память->память с использованием регистров FPU. Молча их использует. Сталкивался с таким у IAR. Даже где-то на форумах описывал эту ситуацию (с приведением примера проекта). Насколько помню: IAR такое может проделывать при копировании структур (оператором присваивания) размером >=8 байт.

Re: Флоаты в STM32F303

Сб фев 12, 2022 17:09:07

Вообще, в Cortex-M4 в указателе стека младшие два бита всегда 0, так что, он автоматом на 4 байта выровнен.
Выравнивание на 8 - это не 2 бита, а 3.
Спасибо, КЭП :)

Если сомневаетесь - сделайте невыровненным и попробуйте активно поработать.
Что вы под этим понимаете? Ну расположил я стек где-то в памяти по адресу кратному хоть 1МБ, его top записал в SP и что дальше? Дальше он мне не принадлежит, им рулит компилятор.

Я точно не помню где именно причина (возможно - внутри _Printf()), но она точно есть.
Я честно попытался найти команды, которые бы вызывали проблемы с выравниванием 4 - не нашёл. На 2 знаю, на 4 нет. Если знаете такие, подскажите.

Достаточно полистать сообщения на многих форумах, например electronix-е. Многие наступали на эти грабли.
На форумах и не такое увидишь, достаточно эту тему перечитать с начала.

И ещё раз вопрос, как мне повлиять на это самое "выравнивание стека на 8"? Данные (по крайней мере статические) расположить в памяти я могу с выравниванием, сам стек (он по сути тоже данные) тоже могу. Стеки задач во всяких RTOS-ах тоже. А дальше, когда пойдут вызовы функций и прерываний, которые обрабатывает компилятор без моего участия? Если это действительно важно, то компилятор с ключом -mfloat-abi=hard должен сам это делать. Как ещё я могу повлиять на этот процесс?

Добавлено after 4 minutes 4 seconds:
Так как иногда компилятор может проводить оптимизацию копирований некоторых объектов память->память с использованием регистров FPU. Молча их использует.
Да и хрен бы с ним, пусть использует до тех пор пока это не RTOS без сохранения FPU при переключении задачи. Какая мне разница будет там в асме R0, S0 или D0?

Добавлено after 15 minutes 42 seconds:
А как же без него?
Как все нормальные люди. Писать код соответствующий стандарту, а не анально огораживаться ключами компилятора.

Re: Флоаты в STM32F303

Сб фев 12, 2022 17:13:46

Reflector писал(а):Помню когда AVI-crak форматирование для float написал я с ходу две ошибки нашел,

Хорошая память. Но я решил окончательно забить на "образцовый" выхлоп, в угоду упрощения и скорости.
Получилось как-то так: https://github.com/AVI-crak/Rtos_cortex ... r/sPrint.c
Время в тиках мк на преобразование чисел, без учёта физики.
Код:
216MGz
float = 351tik   +1280b          printf float = 5259tik  +8208b
double = 301tik  +1376b          printf double = 1570tik  +8208b
int64_t = 487tik +192b           printf int64_t = 3387tik  +8236b
int32_t = 150tik +140b           printf int32_t = 745tik  +8208b
all_format + 1684b

Сравнение с оптимизированным и значительно ускоренным вариантом printf https://github.com/mpaland/printf. Сравнивать с официальным вариантом из GCC - не очень корректно, там разница просто космическая получается.
Ответить