where : ibrtses embedded
the ibrt long message protocol
This simple and compact protocol is an extended version of the short message protocol and optimized to download large amounts of data from embedded devices. The protocol is a binary master-slave with a CRC protection for 2^16 bits, or 8kbytes. The two byte length field would allow a message length to 65535 bytes though. Used with AVR controllers, the message length is restricted by the available RAM buffers.
the fields
The message is composed of fields :
[SYN++] STX (LenLo LenHi) SRC DST Cmd [Data] (CRCLo CRCHi)
where
- [SYN++] is at least 2 SYN character 0x16
- STX is start of message (1 byte) = 0x02
- Len is 2 bytes counting the number of bytes not including the SYN, low byte first
- SRC is the source ID (1 byte)
- DST is the destination ID (1 byte)
- Cmd is a predefined command code (1 byte)
- [Data] is optional of any length depending on the command code
- CRC is a 16 bit CRC, low byte first
Some details
- a slave device only answers to a command
- a device only replies if the ID matches and if the CRC is correct
- a reply has the same command code as the issued command, but the
data field can be composed differently.
- a reply has the SRC and DST fields swapped.
- the broadcast ID to which all devices answer is 0xFF
- the command processing is stateless
- commands are quick to process
the CRC
The CRC is calculated as
PROCEDURE calcCRCbyte(data:BYTE;VAR crc:WORD);
VAR i:BYTE;
BEGIN
FOR i:=0 TO 7 DO BEGIN
IF ((data and $01)XOR(crc AND $0001)<>0) THEN BEGIN
crc:=crc shr 1;
crc:= crc XOR $A001;
END
ELSE BEGIN
crc:=crc shr 1;
END;
data:=data shr 1;
END;
END;
The command to be sent is assumed zero aligned, eg STX is on address 0,
and SYN is not included in the CRC
FUNCTION CRC(VAR DATA;size:word):WORD;
VAR i:word;
BEGIN
CRC:=0;
FOR i:=0 TO size-1 DO BEGIN
calcCRCbyte(DATA[i],CRC);
END;
END;
the receiving state machine
The state machine operates in the following states
- 0 : idle - wait for SYN
- 1 : wait for STX
- 2 : read LenLo
- 3 : read LenHi
- 4 : count down
- 0x0E : Buffer full
- 0x0F : Message received
interrupt rx_interrupt;
var u:byte;
begin
u:=ReadUART;
if (RxPtr=RxBufLen) then RxState:=0x0E;
else begin
case RxState of
0:if u=SYN then RxState :=1; |
1:case u of
SYN:RxState :=1; |
STX:RxBuf[0]:=STX; RxState :=2; |
else state:=0;
end; |
2:RxBuf[1]:=u; LenLo:=u; RxState :=3; |
3:RxBuf[2]:=u; LenHi:=u; Rxcount:=2; RxState :=4; |
4:If RxCount<>RxLen then begin
RxBuf[RxCount]:=u;
if RxCount < BufLen then inc(RxCount);
end;
else RxState :=0x0F; |
end; // case
end; // buf not full
end; // interrupt
This procedure is in the main loop of the embedded controller
and does the slave part.
procedure ComLoop;
begin
if RxState=0x0E then begin // discard content
RxState:=0;
end;
if RxState=0x0F then begin
RxCRCMessage(rxptr-2); // CRC is updated
if (CRChigh=RxBuf[rxptr-2])and
(CRCLow=RxBuf[rxptr-1]) then begin// crc ok.
if (RxBuf[4]=DeviceID)or(RxBuf[4]=$FF) then begin
src:=RxBuf[3];
dst:=RxBuf[4];
cmd:=RxBuf[5];
case cmd of
0x00:// Echo
CopyRxTx;
AddCrc;
SetupTx;|
..
0x44://UserString read
txlen:=ord(UserString[0])+10;
SetupTxFrame;
CopyBlock(@UserString,@TxBuf+7,ord(UserString[0])+1);
AddCrc;
SetupTx;|
end; //case
end; // ID ok
end; // crc ok
RxState:=0;
RxPtr:=0;
end; // 0x0F
end;
independent implementation details
ibrt devices that implement the "ibrt long message protocol" have the following details defined as
- baudrate 115200 or faster
- other serial parameters 8,n,1
- buffer length 560 or 1080 bytes
- the underlying hardware is RS232 or RS422
predefined commands
the following commands are predefined and implemented in all devices
command code |
meaning |
0x00 |
Echo |
0x30 |
write user string |
0x40 |
read device string |
0x41 |
read serial number |
0x42 |
read copyright message |
0x43 |
read URL reference |
0x44 |
read user string |
further
For shorter messages have a look at the ibrt short message protocol
Questions ?
Suggestions?
Feedback ?
sponsored links
embedded
home
last updated: 22.dec.06 or perhaps later
Copyright (99,2006) Ing.Büro R.Tschaggelar