Перейти к содержанию
    

Прерывание от USB в STM32F: косяк KEIL vs. GCC

Коллеги!

Хочу просто поделиться граблей, вдруг кто столкнется.

Портировал большой проект из KEIL в STM32CubeIDE. За исключением бОльшей строгости gcc в сравнении с пофигистом armcc, портировка не очень сложная.

Все завелось с пол-оборота. Пока не воткнул USB (STM32F103VET): попал в HardFault.  Поставил там bx lr, чтобы под отладчиком понять, откуда прилетело, и с удивлением обнаружил, что влетаю туда периодически и спорадически с совершенно разных, надежных по коду, мест. Понял, что это не проблема нарушения стека или чего-то еще, а какая-то синтаксическая ошибка портирования. И нашёл:

 

eсли в startup_stm32f10x_hd.s из CMSIS под KEIL имя слабоопределенного вектора прерывания есть "USB_LP_CAN1_RX0_IRQHandler", то под STM32CubeIDE автоматически присоединяемый файл startup_stm32f103vetx.s обзывает вектор как "USB_LP_CAN_RX0_IRQHandler". Как очевидно, дело было не в HardFault, а в фактическом отсутствии обработчика прерывания от USB. Чтобы сохранить совместимость исходника для обоих IDE, сделал:

// Compatibility with gcc: another name for the interrupt:
void USB_LP_CAN_RX0_IRQHandler (void) __attribute__((alias("USB_LP_CAN1_RX0_IRQHandler")));
void USB_LP_CAN1_RX0_IRQHandler(void)
{

 

Изменено пользователем KnightIgor

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чтобы не было таких накладок, заголовочный файл контроллера и стартап должны лежать в проекте, а не подключаться "откуда-то оттуда". И стартап можно сделать универсальный на разные тулчейны.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

5 minutes ago, VladislavS said:

Чтобы не было таких накладок, заголовочный файл контроллера и стартап должны лежать в проекте

Именно так и делает KEIL, если создать проект в нем. Что логично )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, VladislavS said:

Чтобы не было таких накладок, заголовочный файл контроллера и стартап должны лежать в проекте, а не подключаться "откуда-то оттуда". И стартап можно сделать универсальный на разные тулчейны.

Синтаксисы ассемблеров gcc и KEIL сильно отличаются.

Стартап и лежит в проекте: его туда копирует сам KEIL или STM32CubeIDE при создании проекта. Под "подключается откуда-то" имеется ввиду, что обе оболочки тянут этот файл из своего репозитория (Packs в KEIL и нечто подобное в STM32CubeIDE).

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 минут назад, KnightIgor сказал:

Синтаксисы ассемблеров gcc и KEIL сильно отличаются

Для Cortex-M легко и непринуждённо без ассемблера всё происходит. Не из репозитория, конечно, но с минимальными усилиями.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, VladislavS said:

Для Cortex-M легко и непринуждённо без ассемблера всё происходит. Не из репозитория, конечно, но с минимальными усилиями.

Флаг в руки. Заодно черкните походя свою операционку, например.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

21 minutes ago, VladislavS said:

Для Cortex-M легко и непринуждённо без ассемблера всё происходит

Аналогично сделал себе, причем под cpp. Ни одного asm файла. Не хвастаю, просто нет нужды в них )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, KnightIgor said:

Флаг в руки. Заодно черкните походя свою операционку, например.

На самом деле, действительно можно совсем без внешнего ассемблера (а часто и без встроенного). Например, так делает "из коробки" микрочиповская среда (MPLAB, кажись): там стартовым является сишный файл, а не ассемблерный. Мне лично такое совсем не нравится, но так сделать таки можно, так что Ваш наезд на VladislavS лишён оснований.

Пы.Сы. И да, свою операционку черкнул и даже использую в паре проектов. Может, даже когда-нибудь выложу, когда там побольше функционала будет...

2 hours ago, Forger said:

Аналогично сделал себе, причем под cpp. Ни одного asm файла. Не хвастаю, просто нет нужды в них )

Иногда нужны. В частности, чтобы запустить STM32H7, надо сначала включить правильный режим электропитания и лишь затем можно обращаться к ОЗУ -- а обеспечить это без асма со 100% надёжностью нельзя. Ну или в тех же операционках: переключение потоков и т.п. низкоуровневые операции с регистрами без ассемблера не обходятся, и нередко удобней вынести их в отдельный ассемблерный файл, а не лепить внутри си/си++нутого.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

27 minutes ago, SII said:

а обеспечить это без асма со 100% надёжностью нельзя.

Абсолютно 100% заблуждение!

Связано с недостаточным знанием инструмента. Изучайте и все получится ))

 

27 minutes ago, SII said:

удобней вынести их в отдельный ассемблерный файл, а не лепить внутри си/си++нутого.

У меня вместо груды типовых asm файлов на каждый мк всего ОДИН cpp-файл сразу на целое ядро. Гораздо проще, меньше и понятнее, чем типовой asm. Но так удобнее МНЕ

Вы же вправе делать как угодно. Никто не навязывает ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

20 minutes ago, Forger said:

Абсолютно 100% заблуждение!

Связано с недостаточным знанием инструмента. Изучайте и все получится ))

Извините, не соглашусь. Нет никаких стандартных, а значит, стабильных и переносимых средств заставить компилятор генерировать такой код, который никогда не обращается к ОЗУ, включая стек.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Forger сказал:

Абсолютно 100% заблуждение!

Так покажите: Как на Cortex-M не используя асм эффективно реализовать вытесняющее переключение задач например.

Али положить CPU в сон? Сможете без асма?  :wink:

 

Ну или скажем - опять же без асма написать аналог кода:

Скрытый текст

               SECTION  .text:CODE:NOROOT(2)
               PUBLIC   FindMaxU16
;extern "C" uint FindMaxU16(u32 *);
               THUMB
FindMaxU16:    PUSH     {R4-R9, LR}
               MOVS     R2, #512 / 16 - 1
               MOVS     R1, #0
FindMaxU16_01: SUBS     R2, #1
               LDMIA    R0!, {R3-R9, R12}
               USUB16   LR, R1, R3
               SEL      R1, R1, R3
               USUB16   LR, R1, R4
               SEL      R1, R1, R4
               USUB16   LR, R1, R5
               SEL      R1, R1, R5
               USUB16   LR, R1, R6
               SEL      R1, R1, R6
               USUB16   LR, R1, R7
               SEL      R1, R1, R7
               USUB16   LR, R1, R8
               SEL      R1, R1, R8
               USUB16   LR, R1, R9
               SEL      R1, R1, R9
               USUB16   LR, R1, R12
               SEL      R1, R1, R12
               BPL      FindMaxU16_01
               CMP      R1, R1, LSL #16
               IT       CC
               LSLCC    R1, R1, #16
               LSRS     R0, R1, #16
               POP      {R4-R9, PC}

 

не уступающий ему по эффективности выполнения.

 

А мы посмеёмся...  :wink:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

39 minutes ago, SII said:

Извините, не соглашусь. Нет никаких стандартных, а значит, стабильных и переносимых средств заставить компилятор генерировать такой код, который никогда не обращается к ОЗУ, включая стек.

Повторюсь - изучайте инструмент. Подсказка: короткие asm-вставки ВНУТРИ c/cpp файла.

Городить для этого именно asm-файл вовсе необязательно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...