Skip to content

Building custom firmware

Jonathan Hudson edited this page Apr 5, 2024 · 11 revisions

Rationale

Prebuilt targets may not include the features you wish to use. If a target already exists, it is relatively simple to build your own custom firmware.

This guide provides a high level overview. It is not a detailed development guide.

Prerequisite

You need a working development environment. There is developer / build environment documentation for the major platforms (Linux, MacOS, Windows).

Target Specific Files

Overview

For basic configuration changes, the files are found under src/main/targets/NAME. At the top level this includes a separate directory for each target.

This article considers a prototype flight controller QUARKVISION that was never put into production.

$ cd inav/src/main/target
$ ls QUARKVISION
CMakeFiles           CMakeLists.txt  README.md  target.h
cmake_install.cmake  config.c        target.c

The CMakefles directory and cmake_install.cmake are generated by the build system; the other files are:

  • CMakeLists.txt : Mandatory, defines the target name and variants
  • README.md : Optional, information about the target
  • target.h : Mandatory, defines capabilities and definitions (e.g. sensors, pin definitions)
  • target.c : Mandatory, defines timers and usage (e.g. for motors and servos)
  • config.c : Mandatory, defines configuration defaults (RX type etc).

CMakeLists.txt

The QUARKVISION example contains a single line:

target_stm32f405xg(QUARKVISION HSE_MHZ 16 SKIP_RELEASES)

Here is the definition for:

  • The processor class stm32f405xg
  • The target name QUARKVISION
  • Additional parameters HSE_MHZ 16 (an optional parameter defining a non-default high-speed external (HSE) oscillator clock required by this board) and SKIP_RELEASES as this is not an official target.

If we had other variants, for example a V2 variant with different sensors, we could add another line, for example:

target_stm32f405xg(QUARKVISION_V2 HSE_MHZ 16 SKIP_RELEASES)

We can then reference the QUARKVISION_V2 in target.c or target.h to handle the different capabilities of each variation.

See the developer documentation for more information, including a more detailed CMakeLists.txt and a list of processor options.

target.h

target.h contains hardware definitions, a fragment is below:

#pragma once

#define TARGET_BOARD_IDENTIFIER "QRKV"
#define USBD_PRODUCT_STRING "QuarkVision"

...

#define BEEPER                  PC15
#define BEEPER_INVERTED
#define USE_UART_INVERTER
#define INVERTER_PIN_UART2         PB2 // PB2 used as inverter select GPIO
#define INVERTER_PIN_UART2_RX      PB2 // PB2 used as inverter select GPIO

#define MPU6000_CS_PIN          PC1
#define MPU6000_SPI_BUS                 BUS_SPI2

#define USE_IMU_MPU6000
#define IMU_MPU6000_ALIGN       CW270_DEG

// MPU6000 interrupts
#define USE_EXTI
#define GYRO_INT_EXTI            PC0
#define USE_MPU_DATA_READY_SIGNAL

//*************** MAG *****************************

#define USE_MAG
#define MAG_I2C_BUS             BUS_I2C3
#define USE_MAG_HMC5883
#define USE_MAG_MAG3110
#define USE_MAG_QMC5883
#define USE_MAG_AK8963
#define USE_MAG_AK8975
...

Of note:

  • TARGET_BOARD_IDENTIFIER this should be unique in the first 4 bytes. If the mythical QUARKVISION_V2 existed, it would need a separate ID. For example:
#if defined(QUARKVISION_V2)
# define TARGET_BOARD_IDENTIFIER "QVV2"
#else
# define TARGET_BOARD_IDENTIFIER "QRKV"
#endif

This pattern is required for each variation and the features affected by the variation.

The file fragment then defines hardware options:

  • Pins, Busses
  • Sensors, for example the #define USE_MAG stanza which defines the MAG_I2C_BUS I2C bus for the compass, and the different compass types supported on this board.

There will similar stanzas for all the available sensor components.

target.c

target.c defines the timer and channel usage. The association between timers and channels is provided by the vendor MCU documentation. This defines an array of timerHardware_t, in turn defined by the DEF_TIM (define timer) macro.

