Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • danc/MicroCART
  • snawerdt/MicroCART_17-18
  • bbartels/MicroCART_17-18
  • jonahu/MicroCART
4 results
Show changes
Showing
with 2381 additions and 0 deletions
File deleted
#include <Wire.h> //Library used for i2c
#include <Servo.h>
#include "wiring_private.h"
//The TCC values are the same for both TCC0 and TCC1
#define I2C_SLAVE_ADDRESS 4
#define TC4_FREQ 500 // 2.73 ms period for the TC4 timer
#define TCC_FREQ 366 // 2.73 ms period for the TCC timers
#define TC4_MIN_DUTY 400
#define TC4_MAX_DUTY 750
#define TCC_MIN_DUTY 400
#define TCC_MAX_DUTY 750
#define MAX_PERIOD 0xFFFF
#define PWM_API_RESOLUTION 10
int pot_value; //value from a 1k pot to be used to debug
uint32_t period; //period value used for the TCC
void setup() {
//calculate period
period = 48000000L/TCC_FREQ - 1;
int i = 0;
while (period > MAX_PERIOD){
if (i == 4 || i ==6 || i == 8)
i++;
period = 48000000L / TCC_FREQ / (2 << i) - 1;
i++;
}
//Pins 7-10 are outputs to the motors
//Serial.begin(9600);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(10, OUTPUT);
pinMode(9,OUTPUT);
pinMode(13, OUTPUT);
//Pins 4 & 5 are for i2c communication from the pi
pinMode(4, INPUT);
pinMode(5, INPUT);
Wire.setClock(400000L);
Wire.begin(I2C_SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
/***********************************************************************************
* Calibrate the ESC to map to the correct high and low duty cycles for each motor *
***********************************************************************************/
pwm(7, TC4_FREQ, TC4_MAX_DUTY);
pwm(8, TCC_FREQ, TCC_MAX_DUTY);
pwm(9, TCC_FREQ, TCC_MAX_DUTY);
pwm(10, TCC_FREQ, TCC_MAX_DUTY);
delay(2000);
pwm(7, TC4_FREQ, TC4_MIN_DUTY);
pwm(8, TCC_FREQ, TCC_MIN_DUTY);
pwm(9, TCC_FREQ, TCC_MIN_DUTY);
pwm(10, TCC_FREQ, TCC_MIN_DUTY);
delay(2000);
/*******************************
* Motors have been calibrated *
*******************************/
}
void loop() {
//Wire.requestFrom(I2C_SLAVE_ADDRESS, 2); //Request 2 bytes from slave device number 4
//delay(250); //there needs to be a delay here. Not sure how long though. Currently waits 250 us
}
/*
* This function is used when it receives information on pin 4 from the pi.
* Each 2 bytes is the throttle for each motor in the order it is received.
* First byte is the upper 8 bites for motor 1, second byte is the bottom 8 bits for motor 1, and so on.
* Then, it sets the pwm for the pin with set duty_cycle.
*
* @param bytes - amount of bytes that it receives
*
*/
void receiveEvent(int bytes){
int pin = 7;
uint16_t throttle = 0;
while(Wire.available() > 0){ //loop through all of the bytes
throttle = Wire.read() << 8;
throttle = throttle | Wire.read();
pwmWrite(pin, throttle);
pin++;
}
}
/*
* This function is used to test the motor of a pin. It revs the motor from 0% to 100% throttle
*
* @param pin - number of the pin that the motor is attached to
*/
void revMotor(int pin){
for(int i = 0; i <= 100; i++){
pwmWrite(pin, i);
delay(50);
}
for(int i = 100; i >= 0; i--){
pwmWrite(pin, i);
delay(50);
}
}
/*
* This function is used to write the throttle to a pin.
*
* @param pin - number of the pin that we want to write to
* @param throttle - the throttle we want to set to
*
* NOTE: this may need to change to directly change the timer values because
* the pwm() function initializes everything together.
* Probably do not want to initialize the timers every time
*/
void pwmWrite(int pin, uint16_t throttle){
int duty_cycle;
switch(pin){
case(7):
//map the throttle to between the min and max duty cycle values for tc4
duty_cycle = map(throttle, 0, 65535, TC4_MIN_DUTY, TC4_MAX_DUTY);
duty_cycle = mapResolution(duty_cycle, 10, 16);
TC4->COUNT16.CTRLA.bit.ENABLE = 0;
while(TC4->COUNT16.STATUS.bit.SYNCBUSY);
TC4->COUNT16.CC[1].reg = (uint32_t)duty_cycle;
while(TC4->COUNT16.STATUS.bit.SYNCBUSY);
TC4->COUNT16.CTRLA.bit.ENABLE = 1;
while(TC4->COUNT16.STATUS.bit.SYNCBUSY);
break;
case(8):
//map the throttle to between the min and max duty cycle values for tcc1
duty_cycle = map(throttle, 0, 65535, TCC_MIN_DUTY, TCC_MAX_DUTY);
duty_cycle = map(duty_cycle, 0, (1<<PWM_API_RESOLUTION), 0, period);
TCC1->CTRLA.bit.ENABLE = 0;
while(TCC1->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
TCC1->CC[1].reg = (uint32_t)duty_cycle;
while(TCC1->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
TCC1->CTRLA.bit.ENABLE = 1;
while(TCC1->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
break;
case(9):
//map the throttle to between the min and max duty cycle values for tcc0
duty_cycle = map(throttle, 0, 65535, TCC_MIN_DUTY, TCC_MAX_DUTY);
duty_cycle = map(duty_cycle, 0, (1<<PWM_API_RESOLUTION), 0, period);
TCC0->CTRLA.bit.ENABLE = 0;
while(TCC0->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
TCC0->CC[1].reg = (uint32_t)duty_cycle;
while(TCC0->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
TCC0->CTRLA.bit.ENABLE = 1;
while(TCC0->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
break;
case(10):
//map the throttle to between the min and max duty cycle values for tcc1
duty_cycle = map(throttle, 0, 65535, TCC_MIN_DUTY, TCC_MAX_DUTY);
duty_cycle = map(duty_cycle, 0, (1<<PWM_API_RESOLUTION), 0, period);
TCC1->CTRLA.bit.ENABLE = 0;
while(TCC1->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
TCC1->CC[0].reg = (uint32_t)duty_cycle;
while(TCC1->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
TCC1->CTRLA.bit.ENABLE = 1;
while(TCC1->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
break;
default:
break;
}
}
* text=auto eol=lf
# CI jobs
name: CI
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
cf2:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v2
with:
submodules: true
- name: build
run: docker run --rm -v ${PWD}:/module bitcraze/builder ./tools/build/build PLATFORM=cf2 UNIT_TEST_STYLE=min
- name: Upload Build Artifact
uses: actions/upload-artifact@v2.1.4
with:
name: cf2-${{ github.sha }}
path: cf2.bin
tag:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v2
with:
submodules: true
- name: build
run: docker run --rm -v ${PWD}:/module bitcraze/builder ./tools/build/build PLATFORM=tag UNIT_TEST_STYLE=min
- name: Upload Build Artifact
uses: actions/upload-artifact@v2.1.4
with:
name: tag-${{ github.sha }}
path: tag.bin
all-flags:
runs-on: ubuntu-latest
needs: cf2
steps:
- name: Checkout Repo
uses: actions/checkout@v2
with:
submodules: true
- name: All features
run: docker run --rm -v ${PWD}:/module bitcraze/builder ./tools/build/build PLATFORM=cf2 DEBUG=1 "EXTRA_CFLAGS=-DCALIBRATED_LED_MORSE -DIMU_TAKE_ACCEL_BIAS -DIMU_MPU6500_DLPF_256HZ -DMADWICK_QUATERNION_IMU -DDEBUG_QUEUE_MONITOR -DENABLE_BQ_DECK -DSITAW_ENABLED -DOW_WRITE_TEST -DOW_READ_TEST -DDEBUG_PRINT_ON_UART -DENABLE_UART1 -DENABLE_UART2" UNIT_TEST_STYLE=min
features:
runs-on: ubuntu-latest
needs: cf2
strategy:
fail-fast: false
matrix:
features:
# Build cf2 with bosch sensors
- SENSORS=bosch
# Build cf2 with TDMA
- LPS_TDMA_ENABLE=1 "EXTRA_CFLAGS=-DTDMA_NSLOTS_BITS=1 -DTDMA_SLOT=0"
# Build cf2 with TDOA2 positioning mode
- LPS_TDOA_ENABLE=1
# Build cf2 with TDOA3 positioning mode
- LPS_TDOA3_ENABLE=1
# Build cf2 with TDOA3 and all config options
- LPS_TDOA3_ENABLE=1 "EXTRA_CFLAGS=-DLPS_2D_POSITION_HEIGHT=1.2 -DLPS_LONGER_RANGE -DLPS_FULL_TX_POWER"
# Build Bigquad deck with all config options
- >
"EXTRA_CFLAGS=-DENABLE_BQ_DECK -DBQ_DECK_ENABLE_OSD -DBQ_DECK_ENABLE_PM"
env:
FEATURE: ${{ matrix.features }}
steps:
- name: Checkout Repo
uses: actions/checkout@v2
with:
submodules: true
- name: build
run: docker run --rm -v ${PWD}:/module bitcraze/builder ./tools/build/build PLATFORM=cf2 ${{ env.FEATURE }} UNIT_TEST_STYLE=min
apps:
runs-on: ubuntu-latest
needs: cf2
strategy:
fail-fast: false
matrix:
example:
- app_api
- examples/app_hello_world
- examples/app_peer_to_peer
- examples/demos/app_push_demo
- examples/demos/swarm_demo
env:
EXAMPLE: ${{ matrix.example }}
steps:
- name: Checkout Repo
uses: actions/checkout@v2
with:
submodules: true
- name: build
run: docker run --rm -v ${PWD}:/module bitcraze/builder bash -c "cd ${EXAMPLE}; make -j$(nproc)"
build_info.json
^bin/dep/all
bin/*
.cproject
.project
.pydevproject
.settings/*
.vscode/*
*~
tools/make/config.mk
cflie.*
version.c
tags
/cf2.*
/tag.*
*.gch
current_platform.mk
/generated/test/build/**
!/generated/test/build/.gitkeep
/generated/test/mocks/**
!/generated/test/mocks/.gitkeep
/generated/**
**/__pycache__/**
/docs/.jekyll-metadata
docs/.jekyll-cache
docs/api
Contributing
============
👍🎉 Thanks a lot for considering contributing 🎉👍
We welcome and encourage contribution. There is many way to contribute: you can
write bug report, contribute code or documentation.
You can also go to the [bitcraze forum](https://forum.bitcraze.io) and help others.
## Reporting issues
When reporting issues the more information you can supply the better.
- **Information about the environment:**
- What version of the firmware are you running
- If relevant, what are you using to control the Crazyflie. ie. What lib or client, and what version.
- **How to reproduce the issue:** Step-by-step guide on how the issue can be reproduced (or at least how you reproduce it).
Include everything you think might be useful, the more information the better.
## Improvements request and proposal
We and the community are continuously working to improve the firmware.
Feel free to make an issue to request a new functionality.
## Contributing code/Pull-Request
We welcome code contribution, this can be done by starting a pull-request.
If the change is big, typically if the change span to more than one file, consider starting an issue first to discuss the improvement.
This will makes it much easier to make the change fit well into the firmware.
There is some basic requirement for us to merge a pull request:
- Describe the change
- Refer to any issues it effects
- Separate one pull request per functionality: if you start writing "and" in the feature description consider if it could be separated in two pull requests.
- The pull request must pass the automated test (see test section bellow)
In your code:
- 2 spaces indentation
- Make sure the coding style of your code follows the style of the file.
### Run test
To run the tests please have a look at the [unit test documentation](https://www.bitcraze.io/documentation/repository/crazyflie-firmware/master/development/unit_testing/).
This diff is collapsed.
# CrazyFlie's Makefile
# Copyright (c) 2011-2021 Bitcraze AB
# This Makefile compiles all the object file to ./bin/ and the resulting firmware
# image in ./cfX.elf and ./cfX.bin
CRAZYFLIE_BASE ?= ./
# Put your personal build config in tools/make/config.mk and DO NOT COMMIT IT!
# Make a copy of tools/make/config.mk.example to get you started
-include tools/make/config.mk
CFLAGS += $(EXTRA_CFLAGS)
######### JTAG and environment configuration ##########
OPENOCD ?= openocd
OPENOCD_INTERFACE ?= interface/stlink.cfg
OPENOCD_CMDS ?=
CROSS_COMPILE ?= arm-none-eabi-
PYTHON ?= python3
DFU_UTIL ?= dfu-util
CLOAD ?= 1
DEBUG ?= 0
CLOAD_SCRIPT ?= python3 -m cfloader
CLOAD_CMDS ?=
CLOAD_ARGS ?=
PLATFORM ?= cf2
LPS_TDMA_ENABLE ?= 0
LPS_TDOA_ENABLE ?= 0
LPS_TDOA3_ENABLE ?= 0
# Platform configuration handling
-include current_platform.mk
include $(CRAZYFLIE_BASE)/tools/make/platform.mk
CFLAGS += -DCRAZYFLIE_FW
######### Stabilizer configuration ##########
## These are set by the platform (see tools/make/platforms/*.mk), can be overwritten here
ESTIMATOR ?= any
CONTROLLER ?= Any # one of Any, PID, Mellinger, INDI
POWER_DISTRIBUTION ?= stock
#OpenOCD conf
RTOS_DEBUG ?= 0
LIB = $(CRAZYFLIE_BASE)/src/lib
FREERTOS = $(CRAZYFLIE_BASE)/vendor/FreeRTOS
CFLAGS += -DBLOBS_LOC='"$(CRAZYFLIE_BASE)/blobs/"'
# Communication Link
UART2_LINK ?= 0
############### CPU-specific build configuration ################
ifeq ($(CPU), stm32f4)
PORT = $(FREERTOS)/portable/GCC/ARM_CM4F
LINKER_DIR = $(CRAZYFLIE_BASE)/tools/make/F405/linker
ST_OBJ_DIR = $(CRAZYFLIE_BASE)/tools/make/F405
OPENOCD_TARGET ?= target/stm32f4x.cfg
# St Lib
VPATH += $(LIB)/CMSIS/STM32F4xx/Source/
VPATH += $(LIB)/STM32_USB_Device_Library/Core/src
VPATH += $(LIB)/STM32_USB_OTG_Driver/src
VPATH += $(CRAZYFLIE_BASE)/src/deck/api $(CRAZYFLIE_BASE)/src/deck/core $(CRAZYFLIE_BASE)/src/deck/drivers/src $(CRAZYFLIE_BASE)/src/deck/drivers/src/test
VPATH += $(CRAZYFLIE_BASE)/src/utils/src/tdoa $(CRAZYFLIE_BASE)/src/utils/src/lighthouse
CRT0 = startup_stm32f40xx.o system_stm32f4xx.o
# Add ST lib object files
-include $(ST_OBJ_DIR)/st_obj.mk
# USB obj
ST_OBJ += usb_core.o usb_dcd_int.o usb_dcd.o
# USB Device obj
ST_OBJ += usbd_ioreq.o usbd_req.o usbd_core.o
PROCESSOR = -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
CFLAGS += -fno-math-errno -DARM_MATH_CM4 -D__FPU_PRESENT=1 -mfp16-format=ieee
#Flags required by the ST library
CFLAGS += -DSTM32F4XX -DSTM32F40_41xxx -DHSE_VALUE=8000000 -DUSE_STDPERIPH_DRIVER
LOAD_ADDRESS_stm32f4 = 0x8000000
LOAD_ADDRESS_CLOAD_stm32f4 = 0x8004000
MEM_SIZE_FLASH_K = 1008
MEM_SIZE_RAM_K = 128
MEM_SIZE_CCM_K = 64
endif
################ Build configuration ##################
# libdw dw1000 driver
VPATH += $(CRAZYFLIE_BASE)/vendor/libdw1000/src
# vl53l1 driver
VPATH += $(LIB)/vl53l1/core/src
# FreeRTOS
VPATH += $(PORT)
PORT_OBJ = port.o
VPATH += $(FREERTOS)/portable/MemMang
MEMMANG_OBJ ?= heap_4.o
VPATH += $(FREERTOS)
FREERTOS_OBJ = list.o tasks.o queue.o timers.o $(MEMMANG_OBJ)
#FatFS
VPATH += $(LIB)/FatFS
PROJ_OBJ += ff.o ffunicode.o fatfs_sd.o
ifeq ($(FATFS_DISKIO_TESTS), 1)
PROJ_OBJ += diskio_function_tests.o
CFLAGS += -DUSD_RUN_DISKIO_FUNCTION_TESTS
endif
ifeq ($(APP), 1)
CFLAGS += -DAPP_ENABLED=1
endif
ifdef APP_STACKSIZE
CFLAGS += -DAPP_STACKSIZE=$(APP_STACKSIZE)
endif
ifdef APP_PRIORITY
CFLAGS += -DAPP_PRIORITY=$(APP_PRIORITY)
endif
# Crazyflie sources
VPATH += $(CRAZYFLIE_BASE)/src/init $(CRAZYFLIE_BASE)/src/hal/src $(CRAZYFLIE_BASE)/src/modules/src $(CRAZYFLIE_BASE)/src/modules/src/lighthouse $(CRAZYFLIE_BASE)/src/modules/src/kalman_core $(CRAZYFLIE_BASE)/src/utils/src $(CRAZYFLIE_BASE)/src/drivers/bosch/src $(CRAZYFLIE_BASE)/src/drivers/src $(CRAZYFLIE_BASE)/src/platform
VPATH += $(CRAZYFLIE_BASE)/src/utils/src/kve
############### Source files configuration ################
# Init
PROJ_OBJ += main.o
PROJ_OBJ += platform.o platform_utils.o platform_$(PLATFORM).o platform_$(CPU).o
# Drivers
PROJ_OBJ += exti.o nvic.o motors.o
PROJ_OBJ += led.o mpu6500.o i2cdev.o ws2812_cf2.o lps25h.o i2c_drv.o
PROJ_OBJ += ak8963.o eeprom.o maxsonar.o piezo.o
PROJ_OBJ += uart_syslink.o swd.o uart1.o uart2.o watchdog.o
PROJ_OBJ += cppm.o
PROJ_OBJ += bmi055_accel.o bmi055_gyro.o bmi160.o bmp280.o bstdr_comm_support.o bmm150.o
PROJ_OBJ += bmi088_accel.o bmi088_gyro.o bmi088_fifo.o bmp3.o
PROJ_OBJ += pca9685.o vl53l0x.o pca95x4.o pca9555.o vl53l1x.o pmw3901.o
PROJ_OBJ += amg8833.o lh_bootloader.o
# USB Files
PROJ_OBJ += usb_bsp.o usblink.o usbd_desc.o usb.o
# Hal
PROJ_OBJ += crtp.o ledseq.o freeRTOSdebug.o buzzer.o
PROJ_OBJ += pm_$(CPU).o syslink.o radiolink.o ow_syslink.o ow_common.o proximity.o usec_time.o
PROJ_OBJ += sensors.o
PROJ_OBJ += storage.o
# libdw
PROJ_OBJ += libdw1000.o libdw1000Spi.o
# vl53l1 lib
PROJ_OBJ += vl53l1_api_core.o vl53l1_api.o vl53l1_core.o vl53l1_silicon_core.o vl53l1_api_strings.o
PROJ_OBJ += vl53l1_api_calibration.o vl53l1_api_debug.o vl53l1_api_preset_modes.o vl53l1_error_strings.o
PROJ_OBJ += vl53l1_register_funcs.o vl53l1_wait.o vl53l1_core_support.o
# Modules
PROJ_OBJ += system.o comm.o console.o pid.o crtpservice.o param.o
PROJ_OBJ += bootloader.o
PROJ_OBJ += log.o worker.o queuemonitor.o msp.o
PROJ_OBJ += platformservice.o sound_cf2.o extrx.o sysload.o mem.o
PROJ_OBJ += range.o app_handler.o static_mem.o app_channel.o
PROJ_OBJ += eventtrigger.o supervisor.o
# Stabilizer modules
PROJ_OBJ += commander.o crtp_commander.o crtp_commander_rpyt.o
PROJ_OBJ += crtp_commander_generic.o crtp_localization_service.o peer_localization.o
PROJ_OBJ += attitude_pid_controller.o sensfusion6.o stabilizer.o
PROJ_OBJ += position_estimator_altitude.o position_controller_pid.o position_controller_indi.o
PROJ_OBJ += estimator.o estimator_complementary.o
PROJ_OBJ += controller.o controller_pid.o controller_mellinger.o controller_indi.o
PROJ_OBJ += student_attitude_controller.o student_pid.o
PROJ_OBJ += controller_student.o
PROJ_OBJ += power_distribution_$(POWER_DISTRIBUTION).o
PROJ_OBJ += collision_avoidance.o health.o
# Kalman estimator
PROJ_OBJ += estimator_kalman.o kalman_core.o kalman_supervisor.o
PROJ_OBJ += mm_distance.o mm_absolute_height.o mm_position.o mm_pose.o mm_tdoa.o mm_flow.o mm_tof.o mm_yaw_error.o mm_sweep_angles.o
PROJ_OBJ += mm_tdoa_robust.o mm_distance_robust.o
# High-Level Commander
PROJ_OBJ += crtp_commander_high_level.o planner.o pptraj.o pptraj_compressed.o
# Deck Core
PROJ_OBJ += deck.o deck_info.o deck_drivers.o deck_test.o deck_memory.o
# Deck API
PROJ_OBJ += deck_constants.o
PROJ_OBJ += deck_digital.o
PROJ_OBJ += deck_analog.o
PROJ_OBJ += deck_spi.o
PROJ_OBJ += deck_spi3.o
# Decks
PROJ_OBJ += bigquad.o
PROJ_OBJ += ledring12.o
PROJ_OBJ += buzzdeck.o
PROJ_OBJ += gtgps.o
PROJ_OBJ += cppmdeck.o
PROJ_OBJ += usddeck.o
PROJ_OBJ += zranger.o zranger2.o
PROJ_OBJ += locodeck.o
PROJ_OBJ += clockCorrectionEngine.o
PROJ_OBJ += lpsTwrTag.o
PROJ_OBJ += lpsTdoa2Tag.o
PROJ_OBJ += lpsTdoa3Tag.o tdoaEngineInstance.o tdoaEngine.o tdoaStats.o tdoaStorage.o
PROJ_OBJ += outlierFilter.o
PROJ_OBJ += flowdeck_v1v2.o
PROJ_OBJ += oa.o
PROJ_OBJ += multiranger.o
PROJ_OBJ += lighthouse.o
PROJ_OBJ += activeMarkerDeck.o
# Uart2 Link for CRTP communication is not compatible with decks using uart2
ifeq ($(UART2_LINK), 1)
CFLAGS += -DUART2_LINK_COMM
else
PROJ_OBJ += aideck.o
endif
ifeq ($(LPS_TDOA_ENABLE), 1)
CFLAGS += -DLPS_TDOA_ENABLE
endif
ifeq ($(LPS_TDOA3_ENABLE), 1)
CFLAGS += -DLPS_TDOA3_ENABLE
endif
ifeq ($(LPS_TDMA_ENABLE), 1)
CFLAGS += -DLPS_TDMA_ENABLE
endif
ifdef SENSORS
SENSORS_UPPER = $(shell echo $(SENSORS) | tr a-z A-Z)
CFLAGS += -DSENSORS_FORCE=SensorImplementation_$(SENSORS)
# Add sensor file to the build if needed
ifeq (,$(findstring DSENSOR_INCLUDED_$(SENSORS_UPPER),$(CFLAGS)))
CFLAGS += -DSENSOR_INCLUDED_$(SENSORS_UPPER)
PROJ_OBJ += sensors_$(SENSORS).o
endif
endif
#Deck tests
PROJ_OBJ += exptest.o
PROJ_OBJ += exptestRR.o
PROJ_OBJ += exptestBolt.o
#PROJ_OBJ += bigquadtest.o
#PROJ_OBJ += uarttest.o
#PROJ_OBJ += aidecktest.o
# Utilities
PROJ_OBJ += filter.o cpuid.o cfassert.o eprintf.o crc32.o num.o debug.o
PROJ_OBJ += version.o FreeRTOS-openocd.o
PROJ_OBJ += configblockeeprom.o
PROJ_OBJ += sleepus.o statsCnt.o rateSupervisor.o
PROJ_OBJ += lighthouse_core.o pulse_processor.o pulse_processor_v1.o pulse_processor_v2.o lighthouse_geometry.o ootx_decoder.o lighthouse_calibration.o lighthouse_deck_flasher.o lighthouse_position_est.o lighthouse_storage.o
PROJ_OBJ += kve_storage.o kve.o
ifeq ($(DEBUG_PRINT_ON_SEGGER_RTT), 1)
VPATH += $(LIB)/Segger_RTT/RTT
INCLUDES += -I$(LIB)/Segger_RTT/RTT
PROJ_OBJ += SEGGER_RTT.o SEGGER_RTT_printf.o
CFLAGS += -DDEBUG_PRINT_ON_SEGGER_RTT
endif
# Libs
PROJ_OBJ += libarm_math.a
OBJ = $(FREERTOS_OBJ) $(PORT_OBJ) $(ST_OBJ) $(PROJ_OBJ) $(APP_OBJ) $(CRT0)
############### Compilation configuration ################
AS = $(CROSS_COMPILE)as
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)gcc
SIZE = $(CROSS_COMPILE)size
OBJCOPY = $(CROSS_COMPILE)objcopy
GDB = $(CROSS_COMPILE)gdb
INCLUDES += -I$(CRAZYFLIE_BASE)/vendor/CMSIS/CMSIS/Core/Include -I$(CRAZYFLIE_BASE)/vendor/CMSIS/CMSIS/DSP/Include
INCLUDES += -I$(CRAZYFLIE_BASE)/vendor/libdw1000/inc
INCLUDES += -I$(FREERTOS)/include -I$(PORT)
INCLUDES += -I$(CRAZYFLIE_BASE)/src/config
INCLUDES += -I$(CRAZYFLIE_BASE)/src/platform
INCLUDES += -I$(CRAZYFLIE_BASE)/src/deck/interface -I$(CRAZYFLIE_BASE)/src/deck/drivers/interface
INCLUDES += -I$(CRAZYFLIE_BASE)/src/drivers/interface -I$(CRAZYFLIE_BASE)/src/drivers/bosch/interface
INCLUDES += -I$(CRAZYFLIE_BASE)/src/hal/interface
INCLUDES += -I$(CRAZYFLIE_BASE)/src/modules/interface -I$(CRAZYFLIE_BASE)/src/modules/interface/kalman_core -I$(CRAZYFLIE_BASE)/src/modules/interface/lighthouse
INCLUDES += -I$(CRAZYFLIE_BASE)/src/utils/interface -I$(CRAZYFLIE_BASE)/src/utils/interface/kve -I$(CRAZYFLIE_BASE)/src/utils/interface/lighthouse -I$(CRAZYFLIE_BASE)/src/utils/interface/tdoa
INCLUDES += -I$(LIB)/FatFS
INCLUDES += -I$(LIB)/CMSIS/STM32F4xx/Include
INCLUDES += -I$(LIB)/STM32_USB_Device_Library/Core/inc
INCLUDES += -I$(LIB)/STM32_USB_OTG_Driver/inc
INCLUDES += -I$(LIB)/STM32F4xx_StdPeriph_Driver/inc
INCLUDES += -I$(LIB)/vl53l1 -I$(LIB)/vl53l1/core/inc
CFLAGS += -g3
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -DDEBUG
# Prevent silent errors when converting between types (requires explicit casting)
CFLAGS += -Wconversion
else
CFLAGS += -Os
# Fail on warnings
CFLAGS += -Werror
endif
# Disable warnings for unaligned addresses in packed structs (added in GCC 9)
CFLAGS += -Wno-address-of-packed-member
ifeq ($(LTO), 1)
CFLAGS += -flto
endif
CFLAGS += -DBOARD_REV_$(REV) -DESTIMATOR_NAME=$(ESTIMATOR)Estimator -DCONTROLLER_NAME=ControllerType$(CONTROLLER) -DPOWER_DISTRIBUTION_TYPE_$(POWER_DISTRIBUTION)
CFLAGS += $(PROCESSOR) $(INCLUDES)
CFLAGS += -Wall -Wmissing-braces -fno-strict-aliasing $(C_PROFILE) -std=gnu11
# CFLAGS += -O0 -Wmissing-braces -fno-strict-aliasing $(C_PROFILE) -std=gnu11 #Use this compiler during debugger, as it has a different optimizer so you can better track variables
# Compiler flags to generate dependency files:
CFLAGS += -MD -MP -MF $(BIN)/dep/$(@).d -MQ $(@)
#Permits to remove un-used functions and global variables from output file
CFLAGS += -ffunction-sections -fdata-sections
# Prevent promoting floats to doubles
CFLAGS += -Wdouble-promotion
ASFLAGS = $(PROCESSOR) $(INCLUDES)
LDFLAGS += --specs=nosys.specs --specs=nano.specs $(PROCESSOR) -Wl,-Map=$(PROG).map,--cref,--gc-sections,--undefined=uxTopUsedPriority
LDFLAGS += -L$(CRAZYFLIE_BASE)/tools/make/F405/linker
#Flags required by the ST library
ifeq ($(CLOAD), 1)
LDFLAGS += -T $(LINKER_DIR)/FLASH_CLOAD.ld
LOAD_ADDRESS = $(LOAD_ADDRESS_CLOAD_$(CPU))
else
LDFLAGS += -T $(LINKER_DIR)/FLASH.ld
LOAD_ADDRESS = $(LOAD_ADDRESS_$(CPU))
endif
ifeq ($(LTO), 1)
LDFLAGS += -Os -flto -fuse-linker-plugin
endif
#Program name
PROG = $(PLATFORM)
#Where to compile the .o
BIN = bin
VPATH += $(BIN)
#Dependency files to include
DEPS := $(foreach o,$(OBJ),$(BIN)/dep/$(o).d)
##################### Misc. ################################
ifeq ($(SHELL),/bin/sh)
COL_RED=\033[1;31m
COL_GREEN=\033[1;32m
COL_RESET=\033[m
endif
# This define n-thing is a standard hack to get newlines in GNU Make.
define n
endef
# Make sure that the submodules are up to date.
# Check if there are any files in the vendor directories, if not warn the user.
ifeq ($(wildcard $(CRAZYFLIE_BASE)/vendor/*/*),)
$(error $n \
The submodules does not seem to be present, consider fetching them by:$n \
$$ git submodule init$n \
$$ git submodule update$n \
)
endif
#################### Targets ###############################
all: bin/ bin/dep bin/vendor check_submodules build
build:
# Each target is in a different line, so they are executed one after the other even when the processor has multiple cores (when the -j option for the make command is > 1). See: https://www.gnu.org/software/make/manual/html_node/Parallel.html
@$(MAKE) --no-print-directory clean_version CRAZYFLIE_BASE=$(CRAZYFLIE_BASE)
@$(MAKE) --no-print-directory compile CRAZYFLIE_BASE=$(CRAZYFLIE_BASE)
@$(MAKE) --no-print-directory print_version CRAZYFLIE_BASE=$(CRAZYFLIE_BASE)
@$(MAKE) --no-print-directory size CRAZYFLIE_BASE=$(CRAZYFLIE_BASE)
compile: $(PROG).hex $(PROG).bin $(PROG).dfu
bin/:
mkdir -p bin
bin/dep:
mkdir -p bin/dep
bin/vendor:
mkdir -p bin/vendor
libarm_math.a:
+$(MAKE) -C $(CRAZYFLIE_BASE)/tools/make/cmsis_dsp/ CRAZYFLIE_BASE=$(abspath $(CRAZYFLIE_BASE)) PROJ_ROOT=$(CURDIR) V=$(V) CROSS_COMPILE=$(CROSS_COMPILE)
clean_version:
ifeq ($(SHELL),/bin/sh)
@echo " CLEAN_VERSION"
@rm -f version.c
endif
print_version:
@echo "Build for the $(PLATFORM_NAME_$(PLATFORM))!"
@$(PYTHON) $(CRAZYFLIE_BASE)/tools/make/versionTemplate.py --crazyflie-base $(CRAZYFLIE_BASE) --print-version
ifeq ($(CLOAD), 1)
@echo "Crazyloader build!"
endif
ifeq ($(FATFS_DISKIO_TESTS), 1)
@echo "WARNING: FatFS diskio tests enabled. Erases SD-card!"
endif
size:
@$(PYTHON) $(CRAZYFLIE_BASE)/tools/make/size.py $(SIZE) $(PROG).elf $(MEM_SIZE_FLASH_K) $(MEM_SIZE_RAM_K) $(MEM_SIZE_CCM_K)
#Radio bootloader
cload:
ifeq ($(CLOAD), 1)
$(CLOAD_SCRIPT) $(CLOAD_CMDS) flash $(CLOAD_ARGS) $(PROG).bin stm32-fw
else
@echo "Only cload build can be bootloaded. Launch build and cload with CLOAD=1"
endif
#Flash the stm.
flash:
$(OPENOCD) -d2 -f $(OPENOCD_INTERFACE) $(OPENOCD_CMDS) -f $(OPENOCD_TARGET) -c init -c targets -c "reset halt" \
-c "flash write_image erase $(PROG).bin $(LOAD_ADDRESS) bin" \
-c "verify_image $(PROG).bin $(LOAD_ADDRESS) bin" -c "reset run" -c shutdown
#verify only
flash_verify:
$(OPENOCD) -d2 -f $(OPENOCD_INTERFACE) $(OPENOCD_CMDS) -f $(OPENOCD_TARGET) -c init -c targets -c "reset halt" \
-c "verify_image $(PROG).bin $(LOAD_ADDRESS) bin" -c "reset run" -c shutdown
flash_dfu:
$(PYTHON) tools/make/usb-bootloader.py
$(DFU_UTIL) -d 0483:df11 -a 0 -D $(PROG).dfu -s :leave
#STM utility targets
halt:
$(OPENOCD) -d0 -f $(OPENOCD_INTERFACE) $(OPENOCD_CMDS) -f $(OPENOCD_TARGET) -c init -c targets -c "halt" -c shutdown
reset:
$(OPENOCD) -d0 -f $(OPENOCD_INTERFACE) $(OPENOCD_CMDS) -f $(OPENOCD_TARGET) -c init -c targets -c "reset" -c shutdown
openocd:
$(OPENOCD) -d2 -f $(OPENOCD_INTERFACE) $(OPENOCD_CMDS) -f $(OPENOCD_TARGET) -c init -c targets -c "\$$_TARGETNAME configure -rtos auto"
trace:
$(OPENOCD) -d2 -f $(OPENOCD_INTERFACE) $(OPENOCD_CMDS) -f $(OPENOCD_TARGET) -c init -c targets -f tools/trace/enable_trace.cfg
rtt:
$(OPENOCD) -d2 -f $(OPENOCD_INTERFACE) $(OPENOCD_CMDS) -f $(OPENOCD_TARGET) -c init -c targets \
-c "rtt setup 0x20000000 262144 \"SEGGER RTT\"" -c "rtt start" -c "rtt server start 2000 0"
gdb: $(PROG).elf
$(GDB) -ex "target remote localhost:3333" -ex "monitor reset halt" $^
erase:
$(OPENOCD) -d2 -f $(OPENOCD_INTERFACE) -f $(OPENOCD_TARGET) -c init -c targets -c "halt" -c "stm32f4x mass_erase 0" -c shutdown
#Print preprocessor #defines
prep:
@$(CC) $(CFLAGS) -dM -E - < /dev/null
check_submodules:
@cd $(CRAZYFLIE_BASE); $(PYTHON) tools/make/check-for-submodules.py
include $(CRAZYFLIE_BASE)/tools/make/targets.mk
#include dependencies
-include $(DEPS)
unit:
# The flag "-DUNITY_INCLUDE_DOUBLE" allows comparison of double values in Unity. See: https://stackoverflow.com/a/37790196
rake unit "DEFINES=$(CFLAGS) -DUNITY_INCLUDE_DOUBLE" "FILES=$(FILES)" "UNIT_TEST_STYLE=$(UNIT_TEST_STYLE)"
.PHONY: all clean build compile unit prep erase flash check_submodules trace openocd gdb halt reset flash_dfu flash_verify cload size print_version clean_version
# Crazyflie Firmware [![CI](https://github.com/bitcraze/crazyflie-firmware/workflows/CI/badge.svg)](https://github.com/bitcraze/crazyflie-firmware/actions?query=workflow%3ACI)
This project contains the source code for the firmware used in the Crazyflie range of platforms, including the Crazyflie 2.X and the Roadrunner.
### Crazyflie 1.0 support
The 2017.06 release was the last release with Crazyflie 1.0 support. If you want
to play with the Crazyflie 1.0 and modify the code, please clone this repo and
branch off from the 2017.06 tag.
## Building and Flashing
See the [building and flashing instructions](https://www.bitcraze.io/documentation/repository/crazyflie-firmware/master/building-and-flashing/build/) in the github docs folder.
## Official Documentation
Check out the [Bitcraze crazyflie-firmware documentation](https://www.bitcraze.io/documentation/repository/crazyflie-firmware/master/) on our website.
## Generated documentation
The easiest way to generate the API documentation is to use the [toolbelt](https://github.com/bitcraze/toolbelt)
```tb build-docs```
and to view it in a web page
```tb docs```
## License
The code is licensed under LGPL-3.0
Crazyflie firmware release checklist
====================================
Build
------
1. Generate release candidates usging the build server
Checks
---------
- Verify basic connectivity and flight with client and Crzyradio
- CF 2.0
- CF 2.1
- Bolt
- Roadrunner (no flight obiously)
- Verify basic connectivity and flight with BLE, Android and Iphone clients
- CF 2.0
- CF 2.1
- Bolt
- Roadrunner (no flight obiously)
- Verify that LOG and params are still working
- Verify swarm connectivity using the multi test bench
- Veirfy basic functionality of all decks
- Verify the examples in the python lib
- Verify that positioning works using python example scripts
- LPS
- Lighthouse
- Mocap
- Flow
# Rakefile used for running unit tests
HERE = File.expand_path(File.dirname(__FILE__)) + '/'
require 'rake'
require 'rake/clean'
require 'rake/testtask'
require './tools/test/rakefile_helper'
include RakefileHelpers
# Load default configuration, for now
DEFAULT_CONFIG_FILE = './tools/test/gcc.yml'
configure_toolchain(DEFAULT_CONFIG_FILE)
task :unit do
# This prevents all argumets after 'unit' to be interpreted as targets by rake
ARGV.each { |a| task a.to_sym do ; end }
if ARGV.length == 0
parse_and_run_tests([])
else
parse_and_run_tests(ARGV[1..-1])
end
end
desc "Generate test summary"
task :summary do
report_summary
end
desc "Build and test Unity"
task :all => [:clean, :unit, :summary]
task :default => [:clobber, :all]
task :ci => [:default]
task :cruise => [:default]
desc "Load configuration"
task :config, :config_file do |t, args|
configure_toolchain(args[:config_file])
end
bin/*
cf2.*
# enable app support
APP=1
APP_STACKSIZE=300
VPATH += src/
PROJ_OBJ += app_main.o
CRAZYFLIE_BASE=..
include $(CRAZYFLIE_BASE)/Makefile
# API App for Crazyflie 2.X
This folder contains an app layer application for the Crazyflie that is intended to document which functions that are part of the
app API. This is not an example app with useful code, see the example directroy for examples of how to use functions.
The app is built by CI servers to make sure we do not modify functions that is part of the official app API by misstake.
Please add any new functions that should be part of the API to it.
See App layer API guide [here](https://www.bitcraze.io/documentation/repository/crazyflie-firmware/master/userguides/app_layer/)
## How to use the app
Do NOT flash and use it! It does not do anything useful and may have unpredictable behaviour, it is only intended to be compiled but not to run.
## Build
Make sure that you are in the app_api folder (not the main folder of the crazyflie firmware). Then type the following to build and flash it while the crazyflie is put into bootloader mode:
```
make clean
make
```
/**
* ,---------, ____ _ __
* | ,-^-, | / __ )(_) /_______________ _____ ___
* | ( O ) | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* | / ,--´ | / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* +------` /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2020 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* api_app.c - App layer application that calls app API functions to make
* sure they are compiled in CI.
*/
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "app.h"
#include "FreeRTOS.h"
#include "task.h"
#include "debug.h"
#include "ledseq.h"
#include "crtp_commander_high_level.h"
#include "locodeck.h"
#include "mem.h"
#include "log.h"
#include "param.h"
#include "pm.h"
#include "app_channel.h"
#define DEBUG_MODULE "APPAPI"
void appMain() {
// Do not run this app
ASSERT_FAILED();
// LED sequencer
{
ledseqContext_t ledSeqContext;
ledseqRegisterSequence(&ledSeqContext);
ledseqRun(&ledSeqContext);
ledseqRunBlocking(&ledSeqContext);
ledseqStop(&ledSeqContext);
ledseqStopBlocking(&ledSeqContext);
}
// High level commander
{
uint8_t dummyTrajectory[10];
crtpCommanderHighLevelTakeoff(1.0f, 1.0f);
crtpCommanderHighLevelTakeoffYaw(1.0f, 1.0f, 1.0f);
crtpCommanderHighLevelLand(0.0f, 1.0f);
crtpCommanderHighLevelLandYaw(0.0f, 1.0f, 1.0f);
crtpCommanderHighLevelStop();
crtpCommanderHighLevelGoTo(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, false);
crtpCommanderHighLevelStartTrajectory(3, 1.0f, true, false);
crtpCommanderHighLevelDefineTrajectory(3, CRTP_CHL_TRAJECTORY_TYPE_POLY4D_COMPRESSED, 0, 17);
crtpCommanderHighLevelTrajectoryMemSize();
crtpCommanderHighLevelWriteTrajectory(20, 10, dummyTrajectory);
crtpCommanderHighLevelReadTrajectory(20, 10, dummyTrajectory);
crtpCommanderHighLevelIsTrajectoryFinished();
crtpCommanderHighLevelTakeoffWithVelocity(1.0f, 1.0f, true);
crtpCommanderHighLevelLandWithVelocity(1.0f, 1.0f, true);
}
// LPS
{
point_t position;
uint8_t unorderedAnchorList[5];
locoDeckGetAnchorPosition(0, &position);
locoDeckGetAnchorIdList(unorderedAnchorList, 5);
locoDeckGetActiveAnchorIdList(unorderedAnchorList, 5);
}
// Memory sub system
{
static const MemoryHandlerDef_t memDef = {.type = MEM_TYPE_APP,};
memoryRegisterHandler(&memDef);
}
// Log
{
logVarId_t id = logGetVarId("some", "log");
logGetFloat(id);
logGetInt(id);
logGetUint(id);
}
// Param
{
paramVarId_t id = paramGetVarId("some", "param");
paramGetFloat(id);
paramGetInt(id);
paramGetUint(id);
paramSetInt(id, 0);
paramSetFloat(id, 0.0f);
}
// Power management
{
pmIsBatteryLow();
pmIsChargerConnected();
pmIsCharging();
pmIsDischarging();
}
// App-channel
{
char buffer[APPCHANNEL_MTU];
appchannelSendPacket("hello", 5);
appchannelReceivePacket(buffer, APPCHANNEL_MTU, APPCHANNEL_WAIT_FOREVER);
appchannelHasOverflowOccured();
}
}
- page_id: home
- title: Building and Flashing
subs:
- {page_id: build}
- title: Userguides
subs:
- {page_id: deck}
- {page_id: decks-index}
- {page_id: logparam}
- {page_id: eventtrigger}
- {page_id: app_layer}
- title: Functional areas
subs:
- {page_id: crtp_index}
- {page_id: memory_subsystem}
- {page_id: stabilizer_index}
- {page_id: deck_memory_format}
- {page_id: p2p_api}
- {page_id: trajectory_formats}
- {page_id: lh_overview}
- {page_id: loco_positioning}
- {page_id: persistent_storage}
- title: Development Instructions
subs:
- {page_id: starting_development}
- {page_id: howto}
- {page_id: serial}
- {page_id: openocd_gdb_debugging}
- {page_id: unit_testing}
- {page_id: systemtask}
- {page_id: memory_management}
- {page_id: dfu}
- {page_id: oot}
- title: Auto-generated API Documentation
subs:
- {page_id: logs}
- {page_id: params}
---
title: Building and Flashing
page_id: build
---
## Dependencies
You'll need to use either the [Crazyflie VM](https://wiki.bitcraze.io/projects:virtualmachine:index),
[the toolbelt](https://wiki.bitcraze.io/projects:dockerbuilderimage:index) or
install some ARM toolchain.
### Install a toolchain
#### OS X
```bash
brew tap PX4/homebrew-px4
brew install gcc-arm-none-eabi
```
#### Debian/Ubuntu
Tested on Ubuntu 14.04 64b/16.04 64b/18.04 64b/20.04 64b/20.10 64b:
For Ubuntu 14.04 :
```bash
sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded
sudo apt-get update
sudo apt-get install libnewlib-arm-none-eabi
```
For Ubuntu 16.04 and 18.04:
```bash
sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa
sudo apt-get update
sudo apt install gcc-arm-embedded
```
For Ubuntu 20.04 and 20.10:
```bash
sudo apt-get install make gcc-arm-none-eabi
```
#### Arch Linux
```bash
sudo pacman -S community/arm-none-eabi-gcc community/arm-none-eabi-gdb community/arm-none-eabi-newlib
```
#### Windows
The GCC ARM Embedded toolchain for Windows is available at [launchpad.net](https://launchpad.net/gcc-arm-embedded/+download). Download the zip archive rather than the executable installer. There are a few different systems for running UNIX-style shells and build systems on Windows; the instructions below are for [Cygwin](https://www.cygwin.com/).
Install Cygwin with [setup-x86_64.exe](https://www.cygwin.com/setup-x86_64.exe). Use the standard `C:\cygwin64` installation directory and install at least the `make` and `git` packages.
Download the latest `gcc-arm-none-eabi-*-win32.zip` archive from [launchpad.net](https://launchpad.net/gcc-arm-embedded/+download). Create the directory `C:\cygwin64\opt\gcc-arm-none-eabi` and extract the contents of the zip file to it.
Launch a Cygwin terminal and run the following to append to your `~/.bashrc` file:
```bash
echo '[[ $PATH == */opt/gcc-arm-none-eabi/bin* ]] || export PATH=/opt/gcc-arm-none-eabi/bin:$PATH' >>~/.bashrc
source ~/.bashrc
```
Verify the toolchain installation with `arm-none-eabi-gcc --version`
### Cloning
This repository uses git submodules. Clone with the `--recursive` flag
```bash
git clone --recursive https://github.com/bitcraze/crazyflie-firmware.git
```
If you already have cloned the repo without the `--recursive` option, you need to
get the submodules manually
```bash
cd crazyflie-firmware
git submodule init
git submodule update
```
## Compiling
### Crazyflie 2.X
This is the default build so just running ```make``` is enough or:
```bash
make PLATFORM=cf2
```
or with the toolbelt
```bash
tb make PLATFORM=cf2
```
### Roadrunner
Use the ```tag``` platform
```bash
make PLATFORM=tag
```
or with the toolbelt
```bash
tb make PLATFORM=tag
```
### config.mk
To create custom build options create a file called `config.mk` in the `tools/make/`
folder and fill it with options. E.g.
```
PLATFORM=CF2
DEBUG=1
```
More information can be found on the
[Bitcraze documentation](https://www.bitcraze.io/documentation/repository/crazyflie-firmware/master/)
# Make targets:
```
all : Shortcut for build
compile : Compile cflie.hex. WARNING: Do NOT update version.c
build : Update version.c and compile cflie.elf/hex
clean_o : Clean only the Objects files, keep the executables (ie .elf, .hex)
clean : Clean every compiled files
mrproper : Clean every compiled files and the classical editors backup files
cload : If the crazyflie-clients-python is placed on the same directory level and
the Crazyradio/Crazyradio PA is inserted it will try to flash the firmware
using the wireless bootloader.
flash : Flash .elf using OpenOCD
halt : Halt the target using OpenOCD
reset : Reset the target using OpenOCD
openocd : Launch OpenOCD
rtt : Start RTT server. Compile the firmware with "DEBUG_PRINT_ON_SEGGER_RTT=1"
and the console is visible over TCP on port 2000 "telnet localhost 2000".
```
# Flashing
Writing a new binary to the Crazyflie is called flashing (writing it to the flash memory). This page describes how to flash from the command line and there are a few different ways to do it.
## Using Crazyradio
The most common way to flash is probably to use the Crazyradio.
### Prerequisites
* A Crazyradio with drivers installed
* [crazyflie-clients-python](https://github.com/bitcraze/crazyflie-clients-python) placed on the same directory level in the file tree
* The firmware has been built
* The current working directory is the root of the crazyflie-firmware project
### Manually entering bootloader mode
* Turn the Crazyflie off
* Start the Crazyflie in bootloader mode by pressing the power button for 3 seconds. Both the blue LEDs will blink.
* In your terminal, run `make cload`
It will try to find a Crazyflie in bootloader mode and flash the binary to it.
Warning: if multiple Crazyflies within range are in bootloader mode the result is unpredictable. This method is not suitable in classroom situation where it is likely that several students are flashing at the same time. Also remember that the Crazyradio PA often reaches into the next room.
### Automatically enter bootloader mode
* Add the address of the crazyflie to the [`config.mk`](#configmk) file, for instance `CLOAD_CMDS = -w radio://0/80/2M`
* Make sure the Crazyflie is on
* In your terminal, run `make cload`
It will connect to the Crazyflie with the specified address, put it in bootloader mode and flash the binary. This method is suitable for classroom situations.
Note: this method does not work if the Crazyflie does not start, for instance if the current flashed binary is corrupt. You will have to fall back to manually entering bootloader mode.
## Using a debug adapter
You need:
* An ST Link V2 or V3 Debugger
* open ocd installed ([installation intructions](/docs/development/openocd_gdb_debugging.md))
* The firmware has been built
* The current working directory is the root of the crazyflie-firmware project
In your terminal, run
`make flash`
# Unit testing
## Running all unit tests
With the environment set up locally
make unit
with the docker builder image and the toolbelt
tb make unit
## Running one unit test
When working with one specific file it is often convenient to run only one unit test
make unit FILES=test/utils/src/test_num.c
or with the toolbelt
tb make unit FILES=test/utils/src/test_num.c
## Running unit tests with specific build settings
Defines are managed by make and are passed on to the unit test code. Use the
normal ways of configuring make when running tests. For instance to run test
for Crazyflie 1
make unit LPS_TDOA_ENABLE=1
## Dependencies
Frameworks for unit testing and mocking are pulled in as git submodules.
The testing framework uses ruby and rake to generate and run code.
To minimize the need for installations and configuration, use the docker builder
image (bitcraze/builder) that contains all tools needed. All scripts in the
tools/build directory are intended to be run in the image. The
[toolbelt](https://wiki.bitcraze.io/projects:dockerbuilderimage:index) makes it
easy to run the tool scripts.
---
title: DFU update of the STM32F405
page_id: dfu
redirects:
- /docs/building-and-flashing/dfu/
---
This page explains how to flash bin files over the micro usb connection.
__The DFU update mode should mainly be considered as a recovery mode in
which you can load new firmware to the STM32F405 MCU. Do not use it if you do not know what it is__
The OTA (Over The
Air) update mode is much more convenient and save and it can also update the
nRF51 MCU at the same time.
## Linux (Ubuntu)
Install the dfu-util if you don\'t already have it with apt-get
apt-get install dfu-util
Now it is time to boot the STM32F405 in the DFU update mode
1. Connect a micro-USB cable to you computer but not yet to the Crazyflie 2.0
2. Disconnect the Crazyflie 2.0 battery if it is connected
3. Now hold down the push button (on/off) while inserting the USB cable in the Crazyflie 2.0
4. Hold down the button for about 5 seconds until you reach the second blink rate (1Hz). Then you can release the button.
5. The STM32F405 is now in DFU mode
With the STM32F405 in DFU mode you should be able to find it with lsusb
lsusb
...
Bus XXX Device XXX: ID 0483:df11 STMicroelectronics STM Device in DFU Mode
...
### BIN firmware file DFU flashing
Now the STM32F405 can be updated. Currently we only build binary files
.bin and not .dfu files so we need to specify more things to dfu-util.
If the Crazyflie 2.X firmware was compiled with CLOAD=1 (default option)
the binary should be flashed _after the bootloader_ at address 0x08004000.
sudo dfu-util -d 0483:df11 -a 0 -s 0x08004000 -D cflie.bin
### BIN bootloader recovery
If for some reason, the dfu-utils overflashed the bootloader by flashing the firmware on the wrong address, you can recover the bootloader by getting the [latest release bootloader bin file](https://github.com/bitcraze/crazyflie2-stm-bootloader/releases). The bootloader can then be correctly flashed by typing this in the terminal.
sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D cf2loader-1.0.bin
### DFU file
To flash with a .dfu file
sudo dfu-util -d 0483:df11 -a 0 -D file.dfu
### Output
It takes a couple of seconds and the output should look something like
this
cf@bitcraze:~/projects/crazyflie-firmware$ sudo dfu-util -a 0 -s 0x08004000 -D cflie.bin
dfu-util 0.5
(C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc.
(C) 2010-2011 Tormod Volden (DfuSe support)
This program is Free Software and has ABSOLUTELY NO WARRANTY
dfu-util does currently only support DFU version 1.0
Opening DFU USB device... ID 0483:df11
Run-time device DFU version 011a
Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=0, name="@Internal Flash /0x08000000/04*016Kg,01*064Kg,07*128Kg"
Claiming USB DFU Interface...
Setting Alternate Setting #0 ...
Determining device status: state = dfuERROR, status = 10
dfuERROR, clearing status
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 011a
Device returned transfer size 2048
No valid DFU suffix signature
Warning: File has no DFU suffix
DfuSe interface name: "Internal Flash "
Now you can disconnect the USB, connect the battery, and you are ready
to go. (Actually the only way to reset it is to disconnect the power, if
e.g. the battery wasn\'t disconnected while entering DFU mode)
---
title: Making your first Deck driver
page_id: howto
---
This howto is going to describe step-by-step how to make and flash your
first Crazyflie 2.X deck driver. See the deck [api documentation
page](/docs/userguides/decks/) for more information about the
code.
Development environment
-----------------------
You should have the
[crazyflie-firmware](https://github.com/bitcraze/crazyflie-firmware) and
[crazyflie-clients-python](https://github.com/bitcraze/crazyflie-clients-python)
cloned in the same folder. If you are using the [Bitcraze
VM](https://github.com/bitcraze/bitcraze-vm) this is already the case.
The Crazyflie firmware should be on Master branch.
For the rest of the howto you will work in the crazyflie-firmware
project.
Writing the driver
------------------
Deck drivers are in the src/deck/drivers/src folder. Create this file named
hello.c in the src/deck/drivers/src folder:
``` {.c}
#define DEBUG_MODULE "HelloDeck"
#include "debug.h"
#include "deck.h"
static void helloInit()
{
DEBUG_PRINT("Hello Crazyflie 2.0 deck world!\n");
}
static bool helloTest()
{
DEBUG_PRINT("Hello test passed!\n");
return true;
}
static const DeckDriver helloDriver = {
.name = "myHello",
.init = helloInit,
.test = helloTest,
};
DECK_DRIVER(helloDriver);
```
Adding the driver to the build
------------------------------
Add this to the Makefile, after the line \'\# Decks\':
``` {.make}
PROJ_OBJ += hello.o
```
Enabling the driver
-------------------
Decks can have a memory that contains its name. In our case the hello
driver would be initialised only when a deck identified as \"myHello\"
is installed on the Crazyflie. For development purpose it is possible to
force enabling a deck driver with a compile flag. To do so create the
file tools/make/config.mk with the content:
``` {.make}
CFLAGS += -DDECK_FORCE=myHello
DEBUG=1
```
DEBUG=1 allows to get more information from the Crazyflie console when
it starts. Debug should not be enabled if you intend to fly the
Crazyflie out of the lab (it disables the watchdog).
**Note** Each time you modify config.mk you
should recompile the full firmware by cleaning up the build folder with
\'make clean\'
Compile, flash and run!
-----------------------
Now the last step is to compile and flash your new firmware. Launch the
following commands in a shell:
``` {.bash}
crazyflie-firmware$ make clean && make
crazyflie-firmware$ make cload
```
The output will be similar to the following:
``` {.bash}
crazyflie-firmware$ make
(...)
CC hello.o
(...)
Build for the CF2 platform!
Build 22:f8243162f727 (2020.04 +22) MODIFIED
Version extracted from git
Crazyloader build!
Flash | 218132/1032192 (21%), 814060 free | text: 213024, data: 5108, ccmdata: 0
RAM | 71564/131072 (55%), 59508 free | bss: 66456, data: 5108
CCM | 43528/65536 (66%), 22008 free | ccmbss: 43528, ccmdata: 0
crazyflie-firmware$ make cload
../crazyflie-clients-python/bin/cfloader flash cf2.bin stm32-fw
Restart the Crazyflie you want to bootload in the next
10 seconds ...
done!
Connected to bootloader on Crazyflie 2.0 (version=0x10)
Target info: nrf51 (0xFE)
Flash pages: 232 | Page size: 1024 | Buffer pages: 1 | Start page: 88
144 KBytes of flash available for firmware image.
Target info: stm32 (0xFF)
Flash pages: 1024 | Page size: 1024 | Buffer pages: 10 | Start page: 16
1008 KBytes of flash available for firmware image.
Flashing 1 of 1 to stm32 (fw): 161867 bytes (159 pages) ..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10.........9
Reset in firmware mode ...
$
```
Now you can connect your Crazyflie with the client and see your driver
in the console!
![deck hello console](/docs/images/deckhelloconsole.png){:align-center}
---
title: Memory management
page_id: memory_management
---
The RAM is a limiting resource and has to be managed to be used as efficiently as possible.
## Static VS dynamic allocation
TBD
## Static allocation
Static allocation of RAM memory happens when a variable is declared on a global scope (variables
declared in a function will end up on the stack). The actual allocation is done by the linker by
reserving space in the memory map in the appropriate location.
```
int myStaticallyAllocatedVariable;
static int myOtherStaticallyAllocatedVariable;
void aFunction() {
int myVariableOnTheStack; // This ends up on the stack
...
}
```
Variables that are declared without an assignment will be set to zero at start up,
while variables with an assignment will be initialized to that value. The
values to use for initialized variables are stored in flash together with the
code and is copied to RAM at start up.
```
int zeroInitialized;
int initializedWithAValue = 17;
```
### RAM types
The MCU in the Crazyflie has two types of RAM, "normal" RAM and CCM (Core Coupled Memory).
The CCM and normal ram are attached to different buses internally which gives them
different properties. The most significant difference is that the CCM can not be
used for DMA transfers, since the DMA unit does not have access to the bus used by CCM. The
normal RAM can be used for all types of tasks and should be used for normal development,
further more this is also the memory that will be used when writing "normal" code.
There is a fair amount of CCM in the system, and we want to use it to free up normal
RAM. The over all strategy is to use CCM for system related memory chunks that we
know will not be used for DMA, so that most users don't have to care about the
properties of CCM.
### Using the CCM
*Warning:* Some drivers use DMA to communicate with sensors, it will not work
to pass a pointer to CCM memory to such a driver.
There is a set of macros in [static_mem.h](https://github.com/bitcraze/crazyflie-firmware/blob/master/src/modules/interface/static_mem.h)
that should be used to tell the compiler/linker to use the CCM. Note that only
zero initialization is supported for CCM.
```
int variableInNormalRam; // Initialized to 0
int alsoVariableInNormalRam = 17; // Initialize to 17
NO_DMA_CCM_SAFE_ZERO_INIT int variableInCcm; // Initialized ot 0
NO_DMA_CCM_SAFE_ZERO_INIT int dontDoThisInCcm = 17; // WARNING! Will not work, will be initialized to 0! Will be silently accepted without warning.
````
Queues allocated with the `STATIC_MEM_QUEUE_ALLOC` macro will be allocated in the
CCM, all access to queue memory is done by copy and is safe.
Tasks allocated using the `STATIC_MEM_TASK_ALLOC` macro will allocate the
system buffers in CCM but the task stack in normal RAM. If no pointers
to stack memory will be used for DMA transfers, it is possible to
also allocate the stack in CCM by using the `STATIC_MEM_TASK_ALLOC_STACK_NO_DMA_CCM_SAFE()`
macro instead.
Code that uses DMA through a public API should verify verify that pointers
passed in through the API do not point to CCM. Use `ASSERT_DMA_SAFE` for this
pupose to fail fast and indicate what the reason for the failued is.