Jump to content

    
Sign in to follow this  
_pv

rs485, адресация, бутлоадер, обновление прошивки

Recommended Posts

Есть несколько одинаковых устройств на шине rs485.

У каждого МК есть свой уникальный ID, но 8ми байтный - устанешь сканировать. (хотя наверное можно как-нибудь побитно как в 1wire)

Надо как-то раздать всем логические адреса 1-2 байтные логические адреса.

Можно это конечно делать при первичном программировании своего бутлоадера, или даже задавать джамперами, но не хотелось бы.

Хочется понять есть ли какие-нибудь нормальные способы опросить/просканировать одинаковые устройства на предмет их уникальных ID чтобы потом раздать им адреса, причем через rs485 , у которого нормального collision detection не очень предусмотрено.

хотя у МК даже есть отдельно прерывание на стартовый бит от уарта, так что понять что кто-то начал говорить на шине вроде можно.

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

 

Share this post


Link to post
Share on other sites
20 минут назад, _pv сказал:

Хочется понять есть ли какие-нибудь нормальные способы опросить/просканировать одинаковые устройства на предмет их уникальных ID чтобы потом раздать им адреса, причем через rs485 , у которого нормального collision detection не очень предусмотрено.

Значит - реализовать этот самый "нормальный collision detection" самостоятельно и с помощью него адресовать нужное устройство по длинному адресу. Механизмом, подобным CAN-овскому арбитражу. Только с 8*8-битным адресом.

Ведь физический уровень RS-485 это вроде позволяет.

Таким образом (через длинные адреса) назначить каждому девайсу короткий адрес, а потом уже штатно работать по рабочему протоколу по коротким адресам.

Share this post


Link to post
Share on other sites
17 minutes ago, jcxz said:

Значит - реализовать этот самый "нормальный collision detection" самостоятельно и с помощью него адресовать нужное устройство по длинному адресу. Механизмом, подобным CAN-овскому арбитражу. Только с 8*8-битным адресом.

эти 8байтные ID сначала надо как-то прочитать,

ну и чтобы было веселее RE и DE на драйвере 485 закорочены вместе, так что слушать что сам передаёшь и не испортил ли кто передачу не выйдет.

и у rs485 в отличии от CANа не предусмотрены доминантные/рецессивные уровни, и кто там кого перетянет - хз.

так что вопрос про "нормальный collision detection"  остаётся открытым.

Share this post


Link to post
Share on other sites

Т.е. у вас сеть - одноранговый мультимастер в полный рост, без координатора?
Тогда даже при наличии уже назначенных адресов у вас возникнут вопросы о разрешении коллизий при передаче и также о создании в каждом мастере таблицы адресов других узлов текущей сети.

Так что начальное назначение адресов это только маленький вопросик...

Share this post


Link to post
Share on other sites
1 час назад, _pv сказал:

эти 8байтные ID сначала надо как-то прочитать,

Не надо никак читать. Я же пишу: "назначить короткие адреса, через длинные посредством механизма, подобного CAN-овскому арбитражу".

Цитата

ну и чтобы было веселее RE и DE на драйвере 485 закорочены вместе, так что слушать что сам передаёшь и не испортил ли кто передачу не выйдет.

Выйдет. Если немного подумать.  :unknw:

Цитата

и у rs485 в отличии от CANа не предусмотрены доминантные/рецессивные уровни, и кто там кого перетянет - хз.

Так вроде - это зависит от того, как у вас реализован физический уровень.

В любом случае - это никак не мешает сделать как писал выше.

"доминантный/"рецессивный" - рассматривать просто как логические состояния, реализованные физически возможно иначе чем в CAN, то сам принцип - аналогичный.

Share this post


Link to post
Share on other sites

мультимастера при нормальной работе нет,

он возможно нужен для начальной "енумерации" устройств, если только не опрашивать эти id побитно как в 1wire.

Share this post


Link to post
Share on other sites

Если одно-мастерный режим - реализуемо легко. Обнаруживать слэйвы и назначать им короткие адреса - методом последовательной изоляции.

