Function 指向特定内存的函数指针

Function 指向特定内存的函数指针,function,memory,pointers,embedded,Function,Memory,Pointers,Embedded,我想征求你的意见。我正在与小型嵌入式系统合作 我想把我的各种函数分配给myfunctions结构。如何正确地做到这一点? 然后我想把这个myfunctions(函数指针的结构)放到特定的内存地址(例如0x1000)。实现这一目标的最佳程序是什么 typedef void (*fptr)(void); typedef struct FCN_IMAGE { fptr fcn1; fptr fcn2; fptr fcn3; } FUNC_T; FUNC_T myfuncti

我想征求你的意见。我正在与小型嵌入式系统合作

我想把我的各种函数分配给myfunctions结构。如何正确地做到这一点? 然后我想把这个myfunctions(函数指针的结构)放到特定的内存地址(例如0x1000)。实现这一目标的最佳程序是什么

typedef void (*fptr)(void);

typedef struct FCN_IMAGE
{
    fptr fcn1;
    fptr fcn2;
    fptr fcn3;
} FUNC_T;

FUNC_T myfunctions;
实际上,它应该是一种跳转表


其次,我想从其他程序中直接从指定的地址位置(例如0x1000)读取此函数指针

这意味着第一个代码应该将函数指针的结构分配给特定的内存位置,其他独立的代码应该从特定的内存中读取该表。这两个项目之间的互联互通应该得到加强

#define FCN_BASE_ADDRESS (0x1000)
你有什么想法吗?最好的方法是什么


另外,这将运行在嵌入式处理器上,而不是PC上。

在特定位置定位对象通常最容易通过使用特定于编译器的扩展来实现;该语言没有定义标准方法。也可以通过修改链接器脚本在特定位置定位全局对象,但这是特定于特定工具链的


您使用的编译器/工具链是什么?请参阅其文档。

在特定位置定位对象通常最容易通过使用特定于编译器的扩展来执行;该语言没有定义标准方法。也可以通过修改链接器脚本在特定位置定位全局对象,但这是特定于特定工具链的


您使用的编译器/工具链是什么?请参阅其文档。

以下内容可能会对您有所帮助:

// assign my various functions to myfunctions struct
myfunctions.fcn1 = &YourFunction1;
myfunctions.fcn2 = &YourFunction2;
myfunctions.fcn3 = &YourFunction3;

// assign the struct of function pointers to specific memory location
memcpy((void*)FCN_BASE_ADDRESS, &myfunctions, sizeof(myfunctions));

// read this table from specific memory
memcpy(&myfunctions, (void*)FCN_BASE_ADDRESS, sizeof(myfunctions));

这是基于我对您实际想要做什么的猜测。

也许以下内容将帮助您:

// assign my various functions to myfunctions struct
myfunctions.fcn1 = &YourFunction1;
myfunctions.fcn2 = &YourFunction2;
myfunctions.fcn3 = &YourFunction3;

// assign the struct of function pointers to specific memory location
memcpy((void*)FCN_BASE_ADDRESS, &myfunctions, sizeof(myfunctions));

// read this table from specific memory
memcpy(&myfunctions, (void*)FCN_BASE_ADDRESS, sizeof(myfunctions));

这是基于我对您实际想要做什么的猜测。

这是以便携方式解决此问题的最佳方法:

typedef void (*fptr)(void);

#define FCN_BASE_ADDRESS ((volatile fptr*)0x1000)

/* Make myfunctions an array, not a struct. 
   Structs can have padding and aren't portable.
   It doesn't look like you need a struct in this case.
*/
fptr myfunctions [N] =
{    
  fptr fcn1;
  fptr fcn2;
  fptr fcn3;
};

memcpy(&FCN_BASE_ADDRESS, myfunctions, sizeof(myfunctions));
不过,如果您使用的是Codewarrior,您可能会使用#pragma将它们分配到您想要的位置。下面是一个示例,假设它们存储在读/写RAM和32位地址总线中

// .prm file
SECTIONS
  MEM_FCN_BASE_ADDRESS = READ_WRITE 0x2000 TO 0x200C; 
END

PLACEMENT
  FCN_BASE_ADDRESS INTO MEM_FCN_BASE_ADDRESS;
END

// .c file
#pragma DATA_SEG FCN_BASE_ADDRESS
fptr myfunctions[N] = ...;
#pragma DATA_SEG DEFAULT

