2010-04-19 2 views
2

Я пишу загрузчик для PIC32MX, используя компилятор PICC32 от HiTech (аналогично C90). В какой-то момент мне нужно, чтобы перейти к основной процедуре реального, так что где-то в загрузчике у меня естьОшибка компилятора при указании на функцию

void (*user_main) (void); 
user_main = (void (*) (void)) 0x9D003000; 
user_main(); 

(Обратите внимание, что в настоящем коде функция подписи typedef'd и адрес является макро .)

Я предпочел бы вычислить, что (виртуальный) адрес от физического адреса, и есть что-то вроде:

void (*user_main) (void); 
user_main = (void (*) (void)) (0x1D003000 | 0x80000000); 
user_main(); 

... но когда я пытаюсь, что я получаю ошибку компиляции:

Error #474: ; 0: no psect specified for function variable/argument allocation 

Могу ли я споткнуться о некоторой варильности синтаксиса C здесь?

Эта ошибка не относится к какой-либо конкретной строке, но если я прокомментирую звонок user_main(), она исчезнет. (Это может быть компилятор удаления избыточного кода ветви, но HiTech PICC32 не особенно умный в режиме Lite, так что, возможно, нет.)

Update: Я заметил также, что если я использую

void (*user_main) (void); 
unsigned int x = 0x9D003000; 
user_main = (void (*) (void)) x; 
user_main(); 

У меня такая же ошибка.

+0

Кстати, независимо от того, как вы в конечном итоге убедите своего компилятора понять ваш код, я бы сделал несвязанное изменение, чтобы помочь людям понять ваш код. typedef void (* user_main_t) (void); user_main = (user_main_t) 0x9D003000; –

+0

О да, у меня на самом деле есть 'typedef void (* MainFunction) (void)' в файле заголовка. Функция typedefs - одна из моих любимых функций C;) – detly

ответ

1

Извините, что ответили на мой вопрос, но это было ошибкой в ​​компиляторе. Они прислали мне новую сборку, в которой исправлена ​​проблема.

1

Возможно, вы можете быть прав в отношении удаления избыточного кода компилятором при удалении вызова функции. GCC -S, я думаю, вы получите сборку, которую вы могли бы использовать, чтобы подтвердить отсутствие определения функции после удаления сайта вызова функции.

Я думаю, что это поможет вам прогресс вашей отладки ...

0

Безобразного способ сделать это может быть, чтобы положить ваш тип указателя и без знака длиной в союзе. Вы знаете, что вам нужно делать. Стандарт C делает это неопределенное поведение, но вы уже находитесь на неопределенной территории и по милости своего компилятора, как только вам нужно преобразовать целое число в указатель.

+0

Этот конкретный компилятор полностью поддерживает тип-punning (я проверил) – detly

3

Это не общая проблема C - это спецификация HI-TECH.

Я никогда не использовал продукты HI-TECH, но проблема заключается в том, что компоновщик не знает, где в памяти он должен размещать аргументы или локальные переменные в процедуре user_main. Из PICC manual:

(474) no psect specified for function variable/argument allocation (Linker)

The FNCONF assembler directive which specifies to the linker information regarding the auto/parameter block was never seen. This is supplied in the standard runtime files if necessary. This error may imply that the correct run-time startoff module was not linked. Ensure you have used the FNCONF directive if the runtime startup module is hand-written.

+0

Но зачем он работал для буквального '0x9D003000', но не' (0x1D003000 | 0x80000000) '? – detly

+1

На самом деле, вместо того, чтобы преследовать это здесь, если это не очевидная проблема C, я просто свяжусь с HiTech. – detly

1

Я понимаю, что это не ответ на исходный вопрос, но синтаксис вызова функции с помощью функции указатель на можно было бы сделать гораздо яснее (правильно) с помощью следующей конструкции :

(*user_main)(); 

Если вы сделаете это, вы сразу видите, что user_main является указателем, который разыменовывается и вызов функции выполняется. Это позволяет избежать путаницы с функцией user_main() с помощью функции user_main.

+0

Мне это нравится, спасибо. – detly

Смежные вопросы