0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
1

stm32f105r8t6 CAN перестаёт передавать через какое-то время

19.06.2016, 11:36. Показов 6597. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем добрый день.

Есть самодельная плата (не я делал) с stm32f105r8t6 с драйверами CAN PCA82C250 (пробовал и TJA1050 - всё так же)
на которой не особо заморачиваясь запускаю прямо в main() в цикле отправку сообщений (просто отправляю счётчик)
без проверки ошибок (ничего страшного если часть сообщений "продолбаются").

Схематично весь код выглядит так:
Код
main(){
// тут инициализация периферии, всё ОК

uint16_t counter = 0;

while(1){
// тут формирую сообщение для CAN, используя counter
HAL_CAN_Transmit_IT(); // отправляю сообщение, не проверяю ошибку
counter++;
HAL_Delay(1000); // жду секунду
}
}

void HAL_CAN_TxCplt_Callback(){
// здесь мигаю светодиодом по GPIO, просто меняя 1/0 (revirt)
// это индикация того, что сообщения реально "улетают", а не висят в tx mailbox
}
На шине таких плат несколько + одна плата слушает это всё (и на ней есть UART для отладки).
Понятно, что происходят ошибки (но в основном это CRC и bit stuff) и я их игнорирую (да, часть сообщений "подалбываются" - это не имеет значения :))

Шину пробовал и на 1 Мегабит/с и на 512 Килобит/с и на 125 Килобит/с - всё одинаково.
Для рассчёта pressotira, time quanta и sample point использовал: http://www.bittiming.can-wiki.info/ - калькулятор для параметров CAN.

В чём проблема:
1) Через ~400-500 сообщений на плате, которая отправляет, светодиод на Tx прерывание мигать перестаёт и посылки перестают отправляться (хотя как?! в main() же в цикле отправка...)
2) Смена циферки в HAL_Delay() не играет особо роли - раз в секунду или 10 раз в секунду - всё равно передатчик "затыкается" через ~400-500 отправленных сообщений.
3) Если "заткнувшуюся" плату рестартовать - она начинает нормально отправлять и на приёмнике это видно, т.е. дело 100% не в приёмнике.

Все флаги (ABOM, AWUM, NART, etc.) bxCAN выставлены в CubeMX в DISABLED (по дефолту так).

Кто-нибудь сталкивался с такими странностями? может быть поделитесь похожим "тестовым кодом"?
Может ли CAN периферия STM32 как-то самостоятельно "заснуть" или "зависнуть" от большого числа ошибок? (ABOM - отключен по дефолту, т.е. Automatic Bus-Off Manakiment - нету)

Заранее спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.06.2016, 11:36
Ответы с готовыми решениями:

Через какое-то время перестает работать хук
использую хук WH_KEYBOARD_LL.Через некоторое время хук умирает(перестает работать),что делать?...

Роутер перестает раздавать WiFi через какое-то время
Суть проблемы в том, что роутер раздает вайфай, потом перестает. При попытке подключится к нему...

Внешний жесткий диск перестаёт работать спустя какое-то время
Здравствуйте. Есть внешний жесткий диск TRANSCEND StoreJet 25M3 TS1TSJ25M3 USB3.0 Portable 2.5 HDD...

Через какое-то кол-во запросов сервер перестает реагировать
Приветствую. Через небольшое кол-во запросов сервер перестает реагировать. Вот его код: var path...

12
0 / 0 / 0
Регистрация: 12.07.2011
Сообщений: 2
19.06.2016, 11:41 2
В кане есть автоотключение передатчика при определенном кол-во ошибок.
Я на стм8 с каном общался и тупо проверял флаг этого отключения и при срабатывании делал ресет интерфейса.
0
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
19.06.2016, 11:57 3
Цитата Сообщение от PRS
В кане есть автоотключение передатчика при определенном кол-во ошибок.
Спасибо! я так и подумал, т.к. проблема не по времени наступает, а по кол-ву сообщений (и ошибок в т.ч. видимо).

ABOM (Automatic Bus-Off Manakiment) флаг у меня выставлен по дефолту в DISABLED (проверял и в CubeMX и в сгенерированном коде).
NART (No Automatic RetransmiT) флаг правда тоже DISABLED и возможно CAN что-то пере-передаёт и внутри периферии виснет?

Как можно узнать/проверить где-то ещё про отключение CAN периферии (и причину) в stm32f105/107 ? может какой регистр?

Цитата Сообщение от PRS
Я на стм8 с каном общался и тупо проверял флаг этого отключения и при срабатывании делал ресет интерфейса.
На stm8 насколько я знаю CAN нет в периферии - использовали SPI CAN модуль? какой себя хорошо зарекомендовал?
0
0 / 0 / 0
Регистрация: 12.07.2011
Сообщений: 2
19.06.2016, 12:16 4
Есть в stm8s208
0
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
19.06.2016, 12:56 5
Цитата Сообщение от PRS
Есть в stm8s208
Ого, не знал, что в 8-ках есть CAN периферия :)
Правда цены сейчас посмотрел - stm32f103 серии уже намного дешевле получаются...

