天天看點

Serial Communication Protocol Design Hints And Reference

  前面轉載的幾篇文章詳細介紹了UART、RS-232和RS-485的相關内容,可以知道,序列槽通信的雙方在硬體層面需要約定如波特率、資料位、校驗位和停止位等屬性,才可以正常收發資料。實際項目中使用序列槽通信時,一般還需要設計一套通訊協定。那麼設計序列槽通訊協定有什麼需要注意的地方呢?本文以iPod、車載CAN解碼盒及IoT裝置EnOcean的序列槽通訊協定為例,對通訊協定資料幀的定義做一個簡單的介紹和分析。

  首先看Apple提供的文檔《iPod_Accessory_Protocol_Interface_Spec_R38.pdf》,其中有關于設計序列槽通訊協定的詳細說明,具體如下。

The owner or creator of a protocol for communication between accessories and iPhone OS applications must define the preferences that are required or optional. Each accessory and application must then negotiate their level of compatibility directly. Apple does not referee protocols, and protocol creators must ensure that their accessories and applications can verify that they support the same features. The following suggestions can help with protocol design:

■ Ensure that the accessory can always resynchronize its data stream in the event of an error.

■ The round-trip latency of commands may vary; do not draw inferences from propagation times. There is no guarantee of delivery timing over the communication link.

■ After a connection has been established, clearly establish which end speaks first.

■ Begin communication with an exchange of meta-information, such as confirmation of the protocol and version. Give both ends the opportunity to declare that they cannot proceed due to protocol incompatibilities.

■ Ensure that the transaction order is clear and that both ends know their position in it. Packets within each stream are guaranteed to be ordered but not free of gaps between packets, so ensure that the stream can be resynchronized after a gap.

■ Ensure that responses can always be matched to their corresponding requests. The simplest forms of reliable communication are call and response. Interleaved communication streams are more complicated and less desirable.

■ Establish an unambiguous indicator of the start of each packet.

■ Add security where needed, but recognize that it slows down and complicates each transaction.

■ Ensure that the other end of each transaction has both received and understood the last packet.

■ Ensure that each packet is received intact and error free by adding a CRC value, checksum, or the like.

■ Ensure that incoming data can be cached until it can be processed.

■ Try to make the protocol extensible for future needs.

Command Packet Format

Use the small packet format for payloads up to 255 bytes. Use the large packet format for payloads greater than 255 bytes.

Small packet format

For command packets whose payloads are 255 bytes or less, use the small packet format.

Byte number

Value

Meaning

0x00

0xFF

Sync byte

0x01

0x55

Packet start byte

0x02

0xNN

Packet payload length

0x03

Lingo ID

0x04

Command ID

0x05…0xNN

Command data

(last byte)

Packet payload checksum

Note that the command ID and command data format for packets with currently unspecified lingoes may not follow the format indicated here (1 byte command ID, 0xN bytes command data). Also note that a packet payload length of 0x00 is not valid for the small packet format; it is reserved as a marker for the large packet format.

Large Packet Format

For command packets whose payloads are between 256 bytes and 65535 bytes in length, use the large packet format.

Packet payload length marker

Packet payload length (bits 15:8)

Packet payload length (bits 7:0)

0x05

0x06

0x07…0xNN

Packet Details

The sync byte (0xFF) is not considered part of the packet. It is sent merely to facilitate automatic baud rate detection and correction when using a UART serial port link and, in some cases, to power on the iPod. It is not necessary to send the sync byte when using BT or USB as a link.

The packet payload length is the number of bytes in the packet, not including the sync byte, packet start byte, packet payload length byte, or packet payload checksum byte. That is, it is the length of the command ID, lingo, and command data. Thus, the packet payload data length for a RequestIdentify command would be 0x02. The Lingo ID specifies the broad category that the communication falls under. The Command ID is a more specific indication of the significance of the packet and is interpreted differently depending on the Lingo ID.

Unless otherwise specified, the following rules apply:

■ All packet data fields larger than 8 bits are sent and received in big-endian format; that is, ordered from the most significant byte to the least significant byte.

■ Device command packets that have a valid checksum but contain an invalid parameter, invalid command, or other such failure cause the iPod to respond with an ACK command containing the appropriate error status.

■ A packet with an invalid checksum received by iPod is presumed to be invalid and is ignored. No ACK or other command is sent to the device in response to the invalid packet.

The sum of all the bytes from the packet payload length (or marker, if applicable) to and including the packet payload checksum is 0x00. The checksum must be calculated appropriately, by adding the bytes together as signed 8-bit values, discarding any signed 8-bit overflow, and then negating the sum to create the signed 8-bit checksum byte. All packets received with a nonzero checksum are presumed to be corrupted and will be discarded.

  CAN解碼盒和車載導航之間的通訊協定如下圖所示。

  

Serial Communication Protocol Design Hints And Reference

   EnOcean序列槽通訊協定資料幀格式定義如下圖所示。

Serial Communication Protocol Design Hints And Reference

  可以看到,三個協定的資料幀格式定義雖然有所不同,但基本遵循幀頭、資料幀長度、資料類型、資料及校驗和的格式。其中iPod在幀頭前面還有一個同步位元組0xFF,它實際上并不屬于資料幀,是為了自動波特率檢測和喚醒iPod用的。通常幀頭使用一個位元組即可,無需使用兩個或多個位元組作為幀頭。有些資料幀的定義沒有使用長度,而是使用特殊值作為幀尾,如GPS的NEMA語句,以回車換行作為幀尾。對于GPS子產品輸出的資訊,這沒有問題,但對于複雜序列槽資料的通信,如此定義的局限非常明顯,實際資料内容不能存在幀尾的特殊值,否則即會出錯。故除使用Asiic碼定義的資料幀以外,最好還是以長度屬性來明示資料幀的長度,而不要用幀尾符作為資料幀的結束。資料長度使用一個位元組還是兩個位元組來表示,沒有特别限制,主要看資料通信的大小。如果單幀資料量都很大,則用2個位元組,否則用1個位元組,偶爾需要傳一段大資料時,分包發送即可。像iPod定義了大小包,更靈活,但處理時稍微麻煩一點點。對于有效資料部分,通常還會碰到有些協定使用轉義位元組,以去除與幀頭相同的資料。這麼做,其實既沒有必要,又增加了開銷。通過資料長度足以排除有效資料部分的資料被誤認為是幀頭的可能。為了防止因通信錯誤導緻的程式異常,Checksum還是很有必要加上的,有了Checksum就可以在通信出錯時,向對方請求重新發送本幀資料或者直接丢棄本幀資料,而不會導緻資料解析異常和程式崩潰。像EnOcean協定,在幀頭部分也加了校驗,是雙保險,更可靠,在某些場合還是很有必要的。原來在做車載導航裝置時就曾碰到一個嚴重Bug,因資料幀頭錯誤,導緻通訊異常,且長時間不能恢複,原因就是資料幀長度錯誤地變為60KB多,而實際資料量隻有一百多位元組,導緻接下來所有資料都被認為是那一幀的資料部分。如果幀頭也有校驗就能規避這個這個問題了。

  除了資料幀格式的定義,資料流的定義也是通訊協定的重要部分,而這涉及具體的業務邏輯,這裡不作具體分析,如有興趣,可以參考協定文檔:

繼續閱讀