【问题标题】:Function pointer to specific memory指向特定内存的函数指针
【发布时间】:2011-12-17 20:30:38
【问题描述】:

我想征求意见。我正在使用小型嵌入式 uP。

我想将我的各种函数分配给 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。

【问题讨论】:

  • 我认为这将是您的链接器的功能。
  • 部分你是对的,但是将函数指针放置到特定的内存位置应该是可以实现的,因此不涉及链接器。
  • 例如,我不确定它是否正确:
  • unsigned int volatile * fcn_base = (unsigned short *) FCN_BASE_ADDRESS *fcn_base = ;
  • FUNC_T * myfunctions; *port = myfunctions->fcn1;

标签: function memory pointers embedded


【解决方案1】:

这是以便携方式解决它的最佳方法:

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 中,例如向量表,则必须使用 READ_ONLY 部分、#pragma CONST_SEG 和const fptr 以不同方式完成。 (请注意,当与 typedef:ed 指针结合使用时,C 中的 const 关键字会以非理性的方式表现。在这种情况下,我相信它会给出一个指向非常量函数的常量指针,因此它应该根据需要在 NVM 中结束。)

【讨论】:

    【解决方案2】:

    也许以下内容会对您有所帮助:

    // 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));
    

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

    【讨论】:

    • 我只是试一试。代码按建议编译,但不起作用且没有结果。在特定地址没有 myfunctions。也许 memcpy 对此不起作用(只是因为函数指针而猜测)...
    • @Pepe:memcpy 就是 memcpy;如果这对您不起作用,那么您误解或误用了解决方案。只要FCN_BASE_ADDRESS不是 ROM,这将起作用。然而,有一种更简单的方法;如果FCN_BASE_ADDRESS 的类型为“FUNC_T*”,则可以通过FCN_BASE_ADDRESS->fcn1() 直接访问函数,例如无需第二个memcpy()。
    【解决方案3】:

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

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

    【讨论】:

    • 我正在使用飞思卡尔 CodeWarrior 工具,在我看来只有链接器本身的方法。所以还在研究它...
    • @Pepe:“Codewarior”是飞思卡尔用于其所有架构的开发工具 (IDE) 的名称,它没有告诉我您正在使用哪种编译器。但是,我不相信您是对的,例如,请查看“Global Variable Address Modifier (@address)”的文档。
    • @Pepe,Clifford 已回答您的问题。我使用 Freescale Codewarrior,typename varname @address 格式是做你想做的事的方式。
    猜你喜欢
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 2012-02-11
    相关资源
    最近更新 更多