24-битные константные указатели на XC8 PIC18 не работают

Я дважды сталкивался с этой проблемой в своем проекте, и в последний раз я использовал какое-то грязное решение.

Платформа: PIC18F87J60, XC8 v1.12

Я пытаюсь использовать указатели функций, чтобы указать на функции, которые, возможно, находятся в верхней половине моего ПЗУ (>= 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-битные константные указатели?

Изменить: исправлена ​​опечатка в коде выше &testPointer(); --> (*testPointer()); (нет, это не было причиной моей проблемы)


person Jupiter    schedule 13.08.2013    source источник
comment
На этой картинке 20-битная адресация. Сколько памяти подключено к нему?   -  person trojanfoe    schedule 13.08.2013
comment
@trojanfoe упс, я имею в виду 20. Для ясности: я говорю о диапазоне адресов 0-1FFFF. Никаких микросхем внешней памяти, я использую только встроенное ПЗУ. Отредактировал.   -  person Jupiter    schedule 13.08.2013
comment
И какой объем памяти?   -  person trojanfoe    schedule 13.08.2013
comment
Вы пытались объявить свой указатель как far rom void (*testPointer) (void) = &test; ?   -  person Michael    schedule 13.08.2013
comment
его 16К ПЗУ. Последний адрес 0x1FFFF.   -  person Jupiter    schedule 13.08.2013
comment
@Michael Добавление ключевого слова far решило проблему. rom не распознается XC8, мне пришлось бы использовать для этого константу, но компилятор достаточно умен, чтобы ему не нужна была константа (очевидно). Добавьте ответ официально, и я отмечу его. Спасибо за все предложения, ребята.   -  person Jupiter    schedule 13.08.2013


Ответы (1)


В Руководстве пользователя компилятора MPLAB C18 перечислены несколько дополнительных квалификаторов хранилища, которые могут иметь отношение к вашему варианту использования:

near/far Объекты памяти программы
Спецификатор far используется для обозначения того, что переменная, расположенная в памяти программы, может быть найдена в любом месте памяти программы, или, если это указатель, к которой она может обращаться до и за ее пределами. 64 КБ памяти программ.

ram/rom Квалификаторы
Квалификатор rom означает, что объект расположен в памяти программ, тогда как квалификатор ram означает, что объект находится в памяти данных.

Далее в руководстве показан пример создания "указателя функции, который может получить доступ к объему программной памяти, превышающему 64 КБ":

far rom void (*fp) (void);

В руководстве по XC8 функция квалификатора far менее ясна, но все же указана, что убедительно свидетельствует о том, что она все еще распознается более новыми компиляторами.

person Michael    schedule 13.08.2013
comment
Я не уверен, прав ли я, но AFAIR использование указателей far не является беспроблемным. Возможно, потребуется изменить старший байт какого-либо регистра указателя, если компиляция пронсипа произошла с near. Но поскольку я работал с PIC 3 года назад, я могу ошибаться. - person glglgl; 13.08.2013