1

我在我的项目中两次遇到这个问题,最后一次我使用了一种肮脏的解决方案。

平台:PIC18F87J60XC8 v1.12

我正在尝试使用函数指针指向可能位于我的 ROM 上半部分(> = 0x10000)的函数。这意味着指针本身需要为 17 位或更大(最多 20 位)才能处理这样的函数。

这是相关的代码片段(简化):

void test(void) @ 0x1C000
{
    printf("function pointer called!\r\n");
}

void main(void) {
    void (*testPointer) (void) = &test;
    //Now testPointer contains 0x0C000
    (*testPointer)(); //Doesn't call test. Instead it jumps to 0x0C000
}

发生的事情是测试实际上从未被调用。当我使用调试器 ( PICKIT 3 ) 时,我可以看到 testPointer 中的值是 0x0C000。似乎指针中的地址被四舍五入到最大只有 16 位,而且这种情况总是会发生。但是当我将 test() 放在 0x10000 以下的某个地方时,一切正常,因为指针只需要最大 16 位。

当我从设备中读回程序时,test() 确实位于 0x1C000,所以这不是问题,代码就在那里。

上次我通过将文字 long 转换为指针来解决这种情况,这很有效,但它很脏,现在我想避免它。

有没有人认识到这个问题?这是编译器错误吗?如果是这样,Microchip 是否已经知道这一点?有什么干净的解决方法吗?XC8 编译器是否完全支持 20 位 const 指针?

编辑:修复 &testPointer(); 上面代码中的错字 --> (*testPointer()); (不,这不是我的问题)

4

1 回答 1

2

MPLAB C18 编译器用户指南列出了一些与您的用例相关的额外存储限定符:

near/far程序存储器对象限定符用于表示位于程序存储器中的变量可以在程序存储器中的任何位置找到,
或者,如果是指针,则它可以访问高达或超过 64K 的程序存储器空间。far

ram/rom限定符限定符表示对象位于程序存储器中,而
限定符表示对象位于数据存储器中。romram

稍后,该手册显示了一个创建“可以访问超过 64K 的程序存储空间的函数指针”的示例:

far rom void (*fp) (void);

XC8 手册对far限定符的功能不太清楚,但仍然列出了它,这强烈表明它仍然被较新的编译器识别。

于 2013-08-13T15:41:06.063 回答