I am using SDCC 3.4.0. on Linux
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.4.0 #8981 (Apr 5 2014) (Linux)
Target device: mcs51 (Intel 8051)
When compiling my project it randomly turns from working to not even passing the startup
code. It looks to me as a linkage issue: minor code changes or commenting/uncommenting
blocks of source code turns the behaviour from working fine to not even passing the startup code.
Also, if I change the build process from linking libraries generated with sdcclib to
directly linking .rel files it also turns from working to not working at all.
To me it seems similar to http://sourceforge.net/p/sdcc/bugs/2281/
--> Now you get a working binary under Messcontroller/BIN-AKKUTESTER/bin/Main.bin
--> Now you get a NON-WORKING binary at the same location as above.
Observed behaviour
After the change the system does not execute the startup code (Messcontroller/BIN-AKKUTESTER/Main.c line 53 is not even passed)
The size of the binary image changes from 18087 to 20612 byte with only one small function uncommented. Why ?
--> Now you get a working binary under Messcontroller/BIN-AKKUTESTER/bin/Main.bin
--> Now you get a NON-WORKING binary at the same location as above.
Observed behaviour
Startup code is not passed at all although no change to source code compared to the approach above which leads to working code(Messcontroller/BIN-AKKUTESTER/Main.c line 53 is not even passed)
Size of binary image changes from 18087 to 20609 with only the build process changed. Why ?
Each of the source code directories under Messcontroller/ contain source code that is compiled into a library. A local build script is included in each source code directory. The library gets stored in each source code´s bin directory.
All libraries get linked together in the Messcontroller/BIN-AKKUTESTER directory (local build script). The resulting binary gets stored to Messcontroller/BIN-AKKUTESTER/bin/Main.bin
Most library directories have a testGUI directory which contains a test executable using the library. All libraries have been compiled on their own and work when used with their respective testGUIs.
Some libraries are not implemented yet and contain only empty functions.
Compiling all of them together (BIN-AKKUTESTER) also results in working software but shows the described problem.
===================================================
Please help me fix that. The problem is about to turn some years of hardware and software development for a battery test system into scrap. Do not hesitate to contact me.
Attachment: Source code of the project.
Usually when adding a piece of code makes the MCU not reaching the start of main, it is the initialization of global and static variables taking too long for the watchdog timeout. Try kicking or disabling the watchdog in __sdcc_external_startup().
Also do a diff on the generated map file for the working and non-working versions to see what is using how many bytes. After that you can zoom in on specific generated asm files.
There is no on-chip watchdog present since it is a plain old Intel 8031 chip.
I did a diff of the map files. I did not find anything suspicious. But I am not an expert for this. I attached the .map files:
Working-linkedFromLibs.map (the working example)
NonWorking-linkedFromLibs.map (non-working after uncommenting UMessMC_init.c line 26 )
Working-linkedFromRelFiles-failed.map (same code base as Working-linkedFromLibs.map but linked from .rel files - software does not work)
What else can most likely be ruled out:
execute the first lines of main() before crashing later when reaching a deeper nesting level of function calls
What confuses me is that changing the linking method from sdcclib generated libraries to directly linking .rel files also breaks the software.
Next I will check the resulting binary. Any recommendation for a 8031 disassembler ?
The jump in the file size is because when UMessMC_HWInit() is needed all of the other functions and constants in the same file (HWControl.c) are included, even if they are not needed. If you do not use libraries, but instead link the .rel files directly, again everything in HWControl.rel is included.
Are you using a 27256 EPROM (or some flash equivalent) for the program? In the non-working versions, key functions such as putchar() have been linked to some address above 0x4000, which would fail if the memory device did not have an A14 pin. I have a more recent sdcc version installed (3.4.2 #9147) and can simulate the "not working" version up to the point that putchar() is attempting to output the "b" in from the printf("before initialize"). However, I can't think of any relevant linker bugs that have been corrected since the 3.4.0 release.
The problem is -solved-
Root cause: User error
It turned out that sdcc by default assumes 256 bytes of internal memory for MCS51. My controller (original Intel 8051) indeed only has 128 bytes of internal memory. So sdcc was continuing to allocate internal variables and eating up the stack space completely. Based on the wrong memory size assumption the --stack-size linker option did not create an error message.
I was able to fix the problem by changing from small to medium memory model and adjusting --iram-size accordingly.
Please reject the Bug.
Thank you for your support.
Diff: