pic18f, question regarding data memory bank

Discussion in 'Embedded Systems and Microcontrollers' started by bug13, Feb 26, 2015.

  1. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Hi guys

    In the following codes, it says:
    What exactly does it mean? According to my count,the size of __CONNECTION_ENTRY is 14 bytes, how is that dividable by 256?

    Thanks guys!

    PS: the following code is part of demo code from Microchip MAL library, I can link in the full code if required.
    PS2: I am coming from AVR, but new in PIC

    Code (Text):
    1.    /***************************************************************************
    2.      * Peer Device Information in Connection Table
    3.      *
    4.      *      This structure contains device information about the peer device
    5.      *      of current node. It is the element structure for connection table.
    6.      *      Due to the bank limitation in PIC18 MCU architecture, the size of
    7.      *      CONNECTION_ENTRY must be dividable by 256 in case the array is across
    8.      *      the bank. In this case, the user need to make sure that there is no
    9.      *      problem
    10.      **************************************************************************/
    11.     typedef struct __CONNECTION_ENTRY
    12.     {
    13.         #if !defined(PROTOCOL_P2P)
    14.             API_UINT16_UNION    PANID;                            //2 bytes
    15.             API_UINT16_UNION    AltAddress;                      //2 bytes
    16.         #endif
    17.         uint8_t        Address[MY_ADDRESS_LENGTH];     // 8 bytes
    18.      
    19.         CONNECTION_STATUS status;                                //1 byte
    20.      
    21.         #if ADDITIONAL_NODE_ID_SIZE > 0
    22.             uint8_t        PeerInfo[ADDITIONAL_NODE_ID_SIZE];  // 1 byte
    23.         #endif
    24.     } CONNECTION_ENTRY;
     
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,388
    1,605
    __CONNECTION_ENTRY is just one element of the CONNECTION_ENTRY Table.

    How many 14 byte elements in the whole table?
     
  3. JohnInTX

    Moderator

    Jun 26, 2012
    2,346
    1,029
    They probably mean that the size of each element (struct in this case) is an integral factor of 256. The compiler tries to use direct addressing i.e. within the same RAM bank as a default for compact code. That means it doesn't want to span banks to access a variable. Structs and arrays can easily get big enough to make this a problem.

    If the compound type is a integral factor of 256, it can pack nicely into banks and the compiler can generate bank switching and direct addressing for each complete element without having part of one element in one bank and another part in another. If you imagine what the standard helper routines (that access elements of a struct for example) would look like, you can see why an individual element spanning banks would be a problem.

    The attached text file is from an old PICC-18 FAQ which describes the limitations of that compiler and the banked architecture that I found when I too ran into the dreaded 'cant find space for psect.. problem'.

    Good Luck.
     
    Last edited: Feb 26, 2015
  4. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Say an array of 127 connection:
    Code (Text):
    1. CONNECTION_ENTRY myConnection[127];
     
  5. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    A couple of questions:
    • What are bss and data psect?
    From what I can understand from the FAQ is, if I do these, the compiler will not compile:
    Code (Text):
    1. //can't do these
    2. uint8_t foo1[256];
    3. uint8_t foo2[1];
    but if I do these, it will be ok?
    Code (Text):
    1. //ok to do?
    2. uint8_t foo1[300];
    3. uint8_t foo2[1];
     
  6. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,388
    1,605
    AFAIK how large data segments are handles is compiler specific. I recall the C18 compiler needing assistance by manually editing the link script to set aside a large (>256) RAM block, then only being able to access it thru a pointer in the code.

    YMMV with other compilers.
     
  7. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Interesting, it doesn't seem to stop me doing anything like that. I declared the following 2 different variables and compile them separately. I have no error message.

    I am using XC8 - free mode, pic18f46j50

    Here are my 2 tests:

    Before my foo and foo2:
    Now add something greater that 256 bytes;
    Code (Text):
    1. uint8_t foo[256];
    2. uint8_t foo2;
    New add something even bigger.
    Code (Text):
    1. uint8_t foo[1024]
    2. uint8_t foo2;
     
  8. JohnInTX

    Moderator

    Jun 26, 2012
    2,346
    1,029
    Your two code segments allocate variables bigger that 256 bytes from the get-go compiling a source file yes? ..so the compiler puts them into a psect called bigbss which uses various extended addressing methods. The FAQs described the case when the first variable allocated was less than 256 bytes (an int for example) which started things out in bss which uses direct (banked) addressing. When this happens, if the total bytes needed by the variables in a single file >=256, direct addressing as generated by the compiler won't work and the link fails. The solution in the FAQs (and what I used) was to declare arrays of struct that needed >256 bytes first to force the compiler to use extended addressing then declare any small values from there - or split into several source files.

    I don't know if XC8 still has those issues. It may since XC8 derives from HiTech and presumably the new MAL libraries are recently written and still call out bank limitations.

    BTW: psect, bss from the HiTech manual (too lazy to type..)

     
    bug13 likes this.
Loading...