Я программирую микроконтроллер STM32F413 с помощью SystemWorkbench 4 stm32. Векторы прерываний определяются в файле запуска сборки как слабые псевдонимы, как показано ниже:
.weak TIM1_UP_TIM10_IRQHandler
.thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
И ссылка на объект выглядит следующим образом:
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.....
.word TIM1_UP_TIM10_IRQHandler
.....
Таким образом g_pfnVectors
список адресов функций обработчика IRQ Они объявлены как слабые псевдонимы, поэтому, если они не определены пользователем, используется обработчик по умолчанию.
Я определил обработчик так:
extern "C" {
void TIM1_UP_TIM10_IRQHandler() {
if (SU_TIM->SR & TIM_SR_UIF) {
SU_TIM->SR &= ~TIM_SR_UIF;
...
}
}
}
Это хорошо работает с обычными флагами оптимизации компилятора, однако я хотел попробовать, если я получу меньший и возможно более быстрый код с -flto
(в основном для того, чтобы попробовать, на самом деле это не нужно). Но при компиляции с -flto
g ++ игнорирует мою реализацию обработчика и просто использует обработчик по умолчанию, мой обработчик вообще отсутствует в коде.
Поэтому я попытался заставить g ++ включить функцию, добавив __attribute__((used))
к определению функции, но она все еще не скомпилирована. Однако, если я дам ему другое имя, оно будет включено в двоичный файл. Также, если я удаляю слабый псевдоним и просто имею ссылку на обработчик в файле запуска, он тоже работает.
Так что почему-то слабые псевдонимы не работают с оптимизацией времени соединения g ++. Может быть, кто-то может сказать мне, в чем ошибка и что я здесь делаю неправильно.
РЕДАКТИРОВАТЬ:
Я посмотрел, какие символы создаются с nm в результирующем файле .elf, и TIM1_UP_TIM10_IRQHandler
экспортируется как слабый символ с адресом DefaultHandler. Однако при просмотре только файла .o из модуля компиляции, содержащего TIM1_UP_TIM10_IRQHandler
функция, она экспортируется как символ в текстовом разделе (T). Поэтому компоновщик по какой-то причине предпочитает сохранять слабый символ, даже если существует сильный символ с тем же именем.
Я думаю вы должны сообщить компилятору, что это прерывание __attribute__ ((interrupt ("IRQ")))
, который обычно не требуется, так как F4 имеет стек по умолчанию, выровненный до 8 аппаратным обеспечением.
Если это не помогает, то для обходного пути нужно назначить указатель функции с помощью обработчика, что предотвратит его отбрасывание (если сам указатель не будет удален сам — сверьтесь с вашим отладчиком).
В крайнем случае — измените файл .s с определениями таблицы векторов
Других решений пока нет …