Коллеги, а подскажите, как работать с прерываниями от внешних интерфейсов.
Возьмем, к примеру, CAN.
- Есть две функции приема по CAN: HAL_CAN_Receive() и HAL_CAN_Receive_IT(). В чем между ними разница? Генерит ли HAL_CAN_Receive() прерывания, если нет - как ей пользоваться?
- При каких условиях запускаются обработчики прерываний USB_LP_CAN1_RX0_IRQHandler() и CAN1_RX1_IRQHandler()?
- Как пользоваться HAL_CAN_RxCpltCallback() и почему Cube не создает эту функцию вместе с прочими обработчиками прерываний?
Примеров c HAL в интернетах очень мало, поэтому я не смог найти ответов на эти вопросы... заранее спасибо.
Цитата(nya @ Nov 11 2015, 11:36)

Примеров c HAL в интернетах очень мало, поэтому я не смог найти ответов на эти вопросы... заранее спасибо.
1. Из названия понятно, кажется мне. Если нет прерываний - ждем-опрашиваем.
3. Создает пустышку-затычку с атрибутом __weak. Ведь никто не может читать Ваши мысли... Вы сами у себя в программе пишите обработчик. Без атрибута, тогда Ваша код будет иметь приоритет.
Но зачем два обработчика - Handler и Callback?
Цитата(nya @ Nov 11 2015, 12:06)

Но зачем два обработчика - Handler и Callback?
Это для того, чтобы Вы не возились с регистрами. HAL - Hardware Abstraction Level (Layer).
Цитата(Tanya @ Nov 11 2015, 12:23)

Это для того, чтобы Вы не возились с регистрами. HAL - Hardware Abstraction Level (Layer).
Так это понятно.

Но я сейчас нашел таки рабочий пример для CAN -
http://geektimes.ru/post/255534/Похоже, в моем коде были неправильно выставлены настройки фильтров, вот прерывания и не вызывались.
Поэкспериментировав, выяснил, что оба этих обработчика работают одинаково хорошо. И запускаются одновременно. Поэтому все-такие непонятно в чем между ними разница и когда нужно использовать Handler, а когда - Callback. В обоих случаях "ручной труд" с регистрами равен нулю.
Цитата(nya @ Nov 11 2015, 12:44)

когда нужно использовать Handler, а когда - Callback. В обоих случаях "ручной труд" с регистрами равен нулю.
Нужно использовать Callback. Предполагается, что всегда. Callback вызывается в самом конце обработчика.
Цитата(Tanya @ Nov 11 2015, 12:46)

Нужно использовать Callback. Предполагается, что всегда. Callback вызывается в самом конце обработчика.
То есть я должен писать обработчики Callback в main.c вместо того, чтобы лезть в stm32***_it.c?
Цитата(nya @ Nov 11 2015, 12:58)

То есть я должен писать обработчики Callback в main.c вместо того, чтобы лезть в stm32***_it.c?
Пишите, где хотите... в своем коде. Ведь их код может быть со временем изменен в новой версии.
Tarbal
Nov 11 2015, 15:53
Цитата(nya @ Nov 11 2015, 12:58)

То есть я должен писать обработчики Callback в main.c вместо того, чтобы лезть в stm32***_it.c?
Да. Так будет правильно.
drozel
Nov 12 2015, 02:40
Цитата(Tarbal @ Nov 11 2015, 21:53)

Да. Так будет правильно.
Да вот хз. По идее, даже не смотря на навороченный NVIC, обработчик прерывания должен быть разумно коротким, а в HAL мало того, что обработчик раздутый до нельзя, так еще и калбек вызывается прямо из него. А пользователь в калбеке воротит кучу кода и еще вызовы своих функций. Дай бог, без блокирующих задержек.
_Pasha
Nov 12 2015, 04:33
Цитата(drozel @ Nov 12 2015, 05:40)

Да вот хз. По идее, даже не смотря на навороченный NVIC, обработчик прерывания должен быть разумно коротким, а в HAL мало того, что обработчик раздутый до нельзя, так еще и калбек вызывается прямо из него.
этот HAL переплюнул легендарный индусский код. Его даже в кач-ве справочника использовать нельзя.
но и это цветочки.
по идее, описание регистров всей линейки stm32 должно уместиться в пару файлов 25-30 кб, с весьма удобным API вместо 100 метровых библиотек ни о чем.
Цитата(Tanya @ Nov 11 2015, 15:23)

Это для того, чтобы Вы не возились с регистрами. HAL - Hardware Abstraction Level (Layer).
Как правило: тот кто не хочет возиться с регистрами, возится с кучей кривых исходников написанных школьниками. А потом ещё идёт и строчит в форумы "хелп ми!"....
Цитата(_Pasha @ Nov 12 2015, 10:33)

