Жёсткий пробел в физике can шины.
есть только два устройства на шине.
второе только слушает и просыпается намного позже первого.
Как на первом(stm32) понять что второе проснулось и слушает шину?
Если я тупо пуляю в шину данные, то тут же в ответку получаю прерывание по ошибке:
Acknowledgement error
что логично, абоненты не подтвердили получение.
Есть ли какой способ узнать что хотя бы один абонент проснулся и можно слать данные?
Кинуть пакет и получить ACK.
то есть другого способа не существует? каждый такой пакет генерирует прерывание ошибки и увеличивает счётчик на 8, далее buss-off и последовательность заново. Хотелось бы избежать этого поведения.
CAN-устройство обнаруживает себя только посылкой пакета. Будут ли это данные или ACK - нет разницы.
Иначе извращаться только - спящий может проснуться, пульнуть “I am waked”, подождать и уснуть. А неспящий должен поймать waked-пакет, послать данные.
Ну так Тыжпрограммист))
Сделай что-то типа пустых запросов обмена перед основным. Общий принцип один: запрос-ответ. Иначе никак. Конечно можно и отдельный сигнал готовности меж устройствами пустить,но это извращение)
спасибо, печально конечно. думал, может, что то упустил, и есть в протоколе что то типа keep-alive.
Там нет сессионного уровня, откуда keep-alive взяться.
какой-то бред написан. Какая “последовательность заново”, если обмен еще не начался?
Разбирайте логику своих сообщений, вы явно какую-то ерунду делаете.
В кан-контроллере действительно хитрая система работы с шиной, потому что средств диагностики физики нет.
В МК в буфер кан-контроллеру пакет запихивает, тот его слать пытается несколько раз. Если провод оторвался или замкнут и из него не приходит ACK от любого устройства на линии, начинается увеличение счётчика ошибок и тп. В конце концов контроллер ресетить приходится или лампочкой аварийной моргать.
Наверняка можно отключить подтверждения. Я не знаток ARM , но всегда и везде есть возможность “ручками” делать. Примерно так: шлём без подтверждения запрос какой-либо, если пришло что-то, то переходим уже к основному обмену со всеми ask.
Собственно что в этом такого? Предусмотреть алгоритм действий. Вы же творец кода.
Stm позволяет отключить прерывание, но не увеличение счётчика и уход в bus-off. Надо посмотреть правда даст ли stm обнулить счётчик. Пока ловлю оказию в виде, спорадического ухода ведомого устройства в нирвану. Предполагаю, что когда устройство просыпается( а оно все таки что то шлёт) и в этот момент моя железка в bussoff и ответа ack нет. Надо менять логику. Но тут думаю не ждать первой посылки а попробовать загнать контроллер в sleep(правда не знаю будет ли ответ ack из этого режима), и потом по прерыванию wakeup уже начинать слать данные.
Как говориться - эксперимент рулит.
Копаться надо в даташите глубже. Наверняка проблемы и нет. Может скорость убавить,дабы ответчик успел что-то прислать, либо как-то руками сбрасывать ошибки.
война с мк продолжается. в ходе экспериментов выяснил непонятное поведение. Счётчик упирается в 128, вроде как контроллер переходит в error pasive. Описано, что в этом режиме в шину отправляется кадр ошибки рецессивным флагом состояния. Но что это значит я понять не могу. К ведомому устройству у меня доступа нет, так что что происходит в его недрах я хз, но оно регистрирует ошибку линии. Вышел из ситуации следующим способом - при возникновении прерывания о предупреждении счётчика ребучу контроллер. Это как оказалось ещё тот квест, сначала надо так
CAN1->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2;
__HAL_RCC_CAN1_FORCE_RESET();
__HAL_RCC_CAN1_RELEASE_RESET();
А потом переинициализировать всё снова.
ошибок в ведомом устройстве при этом не появляется.
Непонятно для меня остаётся причина уперания счётчика в 128, почему он не считает дальше и не выпадает в buss-off?
да, и где можно прочитать про оптимизацию скорости загрузки мк? вышеописанное правдиво когда stm32 постоянно запитано, а когда оба устройства вкл одновременно, то ведущее устройство, стартует быстрее и всё-равно детектирует ошибку. Выйду из положения, подачей питания каскадом, но может можно что-то придумать програмно.