мультимастер что это такое

Мультимастер что это такое

You are using an outdated browser. Please upgrade your browser or activate Google Chrome Frame to improve your experience.

САЛОНЫ БЫТОВЫХ УСЛУГ «МУЛЬТИ-МАСТЕР»

Дом быта «МУЛЬТИ-МАСТЕР» – это сеть салонов бытовых услуг. Свою историю компания ведет с 2000 года и успешно работает на рынке бытового обслуживания населения. Основная сфера деятельности: ремонт и реставрация одежды, обуви, сумок, изготовление ключей, гарантийный ремонт чемоданов Samsonite и многое другое.

Большая часть наших салонов представлена в крупных торговых центрах Москвы и Московской области, что обеспечивает шаговую доступность от дома или метро. Только за последний год мы открыли 5 новых салонов в разных районах города.

Наши мастера имеют высокую квалификацию и проходят постоянную аттестацию в собственном учебном центре. К своим заслугам мы относим высокое качество предоставляемых услуг, что дает нам право называться компанией №1 в сфере бытового обслуживания. Сейчас количество наших клиентов превышает 300 000 человек в год и эта цифра постоянно увеличивается.

Еще одним важным преимуществом является предоставление гарантии на выполненные работы до года.

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

Источник

О компании

МУЛЬТИ-МАСТЕР – это сеть салонов бытовых услуг. История компании насчитывает более 20 лет успешной работы на рынке бытового обслуживания населения. Основная сфера деятельности: ремонт и реставрация одежды, обуви, сумок, изготовление ключей и многое другое.

Большая часть наших салонов представлена в крупных торговых центрах Москвы и Московской области, что обеспечивает шаговую доступность от дома или метро. Только за последний год мы открыли 5 новых салонов в разных районах города.

Наши мастера имеют высокую квалификацию и проходят постоянную аттестацию в собственном учебном центре. К своим заслугам мы относим высокое качество предоставляемых услуг, что дает нам право называться компанией №1 в сфере бытового обслуживания. Сейчас количество наших клиентов превышает 300 000 человек в год и эта цифра постоянно увеличивается.

Еще одним важным преимуществом является предоставление гарантии на выполненные работы до года. А так же, предоставление скидок постоянным клиентам и скидки 30% на детскую одежду до 128 роста.

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

Тысячи благодарных клиентов, миллион спасенных вещей

Для подробной информации о расположении салонов бытовых услуг перейдите по ссылке «Все адреса».

Источник

Мультимастер на USI

Это логическое продолжение предыдущей статьи «USI в двухпроводном режиме».
В этой статье пойдет рассказ о построении системы связи нескольких микроконтроллеров в составе одного устройства, на основе аппаратного модуля USI. Описаны «грабли» и «подводные камни» USI, а так же пути их обхода, на основе реального кода.
Все это реализовано и отлажено на двух микроконтроллерах ATtiny44A, один из которых работал на 8МГц, а другой на 1МГц. Размер кода 408 байт (204 слова).

Вступление

Представим себе некоторое устройство, в котором работают сразу несколько микроконтроллеров. Каждый микроконтроллер выполняет свою часть работы и при необходимости сообщает остальным о неких событиях или состояниях. Кроме того он должен отвечать на вопросы соседей или сам их спрашивать. Среди них нет главного, который за всеми следит и всеми командует. Вместо постоянного и регулярного опроса о состоянии, используются нерегулярные сообщения по событиям (изменении состояния это тоже событие).

Разумеется, что такая связь может быть построена только на режиме «мультимастер». Это значит, что в каждый момент времени, кто-то выполняет роль мастера, то есть управляет передачей, но эта роль постоянно перераспределяется среди равноправных участников. Вопрос о приоритете того или иного мастера решается с помощью «неразрушающих коллизий».

Примером таких коллизий может служить дорожный перекресток, когда два автомобиля одновременно хотят проехать. Они должны решить кто сделает это первым, а кто вторым. На эту тему в ПДД есть куча правил и если все их соблюдают, то получаются «неразрушающие коллизии», а если хоть один участник посчитает, что он всегда прав или просто «зевнет», то происходит «разрушающая коллизия»… еще как разрушающая.

В нашем случае правила проще: каждый из претендентов в мастера выставляет свой бит на шину, у кого 0 тот и выигрывает, если у всех 0, то выставляется следующий бит и так далее, в итоге на шине остается один мастер, он-то и продолжает передачу (именно продолжает, а не начинает заново), а все остальные записывают за ним.
На таких принципах построена CAN (англ. Controller Area Network — сеть контроллеров), идеи которой собственно и вдохновили меня на создании нечто подобного, только в более бюджетном варианте.

