xinit sould not use port 2

2012-08-19
2013-03-12
  • Robert Richter
    Robert Richter
    2012-08-19

    The 8051 has too many derivatives that do not use P2 for accessing external memory (that's actually internal) that the default startup code of SDCC should be modified to avoid using port 2.  The way SDCC is currently set up, xdata initialization appears to work until the startup code exceeds 256 bytes and then someone's code will crash.  As it is, I wrote my own (which I can't share because it get's labelled as spam when I try).

     
  • Robert Richter
    Robert Richter
    2012-08-19

    Looking deeper, my particular processor (Silicon Labs C8051F410) can have XDATA set to 0xAA, I still think the default behavior should be to initialize without paging and juggling DPTR in and out of source and destination registers (only use one DPTR by default) .  The default should work on the most products with the least user interaction; not be the fastest and smallest.

     
  • Robert Richter
    Robert Richter
    2012-08-19

    That's XPAGE, not XDATA.

     
  • Maarten Brock
    Maarten Brock
    2012-08-20

    Well, this is documented in the manual and SDCC even comes with a special header file for the C8051F410 that already contains the required _XPAGE definition. All you need to do is include it with < > (instead of " ") around it.

    If we change it to always use DPTR only then others will complain, I'm sure.

    Some derivatives don't even have an _XPAGE equivalent, but luckily they all have multiple DPTRs.

     
  • Robert Richter
    Robert Richter
    2012-08-20

    I've sent an email to Silicon Labs telling them to add this to their header "compiler_defs.h".  I see you have include files, and I was using their files, but their own include file should have this in the header.

    Another nasty gotcha is the watchdog will fault during the startup memory copying.  Is there any way to force the following initialization for their product, but not have it used on other products?  The problem is headers can't include code.

    int _sdcc_external_startup(void) { // Allow initialization without faulting the watch-dog.
    PCA0MD &= ~0x40;
    return 0; // Zero tells SDCC's default initializer to run; 1 means to not run.
    }

     
  • Maarten Brock
    Maarten Brock
    2012-08-20

    SiLabs cannot add it to their compiler_defs.h because they have EMI0CN placed at different addresses in different derivatives. It must be in every C8051Fxxx.h.

    And it is not possible to automatically disable the watchdog for SiLabs devices. It would have been better if they had disabled at startup or set to the largest timeout instead of the shortest.

    I'm afraid this is all just part of the learning curve you have to climb. OTOH SiLabs does have an application note about using SDCC that covers many things. Some may be outdated though.

     
  • Robert Richter
    Robert Richter
    2012-08-20

    I think it could be done by including an external reference in the header file, and when the linker resolves the reference, the .area directive is used to place it in a product specific initializer.  The header file may need to use assembly for the external reference; I don't think C can do this without using a byte of RAM or code.  Have the default _sdcc_external_startup in one area that falls through to another area with product specific code linked in.

     
  • Robert Richter
    Robert Richter
    2012-08-20

    Ignore that last recommendation.  Anything non-standard should not be automatically done, as that makes it less portable.  If Silicon Labs processor cannot handle memory initialization without a watchdog fault and SDCC took care of that in a hidden manner, when the code is ported, it would result in the same nasty bug.  Better to let the disabling of the watchdog be plainly visible and explained in the source code.