Changes by last author:
Changed:
This page will contain a detailed description - for developers - of how the Binary Protocol will be laid out. |
For developers
Quintessence continued on http://wiki.x-dsl.hu/cgi-bin/w/telemetry.cgi?UartPacketComm. Discussion below is history ---- |
* robustness: transmission errors handled gracefully |
* robustness (reliability): transmission errors handled gracefully |
* flexibility: supports several devices on the same bus |
* preferrably industrial standard
SerialComm/SIPR is already implemented (by Hackish). SIPR is much better than MegaTune protocol, since it supports reliability. Unfortunately SIPR does not support flexibility (multiple devices on a bus, or complex topology). Real CAN supports flexibility, but CAN does not support compactness (8byte load is a bit small for logging, for which the 6 byte overhead is a bit prohibitive) and real CAN controller not available on many controllers. |
In order to make an error resilient system we have decided on the following. |
In order to make an error resilient system we have decided on the following.
* we pack CAN-like payloads N * (4byte ID + 8 byte value) into CRC protected frames * we define gigapacks, mainly for logging, with length = N * 12byte. This allows efficient storage of runtime-data logs CAN-IDs CAN-ID is a 29bit address that identifies the data. The beauty of CAN is that the usage is not defined. CAN-ID can identify the source of the data, or the destination. It can be a command, which has some parameters (max 8 bytes of payload). We propose to use * 13bits (most significant part of the ID) for data-type * and 16 bits (least significant part of the ID) for device address. Device addresses are unique on a network. This way a display can be configured to accept a certain datatype (such as WBO2 lambda) from a certain device (eg. WBO2 controller of cyl4), while neglect same datatype from another similar device (eg. WBO2 controller of cyl7). When packing 29bit CAN-IDs into UART frames (this part consumes 4 bytes = 32 bits), we use the remaining 3 bits to mark gigapacks: * 0: normal CAN packet (4+8 byte) ** eg. the configuration values and requests, that are now arranged in pages of 256 bytes each, will be 32 different CAN-IDs, 8 bytes each ** while format of configwrite and configreport command is trivial, we want to make configrequest possible without sacrificing 1 bit from the precious 29 bits: we steal 256 combinations from the 65536 possible (masking the upper byte of the 16 bit to 0x00) hardware addressed, and these mean config-request. It is possible that more than one devices will reply, but that's harmless. * 1..5: gigapack, length: 1..5 x 24 byte (including this 4 byte ID) ** the runtime variable log would probably be 72 or 96 byte long gigapack * 6..7: reserved (for longer packets) |
* All data transferred within frames (length: 8..255 bytes). |
* All data transferred within frames (length: header + Nx12 bytes + 2byte CRC). |
** frame_type word (proposed: 2 bytes; 1 byte is major and 1 minor. The minor might have some meaning, depending on the major number.)
** production data. The layout is determined by the frame_type. See the frame_type_description below. ** 2 CRC16 bytes as defined in the avrlibc CRC_update() routine. Note that this is independent of the CRC7 that is used when talking to MMC in SPI mode. This would be highly redundant when using CAN, as CAN applies frame-logic and error protection automatically (and there might be other similar cases). So the protocol must syntactically support error detection ON/OFF. (but it must not accept a frame (without any previous setup) where the error detection flag has been damaged to OFF. * Since the frame_type determines the length of the frame, we don't need separate length-byte (but it is possible for the minor to be length in some cases; if the developer has no better idea). The description of the frame (frame_type_description) can be queried, so the relevant frames can be interpreted. Byteflight standard allows max 12 byte payload, but I think we want to allow higher lengths too (maybe max 255 bytes - although reasonable lengths recommended). With smaller lengths overhead will be worse, but latency can be better (if a priority packet-scheduler is applied) ** several common frame_type_description-s must live in flash. Can be listed and all can be queried for details. ** at least one (maybe more later) frame_type_description can be defined from menu. This has the same structure as the one in flash, but lives in SRAM (which is more expensive). * the frame_type_description refers to variables, that are boardtype+application specific. Note: 256 variables is not enough for a given application, so 2 bytes is likely. Also helpful if arrays should be needed. Should this be flat or hierarchical? |
** N = payload length (in 12 byte units)
** production data. N*12 bytes, see above. ** 2 CRC16 bytes as defined in the avrlibc CRC_update() routine. Note that this is independent of the CRC7 that is used when talking to MMC in SPI mode. ---- Arbitration Some devices are slave-only. A slave can only talk if it was requested by the master. However, than it is permitted to send it's queued messages, including messages to other slaves. Some devices (eg. ARM and PC) can act as master. Only one master at a time is active. If a master-capable device cannot hear any other master for master_existence_timeout (appr. 20..100msec), takes over the bus (involving some randomness to decrease chance of collision), and grants bandwidth to each slave. example * ARM is master * PC is slave * v3.x is slave |
A frame is defined as
|| frame_marker || frame_type || data || CRC16 || || 0x0A || FRAME TYPE || DATA || CRC || |
PC wants to save a config value to v3.x.
* PC must wait for it's turn, when ARM requests PC to speak. * PC sends the save-config request to v3.x * v3.x saves the config, and generates the configreport reply. v3.x cannot send the reply immediately, as it's not his turn * in the meantime, maybe ARM asks several other devices to speak * after ARM requests v3.x to speak, v3.x can send his configreport which the PC hears too. |
----
Secondary problems * Extended address: besides the 16 bit HW address, there is an extended full HW-address that is unique worldwide. The lower 16 bits is the bootloader address. ** device discovery involves messages that only apply to devices that match certain address/mask. Originally we require the installer to record (in explicite configuration) every HW (including their addresses!) added to the segment. Later we might provide full autodetection and plug and play utilizing smart master that can detect collisions (CRC error). * the flash might have a defined 16 bit address to avoid collision: normally the 16bit bootloader address is inherited Bootloader HW-indication changes Shaking the TX in hope the TX is loopbacked to RX is not desirable. The bootloader will wait (listening to the bus) bootloader_inactive_timeout (appr 200msec) than start the application, unless: * of course, if the app entered the bootloader intentionally, the bootloader will stay in bootloader mode * special stay_in_bootloader frame makes it stay in bootloader mode * special start_app frame makes it start app immediately Above special commands are address/mask addressable selectively. ---- Gigapacks TODO: clean this * several common frame_type_description-s must live in flash. Can be listed and all can be queried for details. * at least one (maybe more later) frame_type_description can be defined from menu. This has the same structure as the one in flash, but lives in SRAM (which is more expensive). * the frame_type_description refers to variables, that are boardtype+application specific. Note: 256 variables is not enough for a given application, so 2 bytes is likely. Also helpful if arrays should be needed. Should this be flat or hierarchical? |
Byte stuffing (escaping the frame_marker byte) is not needed. |
Byte stuffing (escaping the frame_marker byte) is not needed. |
* GenBoard/LoggerIntegration |
* GenBoard/LoggerIntegration |