Информация принимается и отправляется пакетами, это цепочка из двух и более байт данных, которая имеет начало и конец. Для контроля верности передачи, в пакет вводится контрольная информация, обычно CRC (англ. Cyclic redundancy check) — алгоритм нахождения контрольной суммы, предназначенный для проверки целостности данных.
Приняв пакет, микроконтроллер должен проверить его валидность и сообщить отправителю результат, тот в свою очередь, либо повторяет передачу, если пакет попортился в пути, либо успокаивается, с чувством выполненного долга. Верно переданные-принятые пакеты поступают на дальнейшую обработку, иначе — отбрасываются.

Ну вот собственно, предисловие закончено, пора приступать к описании реализации.

Аппаратура

Самое время показать упрощенную схему USI переведенного в двухпроводный режим, так как далее будут ссылки на флаги, биты и регистры его.

От предыдущих картинок, эта несколько отличается, добавлена информация полученная в процессе работы над программой, ну и раскрасил цветами… вот только тени не наложил.

Сейчас видно, что бесполезно пытаться влиять на флаг коллизии USIDC, так как он есть не что иное как «исключающее ИЛИ» от того, что присутствует на SDA и того, что мы хотели туда поместить.
Детектор фронтов окрашен в красное, что бы показать, что он корректно работает, только с импульсами большей длительностью, чем один такт CPU. Если импульс короче, то велика вероятность, что его не сосчитают. Это основное аппаратное ограничение скорости передачи.

Читайте также:  Турунч или ичмелер что выбрать

Добавил транзисторов на выходные линии. На мой взгляд так виднее, что состояние SDA зависит от двух источников управления, а SCL — от трех.

Ключ и инвертор с надписью «удержание» покрасил в красное, потому что наступил на эти грабли… и хорошенько на них потоптался… было больно.

И последнее: дорисовал вентиль NOR на защелке USIDR, он должен показать, что пока лини SCL=0, все что пишется в старший бит USIDR, прямиком попадает на линию SDA, этим надо пользоваться.

Описание аппаратной части USI на этом считаю законченным.

Пакетная передача

Описываемый протокол приема-передачи, не имеет ни какого отношения к I2C(TWI). Разница не только в трактовании отдельных битов(R/W, ASC и прочего), а в том, что мастер никогда не принимает данные от слейва.
В этом протоколе: Master — это тот кто сейчас говорит, а Slave — тот, кто сейчас слушает. Благодаря тому, что роли мастера или слейва действительны только в данной конкретной передаче, участники беседы в следующей передаче могут обменятся ролями и данными.

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


Передача пакета начинается с формирования мастером стартовой кондиции, он прибивает SDA(вверху) к 0 при высоком SCL(внизу), при этом у всех присутствующих на шине сработает флаг USISIF (этот флаг сам по себе не способен уложить SCL, это важно помнить). Потом мастер прижимает SCL и на линии SDA появляется бит7. Слейв (зеленый) готовится к приему и удерживает линию SCL (флагом USISIF!), не давая ей подняться, пока он не будет полностью готов к приему.

Вообще это время, когда на SCL ноль, самое оно для работы программы, ведь она может его растягивать под свой темперамент. Эти островки стабильности синхронизируют всю передачу, мастера отрабатывают каждый такой интервал, а слейвы только некоторые (показано синим).

Когда все погасят свои флаги USISIF, обнулят счетчики фронтов (USICNT0..3), линия SCL поднимется и начнется передача байта из сдвигового регистра USIDR мастера прямиком в USIDR-ы слейвов, сколько-бы их там не было. Почему именно так, а не наоборот? Да просто ключ dSDA замкнут только у мастера, а у слейвов он разомкнут и они не могут повлиять на линию SDA, только слушать. Хуже дело обстоит, когда в деле участвуют два и более мастеров, тут жди коллизии… но об этом позже.

Когда мастер отщелкает 8 импульсов, содержимое его USIDR перекочует в слейвы и они опять будут удерживать SCL, пока не прожуют принятую порцию. Мастер, не тратя время даром, готовит для них 9-й бит(Next), он подскажет слейвам, что делать далее, будет следующий байт или нет. Если очередной Next окажется нулевым, все поймут, что пакет кончился и пора посчитать его CRC, у «правильного» пакета он должен получится нулевым.
Так это или не так, мастер узнает после 10-го бита (NoErr)… Десятый он потому, что идет после 9-го… Задорнов это лучше объясняет.
Итак, на период действия 10-го бита все замыкают свой ключ dSDA, типа «я мастер», и выдают 1 на линию SDA. Если хоть один скажет «0» (у него CRC неверное), это увидят все и мастер в том числе… ну что-ж, «все» выкинут битый пакет, а мастеру придется повторить все заново.
Обычно все проходит нормально, все рапортуют «NoErr», мастер со спокойной совестью формирует кондицию stoP, и уже другой мастер может начать передачу своего «мяу».