Share this post


Link to post
Share on other sites
1 hour ago, jcxz said:

Не надо никак читать. Я же пишу: "назначить короткие адреса, через длинные посредством механизма, подобного CAN-овскому арбитражу".

как я узнаю длинные 8ми байтные ID? подключаться сначала по одному и читать? ну так этого и хотелось бы избежать.
кановский арбитраж на физическом уровне выполняется, и когда передающий видит, что то, что он передаёт в шину отличается от того что он сразу же обратно принимает - это значит что на шине в данный момент есть кто-то с приоритетом повыше и надо пока отвалить. с 485 так не получится
 

Share this post


Link to post
Share on other sites
55 минут назад, _pv сказал:

кановский арбитраж на физическом уровне выполняется, и когда передающий видит, что то, что он передаёт в шину отличается от того что он сразу же обратно принимает - это значит что на шине в данный момент есть кто-то с приоритетом повыше и надо пока отвалить.

Ну вот так же и сделать. Заменив только физический уровень.

На физ.уровне у CAN есть 2 состояния: "доминантный" и "рецессивный". Для каждого бита. "доминантный" перекрывает "рецессивный".

Если для RS-485 принять: "доминантный" = передача какого-то байта; "рецессивный" - нет передачи байта. То всё дальше легко реализуется как у CAN на тех же принципах.

Например:

"доминантный": бит длинного адреса ==1 - передача байта ==255;

"рецессивный": бит длинного адреса ==0 - нет передачи.

T - тайм-слот некоторой фиксированной длительности.

F - флаг участия в цикле последовательной изоляции; изначально значение этого флага после старта ПО F=0.

Тогда один цикл последовательной изоляции

1-й шаг: Мастер посылает кадр "начало цикла, передача бита 63" и входит в ожидание приёма любых символов с линии в течение T (тайм-слот 0). Слэйвы не имеющие короткого адреса, устанавливают флаг F=1 . В дальнейших шагах цикла участвуют только слэйвы у которых F==1. 

2-й шаг: Слэйвы, у которых F=1, отправляют состояние 63-го бита своего длинного адреса в тайм-слоте 0. Если слэйв отправил состояние "рецессивный", то он наблюдает за шиной в данном тайм-слоте: если в тайм-слоте появляется "доминанта" - слэйв сбрасывает F=0 (покидает данный цикл скана).

3-й шаг: По истечении времени тайм-слота мастер начинает тайм-слот 1, отправляя кадр "передача бита 62". Слэйвы, у которых F==1 повторяют те же действия, что в шаге 2, но для бита 62.

...повторяем для всех 64-х бит дл.адреса.

последний шаг цикла последовательной изоляции: Мастер или собрал длинный адрес одного слэйва или собрал 0 (никто не ответил; дл.адрес 0 - запрещён для любого слэйва). Посылает в шину сообщение, назначающее короткий адрес тому слэйву, который дошёл до конца цикла (если собран 0 - то просто сообщение "конец цикла/старт нового цикла"). И запускает следующий цикл. Слэйв, принявший короткий адрес, сбрасывает F=0.

В тайм-слотах, на участках где мастер принимает данные, если наблюдается тишина - этот бит=='0', если там не тишина - бит=='1'. Приёмник мастера на этих участках должен интерпретировать и нормальный приём байта, и приём с ошибкой стоп-бита, и приём нескольких байтов - как приём бита=='1'.

 

Это самый простой вариант. Его можно оптимизировать, ускорив. Разными способами. Например: если все слэйвы (и мастер) имеют малый разброс частот тактирования, то можно удалить передачи от мастера с 3-го по предпоследний шаги, а начала каждого тайм-слота определять по таймеру от 1-го тайм-слота. Будет гораздо быстрее. Это будет асинхронный вариант. Но синхронный - надёжнее.

Можно и по-другому оптимизировать. всё решаемо!  :hi:

Share this post


Link to post
Share on other sites

