In an embedded environment, for example, I declared a look开发者_如何转开发-up table in following way:
const Operation Vehicle_OpNotification[] =
{
{ OP_SET , &Vehicle_Notification_Set},
{ OP_GET , &Vehicle_Notification_Get}
};
May I know this function pointer is pointing to RAM address or ROM address?
That depends on your compiler and target environment, but most likely it points to ROM—executable code is almost always placed in read-only memory when available. You have to take special steps (like using a custom linker script or allocating dynamic memory and asking the operating system to mark it as writable and executable) to get executable code in non-read-only memory.
The linker should be able to generate a map-file where the location of each variable/constant defined at file-scope is shown. Example:
main.c:
static const int constant = 42;
static int volatile variable = 43;
int main (int argc, const char * argv[]) {
variable = constant;
return 0;
}
Generated map-file: (notice how the constant constant
is placed in the same memory segment as the read-only code (TEXT
), while the variable variable
is placed in the DATA
section)
# Sections:
# Address Size Segment Section
0x00001F6C 0x0000008F __TEXT __text
0x00001FFC 0x00000004 __TEXT __literal4
0x00002000 0x00000018 __DATA __data
0x00002018 0x0000001C __DATA __dyld
0x00003000 0x00000008 __IMPORT __pointers
0x00003040 0x00000005 __IMPORT __jump_table
# Symbols:
# Address Size File Name
0x00001F6C 0x00000040 [ 1] start
0x00001FAC 0x00000014 [ 1] dyld_stub_binding_helper
0x00001FC0 0x0000000E [ 1] __dyld_func_lookup
0x00001FCE 0x0000002D [ 2] _main
0x00001FFC 0x00000004 [ 2] _constant
0x00002000 0x00000004 [ 1] ___progname
0x00002004 0x00000004 [ 1] _environ
0x00002008 0x00000004 [ 1] _NXArgv
0x0000200C 0x00000008 [ 1] _NXArgc
0x00002014 0x00000004 [ 2] _variable
0x00002018 0x0000001C [ 1] __dyld@0
0x00003000 0x00000004 [ 2] _variable$non_lazy_ptr
0x00003004 0x00000004 [ 2] _constant$non_lazy_ptr
0x00003040 0x00000005 [ 0] _exit$stub
Its address will be entirely dependent on the location of the function pointed to; the linker will tell you that. Most often application code ie either all in RAM or all in ROM, though for some targets, it may be split for performance reasons if RAM execution is faster as it typically is on processors faster than around 100MHz.
If you need to determine this at runtime (if for example it may be either, and is dynamic), you can simply compare the address with the start and end of the relevant memory sections. These addresses may be emitted as symbols by the linker given an appropriate linker script, or they may be defined constants in a target header file or BSP for example.
All that said, I can think of few reasons you should need to know at run-time (unless you are considering self modifying code!).
This is dependent on architecture.
However, if you have some idea of the address ranges for ROM and RAM, you can check the function pointer to the address.
Or, as Mehrdad says, just try writing to the address, it should be easy to figure out from there.
It all depends on which compiler/processor you use. If I put your definition in Keil Uvision for 8051, surely would point to ROM because of the "CONST" definer although I could modify with XRAM or CODE. But for ARM depends on address and not definer. Keil Uvision Example:
// For 8051 Keil
const char code romdata[2] = {0,1}; //<< this point to ROM/FLASH
const char xram ramdata[2] = {0,1}; // this point to external RAM
const char romdata[2] = {0,1}; // this point to ROM/FLASH
精彩评论