Перейти к содержанию
    

Порядок передачи бинарного числа по USART

Порядок передачи бинарного числа по USART.

 

Собственно, на что ориентироваться.

 

Имеется бинарное 32-разрядное число, например 0x12345678 unsigned int/32

В памяти (стандарт Intel) оно расположено

 

. . . 0x78 0x56 0x34 0x12 . . . .

 

Как это число передать по каналу связи в составе пакета:

---------------------------------------

(1) . . . 0x78 0x56 0x34 0x12 . . . .

или

(2) . . . 0x12 0x34 0x56 0x78 . . . .

---------------------------------------

 

(?) Есть ли какой либо стандарт, правило, обычай, традиция итд итп

как правильно (1) или (2) ?

Изменено пользователем k155la3

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

А вот над чем действительно надо думать - что будет с потоком байт, если какой-то из байтов будет искажен или потерян. В этом случае принимающая сторона не сможет собрать 32-битное число, а также все последующие (если не предпринять соотв. мер), и т. д.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

А вот над чем действительно надо думать - что будет с потоком байт, если какой-то из байтов будет искажен или потерян. В этом случае принимающая сторона не сможет собрать 32-битное число, а также все последующие (если не предпринять соотв. мер), и т. д.

Или говоря другими словами для передачи информации над USART надо надстроить протокол передачи данных. И в нем будет определено начало кадра, кому от кого и сколько... И контрольные суммы, если они нужны. А так же команды - данные, запросы и повторная передача данных при ошибке...

Например WAKE...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

А вот над чем действительно надо думать - что будет с потоком байт, если какой-то из байтов будет искажен или потерян. В этом случае принимающая сторона не сможет собрать 32-битное число, а также все последующие (если не предпринять соотв. мер), и т. д.

 

Если "все свое", то да. Главное, чтобы было однозначное преобразование при передаче в канл и при приеме.

Но может есть какая-то стандартизация, например как MODBUS-RTU укладывает. (надо там посмотреть будет)

 

Мне удобнее было бы передавать данные так, как они уложены в памяти. И принимать в том же порядке.

Но если одно и тоже ПО, передача с PC, а прием на MAC - будет фонарь.

 

С "потоком байт" проблем нет, если изначально отказаться от потока, а работать с фреймами/кадрам.

Отсечка пакета производится по межпакетной паузе (во многих контроллерах сделано аппаратно)

 

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

(тотже Ethernet и прочея работают не на байтовом потоке, а на фреймах)

 

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С "потоком байт" проблем нет, если изначально отказаться от потока, а работать с фреймами/кадрам.

Отсечка пакета производится по межпакетной паузе (во многих контроллерах сделано аппаратно)

Вот только Винды о хитрости с паузами не знают. и при передаче из РС они могут сделать какую угодно паузу...И в каком угодно месте...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

(?) Есть ли какой либо стандарт, правило, обычай, традиция итд итп
Есть понятие "сетевого порядка байт". Пусть у вас не совсем "сеть", используйте его.

 

Мне удобнее было бы передавать данные так, как они уложены в памяти. И принимать в том же порядке.

Но если одно и тоже ПО, передача с PC, а прием на MAC - будет фонарь.

Используйте функции преобразования: http://www.intuit.ru/studies/courses/2249/...ure/1567?page=5

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот только Винды о хитрости с паузами не знают. и при передаче из РС они могут сделать какую угодно паузу...И в каком угодно месте...

Там у них (виндузный драйвер) 3 настройки таймаута - можно юзать их. Я по крайней мере их пользую.

 

 

 

Есть понятие "сетевого порядка байт". Пусть у вас не совсем "сеть", используйте его.

 

Используйте функции преобразования: http://www.intuit.ru/studies/courses/2249/...ure/1567?page=5

 

Ok

Спасибо за инф.

Сетевой порядок посмотрю.

--------------------------

 

Думаю таки более правильно передавать в "Motorola" - порядке (т.е. сперва передаются старшие разряды ),

так как при подсчете CRC пакета, и наличии в конце его CRC16, которая расположена как <CRC_Hi> <CRC_Lo>

мы должны получить CRC == 0

 

А поскольку для этого CRC должна передаваться как <CRC_Hi> <CRC_Lo>, то и все остальные числа передаются

аналогично.

 

---- Посмотрел. Все ясно -----------

. . . .

