I'm trying to diagnose a problem. The problem is my program works fine if I place a printf (specifically printf) in the beginning of the program, and it doesn't if I don't. The issue is very specific to a loop that reads systick variable that I increment in systick_handler.
If I however compile with -fno-common then everything works. Why this behavior?
Also, I have removed .COMMON sections from my linker script because they make the program almost twice as large. Everything has been working well without them anyway, but I'm suspecting that their absence was somehow causing the infinite loop when I was compiling with default (-fcommon) flag. Still I see no reference to .COMMON section in my files. It must be just from libc.
Can anyone explain what is going on?
When you use -fno-common, uninitialized global variables are placed in the .bss section (oh, although the manual says data) by GCC. If you do not use that option, they are placed in a special section called COMMON.
If you omit this section from your linker script, the linker just puts it into RAM, possibly overlapping with other data. You can check it in the map file. I just tried it with my linker script and found that the content of COMMON was placed at the same memory area as the heap in my case. This means that global variables and anything allocated with, e.g., malloc will overwrite each other. Don't do that. Bad things will happen.
Regarding the safety of using -fno-common and ignoring COMMON: I assume that libraries can also contain COMMON. Even though your code does not contain this section because you use -fno-common doesn't mean that the linker doesn't need to handle it. Just add *(COMMON) next to your *(.bss) and you're safe. If the memory consumption is increased by this it has a good reason.
Further readings:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With