The interrupt flag is not cleared automatically for this particular interrupt/uC. The RTC counter works fine, however, once an interrupt is issued, if the flag is not cleared at the end of the handler routine, upon returning from exception handling, the processor will see that the flag is raised and enter the same routine again, thus putting itself in one big while loop. One of my other observations is that this is not always the case - some flags are cleared automatically, whereas others you have to clear via software.
The difference isn't in the platfrom.
The difference is that CodeBlocks probably compiles to no optimisation at Debug setting, whereas many, if not most, embedded compilers - as configured out of the box - optimise away function calls that have no macroscopic effect.
If you go to debug mode you will see you can't put any breakpoints inside mySleep(). This is because the compiler decided to not include it in the limited code space of your processor, since inside it nothing happens.
That said, Atmel has Delay(), Delay_ms() and Delay_us() that use an ASM VOLATILE nop loop to get very close to guaranteed delays if the CPU speed is set correctly.
You can also include inline ASM code (google it if you want) as VOLATILE inside your loop, having it execute a single NOP instruction (NOP = No Operation = Do nothing). For ARM GCC, an online cookbook quotes:
asm volatile("mov r0, r0");
Volatile means "do not touch!" or otherwise "Do not optimise it away for me!".
I'm too lazy to check, but I believe ARM also has the NOP instruction.
You can also probably change the settings for optimisation, but that means your code will become huge very quickly if you're just starting out.
Best Answer
The default interrupt handlers are usually defined as weak symbols somewhere in the startup code.
This means that you can write your own function with exactly the same name and during link time it will "win" over a weak function (otherwise you would get a link error claiming duplicate symbol names).
Example for an STM32L432. This is a piece of the startup code you get from CubeMX (ST's project generation tool). Cut for clarity.
You don't need any assembly knowledge to understand it. The first thing is the
Default_Handler
routine. It is just an empty infinite loop.b Infinite_Loop
means jump (branch) to the place where the labelInfinite_Loop
is placed, just an infinite loop.Later on you have a definition of all handler symbols (+initial stack pointer), for example
ADC1_IRQHandler
(the interrupt that gets fired when ADC has done something).Next a weak linkage is provided that points every of the handlers to the
Default_Handler
. If you enable ADC interrupts and not provide your own handler the default handler will be executed (which means that your CPU will lock up in an infinite loop, I prefer to put a breakpoint instruction in the default handler because it is much more visible in a debugger, than just seeing the board frozen).To override the weak linkage you have to implement a function with the same name anywhere in your project. For example you can implement this function in main.c:
The linker will simply pick your function instead of the weak one.
Due to the nice design of Cortex-M you don't have to use special attributes for the handler function (like for example the
ISR()
macro for AVR cores), so the interrupt handler (from CPU point of view) is a function just like as every other.