Было бы заманчиво обойтись без 9-го (да и 10-го) бита, ведь конец пакета можно отметить stoP кондицией, но тогда пришлось бы отказаться от контроля правильности приема-передачи, выбросить CRC и уповать на то, что «все будет хорошо». Кстати в I2C(TWI) так и сделано.

Тут уже должно быть понятно чем делать и что делать (мне во всяком случае понятно), пора выяснить как это делать.
Себе в помощь я нарисовал алгоритм вот в таком виде:

Вверху состояния через которые проходит микроконтроллер в процессе приема-передачи, а внизу — как это выглядит на линиях SDA и SCL.
Начинается все после сброса (RESET), микроконтроллер инициализируется и тут-же формирует кондицию stoP, а пусть будет у всех присутствующих на данный момент поднят флаг USIPF, это с одной стороны выстраивает линии в нужное состояние (везде 1), а с другой — портит возможно уже начавшуюся передачу, ведь если вклиниться в середину пакета, то все равно возникнет ошибка CRC и пакет придется отбросить.
Потом чип (так короче чем микроконтроллер) начинает ждать стартовую кондицию или поступление данных в буфер передачи, это состояние идентифицируется по двум программным флагам f9 и fB (рыжие на картинке). Эти флаги управляют поведением протокольного автомата, если fB=1 значит принимаем байт, иначе — бит, когда f9=1 мы тоже принимаем бит, только вот 9-й или 10-й зависит от состояния fB. Чудно, но не страшно.
Дождавшись флага USISIF, выполняем подготовительные действия и выставляем fB=1, принимаем байт, ставим f9=1, принимаем 9-й бит, анализируем его, если есть продолжение, гасим f9=0 и переходим в состояние приема байта, опять добираемся до анализа 9-го бита, пусть в этот раз он окажется нулевым (больше байтов не будет), проверяем CRC, сбрасываем fB=0 и переходим на прием 10-го бита, принимает его, анализируем и выполняем действия Err или OK, потом формируем кондицию stoP, гасим f9=0 и плавно переходим в состояние WaitStart, всё, круг замкнулся. Видите как все просто.

Читайте также:  Фалафель в пите что это
Блок-схемы

Программа работы с USI разделена на две части, одна занимается обслуживанием аппаратуры, другая следует протоколу обмена (кстати, если ее подкорректировать, то можно приспособить и к работе с протоколом I2C, всякие там ASK и NASC, но это уже факультатив).
Ниже дана «аппаратная» часть программы.

Эту громко сказано подпрограмму, нужно периодически вызывать из основного цикла, то есть слейв занимается своими делами, забегая иногда взглянуть на свои аппаратные флаги. Стоит напомнить, что эти флаги работают как ловчие силки для птички SCL, если они сработали, то все останавливаются и ждут пока последний не проверит свои силки и не отпустят SCL.

Флаг USISIF обрабатывается прямо тут на месте, а вот USIOIF, требует вызова Вия, то есть протоколиста… а вот и он:

В зависимости от программных флагов f9 и fB, действия развиваются по разным сценариям-веткам.
Если мы приняли байт (f9,fB=0,1), то его нужно сохранить в буфере приема, что и пытаемся сделать, но может оказаться, что буфер кончился и «мест нет»… что-ж, ничего не трогаем и уходим бегать по делам (одним из которых возможно станет чтение ранее принятых пакетов, что освободит немного места в буфере приема) и «пусть весь мир подождет». Потом вернемся и «докуем», то есть переведем стрелки на прием 9-го бита (f9=1) и приготовимся его встречать новой ловушкой (USISR=14).

Если приняли 9-й бит (NEXT) (f9,fB=1,1), то либо идем считать CRC (next=0) и выкладываем на SDA результат, переходим на прием 10-го бита, что бы узнать как обстоят дела с CRC у остальных, либо настраиваемся на прием следующего байта пакета.

Если приняли 10-й бит (NoErr) (f9,fB=1,0), то либо принимаем пакет, то есть делаем его видимым для читателя, либо отбрасываем, но в любом случае формируем стоповую кондицию, это нужно, что бы быстрые мастера не ждали медленного слейва, пока он разрешит им сформировать эту кондицию, они прокукарекали, а там уж… пусть последний закроет дверь.