PS: Если оптимизировать этот алгоритм, завязав его на аппаратные возможности периферии конкретного МК, то можно очень значительно ускорить его. И добиться времени цикла <2мсек (при бодовой скорости == ~1Мбод). Например на периферии инфинеоновского XMC4xxx это возможно - там можно сократить времена тайм-слотов до размера одного байта или чуть больше.

 

PPS: Также на время работы цикла (на время тайм-слотов), UART лучше перевести в режим самой короткой (насколько возможно) длины слова. Например: режим 5N1. Чтобы ускорить.

Share this post


Link to post
Share on other sites
32 minutes ago, jcxz said:

Ну вот так же и сделать. Заменив только физический уровень.

ну да, я это и имел ввиду под "перебирать побитно как в 1wire".

по скорости можно и не оптимизировать особо,

но если реализовать "мультимастер" на время энумерации, когда все просто начитают спрашивать мастера "вот мой ID, кто я?" с радномными задержками, чтобы минимизировать коллизии. У слэйва есть только пара тактов чтобы послушав линию что никто не передаёт, переключиться на передачу именно одновременно с соседом и устроить коллизию, так что вероятность вроде не сильно большая.

так вроде бы будет заметно быстрее, чем по 128байт (запрос+ответ каждого бита) на каждого слэйва, но зато не очень "детерминированно".

з.ы. контроллер xmc48 угадали :) слэйвы msp430.

Share this post


Link to post
Share on other sites
48 минут назад, _pv сказал:

так вроде бы будет заметно быстрее, чем по 128байт (запрос+ответ каждого бита) на каждого слэйва, но зато не очень "детерминированно".

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

И кто говорил про "128 байт"? Я говорил про символы, которые могут быть значительно короче байта.

Цитата

з.ы. контроллер xmc48 угадали :) слэйвы msp430.

А на XMC4800 разве минимальный размер символа UART не равен 1 биту (1 бит данных, или всего 3 бита - старт+данные+стоп)?  :wink:

На нём можно обнаружение одного слэйва уложить в гарантированные 640 мкс (а может даже меньше) при бодовой 1Мбод. Сможете такую же скорость обнаружения реализовать с "рандомными задержками"?  :wink:

 

Да, сможете.... только если на шине будет только 1 слэйв максимум.  :biggrin:

 

PS: И по общей загрузке шины функцией сканирования при большом количестве слэйвов мой вариант выигрывает. И сканирование можно вести прозрачно для основного протокола, почти его не тормозя.

Share this post


Link to post
Share on other sites
26 minutes ago, jcxz said:

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

И кто говорил про "128 байт"? Я говорил про символы, которые могут быть значительно короче байта.

А на XMC4800 разве минимальный размер символа UART не равен 1 биту (1 бит данных, или всего 3 бита - старт+данные+стоп)?  :wink:

На нём можно обнаружение одного слэйва уложить в гарантированные 640 мкс (а может даже меньше) при бодовой 1Мбод. Сможете такую же скорость обнаружения реализовать с "рандомными задержками"?  :wink:

Да, сможете.... только если на шине будет только 1 слэйв максимум.  :biggrin:

PS: И по общей загрузке шины функцией сканирования при большом количестве слэйвов мой вариант выигрывает. И сканирование можно вести прозрачно для основного протокола, почти его не тормозя.

даже с "трёхбитным" байтом вместо 10, (для ответа, для запроса 1 бита всё равно маловато будет) ускорение  раза в 2, то есть как пересылка нормальных 64байт ну или 640мкс.

а слэйву сказать "вот он мой 8ми байтный ID" и ответить мастеру "вот твой ID + вот твой адресный байт" - всего байт 20  туда+обратно или 200мкс.

у слэйва от проверки на занятость шины до её занятия, когда может возникнуть коллизия - ну пусть 0.5мкс (msp430 запись бита в порт которая направление переключит и тем самым прерывания запретит - несколько тактов, пусть будет 8), даже если для 256 слэйвов сделать рандомную задержку от 0 до 0.5*256*4 ~ 512мкс,  что даст в среднем 256мкс задержки на слэйв, то коллизия будет (если меня тервер не подводит) меньше чем у 10% которых надо будет переслать повторно. так что похоже что те же 256+200+10% ~ 500..600мкс на слэйва. но не совсем грантированные, это да.

