-1

My application is split into several static libraries which are linked together.

One of the libraries is a PORT library which contains source code for interrupts handlers. The source code of isr.cpp below has the sys_tick_handler definition optimized out. Whenever the sys_tick interrupt occurs, the null_handler is called.

I have created a simple workaround to fix this, by declaring in isr.h some kind of dummy function. Then defining it in the isr.cpp file. I need to call this dummy function in my main. It helps, because after all, the sys_tick interrupts are invoking the handler from isr.cpp.

I'm not proud of it, it is just workaround as I said — so I'm looking for a real fix for this problem.

Here is the code of isr.cpp:

extern "C" {
    void sys_tick_handler(void) {
    }
}

Workaround isr.h:

void func();

Workaround isr.cpp:

void func() {} 
extern "C" {
    void sys_tick_handler(void) {
    }
}
James Risner
  • 5,451
  • 11
  • 25
  • 47
bielu000
  • 1,826
  • 3
  • 21
  • 45
  • how is it being optimized out? if there is an entry in the vector table for it the linker wont remove it. is there no reference to the label sys_tick_handler anywhere in the project/code? and or where it is reference is also removed because it is not used? – old_timer May 22 '20 at 21:16
  • start with, where is it being removed? what tool, what step? – old_timer May 22 '20 at 21:17
  • Highly unlikely. The linker **will not** remove a function willy-nilly. – SergeyA May 22 '20 at 21:24
  • How does the address of `sys_tick_handler` get associated with the interrupt? – 1201ProgramAlarm May 22 '20 at 21:51
  • If you suspect the compiler is 'optimizing out' some code that needs to run, and should not be ... review the volatile qualifier. "Every access (read or write operation, member function call, etc.) made through a glvalue expression of volatile-qualified type is treated as a visible side-effect for the purposes of optimizations." If you increment a counter in the code that is missing, marking the counter as volatile should prevent the optimization. – 2785528 May 23 '20 at 00:21
  • @2785528 no volatile needed. – 0___________ May 23 '20 at 10:58
  • The answers here are invalid, as OP found out it's not that it's optimized out but the compilation unit is excluded because all symbols (weak or not) are fulfilled. Here's a better answer https://stackoverflow.com/a/37191811/2500384 – jensnielsen Jan 19 '21 at 09:42

2 Answers2

0

Assuming that you have a vector table defined somewhere in your code, the interrupt hanler names must match those names.

For example if you use STM startup code your sys tick handler will have to be called SysTick_Handler. Just check your startup code and see what you have there.

g_pfnVectors:
  .word  _estack
  .word  Reset_Handler

  .word  NMI_Handler
  .word  HardFault_Handler
  .word  MemManage_Handler
  .word  BusFault_Handler
  .word  UsageFault_Handler
  .word  0
  .word  0
  .word  0
  .word  0
  .word  SVC_Handler
  .word  DebugMon_Handler
  .word  0
  .word  PendSV_Handler
  .word  SysTick_Handler

  /* External Interrupts */
  .word     WWDG_IRQHandler                   /* Window WatchDog              */                                        
  .word     PVD_IRQHandler                    /* PVD through EXTI Line detection */                        
  .word     TAMP_STAMP_IRQHandler             /* Tamper and TimeStamps through the EXTI line */            
  .word     RTC_WKUP_IRQHandler               /* RTC Wakeup through the EXTI line */                      
  .word     FLASH_IRQHandler                  /* FLASH                        */                                          

  /* ... */

if you define many handlers with no body(like yours) or the handlers will be identical, the compiler will leave only one definition optimizing out the duplicate code.

0___________
  • 60,014
  • 4
  • 34
  • 74
  • My handler has no empty body - it was just to demonstrate you the problem. The real problem is that my sys_tick handler is defined as #pragma weak sys_tick_handler = null_handler, so if there isn't any reference to any of function defined in translation unit where the appropriate sys_tick_handler is defined, the address of sys_tick_handler function remains unchanged. I found the simple solution to achieve what I need. I 've added the uint8_t variable named ISR_TAG to translation unit where the sys_tick_handler is defined, and I've passed the -u ISR_TAG option to the linker configuration. – bielu000 May 24 '20 at 18:24
  • Now, whenever sys_tick isr occurs the sys_tick_handler from my library is called instaed of null_handler. – bielu000 May 24 '20 at 18:24
0

This is an old question, but I've run into this exact behavior so thought I would contribute a possible explanation here. I built a project and for a while could not figure out why all of my ISR handlers were listed in the discarded section of the map file, everything from HardFault_Handler to USART3_IRQHandler, even though the function names matched the weak definitions in my startup.s. Reason was the linker section for the isr table defined in my linker.ld name was different from the section name used to place the vector table in the startup.s code... really dumb, but this is the result.

Physics
  • 11
  • 2