Как известно, порядок байт в целых числах, представление которых занимает более одного байта, может быть для различных компьютеров неодинаковым. Есть вычислительные системы, в которых старший байт числа имеет меньший адрес, чем младший байт (big-endian byte order), а есть вычислительные системы, в которых старший байт числа имеет больший адрес, чем младший байт (little-endian byte order). При передаче целой числовой информации от машины, имеющей один порядок байт, к машине с другим порядком байт мы можем неправильно истолковать принятую информацию. Для того чтобы этого не произошло, было введено понятие сетевого порядка байт, т.е. порядка байт, в котором должна представляться целая числовая информация в процессе передачи ее по сети (на самом деле – это big-endian byte order). Целые числовые данные из представления, принятого на компьютере-отправителе, переводятся пользовательским процессом в сетевой порядок байт, в таком виде путешествуют по сети и переводятся в нужный порядок байт на машине-получателе процессом, которому они предназначены.

. . . . .

 

Изменено пользователем k155la3

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот только Винды о хитрости с паузами не знают. и при передаче из РС они могут сделать какую угодно паузу...И в каком угодно месте...

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При наличии нормального FIFO в контроллере UART эти "виндовые паузы" не должны вылезать наружу.

Да! Да! Враг не пройдет, паузы наружу не вылезут умирая в "нормальном FIFO". В этом же "нормальном FIFO" сгинут и нужные Вам паузы по которым собрались что то там "отсекать". Сюрпиз!

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да! Да! Враг не пройдет, паузы наружу не вылезут умирая в "нормальном FIFO". В этом же "нормальном FIFO" сгинут и нужные Вам паузы по которым собрались что то там "отсекать". Сюрпиз!

А вот и не сюрприз! :rolleyes:

Есть событие EV_TXEMPTY и WaitCommEvent функция, которые позволяют разблокировать передающий поток по завершении передачи данных. Также есть таймеры, отсчитывающие нужную паузу (см. CreateWaitableTimer).

И вообще - при грамотном использовании виндовых механизмов (потоки, события и overlapped-структуры) последовательный порт работает вполне себе неплохо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я собственно, в смысле настройки драйвера.

Значения 123 456 789

 

        HANDLE hport_Wes;
    DCB dcb1;

    COMMTIMEOUTS CommTimeOutsW;
    GetCommTimeouts(hport_Wes, &CommTimeOutsW);    

    CommTimeOutsW.ReadIntervalTimeout     = 123;
    CommTimeOutsW.ReadTotalTimeoutMultiplier = 456;
    CommTimeOutsW.ReadTotalTimeoutConstant   = 789; 

    SetCommTimeouts(hport_Wes, &CommTimeOutsW);
        succ=SetCommState(hport_Wes,&dcb1);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть событие EV_TXEMPTY и WaitCommEvent функция, которые позволяют разблокировать передающий поток по завершении передачи данных.

"Функции" моут быть декларированы любые. Суть в том, что для начала просто НЕТ в железе сигнала, который сообщит хоть "драйверу", хоть "функции", что передача данных завершена в части разгрузки Shift регистра, а не только FIFO.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Думаю таки более правильно передавать в "Motorola" - порядке (т.е. сперва передаются старшие разряды ),

так как при подсчете CRC пакета, и наличии в конце его CRC16, которая расположена как <CRC_Hi> <CRC_Lo>

мы должны получить CRC == 0

CRC совершенно не зависит от порядка байт.

Все зависит от порядка байт архитектуры на передающей и принимающей стороне.

Из-за большей распространенности little-endian ("интеловкий порядок") удобнее передавать в "неправильном" порядке:

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

CRC совершенно не зависит от порядка байт.

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

http://www.tahapaksu.com/crc/

 

а если ещё и всякой чудо используется в виде инверсии )))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Вы меня никак не расстроили. Написал слишком большой ответ и неудачно сократил.

Попытаюсь кратко повторить. Если обмен по USARTу происходит между "своими" или формируется собственный протокол, то я бы

посоветовал выбрать "интеловский" порядок байт в силу распространения такой архитектуры. Потому что, основное назначение CRC от порядка байт

не зависит, а за сомнительное преимущество загнать первым старший байт в алгоритм CRC при "сетевом" порядке придется расплачиваться постоянным

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

то достаточно всего лишь указания преобразования типа.

Изменено пользователем aiwa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...