Loading ...
Sorry, an error occurred while loading the content.

GNUARM GCC 4.1.1 violates function pre-emption when optimization is not used.

Expand Messages
  • bogdan.kowalczyk
    Hello- This is a warning kind of post with an explanation and a work around proposal(sorry for making it a bit long :-)). When optimization is not used (often
    Message 1 of 1 , Jun 27, 2009
    View Source
    • 0 Attachment
      Hello-

      This is a warning kind of post with an explanation and a work around proposal(sorry for making it a bit long :-)).

      When optimization is not used (often the case when we just start development)GCC 4.1.1 compiler generates function prologue/epilogue
      which is not pre-emption safe that may cause hard to debug
      application crashes (for example uCOS-II GCC port crash during
      interrupt from time to time).

      When functions of type void Function(void) without local parameters
      are compiled below stack frame prologue/epilogue is generated (when
      optimization is not used):

      void Function(void)
      {
      @Function prologue
      5094: b580 push {r7, lr}
      5096: af02 add r7, sp, #8

      FUNCTION BODY...
      }
      @Function epilogue
      509e: 46bd mov sp, r7
      50a0: b082 sub sp, #8
      50a2: bc80 pop {r7}
      50a4: bc01 pop {r0}
      50a6: 4700 bx r0

      (for arm-elf-gcc -c -mthumb -mcpu=arm7tdmi-s -mthumb-interwork -O0,
      addresses shown only for further references)

      When an interrupt is generated at address 509e i.e. when mov sp,r7 is
      executed, and when application is written in that way that
      interrupted function context is preserved on the application's stack
      (task's stack)(very often the case in real time operating systems
      like for example in uCOS-II) just saved context overwrites r7 and lr
      pushed on the stack on function entry. Next after a return from
      interrupt wrong r7 and r0 values are popped on function epilogue
      (because they were overwritten) and return from the function with bx
      r0 instruction switches application to the wrong and not intended
      program address (and possibly to ARM processor instruction set).

      Following Dave Hawkins suggestions (thanks Dave) I have checked
      GNUARM GCC 3.4.3 and for the same case pre-emption safe code is
      generated (!) as shown below:

      void Function(void)
      {
      @Function prologue
      505c: b580 push {r7, lr}
      505e: 466f mov r7, sp

      FUNCTION BODY...

      }
      @Function epilogue
      5066: 46bd mov sp, r7
      5068: bc80 pop {r7}
      506a: bc01 pop {r0}
      506c: 4700 bx r0

      In GCC 3.4.3 there are not pre-emption unsafe stack instruction
      generated (no instruction add r7, sp, #8 on entry and no
      instruction sub sp, #8 on exit).

      In GCC 4.1.1 as a work around you can use -fomit-frame-pointer flag
      or optimization turned on (like –O1 flag which is also turning on
      –fomit-frame-pointer flag) this solves the problem making compiled
      functions pre-emption safe.

      Bogdan
    Your message has been successfully submitted and would be delivered to recipients shortly.