如果它们应该存储在ROM/flash中,例如向量表,则必须使用只读部分、#pragma CONST_SEG和
CONST fptr
进行不同的操作。(请注意,C中的const关键字在与typedef:ed指针组合时的行为是非理性的。在这种情况下,我相信它会给出一个指向非常量函数的常量指针,因此它应该根据需要在NVM中结束。)

这是以可移植方式解决它的最佳方法:

typedef void (*fptr)(void);

#define FCN_BASE_ADDRESS ((volatile fptr*)0x1000)

/* Make myfunctions an array, not a struct. 
   Structs can have padding and aren't portable.
   It doesn't look like you need a struct in this case.
*/
fptr myfunctions [N] =
{    
  fptr fcn1;
  fptr fcn2;
  fptr fcn3;
};

memcpy(&FCN_BASE_ADDRESS, myfunctions, sizeof(myfunctions));
不过,如果您使用的是Codewarrior,您可能会使用#pragma将它们分配到您想要的位置。下面是一个示例,假设它们存储在读/写RAM和32位地址总线中

// .prm file
SECTIONS
  MEM_FCN_BASE_ADDRESS = READ_WRITE 0x2000 TO 0x200C; 
END

PLACEMENT
  FCN_BASE_ADDRESS INTO MEM_FCN_BASE_ADDRESS;
END

// .c file
#pragma DATA_SEG FCN_BASE_ADDRESS
fptr myfunctions[N] = ...;
#pragma DATA_SEG DEFAULT


如果它们应该存储在ROM/flash中,例如向量表,则必须使用只读部分、#pragma CONST_SEG和
CONST fptr
进行不同的操作。(请注意,C中的const关键字在与typedef:ed指针组合时的行为是非理性的。在这种情况下,我相信它会给出一个指向非常量函数的常量指针,因此它应该根据需要在NVM中结束。)

我认为这可能是链接器的一个功能。你部分是对的,但应该可以将函数指针放在特定的内存位置,这样链接器就不会涉及。例如,我不确定它是否正确:unsigned int volatile*fcn_base=(unsigned short*)fcn_base_ADDRESS*fcn_base=;FUNC_T*myfunctions*端口=myfunctions->fcn1;我认为这可能是链接器的一个函数。部分正确,但将函数指针放在特定的内存位置应该是可以实现的,因此链接器不涉及。例如,我不确定它是否正确:unsigned int volatile*fcn_base=(unsigned short*)fcn_base_ADDRESS*fcn_base=;FUNC_T*myfunctions*端口=myfunctions->fcn1;我使用的是飞思卡尔CodeWarrior工具,在我看来,只有通过链接器本身才能实现。所以仍在研究它…@Pepe:“Codewarior”是飞思卡尔开发工具(IDE)在其所有体系结构中的名称,它没有告诉我您正在使用哪种编译器。我不相信你是对的,但是,在文档中查找“”例如。@Pepe,Clifford已经回答了你的问题。我使用飞思卡尔Codewarrior,而
typename varname@address
格式就是你想要的方式。我使用的是飞思卡尔Codewarrior工具,在我看来,链接器本身是唯一的方式。所以仍在研究它…@Pepe:“Codewarior”是飞思卡尔开发工具(IDE)在其所有体系结构中的名称,它没有告诉我您正在使用哪种编译器。我不相信你是对的,但是,在文档中查找“”例如。@Pepe,Clifford已经回答了你的问题。我使用飞思卡尔Codewarrior,而
typename varname@address
格式就是你想要的方式。我只是尝试一下。代码按建议编译,但不起作用,也没有结果。在特定地址没有myfunctions。也许memcpy在这方面不起作用(只是因为函数指针而猜测)…@Pepe:memcpy就是memcpy;如果这对您不起作用,那么您误解或误用了解决方案。只要
FCN\u BASE\u ADDRESS
不是ROM,这就行了。不过有一种更简单的方法;如果
FCN\u BASE\u ADDRESS
是'FUNC\u T*`类型,那么可以通过
FCN\u BASE\u ADDRESS->fcn1()
直接访问函数,例如,不需要第二个memcpy()。我只是尝试一下。代码按建议编译,但不起作用,也没有结果。在特定地址没有myfunctions。也许memcpy在这方面不起作用(只是因为函数指针而猜测)…@Pepe:memcpy就是memcpy;如果这对您不起作用,那么您误解或误用了解决方案。只要