This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Initializing a Variable with Part of Another Variables Address

I have very tight memory constraints with my ARM device.  (It is an M0 device, but I think that this question would apply to any ARM device.)  I have the need to create a table of addresses to variables.  I know because of my small amount of memory that there is a small address space – less than 16 bit.  So, I would like to save memory and only put the bottom 16 bits of the address in the table.  I am running into compiler problems though.

 

It basically boils down to getting some form of this to compile…

unsigned short x;

unsigned short y = (unsigned long)&x;

 

unsigned short x;

unsigned short y = (unsigned short)((unsigned long)&x);

 

unsigned short x;

unsigned short y = ((unsigned long)&x) & 0xFFFF;

 

Or is there another approach?

 

Thanks,

 

Bill Waters

_____________________

USB Power Delivery (PD)

Power Interface

Texas Instruments

  • First off, I do NOT recommend the technique described in this post for general use.  I think it will work in the narrow case described above.  Even then, because I have not tested it, I cannot be certain.

    I'll describe this technique by direct example.  Here is the contents of file.c

    short x;
    short y = (short)&x;

    Build it as follows ...

    % cl470 --display_error_number file.c
    "file.c", line 2: warning #770-D: conversion from pointer to smaller integer
    "file.c", line 2: error #70-D: integer conversion resulted in truncation
    1 error detected in the compilation of "file.c".

    >> Compilation failure

    I use --display_error_number both to show me the ID number of the diagnostics, but also whether those diagnostics are discretionary (indicated by the presence of -D).  I presume you are having problems with the second diagnostic.  Since it is discretionary, you can suppress it ...

    % cl470 --display_error_number --diag_suppress=70 file.c
    "file.c", line 2: warning #770-D: conversion from pointer to smaller integer

    I looked at the resulting assembly code.  It appears correct to me.  But I have not executed it to be sure.

    Hope this helps ...

    -George

  • Thanks!

    And now, what if we made this more difficult by saying that the 32-bit address is a function pointer?

    void func(void);

    unsigned short func_addr = (unsigned short)func;

    void func(void)
    {
    }

    I am not sure how to do this to begin with though...

    unsigned long func_addr = (unsigned long)func;

  • This might actually be the same as what was done in the case of the variable?

    And my problem now is how do I call this?

    unsigned short func_addr = (unsigned short)func;

    ( ( void ( * ) ( void ) ) func_addr )( );

    Or something like that?

  • unsigned short y = (unsigned short)((unsigned long)&x & 0xFFFF); // should work, perhaps with a non-fatal warning

    A PORTABLE APPROACH:

    struct context {

        int a;

        unsigned short x;

        /* ... all relevant variables ... */

    } ctx;

    Then your table can be initialized with the (short) offsets of each variable from the start of ctx.

    #define X(var) ((unsigned short)((char *)&ctx.var - (char *)&ctx))

    unsigned short table[] = { X(a), X(x), /* ... */ };

    To access the variable via the table:

    #define V(index,type) (*(type *)((char *)&ctx + table[index]))

    #define a V(0,int)

    #define x V(1,unsigned short)

    /* ... */

    a += x;  // add x to a

    /* etc. */

     

  • Thanks Douglas.  I'll give that a try...

  • George,

    Unfortunately with the Cortex-M0 compiler from Keil, the error that I get is not a -D error.  I get this...

    ..\SMBus\smbus_cmds.c(61): error:  #69: integer conversion resulted in truncation

    ...and there is no way to get around it.

    Does Code Composer Studio support the Cortex-M0?

    Thanks,

    Bill

  • The TI ARM compiler, starting with version 5.0.0, does support Cortex-M0.  The build switch is -mv6M0.  Note 5.0.0 is the version number of the compiler, and is not the version number of CCS.

    Thanks and regards,

    -George

  • Thanks.  Does the rest of the CCS functionality (debugger, etc) support the M0 as well?

  • Bill,

    The plan was to add M0 in our XDS products (in CCS) this year.  I don't see it in the 5.3 beta so I will check on the status.

    John

  • One other thing I need to know is which M0 device this is and specifically if it has JTAG.  The reason I need to know this is that I know that one of the analog M0 parts does not export JTAG and instead only supports Serial Wire Debug (SWD).  Currently our XDS emulators do not support SWD so that leaves us with the option of supporting it using JLink in CCS which we have been looking into.  Having a JTAG type header on the board doesn't necessarily mean that it supports JTAG, the Nuvation board for the M0 device we have has a 20pin ARM header but it only exports SWD over the pins, no clue why they put the 20pin header there as you do not need 20 pins for SWD.

    John

  • I think that you will find is that most of the M0-based devices are "small".  And that "small" applies to pin count as well.  And that means SWD instead of JTAG.  That is the case with our device.

    Thanks,

    Bill

  • Sorry, that should be...  I think WHAT you will find...

  • We will have M0 JTAG support in a month however SWD support isn't planned until next year.  Once we have the package that enables M0 support we can try to use that to enable JLink support for M0 in CCS so that you can use SWD.  We have a package that enables JLink for M3/M4/R4 today.

    John

  • Thanks for the update.

    Bill