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

How to assign initial values in code memory with specific location?

I want to define some values in code memory with specific location. For example

code unsigned char MyArray[] _at_ 0xF000 = {0x01, 0x02};


After that, I can use "MyArray[0]" and "MyArray[1]" to access the memory at 0xF000 and 0xF001.
How can I achieve this?

Parents
  • I know this kind of memory allocation. But I want to achieve this in C file. Is it possible?
    For example, I want to define an array in 2 dimension.
    MyArray[][2] =
    { {0xABCD, 0x01},
    {0x1234, 0x02},
    };
    In assembly, I have to do :
    DB 0xCD
    DB 0xAB
    DB 0x01
    DB 0x34
    DB 0x12
    DB 0x02

    The '0xABCD' is an index, if divided into 2 bytes, it will be very difficult to read for programmers.

Reply
  • I know this kind of memory allocation. But I want to achieve this in C file. Is it possible?
    For example, I want to define an array in 2 dimension.
    MyArray[][2] =
    { {0xABCD, 0x01},
    {0x1234, 0x02},
    };
    In assembly, I have to do :
    DB 0xCD
    DB 0xAB
    DB 0x01
    DB 0x34
    DB 0x12
    DB 0x02

    The '0xABCD' is an index, if divided into 2 bytes, it will be very difficult to read for programmers.

Children
  • I've never looked into doing this in C (for the C51), so I don't know if it is possible there.

    But, again, I have done a similar thing with structures in assembler.

    You could, for example, do something like:

    ;Within assembly file
    
             Public MyArray
    
             Cseg At 0F000h
    
    MyArray:
             Dw   0ABCDh,00001h
             Dw   01234h,00002h
    
    ;Within C file
    extern int code MyArray[][2];
    ...
      Val = MyArray[0][1];
    ...
    

    I think you have to be a bit careful in your description, because it now looks like what you are wanting is an array of structures; i.e., element 0 is an int, element 1 is a char etc.

    You can order the source in the assembler to make it more 'programmer friendly' and, so long as you have the C external declaration correct, you can access that data in any way you want.

  • In my case, the first element is 2-byte data and the second element is 1-byte data. So in C file, I have to use "unsigned char" to read the data and re-merge them to 2-byte data.
    Thanks for your fast reply. I've got a better way to program.

  • "I've got a better way to program."

    Please let us know what the way is - Most of us here are always ready to learn.

  • "Better way" means better than current programming style. i.e. {0xABCD, 0x01}.
    My current programming CSEG AT 0xF000
    ADDR_LBYTE: DB 0xCD
    ADDR_HBYTE: DB 0xAB
    DATA_BYTE: DB 0x01

    But now, I can re-write to : CSEG AT 0xF000
    ADDR_: DW 0xABCD
    DATA_BYTE: DB 0x01

    It's much friendly to programmers. I just need to change the parsing algorithm to reverse high-low byte order.

    I found some guys said KeilC does not support initial values in fixed allocation. If this is true, I think I've got the best way to program my firmware.

  • I've never looked into doing this in C (for the C51), so I don't know if it is possible there.

    It can be done in 'C', at least in the sense that no assembly language is required to achieve it. The defining declaration and initialisation needs to be placed in a separate source file and included in the project. The linker project options can then be modified to locate the resulting segment at the required address.

    If multiple objects are required at sequential addresses (as though they were contained in a structure) it is necessary to check the 'keep variables in order' box in the options for the source file or the entire project.

  • I understand.

    DW stores data of a word with the high byte first - I thought there was an equivalent to store the low byte first. Can't remember it though. Might even have been another assembler???

    Maybe someone else knows it - Or can correct me.

  • "The linker project options can then be modified to locate the resulting segment at the required address."

    Yes, I'd forgotten that option. I've done it that way a number of times before, but have nearly always ended up going back to my assembler 'comfort zone'!

  • If you want the data to be 'easy to read' in the source code, consider using macros.

  • "I found some guys said KeilC does not support initial values in fixed allocation."

    You don't need "some guys" to tell you that - Keil themselves clearly state it in their documentation:

    http://www.keil.com/support/man/docs/c51/c51_le_absvarloc.htm

    "If this is true"

    Yes, it does exactly what it says on the tin!

    "I think I've got the best way to program my firmware."

    Maybe not "best", but perfectly acceptable!