Data pointers and code pointers

Technical Note 84583

Architectures:

AVR

Component:

compiler

Updated:

11/6/2015 12:47 PM

Introduction

This Technical Note discusses inconsistent use of a DATA pointer to point into CODE memory, (which the IAR AVR C/C++ compiler detects).

Discussion

The below source code...

void fun (void)
{
;
}
void *p = (void*)fun;
int main( void )
{
return 0;
}

...will give this error message:

Error[Pe028]: expression must have a constant value ...\main.c

Background to the message

The message is produced because the pointer "void *" is a DATA pointer. This pointer type is very different from a FUNCTION pointer which points into CODE memory. The reported error occurs when the data pointer is smaller than the code pointer. Using the option -mt the default data pointer is 8 bits and with the -ms the default data pointer is 16 bits.

Solution

  • The IAR AVR C/C++ compiler version 6.10 (and nwere) is able to detect these kinds of problems. The correct way of re-writing the source is:
  • void fun (void)
    {
    ;
    }
    typedef void (*f_p)(void);
    f_p p = fun;
  • To avoid the problem use the compiler options -v3 -ms or -v6 -mh to get the same size for the data pointer and the code pointer.
  • If using an xmega device, for example ATxmega128D4, that is an -v5 device use the options -v5 -ms but place the function in 'near memory' with the keyword __nearfunc.
    __nearfunc void fun (void)
    {
    ;
    }
    void *p = (void*)fun;
    or use the pragma type_attribute:
    #pragma type_attribute=__nearfunc

    void fun (void)
    {
    ;
    }

    void *p = (void*)fun;

 

All product names are trademarks or registered trademarks of their respective owners.

We do no longer support Internet Explorer. To get the best experience of iar.com, we recommend upgrading to a modern browser such as Chrome or Edge.