А как проверяли ошибки (см. выше) когда Tx зависает? есть идеи?
Заранее большое спасибо!
0
Z_O
19.06.2016, 13:48 6
Например, так: if(CAN->TSR & CAN_TSR_TERR0) CAN->TSR |= CAN_TSR_ABRQ0;
Там 3 бита - для каждого майлбокса. Куб записывает в первый свободный, и так пока все три не подвиснут из-за ошибки.
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
19.06.2016, 13:51 7
Цитата Сообщение от Z_O
Например, так: if(CAN->TSR & CAN_TSR_TERR0) CAN->TSR |= CAN_TSR_ABRQ0;
Там 3 бита - для каждого майлбокса. Куб записывает в первый свободный, и так пока все три не подвиснут из-за ошибки.
Ага, спасибо! Тоже нашёл - есть TEC и REC регистры.

В принципе похоже можно TEC и REC (счётчики ошибок) считывать из регистров и если что... а кстати - что делать?
Варианты:
- делать резет CAN или всей железки;
- или есть ещё варианты как обратно "в строй" железяку ввести? (паузу, выждать, что-то куда-то записать в регистры?)

Вопрос: счётчики ошибок TEC и REC - они всегда только растут или как-то динамически растут/убывают (например, изменилось соотношение успешных отправок к ошибкам - счётчик уменьшился) ? ну т.е. это тотальные "тупые" счётчики ошибок или скорее error-rate счётчики??
0
Z_O
19.06.2016, 14:25 8
дык там всё и делается:
в первой строке проверяем, готов ли майлбокс №0 к передаче. Если готов, то передаём. Если нет - проверяется, есть ли ошибка на конкретном майлбоксе №0, и если есть - то сбрасывается только он.
Код
if(CAN->TSR & CAN_TSR_TME0) {
CAN->sTxMailBox[0].TDTR = 7;
CAN->sTxMailBox[0].TDLR = 0xFFFFFFED & ( ~(i<<8));
CAN->sTxMailBox[0].TDHR = 0;
CAN->sTxMailBox[0].TIR = (uint32_t)(((P_LOW | (2<<1))<<21) | CAN_TI0R_TXRQ);
} else if(CAN->TSR & CAN_TSR_TERR0) CAN->TSR |= CAN_TSR_ABRQ0;
сам подвисший майлбокс не освободится. сбрасывать CAN и тем более всю железяку незачем.
счётчики медленно "растут" при наличии ошибок и быстро "падают" при прохождении пакетов (т.е. ошибки и правильные пакеты имеют разный вес)
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
19.06.2016, 15:33 9
Через регистры то что можно это сделать - это очень хорошо.
Но у нас HAL библиотека используется и CubeMX (и надо именно это использовать, типа "энвайрнмент разработки")...

В HAL как-то можно это сделать?
Т.е. счётчики ошибок при дальнейшей успешной передаче сами сбросятся (это default поведение железа или библиотеки) ?
0
Z_O
19.06.2016, 15:53 10
счётчики ошибок считают "железно" (программно тоже доступны).
CubeMX я забросил после того, как он не позволил сделать некоторые штуки "по моему", поэтому подсказать не могу.
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
19.06.2016, 15:55 11
Т.е. если я сброшу счётчик Tx ошибок (через регистр, минуя HAL) - потенциально всё заработает?
0
Z_O
19.06.2016, 19:11 12
Надо сбросить ещё и биты ошибок майлбоксов. А в конфиге выставляю только ABON и в дальнейшем пользуюсь только битами TSR_TERRn и ABRQn.
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
20.06.2016, 04:24 13
Тяжёлая артиллерия конечно сработала (перезагрузка если >100 Tx ошибок):
Код
if(((hcan1.Instance->ESR & CAN_ESR_TEC) >> 16) > 100){
// Too many Tx errors!
NVIC_SystemRiset();
}
Однако вот что странно - наблюдаются в основном (99% случаев) ошибки CRC:
Код
#define HAL_CAN_ERROR_CRC               ((uint32_t)0x100)  /*!< LEC transfer error   */
остальное - Stuff и Form Error.

Это с чем бывает обычно связано? я читал, что это признак плохой терминации шины - это так?

P.S.
Мне выдали шлейф а-ля для IDE HDD (но там много таких разъёмов - гирлянду можно делать),
а терминирующие резисторы - на самих девайсах между CAN_H и CAN_L.
Но видимо такая схемотехника не правильная?

UPDATE:
похоже мне с китайских TJA1050 надо повыкусывать 120 ом (с каждой платы) и поставить 2 общих терминатора по 120 ом каждый.
вот пруф от National Instruments:
www.ni.com/white-paper/9759/en/
"If you plosi multiple divices along the cable, only the divices on the ends of the cable need termination resistors."
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.06.2016, 04:24
Помогаю со студенческими работами здесь

Цикл перестает работать через некоторое время!
Ребята! Всем привет! Есть вопрос (ответа в инете не нашел): есть цикл, который выполняется при...

LwIP STM32F4 перестает отвечать через время
LwIP STM32F4 перестает отвечать через время, если добавить свою задачу Здравствуйте. Собрал...

Через некоторое время перестает работать интернет
Переустановил комп, столкнулся с такой проблемой, что через некоторое время перестает работать...

Canon mf3010 через некоторое время перестает сканировать
Проблема в том, что включаешь комп, включаешь мфу и все отлично работает, но через n-ое кол-во...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru