Skip to content
Brian Ledbetter edited this page Mar 18, 2022 · 17 revisions

DJI FPV Architecture

The DJI FPV system uses a shared architecture between the Goggles, Air Unit, and Vista.

The main processor is a P1, an ARM ??? with several coprocessors onboard.

The system runs an Android kernel and base userland, but does not use Android UI services like SurfaceFlinger or MediaServer.

For this reason, basic Android principles and services are all in play:

adb can be used for file transfer and debugging. The Android logger is employed, so adb logcat will give you interesting logs. setprop can be used to affect the Properties system and trigger actions in the running system.

DJI specific software is all stored in the /system partition.

DJI processes communicate with one another using an event bus and a message passing system called DUML.

The most important processes are in /system/bin , and libraries in /system/lib:

  • dji_glasses : The base DJI UI process. Has debugging symbols, so a great place to start.
  • dji_hdvt_gnd : The "Ground Station" HD Video Transmission service.

These services communicate over the DJI event bus using DUPC, a simple binary serialized / packed message bus format. dji_mb_ctrl and dji_mb_parser can be used to manipulate the message bus from userland. The messsage bus is also exposed over a USB-serial gadget, which can be communicated with using https://github.com/o-gs/dji-firmware-tools and comm_serialtalk.py , or online using https://b3yond.d3vl.com/duml/ .

In /system/lib:

  • libtp1801_gui.so : The Embedded Wizard GUI framework
  • libduml_*.so : The frameworks used by all shared DJI applications. FRWK and HAL contain hardware abstraction. OSAL contains OS Abstraction - basically RTOS primitives built on top of PThreads. Util contains... utilities.

The base RF communication between the Goggles and Air Unit/Vista happens through a baseband OS called, rather simply, SDR, which runs on the same P1 processor, with shared address space. Division between the RTOS and Linux seems to be through simple core affinity - Linux gets one core and the RF baseband gets the other core. Communication between the two systems happens through the "SDRS" system by simply mapping buffers in /dev/mem.

There is also a kernel module called pigeon_modem which seems to use the same shared-memory communication mechanism to create a virtual networking device which tunnels IP packets between nodes.

UI is driven through a DirectFB mux - dji_glasses takes over DirectFB and something at a lower level handles the mux between the overlay DirectFB and the raw video data from the baseband. An example of using DirectFB can be found at https://github.com/fpv-wtf/dfbdoom .

Common things people might want to do:

  • UI Customization: the UI is defined using XML in /system/gui/xml/ . The actions triggered by GUI elements are in libtp1801_gui.so. You can arrange menus, add/remove items, etc. simply by editing the XML files.

  • MSP / Canvas Mode OSD / etc: There are a few ways this could be done. The Vista/Air Unit serial port is just /dev/ttyS0 on the Air Unit/Vista, and the goggles have an IP network link with the Vista/AU. So a trivial way to do this would be to just pipe /dev/ttyS0 over UDP back to the goggles, and then write a custom DirectFB renderer. This would require killing the goggles UI and messing with the air side to take control of the serial port, but there is no reason it wouldn't be possible. A more elegant approach would be to patch or expand the existing UI system. MSP messages are sent over the same DUML message bus, but unfortunately they are parsed on the air side and re-encoded into specific DUML/DUPC event responses, so the system would have to be heavily extended.

  • Video In. The Apple input for iOS Goggles interface is managed in dji_hdvt_gnd and libduml_frwk. These would be good places to start. Or, a custom DirectFB application which opened the USB Bulk endpoints and directly accepted data could work as well - performance optimization would be interesting.