2022-02-11

eddy_em: (Default)
2022-02-11 10:12 pm
Entry tags:

Не натыкайтесь на грабли при работе с флоатами в STM32!

Промучился два часа, пытаясь понять, почему у меня при попытке использования хардфлоатов на STM32F303 МК уходит в хардфолт. Оказалось, что проблема в том, что я в стартапе инициализирую переменные и тут же вызываю main(). А уже оттуда вызываю все настройки (и, собственно, разрешение работы FPU). А gcc тем временем, еще до вызова разрешения работы FPU, пытается запихать в стек флоаты из main()! Поэтому в стартапе следует изменить реакцию на прерывание сброса:
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(;;) {}
}