...
timerHardware_t timerHardware[] = {
    DEF_TIM(TIM1, CH3, PA10, TIM_USE_PPM, 0, 0), // S1_IN_PPM A01
    DEF_TIM(TIM8, CH2, PC7, TIM_USE_ANY, 0, 0), // SSERIAL1 RX c07
    DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0), // SSERIAL1 TX
    DEF_TIM(TIM2, CH1, PA15, 0, 0, 0), // LED A15
    DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0),   // S1_OUT
    DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0),   // S2_OUT
    DEF_TIM(TIM12, CH1, PB14, TIM_USE_OUTPUT_AUTO, 0, 0), // S3_OUT
    DEF_TIM(TIM12, CH2, PB15, TIM_USE_OUTPUT_AUTO, 0, 0), // S4_OUT
    DEF_TIM(TIM11, CH1, PB9, TIM_USE_OUTPUT_AUTO, 0, 0),  // S5_OUT
    DEF_TIM(TIM10, CH1, PB8, TIM_USE_OUTPUT_AUTO, 0, 0),  // S6_OUT
    DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0),   // S7_OUT
    DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0),   // S8_OUT
    DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0),   // S9_OUT
    DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 0),   // S10_OUT
};
...

The parameters are:

  • TIMn: The timer
  • CHn : The channel
  • Pxy : The hardware (MCU) pin
  • The usage function(s) available in this pin. Note that each timer is assigned a rate defined by function, so it is inadvisable to have both MOTOR and SERVO definition on the same timer. TIM_USE_OUTPUT_AUTO will let INAV assign the output to either MOTOR or SERVO automatically.
  • The final two parameters (flags, dmavar are hardware specific / required for DMA (e.g. DSHOT), which is turn is defined by #define USE_DSHOT in target.h. See vendor's technical definitions perhaps compared to comparable targets. The example target here does not define USE_DSHOT and the values are 0. These parameters provide a DMA descriptor table compatible with Betaflight.

Adding a new source file

If a new source file is added outside of the target/NAME directory, it must be added to the top level src/main/CMakeLists.txt.

Further reading

Other recommendations

Use a separate branch

$ git checkout -b my_super_special_branch

This will isolate your work from the base repo and facilitate making a pull request if you decide to contribute your changes back to the project.

Building

Build the target.

$ make -j  $(nproc) QUARKVISION
## or (using ninja as the build manager)
$ ninja QUARKVISION
...
[365/366] Linking C executable bin/QUARKVISION.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:      519160 B       896 KB     56.58%
    FLASH_CONFIG:          0 GB       128 KB      0.00%
             RAM:       76476 B       128 KB     58.35%
             CCM:       13852 B        64 KB     21.14%
     BACKUP_SRAM:          0 GB         4 KB      0.00%
       MEMORY_B1:          0 GB         0 GB
[366/366] cd /home/jrh/Projects/fc/ina.../inav/build/inav_6.0.0_QUARKVISION.hex

Fix any errors / warnings

If you changes introduce compiler warnings, please fix them. Submissions (pull requests) with compiler errors / warnings will not be accepted. If your changes overflow the flash size, consider removing unwanted features in target.h. Your target.h can always #undef generic features from src/main/target/common.h (e.g. unwanted RX or telemetry options).

Commit your changes

You can now commit the changes to your branch, e.g. git commit -a -m "my descriptive commit message" ; otherwise if one wanted to update to the upstream the source tree (e.g.)

git pull

git will complain that there are uncommitted changes and won't perform the update.

  • Commit to your private branch as above ; or
  • $ git reset --hard before pulling ; or
  • Stash away the original files and restore them after pulling.

The developer documentation has more information on synchronising a custom branch with upstream Github.

Other tools and resources

Migrate Betaflight Targets

There is a script in the repo that can help automate conversion of Betaflight targets to INAV. The developer, @mosca, will be grateful for any reports of success (or failure).

Paweł Spychalski has also made YouTube videos on the subject.

WIKI TOPICS

Wiki Home Page

INAV Version Release Notes

7.1.0 Release Notes
7.0.0 Release Notes
6.0.0 Release Notes
5.1 Release notes
5.0.0 Release Notes
4.1.0 Release Notes
4.0.0 Release Notes
3.0.0 Release Notes
2.6.0 Release Notes
2.5.1 Release notes
2.5.0 Release Notes
2.4.0 Release Notes
2.3.0 Release Notes
2.2.1 Release Notes
2.2.0 Release Notes
2.1.0 Release Notes
2.0.0 Release Notes
1.9.1 Release notes
1.9.0 Release notes
1.8.0 Release notes
1.7.3 Release notes
Older Release Notes

QUICK START GUIDES

Getting started with iNav
Fixed Wing Guide
Howto: CC3D flight controller, minimOSD , telemetry and GPS for fixed wing
Howto: CC3D flight controller, minimOSD, GPS and LTM telemetry for fixed wing
INAV for BetaFlight users
launch mode
Multirotor guide
YouTube video guides
DevDocs Getting Started.md
DevDocs INAV_Fixed_Wing_Setup_Guide.pdf
DevDocs Safety.md

Connecting to INAV

Bluetooth setup to configure your flight controller
DevDocs Wireless Connections (BLE, TCP and UDP).md\

Flashing and Upgrading

Boards, Targets and PWM allocations
Upgrading from an older version of INAV to the current version
DevDocs Installation.md
DevDocs USB Flashing.md

Setup Tab
Live 3D Graphic & Pre-Arming Checks

Calibration Tab
Accelerometer, Compass, & Optic Flow Calibration

Alignment Tool Tab
Adjust mount angle of FC & Compass

Ports Tab
Map Devices to UART Serial Ports

Receiver Tab
Set protocol and channel mapping

Mixer

Mixer Tab
Custom mixes for exotic setups
DevDocs Mixer.md

Outputs

DevDocs ESC and servo outputs.md
DevDocs Servo.md

Modes

Modes
Navigation modes
Navigation Mode: Return to Home
DevDocs Controls.md
DevDocs INAV_Modes.pdf
DevDocs Navigation.md

Configuration

Sensor auto detect and hardware failure detection

Failsafe

Failsafe
DevDocs Failsafe.md

PID Tuning

PID Attenuation and scaling
Fixed Wing Tuning for INAV 3.0
Tune INAV PIFF controller for fixedwing
DevDocs Autotune - fixedwing.md
DevDocs INAV PID Controller.md
DevDocs INAV_Wing_Tuning_Masterclass.pdf
DevDocs PID tuning.md
DevDocs Profiles.md

GPS

GPS and Compass setup
GPS Failsafe and Glitch Protection

OSD and VTx

DevDocs Betaflight 4.3 compatible OSD.md
OSD custom messages
OSD Hud and ESP32 radars
DevDocs OSD.md
DevDocs VTx.md

LED Strip

DevDocs LedStrip.md

ADVANCED

Advanced Tuning

Fixed Wing Autolaunch
DevDocs INAV_Autolaunch.pdf

Programming

DevDocs Programming Framework.md

Adjustments

DevDocs Inflight Adjustments.md

Mission Control

iNavFlight Missions
DevDocs Safehomes.md

Tethered Logging

Log when FC is connected via USB

Blackbox

DevDocs Blackbox.md
INAV blackbox variables
DevDocs USB_Mass_Storage_(MSC)_mode.md

CLI

iNav CLI variables
DevDocs Cli.md
DevDocs Settings.md

VTOL

DevDocs MixerProfile.md
DevDocs VTOL.md

TROUBLESHOOTING

"Something" is disabled Reasons
Blinkenlights
Pixel OSD FAQs
TROUBLESHOOTING
Why do I have limited servo throw in my airplane

ADTL TOPICS, FEATURES, DEV INFO

AAT Automatic Antenna Tracker
Building custom firmware
Default values for different type of aircrafts
Features safe to add and remove to fit your needs.
Developer info
INAV MSP frames changelog
INAV Remote Management, Control and Telemetry
Lightweight Telemetry (LTM)
Making a new Virtualbox to make your own INAV
MSP Navigation Messages
MSP V2
OrangeRX LRS RX and OMNIBUS F4
Rate Dynamics
Target and Sensor support
UAV Interconnect Bus
Ublox 3.01 firmware and Galileo
DevDocs 1wire.md
DevDocs ADSB.md
DevDocs Battery.md
DevDocs Buzzer.md
DevDocs Channel forwarding.md
DevDocs Display.md
DevDocs Fixed Wing Landing.md
DevDocs GPS_fix_estimation.md
DevDocs LED pin PWM.md
DevDocs Lights.md
DevDocs OSD Joystick.md
DevDocs Servo Gimbal.md
DevDocs Temperature sensors.md

OLD LEGACY INFO

Supported boards
DevDocs Boards.md
Legacy Mixers
Legacy target ChebuzzF3
Legacy target Colibri RACE
Legacy target Motolab
Legacy target Omnibus F3
Legacy target Paris Air Hero 32
Legacy target Paris Air Hero 32 F3
Legacy target Sparky
Legacy target SPRacingF3
Legacy target SPRacingF3EVO
Legacy target SPRacingF3EVO_1SS
DevDocs Configuration.md
Request form new PRESET
DevDocs Introduction.md
Welcome to INAV, useful links and products
iNav Telemetry
DevDocs Rangefinder.md
DevDocs Rssi.md
DevDocs Runcam device.md
DevDocs Serial.md
DevDocs Telemetry.md
DevDocs Rx.md
DevDocs Spektrum bind.md

Clone this wiki locally