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

24 bit address in 16 bit processor

Please do not say 'paging' I can not handle the overhead for all the other stuff that fit nicely within 64k.

I have a 2Mbyte flash that occasionally is accessed and the time here is not critical (the system pauses) as opposed to other processes that use only RAM.

Is there an elegant way to access structures in that 24 bit address space or does it have to be bent folded and mutilated to access?

Currently all addresses are specified with an 8 bit 'page' and a 16 bit 'address' and processed as such. I could gain some readability by having the whole in a long.

Also this method require data to be stored so no structure cross a page boundary and that limitation is a nuisance.

Erik

Parents
  • We are drifting off the subject here, I only need abt 40k of code and 64k of data.
    BUT rarely, I need to access a 2 megabyte DATA flash which contain structures and arrays uploaded from a PC program that generate them. This works fine once I have created pointers (page and offset) where the endianness is reversed EXCEPT when a struct/array cross a 64k boundary. Since the page/offset is a long (32 bits) the result should be ok, but the calculation of the address of an entity in a struct/array is 16 bit only and thus if the base of the struct/array is high in a page the offset to an entry in the struct/array may come out wrong because that entity is in the next page.

    example:
    U32 myarr[64];

    if myarr is located at address fff0 and I access
    myarr[8]
    the access will be to address 000010, not 10010

    Please note that the data is structures within structures within structures and arrays of structures etc, the example above is an extreme simplification.

    ALSO: because some control bits must be changed to access the flash, all accesses to that flash are done via
    U8 ReadFlash (U32 location);

    Erik

Reply
  • We are drifting off the subject here, I only need abt 40k of code and 64k of data.
    BUT rarely, I need to access a 2 megabyte DATA flash which contain structures and arrays uploaded from a PC program that generate them. This works fine once I have created pointers (page and offset) where the endianness is reversed EXCEPT when a struct/array cross a 64k boundary. Since the page/offset is a long (32 bits) the result should be ok, but the calculation of the address of an entity in a struct/array is 16 bit only and thus if the base of the struct/array is high in a page the offset to an entry in the struct/array may come out wrong because that entity is in the next page.

    example:
    U32 myarr[64];

    if myarr is located at address fff0 and I access
    myarr[8]
    the access will be to address 000010, not 10010

    Please note that the data is structures within structures within structures and arrays of structures etc, the example above is an extreme simplification.

    ALSO: because some control bits must be changed to access the flash, all accesses to that flash are done via
    U8 ReadFlash (U32 location);

    Erik

Children
  • We are aware of the 16-bit offset limitation. This is why the compiler does not let you define objects that cross a 64KB boundary.


    AppNote 160 shows ways to solve this problem.
    Take a look to: http://www.keil.com/appnotes/docs/apnt_160.asp. See "EXPAND VARIABLE SPACE".

  • I tried the AN160 suggestion, there is no difference. In the case of actually using a MX chip and CX51, this would be a gross error.

    C51  XMACtemq = (ReadPagedFlashC ((U32) (GPtsd + TSDflags), GC_TXI_pg) & OCU_TEXT_MASK);
    001E E500        E     MOV     A,GPtsd+01H
    0020 2401              ADD     A,#01H
    0022 FF                MOV     R7,A
    0023 E500        E     MOV     A,GPtsd
    0025 3400              ADDC    A,#00H
    0027 FE                MOV     R6,A
    0028 E4                CLR     A
    0029 FC                MOV     R4,A
    002A FD                MOV     R5,A
    002B AD00        E     MOV     R5,GC_TXI_pg
    002D 120000      E     LCALL   _ReadPagedFlashC
    
    C51  XMACtemq = (ReadPagedFlashC ((U16) (GPtsd + TSDflags), GC_TXI_pg) & OCU_TEXT_MASK);
    001E E500        E     MOV     A,GPtsd+01H
    0020 2401              ADD     A,#01H
    0022 FF                MOV     R7,A
    0023 E500        E     MOV     A,GPtsd
    0025 3400              ADDC    A,#00H
    0027 FE                MOV     R6,A
    0028 AD00        E     MOV     R5,GC_TXI_pg
    002A 120000      E     LCALL   _ReadPagedFlashC
    
    CX51  XMACtemq = (ReadPagedFlashC ((U16) (GPtsd + TSDflags), GC_TXI_pg) & OCU_TEXT_MASK);
    001E E500        E     MOV     A,GPtsd+01H
    0020 2401              ADD     A,#01H
    0022 FF                MOV     R7,A
    0023 E500        E     MOV     A,GPtsd
    0025 3400              ADDC    A,#00H
    0027 FE                MOV     R6,A
    0028 AD00        E     MOV     R5,GC_TXI_pg
    002A 120000      E     LCALL   _ReadPagedFlashC
    
    CX51  XMACtemq = (ReadPagedFlashC ((U32) (GPtsd + TSDflags), GC_TXI_pg) & OCU_TEXT_MASK);
    001E E500        E     MOV     A,GPtsd+01H
    0020 2401              ADD     A,#01H
    0022 FF                MOV     R7,A
    0023 E500        E     MOV     A,GPtsd
    0025 3400              ADDC    A,#00H
    0027 FE                MOV     R6,A
    0028 E4                CLR     A
    0029 FC                MOV     R4,A
    002A FD                MOV     R5,A
    002B AD00        E     MOV     R5,GC_TXI_pg
    002D 120000      E     LCALL   _ReadPagedFlashC
    

    Erik

  • Instead of:

    U32 address = &MyStruct.MyField;

    what about:

    U32 address = (U32)&MyStruct + offsetof(MyStruct, MyField)

  • fine, but when it is structure within array fo structures within a structure and so on it becomes very unreadable.

    Erik

    Anyhow, with CX51 it should work, bcause there you can address 8Mbyte linearily.

  • hi,
    I need to access a 2 megabyte DATA flash

    Erik, what is about usage serial flash? For example, Atmel DataFlash which is 3.0V device with SPI. For me, it helps to eliminate these 16-24bits problems.



    Regards,
    Oleg

  • Serial flash is fine for "data" but a pain in your largest muscle for structures within arrays within structures within structures within arrays.


    Anyhow, if using serial flash, the code for access of a given byte would become as unreadable as Drew Davis suggection (going 5 layers down - for a simple one entry in one structure as he show it is not too bad)

    Erik

    Regardless, the example I show above using CX51 would make a MX based program have exactly the problem I describe (and that would be a BUG).

    Erik