1

Context is: bare-metal development on STM32H753 (cortex M7) with arm-none-eabi-gcc

There is a compilation option __attribute((interrupt)) dedicated to IRQ handlers:

enter image description here

Doing some test, I confirmed the only difference is that the stack is aligned on 8 bytes (ie. the 3 least signficant bits of the stack pointer adress are zeroed before the function pushes on the stack).

What I don't understand is:

  • why is the stack alignement different in thread mode and in handler mode ?
  • why is this attribute not used in STMicro HAL and other sample code I've found ?
Guillaume Petitjean
  • 2,408
  • 1
  • 21
  • 47
  • 1
    I don't know if the answer to this question helps? [Stack alignment and ISR](https://stackoverflow.com/questions/70643854/stack-alignment-and-isr) – pmacfarlane Jun 08 '23 at 18:08
  • on ARMv7-M the interrupt type is ignored.... – old_timer Jun 09 '23 at 05:32
  • where is this quote from, note that something like this is specific to a compiler and not part of the language, so you have to be using a matching compiler. but again On ARMv7-M the interrupt type is igored. Also IRQ/FIQ etc are not related to cortex-m even the v6-m they are a thing of the pre armv7-a full sized cores. cortex-m you just make any old function an interrupt handler by design, read the arm docs. – old_timer Jun 09 '23 at 05:34
  • @old_timer indeed the interrupt type is ignored, it doesn't mean that the attribute is useless. It is obviously related to compiler, `__attribute__` is gcc syntax – Guillaume Petitjean Jun 09 '23 at 06:36
  • @pmacfarlane thank you, it indeed helped. So I misunderstood. The stack alignment is managed by hardware so there is nothing to do in software. It looks like the gcc alignment is useless for cortex M7-M ? Strange that gcc manual does not mention that. – Guillaume Petitjean Jun 09 '23 at 06:57
  • my comment is repeated in the approved answer. the attribute does not do anything. – old_timer Jun 09 '23 at 16:18

1 Answers1

4

In Cortex-M the "interrupt" attribute doesn't make any difference. Cortex-M is built in such a way that interrupt handlers are just regular C functions, and don't require any special function prologue/epilogue like some other architectures do. Therefore, you don't need to use this attribute at all, and HAL doesn't use it.

ARMv7-M recommends to keep stack 8-byte (2 word, 64-bit) aligned at all times, but it doesn't force it. If you push or pop just 1 word at a time, it will work perfectly ok. Nevertheless, such is the recommendation. So if you write a piece in assembly, it's considered a good practice to push/pop an even number of registers at a time, but it's not strictly forced, and to be honest I've never had a situation where it would matter in any way at all. Nothing in the docs actually prohibits it. As a pure speculation, it could be due to internal AHB bus being 64-bit wide, but I know too little about how it works down on that level.

When you're in thread mode, and an interrupt occurs, Cortex-M automatically stacks R0-R3, R12, LR, PC (of the next instr.) and xPSR without any instructions in the code to do so. Which is exactly why you don't need an "interrupt" attribute, and why Cortex-M interrupt handlers are basic C functions - the registers automatically stacked are basically the same as caller-saved registers in regular C-code thread. Except that stacking/unstacking happens automatically in hardware. So by the time you enter interrupt handler, you have all caller-saved registers already saved on stack, and if you were using dedicated thread stack pointer, then it will switch to main stack pointer in the interrupts. If at the moment of interrupt your thread (or other interrupt that will be interrupted) had stack 4-byte aligned and not 8, the automatic stacking mechanism will push one extra dummy register on stack, and it will be thrown out when unstacking. Again, no user action required.

Ilya
  • 992
  • 7
  • 14
  • crystal clear, thank you. – Guillaume Petitjean Jun 09 '23 at 11:23
  • 1
    Not exactly. You do not see the problems as STM32 parts except some old models have STKALIGN set to 4 bytes, which may cause issues. All newer ones have it set to 8, and it is automatically restored on the exception exit. So this attribute might have some role when using older STM32 parts. I personally was simply changing this FLAG in the reset handler when using those parts (many, many years ago). – 0___________ Jun 09 '23 at 22:45