по идее, описание регистров всей линейки stm32 должно уместиться в пару файлов 25-30 кб, с весьма удобным API вместо 100 метровых библиотек ни о чем.
согласен с Вами.
drozel
Nov 12 2015, 05:08
Цитата(jcxz @ Nov 12 2015, 10:42)

Как правило: тот кто не хочет возиться с регистрами, возится с кучей кривых исходников написанных школьниками.
Я за среднее. Не люблю возиться с регистрами (тем не менее, знаю их и могу анализировать исходники), но и HAL - ужас.
Должна быть либа, абстрагирующая от регистров с четким todo. stdlib был ближе к моему идеалу, нежели HAL. libopencm3 - ничего
Tarbal
Nov 12 2015, 23:17
А у меня подход простой. Срочно надо сделать проект -- берем то, что проще заставить работать. По ходу те части, что работают неудовлетворительно перепишем. К сожалению нет времени заниматься перфекционизмом. Остаются компромисы.
MikleV
Nov 17 2015, 06:28
Подниму тему по аналогичному вопросу.
Есть STM32 с bsp кокос. Есть пины подключенные в ISM приемопередатчику и отслеживающие его состояния(помимо SPI связи с ним) Задача в обработчике прерывания запрещать и разрешать прерывания(в т.ч. в обработчике скажем void EXTI2_IRQHandler(void) его же и запрещать) ну и дополнительно переключать срабатывания по фронтам. Т.е четко отслеживать передний фронт и потом переключиться на отслеживание заднего фронта.
По запрещению и разрешению:
Сначала пробовал с помощью NVIC_EnableIRQ(); NVIC_DisableIRQ();
Потом написал поделку c использованием NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE/DISABLE
Работает на половину ((
Вопрос такой: надо ли после каждого такого телодвижения заново инициализировать PIN по пути GPIO->EXTI->NVIC?
К сожалению лог/анализатора нет и в схему также вносит значительные искажения отладка.
drozel
Nov 17 2015, 07:32
Цитата(MikleV @ Nov 17 2015, 12:28)

Вопрос такой: надо ли после каждого такого телодвижения заново инициализировать PIN по пути GPIO->EXTI->NVIC?
Код либы же открыт? Надо посмотреть код, что делают эти ваши функции.
По логике, функции типа NVIC_* не должны влиять на периферию пинов, ибо это даже не то что разные блоки, NVIC вообще относится к ядру.
Но что там делает конкретная либа видно из ее кода.
MikleV
Nov 17 2015, 08:05
Эти функции просто устанавливают биты в соответствующих регистрах. Т.к. в программировании именно для МК я скажем так начинающий то "железная составляющая" кода для меня не совсем прозрачна.
Например разрешение тактирования GPIO: RCC_AHB1PeriphClockCmd(GPIOXXX,ENABLE)
или EXTI/NVIC: RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE) означает что теперь эти части МК всегда будут работать? Т.е. если они один раз вызывались то повторно их вызывать не имеет смысла?
То же и по установке битов в регистры NVIC и EXTI. Есть ли моменты (кроме инициализации и прямого управления) способные их сбросить?
drozel
Nov 17 2015, 11:02
Ну тык а биты описаны в даташите. С этого и надо начать.
Для начала нужно открыть блок-схему МК, она обычно в даташите в начале. Там видно, какие блоки к чему подключены. У всех этих блоков есть свои регистры, через которые вы ими управляете (ну это на пальцах)
К примеру: RCC - блок клоков и ресета. RCC_AHB1PeriphClockCmd - включение клока для определенной периферии (их можно включать по отдельности для снижения энергопотребления, когда блок не нужен).
Если конкретно по вашим вопросам, то:
нет, регистры никто, кроме вас сбросить не может, если в даташите не указано обратное (например, флаги, которые вы наоборот должны читать, чтобы узнать о состоянии блоков).
Логика запуска МК:
1) Настройка клока
2) Включение RCC
3) настройка периферийного блока
4) настройка прерываний (NVIC + само прерывание)
MikleV
Nov 17 2015, 13:46
Спасибо. Мне собственно и нужно было понять принципы инициализации.
Тогда еще один вопрос про энергосберегающие режимы(LPM):
Меньшая частота тактирования GPIO по которому ожидается выход из LPMХ означает ли автоматически меньшее энергопотребление?
esaulenka
Nov 17 2015, 15:15
Какой конкретно режим? Если в его описании написано "периферия отключена", то она отключена, частота ноль.
Если включена, то какое-то влияние на потребление будет (хотя, конечно, куда больше пользы будет, если в том же sleep отключать внешний кварц и PLL).
ASDFG123
Feb 23 2017, 03:52
Как в отладчике Coocox Coide симитировать прерывание EXTI_11 запуск АЦП ? В железе работает, но хотелось бы и софтого запустить.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.