我在项目中遇到过这个问题两次,上次我使用了一种肮脏的解决方案。
平台: PIC18F87J60 , XC8 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,这不是问题,代码就在那里。
我最后一次通过将一个文字长度转换为一个指针来解决这个问题,但它很脏但现在我想避免它。
有人认出这个问题吗?这是编译器错误吗?如果是这样,Microchip是否已经知道这一点?任何干净的解决方案? XC8编译器是否支持20位常量指针?
编辑:在上面的代码中修复拼写错误& testPointer(); - > (* testPointer()); (不,这不会导致我的问题)
答案 0 :(得分:2)
“MPLAB C18编译器用户指南”列出了一些与您的用例相关的额外存储限定符:
near
/far
程序记忆对象
far
限定符用于表示位于程序存储器中的变量可以在程序存储器的任何位置找到,,或者,如果是指针,它可以访问最多64K的程序存储空间强>
ram
/rom
限定符
rom
限定符表示对象位于程序存储器中,而ram
限定符表示对象位于数据存储器中。
稍后,该手册显示了创建“一个可以访问超过64K程序存储空间的函数指针”的示例:
far rom void (*fp) (void);
XC8手册对far
限定符的功能不太清楚,但仍然列出它,强烈暗示它仍然被较新的编译器识别。