This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

XC800, IDATA not used

I'm running into the dreaded L107 (DATA space), so I checked all the .lst files and took a look at the largest one:

MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =   3806    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =   ----      89
   IDATA SIZE       =   ----    ----
   BIT SIZE         =      1       8
   EDATA SIZE       =   ----    ----
   HDATA SIZE       =   ----    ----
   XDATA CONST SIZE =   ----    ----
   FAR CONST SIZE   =   ----    ----
END OF MODULE INFORMATION.

What's extraordinary about this, is that all DATA variables summed up only come together to 30 bytes. There is however plenty of IDATA usage, which is apparently all accounted for as DATA usage.

I've tried moving some more variables from DATA to IDATA, leading the L107 to complain about just that much more DATA usage.

How do I make C51/LX51 acknowledge the existence of IDATA? As far as I can tell it should just work out of the box.

BTW, message preview claims I'm from the US, even though I selected Germany.

  • I tried some things:
    I manually placed an idata byte in the upper address range with the _at_ keyword. This worked in so far that the stack pointer was moved behind this byte. It didn't make the linker use the memory below that byte though.

    I also moved the stack with SEGMENTS (?STACK (0x20)), which was acknowledged by the linker as a gap in the DATA table:

    * * * * * * * * * * *   D A T A   M E M O R Y   * * * * * * * * * * * * *
    000000H   000007H   000008H   ---    AT..     DATA           "REG BANK 0"
    000008H   00000FH   000008H   ---    AT..     DATA           "REG BANK 1"
    000010H   000017H   000008H   ---    AT..     DATA           "REG BANK 2"
    000018H   00001EH   000007H   BYTE   UNIT     DATA           ?DT?_HSK_ICM7228_WRITESTRING?HSK_ICM7228
    ...
    000077H   00007BH   000005H   BYTE   UNIT     DATA           ?DT?_DISPLAY_WRITESTRING?MAIN
    00007CH   00007FH   000004H   BYTE   UNIT     DATA           ?DT?_HSK_CAN_FIFO_GETID?HSK_CAN
    000080H   00009FH   000020H   ---    ---      **GAP**
    0000A0H   0000A0H   000001H   BYTE   UNIT     IDATA          ?STACK
    

    Nonetheless, ?STACK is the only IDATA segment in that table, all other segments are BIT and DATA segments:

    linking...
    *** ERROR L107: ADDRESS SPACE OVERFLOW
        SPACE:   DATA
        SEGMENT: ?DT?_HSK_CAN_FIFO_SETRXMASK?HSK_CAN
        LENGTH:  000005H
    Program Size: data=134.0 xdata=240 const=147 code=14865
    Target not created
    

  • Remember that the bottom 128 bytes of IDATA is just a synonym for DATA...?

  • Not in terms of access time (at least on the XC800, DATA access is one machine cycle (2 clock cycles) and IDATA access is 2 machine cycles (4 clock cycles).

    Also, I want to use the upper 128 bytes. And data access to them is SFR access.

    Most of my variables are idata to give the linker the freedom to place them where needed. So why doesn't it? I can only use the upper 128 bytes as stack and when I manually assign an address.

  • Maybe the SDCC output for the same program can illustrate what I want:

    Internal RAM layout:
          0 1 2 3 4 5 6 7 8 9 A B C D E F
    0x00:|0|0|0|0|0|0|0|0|1|1|1|1|1|1|1|1|
    0x10:|2|2|2|2|2|2|2|2|a|a|a|a|a|a| | |
    0x20:|B|B|B|B|T|b|b|b|b|b|b|b|b|b|b|b|
    0x30:|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|
    0x40:|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|
    0x50:|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|
    0x60:|b|b|b|b|b|b|b|b|b|b|b|b|b|c|c|c|
    0x70:|c|c|d|d|d|Q|Q|Q|Q|Q|Q|Q|Q|Q|I|I|
    0x80:|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|
    0x90:|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|
    0xa0:|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|
    0xb0:|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|
    0xc0:|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|
    0xd0:|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|
    0xe0:|I|I|I|I|I|I|I|I|S|S|S|S|S|S|S|S|
    0xf0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
    0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack, A:Absolute
    

    In short, I want to use all of the internal RAM, there's not enough to spare half of it for a stack that grows to 18 bytes in the worst case.

  • This matter has been resolved with the Keil support.

    The issue is that C51 ignores explicit memory types in function parameters and always uses the primary type of memory depending on the memory model (i.e. data for small, pdata for compact and xdata for large).

    Whereas I have used the convention that parameters be passed in idata. Both compilers I use (SDCC and C51) pass parameters in registers when possible, but SDCC passes the remainder in the specified memory. I wrongly assumed that C51 behaves in a similar manner.

    To my defence, if this information is anywhere in the documentation, it must be really hard to find.