- Breakout boards
The Crazyflie communication stack is divided into three layers:
Each layer communicates on a logical level with the same layer on the other side.
Each module is assigned a port, which works much like the ports in UDP. Sending data on a specific port will make sure it's routed to the registered module for this port. The data that is sent to/from a specific port also contains a channel id of 3 bits. This channel id can be used to more easily route the data once inside the module.
The protocol used for sending data to/from the Crazyflie is named CRTP (Crazyflie RealTime Protocol). In it's current state the protocol isn't real-time, but there's bits over in the header to implement this functionality.
Each CRTP packet is 32 bytes, of which 1 byte is taken by the header. This gives a total payload of 31 bytes per packet. The header holds the port (8 bits), channel (2 bits) and reserved (2 bits).
The link is responsible for transferring the packet to/from the Crazyflie. Currently there's two types of physical links implemented: A radio link using the Crazyradio and a wired link using USB directly to the Crazyflie (only implemented for 2.0).
Since no CRC/checksum is added to the CRTP packet it's the link layers responsibility to check the integrity of the packets.
In the firmware most modules (that are connected to ports) are implemented as tasks. Each task is blocking on a message delivery queue where incoming CRTP packets are delivered. At start up each of these tasks (and other modules) register a callback with the communication layer for their pre-defined ports.
For every module that is used to send/receive CRTP packets there's a Python API object that is used to interact with it. For instance for logging there's a module named log.c in the Crazyflie firmware and a class named Log in the Python API. This part of the API is then used to directly interact with the logging functionality in the Crazyflie.