Menu

#2335 mcs51: Non-working code generated depending on link process

closed-rejected
nobody
None
MCS51
2
2015-02-06
2014-12-26
No

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/

How to reproduce the problem by code change:

  • unpack Messcontroller.tar.gz
  • enter Messcontroller/BIN-AKKUTESTER
  • run ./build

--> Now you get a working binary under Messcontroller/BIN-AKKUTESTER/bin/Main.bin

  • enter Messcontroller/HW-UMessMultikanal
  • uncomment UMessMC_init.c line 26
  • enter Messcontroller/BIN-AKKUTESTER
  • run ./build

--> 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 ?

  • unpack Messcontroller.tar.gz
  • enter Messcontroller/BIN-AKKUTESTER
  • run ./build

--> Now you get a working binary under Messcontroller/BIN-AKKUTESTER/bin/Main.bin

  • change Messcontroller/BIN-AKKUTESTER/build
    comment out section: # Link full application using libraries
    uncomment section: # Link full application using .rel files directly
  • run ./build

--> 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 ?

How my software is organized:

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.

1 Attachments

Discussion

  • Maarten Brock

    Maarten Brock - 2014-12-26

    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.

     
  • Matthias Krueger

    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:

    • a Stack issue: If stack size would be a problem the system would at least
      execute the first lines of main() before crashing later when reaching a deeper nesting level of function calls
    • a software bug: Also, at least the first lines of main() should be executed. All modules (libraries) have been tested with their respective TestGUIs

    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 ?

     
  • Erik Petrich

    Erik Petrich - 2014-12-29

    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.

     
  • Matthias Krueger

    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.

     
  • Ben Shi

    Ben Shi - 2015-01-18
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,4 +1,3 @@
    -
     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)
    
    • status: open --> closed-rejected
     

Log in to post a comment.

Auth0 Logo