Есть еще одна ветка (f9,fB=0,0), но ей тут вообще нечего делать, ведь это состояние ожидания Start, а протокольные дела начинаются после USIOIF=1, что никак не связано со стартом передачи.

Так, со слейвом разобрались… посмотри, что там у мастера:

Видно, что работы у него побольше…
Сразу бросается в глаза, что чипу, что-бы стать мастером (покраснеть), необходимо иметь данные для передачи (разумно, не правда-ли?), но этого недостаточно, нужно также еще разрешение на начало передачи (USIPF=1) или хотя-бы повод (USISIF=1).

Когда эти условия выполнены и байт помещен в USIDR (этим занимается подпрограмма NextByte) чип начинает трудится в поте лица, не отвлекаясь на другие дела… но без фанатизма, если кто-то где-то тормозит, мастер уходит заниматься другими делами и продолжает свою передачу позже.

Мастеру приходится рулить линией SCL, что бы сформировать на ней тактирующие импульсы, её нужно отпускать, следить за подъемом и снова опускать и так по быстрому кругу (медленный круг — это с выходом в основной цикл). Что бы следить за каждым импульсом, он должен всегда устанавливать USISR=14, чтобы флаг USUOIF сработал на следующем отрицательном фронте, то есть не может использовать USICNT0..3 как счетчик битов (не то, что слейв). Поэтому он использует один из регистров CPU (stBit) для подсчета (вычита) переданных бит (или, если угодно, сформированных импульсов).
Тут не используется бит тактирования USITC из регистра USICR. Дело в том, что эти битом удобно пользоваться для перевода линии SCL в оппозитное состояние, если есть гарантия, что этим кроме тебя никто не занимается. Если в системе есть несколько мастеров и каждый дергает общую линию SCL в свою сторону, то есть вероятность, что линия никогда не поднимется: то один, то второй будет ее удерживать, оба захотят отпустить, а в третий её уже держит… так и будут играть в догоняли.
Вместо этого линия SCL управляется через portSCL, с оглядкой на её текущее состояние. Если мастер «видит», что линия поднялась, а флаги из USISR еще не сработали, то он укладывает SCL опять в 0, формируя тем самым отрицательный фронт импульса. Еще он должен учитывать, что на шине могут присутствовать более медленные устройства, и специально затягивать импульс SCL, что бы эти ленивцы могли его заметить.
Обращаю внимание на «странность»: когда USIOIF=1, первым делом мастер отпускает SCL (_/ SCL)… якобы. Дело в том, что в этот момент линия SCL удерживается внизу самим флагом и, возможно, битом portSCL, вот его-то мы и убираем, что бы быть уверенными, что впоследствии, погасив флаг USIOIF, мы реально отпустим линию SCL.

В конце концов мастер, запыхавшись, добирается до протокольных дел:

Тут мало отличий от слейва, разве что необходимость сформировать бит Next, глядя в свой пустой карман (ромбик Last)… а потом опять бить в барабан, проталкивать биты и байты. Еще можно заметить, что мастер сам не принимает переданный пакет («нафига он Нам, когда он Вам?»), вместо этого он сбрасывает переданный пакет, убирая его из буфера передачи.

Ну вот и добрались до самого интересного, прием и передачу мы уже освоили… теперь осталось все это слить в один шейкер, добавить немного коллизий, хорошенько перемешать (но не взбалтывать!) и посмотреть на коктейль под названием «Мультимастер»:

Тут и далее зеленым цветом помечены пути и действий для слейва, красным — для мастера, а черным — то где они оба топчутся.
Желтые ромбики разделяют дела мастера и слейва, то есть бит dSDA служит индикатором режима.

Обработкой коллизий занимаются только мастера, это их тёрки. «Обработка» это громком сказано, на самом-то деле это всего лишь сравнение переданного бит (b7) с принятым b0, когда они равны — коллизии нет, если-же передавали 1, а получили 0, вот тут и она — коллизия. Правила хорошего тона, требуют, что бы проигравший мастер срочно перекрасился в слейва. Это может произойти при передаче любого бита, поэтому новоиспеченный слейв, корректирует свой счетчик фронтов, таким образом, как будто он с самого начала пакета и был слейвом. Как видим это не сложно (USISR=16-2*stBit).

Читайте также:  можно есть перловку каждый день

Тут нужно обратить внимание на то, что (b7) это специальный программный флаг, он равен содержимому 7-го бита сдвигового регистра USIDR, до того как поднялась линия SCL, то есть ДО сдвига USIDR положительным фронтом SCL.

