Author Topic: Gracefully recovering from HardFault on Cortex-M4  (Read 22565 times)

0 Members and 1 Guest are viewing this topic.

Online nctnico

  • Super Contributor
  • ***
  • Posts: 28612
  • Country: nl
    • NCT Developments
Re: Gracefully recovering from HardFault on Cortex-M4
« Reply #25 on: December 05, 2014, 12:57:16 am »
Alignment is a PITA. One of the biggest problems is casting a struct onto a pointer which is passed as a void or 8 bit type. There is no way the compiler can know whether the struct is aligned properly or not so it defaults to accessing it byte-by-byte and reconstructing larger types. That is a safe but slow way. You could force the compiler to assume a struct is properly aligned but if it isn't you'll get a fault. The root of the problem is sloppy pointer passing. Better fix that so the compiler can check alignment itself and you don't have to worry about it.

Long story short: Write your C software in a way so it doesn't matter how data is stored in memory.
« Last Edit: December 05, 2014, 01:14:32 am by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4232
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Gracefully recovering from HardFault on Cortex-M4
« Reply #26 on: December 05, 2014, 06:31:10 am »
Long story short: Write your C software in a way so it doesn't matter how data is stored in memory.
I do not agree with you. You have a specific embedded platform, so you can use some specific memory layouts.

Always make structs a multiple of the word size, this prevents the optimizer from mis-aligning the struct since it won't save space anymore. You'll lose some padding bytes, but you should have plenty. You wanted performance right?
And please don't do this:
uint8_t
uint32_t
uint8_t
You'll lose 6 bytes.

This _attribute_((aligned(4))) is a must when you're inserting SIMD assembler inlines. You might even want to use the register keyword before it. You might also want to align constants in flash too. It is usually 128 bit or something larger.
But that depends on the prefetching and caching configuration.
« Last Edit: December 05, 2014, 06:33:12 am by Jeroen3 »
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 28612
  • Country: nl
    • NCT Developments
Re: Gracefully recovering from HardFault on Cortex-M4
« Reply #27 on: December 05, 2014, 05:46:59 pm »
Long story short: Write your C software in a way so it doesn't matter how data is stored in memory.
I do not agree with you. You have a specific embedded platform, so you can use some specific memory layouts.
But don't complain if you shoot yourself in the foot  O0
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline jerry507

  • Regular Contributor
  • *
  • Posts: 247
Re: Gracefully recovering from HardFault on Cortex-M4
« Reply #28 on: December 05, 2014, 08:17:27 pm »
You should always be keeping alignment in mind. The only excuse is if you don't yet understand why alignment matters. You should only get to use that excuse once...
 

Offline megajocke

  • Regular Contributor
  • *
  • Posts: 191
  • Country: 00
Re: Gracefully recovering from HardFault on Cortex-M4
« Reply #29 on: December 05, 2014, 11:19:10 pm »
Alignment is a PITA. One of the biggest problems is casting a struct onto a pointer which is passed as a void or 8 bit type. There is no way the compiler can know whether the struct is aligned properly or not so it defaults to accessing it byte-by-byte and reconstructing larger types. That is a safe but slow way. You could force the compiler to assume a struct is properly aligned but if it isn't you'll get a fault. The root of the problem is sloppy pointer passing. Better fix that so the compiler can check alignment itself and you don't have to worry about it.

Long story short: Write your C software in a way so it doesn't matter how data is stored in memory.

I'm not sure I follow exactly what you mean here, but if you mean something like having a char array and accessing it as if it were a struct by casting to the struct pointer type, then that leads to undefined behavior according to the standard, at least in C99 and later.

See for example:

http://stackoverflow.com/questions/7630150/dereferencing-type-punned-pointer-will-break-strict-aliasing-rules

The compiler is within full rights to assume a structure is properly aligned and such.
 

Offline megajocke

  • Regular Contributor
  • *
  • Posts: 191
  • Country: 00
Re: Gracefully recovering from HardFault on Cortex-M4
« Reply #30 on: December 05, 2014, 11:30:00 pm »
Well,  I may be onto something,  although not necessarily connected to the mysterious hard faults caused by FFT. It seems that for some reason compiler will mess up structure alignment in memory. There are some instructions in CM4 that can do unaligned  (byte)  access,  but they are limited and slow.  When I tried to use arm_copy_q7 math function to copy structures (this function works just like memcpy,  but uses SIMD instructions) I was getting Usage Faults coming from unaligned access. Adding _attribute_((aligned(4))) to structure declaration fixes the issue. One could think that compiler will do stuff like that automatically...

Are you using the function to copy anything else than variables declared as q7_t then you can expect breakage, because this breaks the rules of the C language. Accessing anything as if it were something else is disallowed with just a few exceptions. The reason you can use memcpy and its friends is that one of the exceptions is for char types: any object can be accessed as chars.

There are some good explanations over here for example:

http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule

and in the link in my previous post.

Could it be that you are passing the FFT function some buffer which is of an unsuitable type? For example declared as char but accessed as ints or something? The char exception only applies for any object accessed as char, but not the other way around.
 

Offline Feynman

  • Regular Contributor
  • *
  • Posts: 201
  • Country: ch
Re: Gracefully recovering from HardFault on Cortex-M4
« Reply #31 on: December 07, 2014, 09:33:15 am »
Neither "divide by zero" or "bus error" counts as a "hard fault", although I guess it's easy for them to get escalated to hard faults if there is an error in the MemManage, BusFault, or UsageFault handlers.

The way I read the documentation, a "hard fault" is hardly ever the result of the primary error; it's the result of an error during attempts to handle some other error.  Make sure you have correct handlers installed and enabled for the other faults/interrupts, and you'll be closer to debugging the actual problem.

HardFault is the default fault. If a BusFault occurs, and the BusFault-Handler is not enabled, you get a HardFault. So first step would be, to setup and enable all Faul-Handlers the CPU supports.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf