Skip to main content
Kasapoglu.Orkun
Senior
November 9, 2017
Question

Float Assignment Causing HardFault

  • November 9, 2017
  • 1 reply
  • 2272 views
Posted on November 09, 2017 at 21:27

Hello. I am trying to control a step motor with a driver like m542 stepper driver. I can control the rotation speed and direction of the motor. I'm working with STM32F4-Discovery to get prototype done. Everything was good when I tried to add some distance control functions. So, the step motor is 200 pulse/rev and I need to control some small size distances and the timers have capabilities about that. I created a struct and it just has five elements one of them is float.

I want to calculate the pulse ratio between motor and driver and send pulses due to the range. But I cannot assign any value to that float ratio element of struct. The core goes hard fault handler when I want to simple assignment to that variable like as; `STRUCT.fVAR = (float)40.0;`. Here is my struct and code which is causing the fault;

typedef enum

{

  Z = 0,

  Y1 = 1,

  Y2 = 2

}MSMD_AxesEnum_t;

typedef struct

{

  __IO MSMD_DirectionEnum_t dir;

  __IO int speed;

  __IO float sensitivity;

  __IO uint32_t driverPPR;

  __IO uint32_t motorPPR;

}MSMD_TypeDef_t;

__IO MSMD_TypeDef_t  MSMD[3]; // Using 3 different motor

static __inline void MSMD_CalculateRatio(MSMD_AxesEnum_t axis)

{

  if ((MSMD[axis].motorPPR != 0) && (MSMD[axis].driverPPR != 0))

  {

    /*

    HardFault occurred first here but I didn't understand why then I added a simple assignment line before calling this function in init.

    */

    MSMD[axis].sensitivity = ((float)MSMD[axis].motorPPR / (float)MSMD[axis].driverPPR);

  }

}

int MSMD_Init(MSMD_AxesEnum_t axis)

{

  /**

  **  Timer and GPIO initializations. They are working well I added the problematic part after check all the functionalities

  **/

  MSMD[axis].driverPPR = 40000;

  MSMD[axis].motorPPR = 200;

  MSMD[axis].sensitivity = (float)40.0; // Then HardFault occurred in here again.

  MSMD_CalculateRatio(axis);

}

I'm using Keil MDK 5.24 Plus edition and STM32F4-Discovery_FW_V1.1.0. And I checked the Fault Reports then saw the hard fault was forced. I understand that it is forced by another disabled fault handler and the NOCP bit is set in the UsageFault section. I'm adding the Fault Report screen image.

I didn't see any unusual thing on the SFRs and/or SP, PC.

EDIT: When I comment just these lines everything works well.

Thanks.

#stm32f4 #float #hardfault
This topic has been closed for replies.

1 reply

Tesla DeLorean
Guru
November 9, 2017
Posted on November 09, 2017 at 21:53

Look at the instruction that is faulting. Look at a disassembly.

Make sure the FPU is enabled, code would frequently be in SystemInit() or in the Reset Handler

Make sure MSMD[axis].driverPPR is not ZERO, check for that before doing the division.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Kasapoglu.Orkun
Senior
November 9, 2017
Posted on November 09, 2017 at 22:20

Thanks

Turvey.Clive.002

‌ I'm checking the divider MSMD[axis].driverPPR before calculating. This is a compiler problem that I've seen. I didn't see any necessity about FPU enabling in SystemInit() or in the Reset Handler because I cannot assign simple constant assignment to a fload/double/long double variable and The Floating Point Hardware is selected as Single Precision in the Code Generation section of the Flash/Configure Flash Tools/Target menu. The weird thing is assignment line so I tried to check another settings in the project. I've looked the Target menu then saw the ARM compiler is selected defaultly

Use default compiler version 5 then changed it to

v5.06 update 5 (build 528) in Code Generation section. Now the code is working fine. There is no Hard Fault and the values are correct in calculation. This is a Keil issue I think. Or as you said the compiler that is used now is handling the FPU things itself. I'll try. Thanks again for quick reply.

Tesla DeLorean
Guru
November 10, 2017
Posted on November 10, 2017 at 01:06

>>

This is a Keil issue I think.

Well it should be easy enough to see exactly what the CPU is complaining about, then you'd know.

If the compiler uses FPU instructions your startup code must enable it, doesn't happen by itself. Different compilers might use push/pop s0/d0 register, or constants might be loaded into the FPU, others just use ARM registers.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..