Share this post


Link to post
Share on other sites
1 час назад, _pv сказал:

так что похоже что те же 256+200+10% ~ 500..600мкс на слэйва. но не совсем грантированные, это да.

Не понял как Вы получили вероятность коллизии в 10%, если у вас время на один слэйв составляет всего примерно в 2.5...3 раза больше чем длительность передачи??

При таком соотношении вероятность коллизии, должна быть == 1/2.5...1/3, т.е. = 33%...40%. В несколько раз больше. И это только при первой отправке кадров всеми слэйвами. Допустим мастер выделил из этой каши несколько целых, а остальные должны дальше опять в след. раз передавать. А там опять могут быть коллизии. И т.д.

Да к тому же ещё мастер должен разбирать эту кашу (из коллизий) и выделять из неё полезные кадры - нужно ещё какое-то кодирование кадров, чтобы выделять целые неповреждённые.

 

А теперь думаем дальше. Ок, предположим те же 500...600мкс. Итого по вашему алгоритму, если максимальное количество одновременно появляющихся слэйвов (которым нужно назначить адреса), принять равным 256 шт., то в случае одновременного их появления всех 256, суммарные затраты времени на обнаружение будут такими же как с моим алгоритмом. Допустим.

Но если одновременно появляется не все 256, а скажем - по одному? Что тогда? Тогда по вашему алгоритму на обнаружение даже одного нового слэйва, нужно потратить столько же времени, как на все 256. А по моему алгоритму - если появляется N новых, то на их обнаружение нужно потратить всего N+1 циклов скана.

Более того: если слэйвы могут иногда включаться и выключаться в процессе работы по одиночке и группами, то нужно периодически проводить их поиск. И по вашему алгоритму на каждый такой поиск придётся тратить столько же времени, сколько на поиск всех 256 шт.! И если подключение новых нужно обнаруживать оперативно, то придётся это делать часто и тратить дофига времени шины на это.  :cray:

А по-моему алгоритму всегда тратится только N+1 циклов скана на каждый поиск. Не зря я выше писал, что мой алгоритм эффективнее по общей загрузке шины.  :wink:

 

Да и вообще - реализация вашего алгоритма будет привязана к максимальному количеству слэйвов на шине - нужно его заранее знать (или заранее заложить максимально возможное число). Потому что если потом окажется, что слэйвов надо больше, то придётся всё переделывать, увеличивая время обнаружения (и снижая ещё более эффекивность). А по моему алгоритму - количество слэйвов на шине почти не играет никакой роли (в разумных пределах).

Share this post


Link to post
Share on other sites
5 hours ago, jcxz said:

При таком соотношении вероятность коллизии, должна быть == 1/2.5...1/3, т.е. = 33%...40%. В несколько раз больше.

вероятность коллизии сильно меньше, так как слэйвы старт биты других всё же могут отлавливать и соответственно заведомо не начинать передавать в течении следующих 10бит.

чтобы коллизия произошла надо двум точно попасть друг в друга с точностью ~ 0.3-0.5мкс (время переключения приём/передача) тогда, не заметив друг друга, начнут передавать оба.

если появляются по одному, то времени надо ровно те же 500мкс, на посылку слэйвом запроса "вот мой ID, кто я?" и получение ответа.

на ходу никто подключаться/отключаться скорее всего не будет, но если будет, то слэйв сам сразу же сообщающий при появлении "а вот он я", как только увидел что шина свободна (без активности больше 10мкс), всяко быстрее чем периодический поллинг мастером "а не появился ли кто?", но ценой хоть и мало-, но всё же вероятных коллизий, на время присвоения адресов.

а 500мкс получились и так для для максимального возможного количества слэйвов на шине, больше драйвера просто не потянут электрически.

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this