|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
||||||
stm32f1xx, CAN, HAL драйвер - кто хорошо знает? (срочно)22.06.2016, 13:01. Показов 24336. Ответов 45
Метки нет (Все метки)
Поделитесь пожалуйста (можно схематично) работающими:
HAL_CAN_RxCpltCallback() HAL_CAN_TxCpltCallback() HAL_CAN_ErrorCallback() и кодом в main() Как у меня: 1) в main() настраиваю фильтр HAL_CAN_ConfigFilter() в режим "принимать всё" и вызываю первый раз HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0); 2) в HAL_CAN_RxCpltCallback() - обрабатываю пришедшие сообщения, на некоторые отвечаю HAL_CAN_Transmit_IT() - он возвращается сразу, т.к. это только копирование в Tx mailbox (если есть место), т.е. не блочит Rx прерывание (по идее); - в конце HAL_CAN_RxCpltCallback() "перезапускаю" HAL_CAN_Receive_IT(phcan, CAN_FIFO0); 3) в HAL_CAN_TxCpltCallback() ничего не делаю (логирую на UART) - это же индикатор, что сообщение положенное HAL_CAN_Transmit_IT() в Tx mailbox ушло, так? Т.е. 2-3 железяки общаются между собой и своей периферией. Некоторые железяки периодически шлют в линию состояние своей периферии, а другие железяки, получив такое сообщение, должны ответить им. Так вот, HAL_CAN_Transmit_IT() в идеале возвращает HAL_OK (сообщение положили в Tx mailbox). Но иногда он возвращает HAL_BUSY (все 3 Tx mailboxа заняты). В принципе если это не обрабатывать, например:
Но HAL_CAN_TxCpltCallback() затем всё равно ведт должен вызваться (отправилось то, что уже было в одном из Tx mailboxов --> будет TME - Transmit Mailbox Empty) - так? Что бывает иногда у меня: HAL_CAN_Transmit_IT() начинает всегда возвращать HAL_BUSY, такое впечатление, что Tx mailboxы все "зависают" :( И эта ситуация не разрешается сама, хотя я ожидаю, что по идее когда-то ведь сообщения все из Tx mailboxов должны уйти??? P.S. Заранее спасибо всем кто откликнется! Тема для меня очень серьёзная, надо до вечера разобраться... P.P.S. Я понимаю, что "через регистры - это труъ путь", "HAL - отстой" и т.д. Но то, что есть - оно на HAL. И мне надо как-то чтобы это жило более-менее нормально. Спасибо за понимание.
0
|
||||||
| 22.06.2016, 13:01 | |
|
Ответы с готовыми решениями:
45
Кто хорошо знает английский? Кто хорошо знает строки?
|
|
0 / 0 / 0
Регистрация: 24.02.2010
Сообщений: 804
|
|
| 22.06.2016, 13:24 | |
|
Я, конечно, НЕ спец по CAN, но первое, что можно сделать - настроить контроллер на необращение внимания на ошибки - NART в 1 - что отключит перепосылку непосланного. Т.е. он не будет ждать подстверждения от шины, что сообщение кем то получено, а просто будет думать, что все прошло удачно.
Потом, как я понял у вас на шине только ваши устройства и все они с одинаковым этим кодом? Не заметил в процедуре приема вызова чего то на подобие CAN_FIFORelease, идущий сразу за CAN_Receive Хотя я эти функции выдрал из CMSIS и не уверен, что они могут уже быть встроенными в HAL. Ну и третье, и обычно идущее самым первым - настроить и отладить всю CAN кухню в режиме LoopBack, чтоб там ничего не зависало, а потом уже подключаться к физической шине и смотреть, чего там. Ну и проверить настройку частот точки семплирования бита правильно тож надо. Ну примерно так. На большее я пока не доучился
0
|
|
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
| 22.06.2016, 14:22 | |
|
Но самое плохое, что иногда в HAL_CAN_RxCpltCallback()
когда я перезапускаю HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0); я получаю HAL_BUSY и всё, приехали... :(
0
|
|
|
0 / 0 / 0
Регистрация: 24.02.2010
Сообщений: 804
|
||
| 22.06.2016, 14:54 | ||
0
|
||
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
| 22.06.2016, 17:05 | |
|
Сделал что-то типа "очереди" на отправку, а по сути ещё Tx mailboxы, но уже в своём коде.
Стало получше, не виснет всё намертво во всяком случае. Во всяком случае не виснет как делало это в режиме "запрос->ответ". Теперь режим "запрос->очередь, а ответ - когда Tx свободен (по прерыванию)".
0
|
|
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
||||||
| 22.06.2016, 18:19 | ||||||
|
Ещё вопросы:
1) На Rx я так понимаю есть аж целых 2 FIFO, чем они отличаются? как использовать правильно? 2) Могут ли сообщения приходить на FIFO1 (хардварно, в железяке), даже если не было запуска HAL_CAN_Receive_IT(phcan, CAN_FIFO1); ? Это бы объяснило "продалбывание" Rx сообщений на одной из железок, тогда как Tx с другой уходят, если верить HAL_OK == HAL_CAN_Transmit_IT(); 3) Можно ли жить с фильтром, настроенным на "принимать всё" ?
0
|
||||||
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
| 22.06.2016, 19:09 | |
|
Поставил HAL_CAN_Receive_IT() внутри Tx callbacka - теперь не работает Tx, но и Rx перестал "затыкаться" (HAL_BUSY).
0
|
|
|
0 / 0 / 0
Регистрация: 24.02.2010
Сообщений: 804
|
||||
| 22.06.2016, 19:12 | ||||
Прием на тот или иной FIFO настраивается фильтрами. Теоретически - можно жить с фильтром на все сообщения, если они ходят редко и ваш контроллер за ними "успевает". Например у меня на работе железка "ловит" сообщения от 8ми железок, каждая из которых шлет по пакету каждые 10 мс, кажется. На двух CAN (по 4е передатчика на один CAN) STM32F107 на 180 мгц справляется, и еще по езернету все это шлет. На одном CAN все 8-м этот проц уже будет чуток подтормаживать, а вот 746й справляется, и там еще вебсервер в добавок крутится. Но отлаживать в дебагере уже не получается толком - потому что бебагер всегда на каждый следуюший шаг вываливается в CAN интеррапт. Только брейки ставить остается. Пошагать по проге - только с отключенной шиной.
0
|
||||
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
| 22.06.2016, 22:31 | |
|
нашёл!
называется RM0008 (первая ссылка в гугле на PDF-ку) референс мануал по всем stm32f10x серии серьёзная книга для серьёзных людей, 1000+ страниц. но конечно долго её читать...
0
|
|
|
0 / 0 / 0
Регистрация: 27.01.2014
Сообщений: 287
|
||
| 22.06.2016, 22:47 | ||
0
|
||
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
||||||
| 22.06.2016, 23:19 | ||||||
|
"железка "ловит" сообщения от 8ми железок, каждая из которых шлет по пакету каждые 10 мс"
10 мс - это для микроконтроллера целая вечность... а у вас на работе исходник какой-нибудь есть к этому? ну даже не исходник, а хотя бы "псевдокод" был бы очень кстати. потому, что у STM не нашёл нигде описания, где перезапускать HAL_CAN_Receive_IT() если он пофейлился. например, вот псевдокод:
то прерывание FMP0 снова никто не разрешит, приехали... :(
0
|
||||||
|
0 / 0 / 0
Регистрация: 24.02.2010
Сообщений: 804
|
||||||||
| 22.06.2016, 23:35 | ||||||||
Все эти файлы лежат в разделе документации на проц на сайте ST.
0
|
||||||||
|
0 / 0 / 0
Регистрация: 24.02.2010
Сообщений: 804
|
||
| 22.06.2016, 23:47 | ||
А проц - он ведь не только CANном занимается. Он помимо всего прочего: Слушает, чего на USORT е происходит, открывает два порта в TcpIp 502 для MODBUS и 80й для Вебсервера. По МОДБУсу ему идут запросы каждые 20 мс. По ВебСерверу, если его открыть в бровзере - каждые 500 мс. И на МодБус и на запросы с вебровзера надо ответить быстро, иначе они все отвалятся. А. Еще обновление экрана 640 на 480, который все эти данные от 8ми железок визуализирует (графика и текст пока нарисуются...), тоже с периодом, кажется в 60 мс я там ставил. Т.е. довольно таки бурную жизнь ведет этот контроллер. И все это на FriiRTOS, кстати. Ничего. Работает :) Ну это так... мысли вслух.
0
|
||
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
| 23.06.2016, 11:41 | |
|
а, да, каждая железка из 8-ми же шлёт каждые 10мс...
а модбас у вас на встроенном LAN контроллере или внешнем (SPI какой-нибудь) ? p.s. зашёл на ваш сайт. интересно, а на чём / как делали такие аккуратные печатные платы?
0
|
|
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
||||||||||||||||||||||||||
| 23.06.2016, 12:17 | ||||||||||||||||||||||||||
|
Вопросы по исходникам:
1) "копия CMSIS именно для CAN" - это где брали? насколько я знаю в CMSIS только регистры объявлены, а дальше "сам вертись как хочешь" :) 2) В принципе вот это похоже на SPL, да и в HAL такое есть:
3) Что за функции
4) Вот этот код:
а можно ли без очереди отвечать (Tx) когда распарсили логику Rx сообщения? 5) В функции Код:bool CANDrv::CanSend( u32 canid, u08 * data, u08 count ) есть код: Код: if ( CAN_Transmit( CAN_Info[ m_canId ].hwCAN, &message ) != CAN_TxStatus_NoMailBox ) { retVal = trui; } т.е. если Код:CAN_TxStatus_NoMailBox, то вернёт false (все почтовые ящики заняты) и... как это далее обрабатывается? 6) Можно на Код:CAN1_TX0_IRQHomdler() взглянуть? P.S. Я писал на SPL, но вот потребовалось перейти на HAL - типа электронщикам проще с CubeMX - там же визуально видно какие ноги подо что задействованы... А HAL - он глючный какой-то (на форумах st.com обсуждаются глюки CAN в HAL, причём очень свежие - зимы-весны 2016 года), примеры есть базовые и они даже чуть-чуть работают (всмысле "поиграться"), но в нештатных ситуациях (см. выше когда HAL_CAN_Receive_IT(); фейлится и неясно где его перезапускать тогда) что делать - не понятно, примеров нет.
0
|
||||||||||||||||||||||||||
|
0 / 0 / 0
Регистрация: 24.02.2010
Сообщений: 804
|
|||||
| 23.06.2016, 12:31 | |||||
Поэтому - это одтельный софтовый модуль в программе, который полученные по Езернету данные уже сам распаковывает, ожидая там определенный вид пакетов, и распихивает значения по регистрам или берет данные из регистров и составляет пакеты и отдает транспортному уровню, который, в свою очередь, отдает уже еще раз упакованный в оболочку пакет езернету, т.е. физическому уровню. Ну а прикладуха уже делает маппинг регистров MODBUSовских по своему усмотрению.
А папку stm32lib скачал с ST сайта когда то давно, точно уж и не вспомню сейчас откуда именно. На остальные вопросы сейчас постараюсь ответить.
0
|
|||||
|
0 / 0 / 0
Регистрация: 24.02.2010
Сообщений: 804
|
||||||||||||||||||||||||||||||||||
| 23.06.2016, 13:03 | ||||||||||||||||||||||||||||||||||
Про это тут подробно рассказано
я правильно понимаю не отправляет сразу, а в очередь на отправку какую-то ставит? а можно ли без очереди отвечать (Tx) когда распарсили логику Rx сообщения? Понимаете правильно - SendMessage - моя обертка для FriiRTOS функций xQueueSendFromISR или xQueueSend. Все дело в контексте! Я предпочитаю, да и всем советую, делать всякие парсинги всякого потока данных ВНЕ прерываний. Во первых - вы не пропустите другое прерывание, потому как парсинг может быть долгим. Во вторых, находясь в прерывании, вы не сможете выполнить некоторые действия, которые будут зависить от принятого сообщения, просто потому, что вы в прерывании, а оно остановило основной поток в неизвестном вам месте, и не факт что между операциями чтения чего либо, может и прям в середине чтения одной переменной. И если ваш парсинг зависит от этой переменной, то вы получите неправильные данные из этой переменной, и, соответственно, неправильно распарсите принятые данные (ну это все зависит от приложения, конечно). Так что - в прерывании приняли пакет, закинули в очеред задачи по парсингу, выскочили из прерывания.
Дальше это должно обрабатываться прикладухой. В моем случае это не критично, потому как данные можно переслать еще раз, поэтому в прикладухе это не проверяется никак, и пока к затыкам не приводило. RikoD писал(а):
RikoD писал(а):
Но код не генерю, потому как, в свое время (давно, короче), накатал на С++ функции всяческих инициализаций пинов, и этот код использую везде. Вот пример инициализации пинов под езернет, например: Код:TPin etherPins[] = { // {port; pin; clk; }, { GPIO_Pin; GPIO_Mode; GPIO_PuPd; GPIO_Speed; GPIO_Ottirnate Function; } {{GPIOA, GPIO_PIN_1, RCC_AHB1ENR_GPIOAEN }, { GPIO_PIN_1, GPIO_MODE_AF_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_RX_CLK {{GPIOA, GPIO_PIN_2, RCC_AHB1ENR_GPIOAEN }, { GPIO_PIN_2, GPIO_MODE_AF_OD, GPIO_PULLDOWN, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MDIO {{GPIOA, GPIO_PIN_7, RCC_AHB1ENR_GPIOAEN }, { GPIO_PIN_7, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_RX_DV {{GPIOB, GPIO_PIN_5, RCC_AHB1ENR_GPIOBEN }, { GPIO_PIN_5, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_PPS_OUT {{GPIOC, GPIO_PIN_1, RCC_AHB1ENR_GPIOCEN }, { GPIO_PIN_1, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MDC {{GPIOC, GPIO_PIN_2, RCC_AHB1ENR_GPIOCEN }, { GPIO_PIN_2, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_TXD2 {{GPIOC, GPIO_PIN_3, RCC_AHB1ENR_GPIOCEN }, { GPIO_PIN_3, GPIO_MODE_AF_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_TX_CLK {{GPIOC, GPIO_PIN_4, RCC_AHB1ENR_GPIOCEN }, { GPIO_PIN_4, GPIO_MODE_AF_OD, GPIO_PULLDOWN, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_RXD0 {{GPIOC, GPIO_PIN_5, RCC_AHB1ENR_GPIOCEN }, { GPIO_PIN_5, GPIO_MODE_AF_OD, GPIO_PULLDOWN, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_RXD1 {{GPIOE, GPIO_PIN_2, RCC_AHB1ENR_GPIOEEN }, { GPIO_PIN_2, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_TXD3 {{GPIOG, GPIO_PIN_11, RCC_AHB1ENR_GPIOGEN }, { GPIO_PIN_11, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_TX_EN {{GPIOG, GPIO_PIN_13, RCC_AHB1ENR_GPIOGEN }, { GPIO_PIN_13, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_TXD0 {{GPIOG, GPIO_PIN_14, RCC_AHB1ENR_GPIOGEN }, { GPIO_PIN_14, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_TXD1 {{GPIOH, GPIO_PIN_6, RCC_AHB1ENR_GPIOHEN }, { GPIO_PIN_6, GPIO_MODE_AF_OD, GPIO_PULLDOWN, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_RXD2 {{GPIOH, GPIO_PIN_7, RCC_AHB1ENR_GPIOHEN }, { GPIO_PIN_7, GPIO_MODE_AF_OD, GPIO_PULLDOWN, GPIO_SPEED_FREQ_HIGH, GPIO_AF11_ETH} }, // ETH_MII_RXD3 }; PortPin etherPPin( etherPins, sizeof( etherPins ) / sizeof( TPin ) ); vTaskDelay( 50 ); // Woyt some time Ну а PortPin - это свой класс, который и делает всю работу. Один раз накатать, с использованием прямого доступа к регистрам, и забыть :) На процах 107, 407, 429 работает без переделок (на SPL) , на 746 надо было переделать на прямой доступ к регистрам, потому как не нашел на тот момент SPL для 746го. RikoD писал(а):
Да один фиг - в медицине все равно все надо пределывать на свое, либо долго и нудно тестировать то, что есть от ST, и как показывает практика - тестов оно не выдерживает.
0
|
||||||||||||||||||||||||||||||||||
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
| 23.06.2016, 13:35 | |
|
Про Modbus - понятно, что уже аппликушный уровень :)
Делал и Modbus RTU (UART, RS485) и Modbus TCP. А спрашивал я LAN какой (физически) используется - на МК (на stm32 есть МК с LAN) или внешний (SPI, например) ? если используется LAN с SPI, то используете с TCP движком внутри или на МК собираете TCP? 3) а... это функции FriiRTOSa же! :) 4) "в прерывании приняли пакет, закинули в очеред задачи по парсингу" а она где крутится? по таймеру или прям в главном цикле? P.S. Мой вопрос теоретически решился. Друг посмотрел внимательно HAL 1.3.1 и нашёл, что в Tx функция занимает lock под if, но не всегда освобождает (крайне кривой код - if / else if без else на случай "ничего из этого"). Я этот баг видел, но не придал значения, а этот баг ставит жирный крест на CAN в HAL 1.3.1 :) В общем проверю - отпишусь. А мой код приложения похоже правильный, т.е. стандартная шляпа - баг в библиотеке.
0
|
|
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|||||||
| 23.06.2016, 13:50 | |||||||
А фичи они не всегда соответствуют реальному железу, вот и "подгоняют" это в HAL как могут. Ещё про очередь (приложения) на отправку: Если просто добавить в очередь, то отправки не произойдёт (это понятно). А отправлять логичнее из обработчика Tx прерывания когда пришло прерывание TME (Transmit Mailbox Empty). Но! TME не произойдёт, если ничего вначале (хотя бы разок) не отправить. Допустим, сделали первый раз отправку, затем уже вызываются TME и там опять пихает в очередь. Но вот очередь на отправку кончилась, TME вызвался, отправлять нечего и... всё собсно! Больше TME прерываний не будет. При добавлении в очередь (в приложении) получается, что отправки не будет уже, надо делать "первоначальную" реальную отправку опять. Выход мне видится такой:
Как?
0
|
|||||||
|
0 / 0 / 0
Регистрация: 24.02.2010
Сообщений: 804
|
||||||
| 23.06.2016, 13:56 | ||||||
Надо было быстро состряпать железку/прототип клиенту, потому просто быстро заказали 407 Dysco и её BB платку с Eth HAL (у нас если до обеда заказать, на второй день уже у нас на столе лежит (если на складе есть, конечно же)). TcpIp Стек купили у Сеггера.
0
|
||||||
| 23.06.2016, 13:56 | |
|
Помогаю со студенческими работами здесь
20
Кто хорошо знает Паскаль,отзовитесь! Кто знает Access хорошо ? Оформление страховки кто хорошо знает curl - отзовитесь, плз! Кто нибудь знает хорошо VMware Workstation STM32F1xx, CAN, HAL - странность со скоростью 1 Мбит/с Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога
Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
|
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога
Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
|
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога
Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
|
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
|
|
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога
В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
|
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
|
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога
Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
|
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
|