15.2.30 Ramfunc Function Attribute

The ramfunc attribute locates the attributed routine in RAM rather than in Flash memory on devices that normally execute code from Flash. This attribute can be used for both C functions and C++ class methods. The compiler's default runtime startup code uses the data-initialization template to copy the code associated with functions using this attribute from Flash to RAM at program startup.

When this attribute is used with C functions, the function is placed at the highest appropriately aligned address for executable code. Note that due to ramfunc alignment and placement requirements, the address attribute should not be used with the ramfunc attribute. The presence of the ramfunc section causes the linker to emit the symbols necessary for the crt0.S start-up code to initialize the bus matrix appropriately for executing code out of data memory.

Use this attribute along with the far/longcall attribute and the section attribute. For example:
  __attribute__((ramfunc,section(".ramfunc"),far,unique_section))
  unsigned int myramfunct (void)
    { /* code */ }
A macro in the <sys/attribs.h> header file makes the ramfunc attribute simple to use:
  #include <sys/attribs.h>
  __ramfunc__ unsigned int  myramfunct (void)
    { /* code */ }
In C++ code, the attribute can be used with class methods, as shown in the following example.
class printmyname {
    // Access specifier
public:
    // Data  Members
    string myname;
    int  dummy ;
    // Member Functions()
    printmyname (){
        myname = "microchip";
    }
    
    void  __attribute__((ramfunc, long_call)) set_name(string newname){
        myname = newname;
        dummy = 9;
    }
    void printname() { cout << "name is:" << myname; }
};
The MIPs JAL instruction only has an 28-bit addressing range. As a result, RAM might not be within range of calls made from code in Flash. To allow such calls, additionally use the long_call attribute with the definition of the function located in RAM when it must be called from functions in Flash. For example:
__attribute__((ramfunc, long_call))
unsigned int myramfunct(void)
{ /* code */ }
The <sys/attribs.h> header file provides a __longramfunc__ macro that will specify both the ramfunc and long_call attributes. For example:
#include <sys/attribs.h>
__longramfunc__ unsigned int myramfunct(void)
{ /* code */ }
If a function in Flash is called by a function located in RAM, the Flash-based function definition must include the long_call attribute.
__attribute__ ((long_call))
unsigned int myflashfunct(void)
{ /* code */ }

__attribute__((ramfunc))
unsigned int myramfunct(void)
{
        return myflashfunct();
}

Having functions located in RAM rather than Flash can increase code size as well as startup time, as the attributed functions must be copied from Flash to RAM at startup. It may also have an impact on runtime performance, depending on your target device. Verify that your application meets your startup timing constraints. Also verify that the increased runtime performance meets your application's timing requirements and that your application does not have hidden dependencies on timing that is negatively impacted by this design selection.