Аппаратный флаг USIDC, который должен показывать коллизию (для этого он и сделан)… врёт, не постоянно, а иногда. Его беда в том, что он не имеет памяти, он показывает текущее состояние, «что вижу, то пою». Во время приема-передачи байта, он ведет себя правильно, так как данные на SDA появляются синхронно (по спаду SCL) и остаются неизменными на весь период SCL=0. Когда же мастера меняют байт, на линии SDA данные меняются асинхронно, сначала появятся бит7 от одного мастера (напомню, что пока SCL=0, все что пишется в бит7 USIDRа, сразу появляется на SDA), потом от второго, третьего…
Флаг USIDC, добросовестно покажет первому мастеру «все ОК», так как в этот момент коллизии действительно нет, мастер пока один влияет на SDA, потом приходит второй мастер и ставить SDA в свое положение и если у него на выхлопе 0, то и ему USIDC покажет «усе в порядке шев» и это будет правдой, вот только первый уже не узнает о том, что он проиграл (возможно) и должен уступить. В итоге два мастера могут одновременно передавать, гася своими нулями единицы другого и совершенно не замечая этого. В конце концов USIDC разрулит коллизию и один из мастеров наконец-то уступит, но если было хоть одно наложение данных, то испорченным окажется весь пакет и не факт, что в следующую попытку ситуация не повториться.

USIDC не то что-бы врет, он вводит в заблуждение, если в системе более одного мастера (хм, а если мастер всегда один, то нафига он вообще нужен? ). На мой взгляд, он должен бы запоминать свое состояние на момент положительного фронта SCL, то есть когда бит реально вдвигается в USIDR и держать его до следующего положительного фронта, тогда мастера успеют вовремя заметить коллизию и мирно разойтись, не разрушая данные и пакет.
Поскольку аппаратно это не реализовано, пришлось сделать программно.

Настал черёд сделать коктейль из протокольных автоматов:

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

Исходники

Все это реализовано и отлажено на двух чипах ATtiny44A, один из которых работал на 8МГц, а другой на 1МГц. Размер кода 408 байт (204 слова), правда без подсистемы управления буферами FIFO (еще 140 слов), но эта подсистема работает не только на USI.

Программа состоит из нескольких функций. Ниже я даю их реальные листинги, однако проблема в том, что ни один компилятор их не прожуёт (ну разумеется кроме моего), но зато они снабжены подробными комментариями и слегка похожи на С, что, надеюсь, поможет разобраться, что и как было сделано.

После рестарта чипа вызывается функция USIreset,

она проваливается в функции USIstoP, которая формирует стоповую кондицию. Инициализация USI на этом заканчивается.

Далее из основного цикла программы регулярно вызывается функция USIdo:

Её задача сохранить и восстановить регистры задействованные в работе основной функции [USI]:

Это как раз обработка аппаратных флагов USI. Тут надо быть острожным в обращение с флагами в USISR.
Дело в том, что есть как минимум две модификации аппаратуры USI. Одна из них например реализована в чипе ATtiny26, там доступ к флагам USISR сделана по принципу «чтение-модификация-запись», то есть, если попытаться погасить один флаг, послав в него 1 командой SBI USISR,x, то вместе с ним погаснут и другие, ведь они тоже стоят в 1.
В другой модификации, такой как в ATtiny44A, эта бага устранена и можно свободно пользоваться битовыми командами, без опасения повлиять не на тот флаг. Тем не менее, для совместимости все операции с USISR, производятся через OUT, как это и рекомендовано в описании ATtiny26.

Функции NextByteTx и USIchskCRC зависят от реализации буферов и тут не приводятся, а протокольный автомат вот:

Заключение

И напоследок пара «семейных фотографий» от знакомого осциллографа:


На этой «фотографии» ATtiny44A с тактовой частотой 8МГц, передает самому себе пакет из двух байт.
Хорошо видно (слева на право): стартовую кондицию, байт 0x33, бит Next=1, байт CRC (0x17), следующий бит Next=0, бит NoErr=1 и, наконец, стоповая кондиция. Байт передается со скоростью 138кб/сек.

А вот тот же пакет, и тот же чип, только в присутствии «медленного слейва», в качестве которого используется ATtiny44A с тактовой частотой 1МГц.


Стартовая кондиция не влезла в экран, но хорошо видно, что скорость передачи байта осталась прежней, а вот паузы на обработку байтов и битов заметно выросли, тем не менее оба чипа успешно приняли пакет, о чем свиделельствует 1 в бите NoErr.
Эта картинка показывает, что на одной шине могут совместно жить и понимать друг друга чипы с 8-ми кратной разностью в скорости работы. На мой взгляд это намного «вкуснее» чем 7% допуска на несовпадение частот для UART.

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

Источник

Строительный портал