Build System
Build System
Section titled “Build System”Comprehensive guide to the PlatformIO build system configuration for Multiflexmeter 3.7.0.
PlatformIO Configuration
Section titled “PlatformIO Configuration”The project uses PlatformIO as the build system, configured via platformio.ini
.
Complete Configuration
Section titled “Complete Configuration”[platformio]boards_dir = boards
[env]platform = atmelavrframework = arduino
# LMIC library configurationbuild_flags = -DARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS -DDISABLE_BEACONS -DDISABLE_PING -DLMIC_PRINTF_TO=Serial -DLMIC_DEBUG_LEVEL=2 -DFW_VERSION_MAJOR=0 -DFW_VERSION_MINOR=0 -DFW_VERSION_PATCH=0 -DFW_VERSION_PROTO=1
upload_protocol = atmelice_ispupload_port = usbupload_flags = -e -B0.25board_upload.require_upload_port = nomonitor_port = /dev/ttyUSB0monitor_speed = 115200
lib_deps = adafruit/Adafruit SleepyDog Library@^1.4.0 https://github.com/mcci-catena/arduino-lmic.git
[env:mfm_v3_m1284p]board = mfm_v3_m1284pboard_fuses.lfuse = 0xFFboard_fuses.hfuse = 0xD1board_fuses.efuse = 0xFF
Build Targets
Section titled “Build Targets”Available Environments
Section titled “Available Environments”Environment | MCU | Flash | SRAM | EEPROM |
---|---|---|---|---|
mfm_v3_m1284p | ATmega1284P | 128KB | 16KB | 4KB |
Build Commands
Section titled “Build Commands”# Build firmware (default environment)pio run
# Build specific environmentpio run -e mfm_v3_m1284p
# Clean build filespio run --target clean
# Upload to devicepio run --target upload
# Upload with fusespio run --target fuses
# Build verbose outputpio run -v
Build Flags
Section titled “Build Flags”Optimization
Section titled “Optimization”-Os # Optimize for size-ffunction-sections # Place functions in separate sections-fdata-sections # Place data in separate sections-flto # Link-time optimization-Wl,--gc-sections # Remove unused sections
Result: Typical firmware size ~50-60KB (out of 128KB available)
LoRaWAN Configuration
Section titled “LoRaWAN Configuration”-DCFG_eu868=1 # EU868 frequency plan-DCFG_sx1276_radio=1 # RFM95 uses SX1276-DARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS # Use board config
Frequency Plan Options:
CFG_eu868
- Europe 868MHzCFG_us915
- USA 915MHzCFG_au915
- Australia 915MHzCFG_as923
- Asia 923MHz
Debug Configuration
Section titled “Debug Configuration”# Add for debugging-DDEBUG=1-DDEBUG_SERIAL=1-DSERIAL_BAUD=115200
Dependencies
Section titled “Dependencies”Library Management
Section titled “Library Management”Libraries are managed via lib_deps
in platformio.ini
:
lib_deps = mcci-catena/MCCI Arduino LoRaWAN Library @ ^0.9.2 adafruit/Adafruit SleepyDog Library @ ^1.6.4
Installed Libraries:
-
MCCI Arduino LoRaWAN (arduino-lmic)
- Version: 0.9.2 or compatible
- Purpose: LoRaWAN protocol stack
- Size: ~30KB flash
-
Adafruit SleepyDog
- Version: 1.6.4 or compatible
- Purpose: Declared dependency (unused)
- Note: Listed in
platformio.ini
but not used in source code. Actual watchdog functionality is implemented in customwdt.cpp
- Size: 0KB (not compiled in)
Local Libraries
Section titled “Local Libraries”Custom libraries in lib/
directory:
lib/├── arduino-lmic/ # Modified LMIC library└── MedianFilter/ # Median filter for sensor data
MedianFilter:
- Purpose: Statistical filtering of sensor readings
- Files:
MedianFilter.cpp
,MedianFilter.h
- Size: <1KB
Upload Configuration
Section titled “Upload Configuration”USB ASP Programmer
Section titled “USB ASP Programmer”Default configuration uses USBasp:
upload_protocol = usbaspupload_flags = -Pusb # Use USB port -B10 # SCK clock divider (slower for reliability)
Connection:
- Programmer: USBasp v2.0 or compatible
- Interface: 6-pin ISP header
- Voltage: 5V (set jumper on USBasp)
Alternative Programmers
Section titled “Alternative Programmers”Arduino as ISP
Section titled “Arduino as ISP”upload_protocol = stk500v1upload_flags = -P/dev/ttyUSB0 # Serial port -b19200 # Baud rate
AVRISP mkII
Section titled “AVRISP mkII”upload_protocol = avrispmkii
Fuse Settings
Section titled “Fuse Settings”Fuse Configuration
Section titled “Fuse Configuration”board_fuses.lfuse = 0xFF # Low fuseboard_fuses.hfuse = 0xD1 # High fuseboard_fuses.efuse = 0xFF # Extended fuse
Fuse Breakdown
Section titled “Fuse Breakdown”Low Fuse (0xFF):
CKSEL[3:0]
= 1111 - Full swing crystal oscillatorSUT[1:0]
= 11 - Slow rising powerCKOUT
= 1 - No clock outputCKDIV8
= 1 - No clock division (16MHz)
High Fuse (0xD1):
BOOTRST
= 1 - Boot to applicationBOOTSZ[1:0]
= 10 - 512 words boot sizeEESAVE
= 1 - EEPROM preserved on chip eraseWDTON
= 0 - Watchdog timer not always onSPIEN
= 0 - SPI programming enabledJTAGEN
= 1 - JTAG disabledOCDEN
= 1 - On-chip debug disabled
Extended Fuse (0xFF):
BODLEVEL[2:0]
= 111 - BOD disabled
Setting Fuses
Section titled “Setting Fuses”# Upload fuses via PlatformIOpio run --target fuses
# Manual with avrdudeavrdude -c usbasp -p m1284p -U lfuse:w:0xFF:m -U hfuse:w:0xD1:m -U efuse:w:0xFF:m
Memory Sections
Section titled “Memory Sections”Flash Layout
Section titled “Flash Layout”0x0000 - 0x01FF Bootloader (512 bytes)0x0200 - 0x1FFFF Application (127.5KB)
Build Size Analysis
Section titled “Build Size Analysis”# Show memory usagepio run --target size
# Detailed section informationavr-size -C --mcu=atmega1284p .pio/build/mfm_v3_m1284p/firmware.elf
Typical Output:
AVR Memory Usage----------------Device: atmega1284p
Program: 58234 bytes (44.3% Full)(.text + .data + .bootloader)
Data: 4326 bytes (26.3% Full)(.data + .bss + .noinit)
EEPROM: 41 bytes (1.0% Full)(.eeprom)
Custom Board Definition
Section titled “Custom Board Definition”Board JSON
Section titled “Board JSON”Custom board defined in boards/mfm_v3_m1284p.json
:
{ "build": { "core": "arduino", "extra_flags": "-DARDUINO_AVR_ATmega1284P", "f_cpu": "16000000L", "mcu": "atmega1284p", "variant": "standard" }, "frameworks": ["arduino"], "name": "Multiflexmeter 3.7.0 (ATmega1284P)", "upload": { "maximum_ram_size": 16384, "maximum_size": 130048, "protocol": "usbasp", "speed": 19200 }, "url": "https://github.com/MrMisterMisterMister/MFM-docs", "vendor": "Multiflexmeter"}
Installation:
- File location:
boards/mfm_v3_m1284p.json
- Automatically discovered by PlatformIO
- No manual installation needed
Compilation Process
Section titled “Compilation Process”Build Workflow
Section titled “Build Workflow”graph LR A[Source Files] --> B[Preprocessor] B --> C[Compiler] C --> D[Object Files] D --> E[Linker] E --> F[ELF Binary] F --> G[HEX File] G --> H[Upload]
Compilation Steps
Section titled “Compilation Steps”-
Preprocessing
- Expand macros
- Handle
#include
directives - Process conditional compilation
-
Compilation
- Compile C/C++ to object files
- Apply optimization flags
- Generate assembly
-
Linking
- Combine object files
- Link libraries (LMIC, Arduino core)
- Generate ELF binary
-
Binary Conversion
- Convert ELF to HEX format
- Intel HEX format for AVR
- Ready for upload
Generated Files
Section titled “Generated Files”.pio/build/mfm_v3_m1284p/├── firmware.elf # ELF binary with debug symbols├── firmware.hex # Intel HEX for upload├── firmware.map # Linker map file└── src/ # Compiled object files
Troubleshooting
Section titled “Troubleshooting”Common Build Issues
Section titled “Common Build Issues”Problem: avr-g++: error: unrecognized command line option
Solution: Update PlatformIO platform:
pio pkg update
Problem: Library not found: MCCI_LoRaWAN_LMIC_library
Solution: Install dependencies:
pio lib install
Problem: Multiple definition of 'os_init'
Solution: Clean and rebuild:
pio run --target cleanpio run
Problem: Upload fails with USBasp
Solution: Check connections, try slower clock:
upload_flags = -Pusb -B100 # Much slower, more reliable
Advanced Configuration
Section titled “Advanced Configuration”Custom Build Flags
Section titled “Custom Build Flags”Add project-specific flags in platformio.ini
:
build_flags = ${env.build_flags} # Inherit existing flags -DCUSTOM_FEATURE=1 # Enable custom feature -DMAX_SENSORS=4 # Define constant -Wall # All warnings -Wextra # Extra warnings
Debug Build
Section titled “Debug Build”Create separate debug environment:
[env:mfm_v3_m1284p_debug]extends = env:mfm_v3_m1284pbuild_flags = ${env:mfm_v3_m1284p.build_flags} -DDEBUG=1 -O0 # No optimization -g # Debug symbols
Conditional Compilation
Section titled “Conditional Compilation”Use build flags for compile-time features:
#ifdef DEBUG Serial.println("Debug build");#endif
#if MAX_SENSORS > 2 // Support for more sensors#endif
Next Steps
Section titled “Next Steps”- Development Guide - Build and flash firmware
- Firmware Architecture - Code structure
- API Reference - Function documentation