2017-01-09 2 views
0

Я просто поместил функцию на конкретный адрес, используя раздел, а затем я вывожу адрес этой функции, а результат - выбранный адрес раздела + 1. Это то, что я сделал:GCC производит неравновесный адрес функции на Cortex M3

void __attribute__((section (".my_fct_address"))) Fct_Ptr_Test (void) 
{ 
... 
} 

и

void (*fct_ptr) (void); 
fct_ptr = Fct_Ptr_Test; 
printf ("0X%X\r\n", (uint32_t)(fct_ptr)); 
fct_ptr(); 

в LD-файле:

.my_fct_address 0x800F000 : 
{ 
    KEEP(*(.my_fct_address)) /* keep my variable even if not referenced */ 
} > FLASH 

Вышеприведенные Printf заявление выводит 0x800F001 и Fct_Ptr_Test называется правильно

Если установить

fct_ptr = 0x800F000; 

аварии системы. Если установить

fct_ptr = 0x800F001; 

все нормально снова. Если я не размещаю Fct_Ptr_Test в своем собственном разделе, то есть пусть компоновщик помещает его куда угодно, я также получаю нечетный адрес. Теперь мне интересно, как 0x800F001 может быть правильным адресом на 32-битном контроллере (ARM cortex M3) и том, что хранится в 0x800F000. Еще более странно: map-file всегда показывает четные адреса Может ли кто-нибудь помочь?

Благодаря

Martin

+0

Полностью не связанный с вашим вопросом и проблемой, но переносимый способ печати указателя с использованием 'printf' имеет формат' '% p ''. Это требует, чтобы аргумент был «void *». –

ответ

2

Linker устанавливает младший бит функций Thumb 1 для облегчения межсетевого взаимодействия (см docs). Возможно, это ваш случай?

+0

Привет, юг, да, я думаю, что все. Большое спасибо и за ссылку. Martin –

+0

Это, безусловно, так! –

+1

Чтобы сказать это по-другому, поскольку на компьютере с большим пальцем (cortex-m3) нет взаимодействия, некоторые инструкции, такие как bx и pop, ожидают, что lsbit будет настроен для филиалов или возвратных адресов на основе большого пальца. См. Инструкцию по эксплуатации BX. –

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