Initial commit with supported platforms: Atmel AVR, TI MSP430 and TI C Series MCU

This commit is contained in:
Ivan Kravets committed 2014-05-18 23:38:59 +03:00
1 parent 6e2cf47303
commit 5bee43540c
16 files changed
+877 -1

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
+54
View File
@@ -0,0 +1,54 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
from os.path import isdir, join
from SCons.Script import (DefaultEnvironment, Exit, SConscript,
SConscriptChdir, Variables)
from platformio.util import get_home_dir, get_project_dir, get_source_dir
PIOBUILDER_DIR = join(get_source_dir(), "builder")
# AllowSubstExceptions()
# define user's variables
clivars = Variables(None)
clivars.AddVariables(
("PIOENV",),
("PLATFORM",),
("BOARD",),
("UPLOAD_PORT",)
)
# print sdf
DefaultEnvironment(
tools=["default", "platformio"],
toolpath=[join(PIOBUILDER_DIR, "tools")],
variables=clivars,
PROJECT_DIR=get_project_dir(),
PLATFORMIOHOME_DIR=get_home_dir(),
PLATFORM_DIR=join("$PLATFORMIOHOME_DIR", "${PLATFORM}"),
PLATFORMCORE_DIR=join("$PLATFORM_DIR", "core"),
PLATFORMTOOLS_DIR=join("$PLATFORM_DIR", "tools"),
BUILD_DIR=join("$PROJECT_DIR", ".pioenvs", "${PIOENV}"),
BUILDCORE_DIR=join("$BUILD_DIR", "core"),
BUILDSRC_DIR=join("$BUILD_DIR", "src")
)
PLATFORM = DefaultEnvironment().subst("${PLATFORM}")
if not isdir(DefaultEnvironment().subst("$PLATFORMIOHOME_DIR")):
Exit("You haven't installed any platforms yet. Please use"
"`platformio install` command")
elif not isdir(DefaultEnvironment().subst("$PLATFORM_DIR")):
Exit("An '%s' platform hasn't been installed yet. Please use "
"`platformio install %s` command" % (PLATFORM.upper(),
PLATFORM))
SConscriptChdir(0)
SConscript(join(PIOBUILDER_DIR, "scripts", PLATFORM + ".py"))
+2
View File
@@ -0,0 +1,2 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
+190
View File
@@ -0,0 +1,190 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
"""
Builder for Atmel AVR series of microcontrollers
Fully compatible with Arduino programming language (based on Wiring)
"""
from os.path import join
from SCons.Script import (AlwaysBuild, Builder, COMMAND_LINE_TARGETS, Default,
DefaultEnvironment, Exit)
#
# SETUP ENVIRONMENT
#
env = DefaultEnvironment()
BOARD_OPTIONS = env.ParseBoardOptions(join("$PLATFORM_DIR", "boards.txt"),
"${BOARD}")
env.Replace(
ARDUINO_VERSION=open(join(env.subst("$PLATFORM_DIR"),
"version.txt")).read().replace(".", "").strip(),
BOARD_MCU=BOARD_OPTIONS['build.mcu'],
BOARD_F_CPU=BOARD_OPTIONS['build.f_cpu'],
BOARD_VID=BOARD_OPTIONS.get("build.vid", "0"),
BOARD_PID=BOARD_OPTIONS.get("build.pid", "0"),
AR="avr-ar",
AS="avr-as",
CC="avr-gcc",
CXX="avr-g++",
OBJCOPY="avr-objcopy",
RANLIB="avr-ranlib",
ARFLAGS=["rcs"],
ASFLAGS=[
"-g", # include debugging info (so errors include line numbers)
"-x", "assembler-with-cpp",
"-mmcu=$BOARD_MCU",
"-DF_CPU=$BOARD_F_CPU",
"-DUSB_VID=$BOARD_VID",
"-DUSB_PID=$BOARD_PID",
"-DARDUINO=$ARDUINO_VERSION"
],
CCFLAGS=[
"-g", # include debugging info (so errors include line numbers)
"-Os", # optimize for size
"-Wall", # show warnings
"-fno-exceptions",
"-ffunction-sections", # place each function in its own section
"-fdata-sections",
"-mmcu=$BOARD_MCU",
"-DF_CPU=$BOARD_F_CPU",
"-MMD", # output dependancy info
"-DUSB_VID=$BOARD_VID",
"-DUSB_PID=$BOARD_PID",
"-DARDUINO=$ARDUINO_VERSION"
],
CFLAGS=["-std=gnu99"],
LINKFLAGS=[
"-Os",
"-Wl,--gc-sections" + (",--relax" if BOARD_OPTIONS['build.mcu'] ==
"atmega2560" else ""),
"-mmcu=$BOARD_MCU",
"-lm"
],
CPPPATH=[
"$PLATFORMCORE_DIR",
join("$PLATFORM_DIR", "variants", BOARD_OPTIONS['build.variant'])
],
UPLOADER="avrdude",
UPLOADERFLAGS=[
"-V", # do not verify
"-q", # suppress progress output
"-D", # disable auto erase for flash memory
"-p", "$BOARD_MCU",
"-C", join("$PLATFORMTOOLS_DIR", "avr", "etc", "avrdude.conf"),
"-c", ("stk500v1" if BOARD_OPTIONS['upload.protocol'] == "stk500" else
BOARD_OPTIONS['upload.protocol']),
"-b", BOARD_OPTIONS['upload.speed'],
"-P", "${UPLOAD_PORT}"
],
UPLOADHEXCMD="$UPLOADER $UPLOADERFLAGS -U flash:w:$SOURCES:i",
UPLOADEEPCMD="$UPLOADER $UPLOADERFLAGS -U eeprom:w:$SOURCES:i"
)
env.Append(
BUILDERS=dict(
ElfToEep=Builder(
action=" ".join([
"$OBJCOPY",
"-O",
"ihex",
"-j",
".eeprom",
'--set-section-flags=.eeprom="alloc,load"',
"--no-change-warnings",
"--change-section-lma",
".eeprom=0",
"$SOURCES",
"$TARGET"]),
suffix=".eep"
),
ElfToHex=Builder(
action=" ".join([
"$OBJCOPY",
"-O",
"ihex",
"-R",
".eeprom",
"$SOURCES",
"$TARGET"]),
suffix=".hex"
)
)
)
env.PrependENVPath(
"PATH",
join(env.subst("$PLATFORMTOOLS_DIR"), "avr", "bin")
)
#
# Target: Build Core Library
#
target_corelib = env.BuildCoreLibrary()
#
# Target: Build executable and linkable firmware
#
target_elf = env.BuildFirmware([target_corelib])
#
# Target: Extract EEPROM data (from EEMEM directive) to .eep file
#
target_eep = env.ElfToEep(join("$BUILD_DIR", "firmware"), target_elf)
#
# Target: Build the .hex file
#
target_hex = env.ElfToHex(join("$BUILD_DIR", "firmware"), target_elf)
#
# Target: Upload .eep file
#
eep = env.Alias("eep", target_eep, [
lambda target, source, env: env.ResetDevice(), "$UPLOADEEPCMD"])
AlwaysBuild(eep)
#
# Target: Upload .hex file
#
upload = env.Alias("upload", target_hex, [
lambda target, source, env: env.ResetDevice(), "$UPLOADHEXCMD"])
AlwaysBuild(upload)
#
# Target: Define targets
#
env.Alias("build-eep", [target_eep])
Default([target_corelib, target_elf, target_hex])
# check for $UPLOAD_PORT variable
is_uptarget = ("eep" in COMMAND_LINE_TARGETS or "upload" in
COMMAND_LINE_TARGETS)
if is_uptarget and not env.subst("$UPLOAD_PORT"):
Exit("Please specify 'upload_port'")
+137
View File
@@ -0,0 +1,137 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
"""
Builder for Texas Instruments
MSP430 Ultra-Low Power 16-bit microcontrollers
Fully compatible with Energia programming language (based on Wiring).
"""
from os.path import join
from SCons.Script import AlwaysBuild, Builder, Default, DefaultEnvironment
#
# SETUP ENVIRONMENT
#
env = DefaultEnvironment()
BOARD_OPTIONS = env.ParseBoardOptions(join("$PLATFORM_DIR", "boards.txt"),
"${BOARD}")
env.Replace(
# See https://github.com/energia/Energia/blob/master/app/src/
# processing/app/Base.java#L45
ARDUINO_VERSION="101",
ENERGIA_VERSION="12",
BOARD_MCU=BOARD_OPTIONS['build.mcu'],
BOARD_F_CPU=BOARD_OPTIONS['build.f_cpu'],
AR="msp430-ar",
AS="msp430-as",
CC="msp430-gcc",
CXX="msp430-g++",
OBJCOPY="msp430-objcopy",
RANLIB="msp430-ranlib",
ARFLAGS=["rcs"],
ASFLAGS=[
"-g", # include debugging info (so errors include line numbers)
"-assembler-with-cpp",
"-mmcu=$BOARD_MCU",
"-DF_CPU=$BOARD_F_CPU",
"-DARDUINO=$ARDUINO_VERSION",
"-DENERGIA=$ENERGIA_VERSION"
],
CCFLAGS=[
"-g", # include debugging info (so errors include line numbers)
"-Os", # optimize for size
"-Wall", # show warnings
"-ffunction-sections", # place each function in its own section
"-fdata-sections",
"-mmcu=$BOARD_MCU",
"-DF_CPU=$BOARD_F_CPU",
"-MMD", # output dependancy info
"-DARDUINO=$ARDUINO_VERSION",
"-DENERGIA=$ENERGIA_VERSION"
],
LINK="$CC",
LINKFLAGS=[
"-Os",
"-mmcu=$BOARD_MCU",
"-Wl,-gc-sections,-u,main"
],
CPPPATH=[
"$PLATFORMCORE_DIR",
join("$PLATFORM_DIR", "variants", BOARD_OPTIONS['build.variant'])
],
UPLOADER=(join("$PLATFORMTOOLS_DIR", "msp430", "mspdebug", "mspdebug")),
UPLOADERFLAGS=[
BOARD_OPTIONS['upload.protocol'],
"--force-reset"
],
UPLOADCMD='$UPLOADER $UPLOADERFLAGS "prog $SOURCES"'
)
env.Append(
BUILDERS=dict(
ElfToHex=Builder(
action=" ".join([
"$OBJCOPY",
"-O",
"ihex",
"-R",
".eeprom",
"$SOURCES",
"$TARGET"]),
suffix=".hex"
)
)
)
env.PrependENVPath(
"PATH",
join(env.subst("$PLATFORMTOOLS_DIR"), "msp430", "bin")
)
#
# Target: Build Core Library
#
target_corelib = env.BuildCoreLibrary()
#
# Target: Build executable and linkable firmware
#
target_elf = env.BuildFirmware([target_corelib, "m"])
#
# Target: Build the .hex
#
target_hex = env.ElfToHex(join("$BUILD_DIR", "firmware"), target_elf)
#
# Target: Upload firmware
#
upload = env.Alias("upload", target_hex, ["$UPLOADCMD"])
AlwaysBuild(upload)
#
# Target: Define targets
#
Default([target_corelib, target_elf, target_hex])
+152
View File
@@ -0,0 +1,152 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
"""
Builder for Texas Instruments
Tiva C Series ARM Cortex-M4 microcontrollers.
Fully compatible with Energia programming language (based on Wiring).
"""
from os.path import join
from SCons.Script import AlwaysBuild, Builder, Default, DefaultEnvironment
#
# SETUP ENVIRONMENT
#
env = DefaultEnvironment()
BOARD_OPTIONS = env.ParseBoardOptions(join("$PLATFORM_DIR", "boards.txt"),
"${BOARD}")
env.Replace(
ARDUINO_VERSION="101",
ENERGIA_VERSION="12",
BOARD_MCU=BOARD_OPTIONS['build.mcu'],
BOARD_F_CPU=BOARD_OPTIONS['build.f_cpu'],
AR="arm-none-eabi-ar",
AS="arm-none-eabi-as",
CC="arm-none-eabi-gcc",
CXX="arm-none-eabi-g++",
OBJCOPY="arm-none-eabi-objcopy",
RANLIB="arm-none-eabi-ranlib",
ARFLAGS=["rcs"],
ASFLAGS=[
"-g", # include debugging info (so errors include line numbers)
"-assembler-with-cpp",
"-Wall",
"-mthumb",
"-mcpu=cortex-m4",
"-mfloat-abi=hard",
"-mfpu=fpv4-sp-d16",
"-fsingle-precision-constant",
"-DF_CPU=$BOARD_F_CPU",
"-DARDUINO=$ARDUINO_VERSION",
"-DENERGIA=$ENERGIA_VERSION"
],
CCFLAGS=[
"-g", # include debugging info (so errors include line numbers)
"-Os", # optimize for size
"-Wall", # show warnings
"-ffunction-sections", # place each function in its own section
"-fdata-sections",
"-Wall",
"-mthumb",
"-mcpu=cortex-m4",
"-mfloat-abi=hard",
"-mfpu=fpv4-sp-d16",
"-fsingle-precision-constant",
"-DF_CPU=$BOARD_F_CPU",
"-MMD", # output dependancy info
"-DARDUINO=$ARDUINO_VERSION",
"-DENERGIA=$ENERGIA_VERSION"
],
CXXFLAGS=[
"-fno-rtti",
"-fno-exceptions"
],
LINKFLAGS=[
"-Os",
"-nostartfiles",
"-nostdlib",
"-Wl,--gc-sections",
"-T", join("$PLATFORMCORE_DIR", BOARD_OPTIONS['ldscript']),
"-Wl,--entry=ResetISR",
"-mthumb",
"-mcpu=cortex-m4",
"-mfloat-abi=hard",
"-mfpu=fpv4-sp-d16",
"-fsingle-precision-constant"
],
CPPPATH=[
"$PLATFORMCORE_DIR",
join("$PLATFORM_DIR", "variants", BOARD_OPTIONS['build.variant'])
],
UPLOADER="lm4flash",
UPLOADCMD="$UPLOADER $SOURCES"
)
env.Append(
BUILDERS=dict(
ElfToBin=Builder(
action=" ".join([
"$OBJCOPY",
"-O",
"binary",
"$SOURCES",
"$TARGET"]),
suffix=".hex"
)
)
)
env.PrependENVPath(
"PATH",
join(env.subst("$PLATFORMTOOLS_DIR"), "lm4f", "bin")
)
#
# Target: Build Core Library
#
target_corelib = env.BuildCoreLibrary()
#
# Target: Build executable and linkable firmware
#
target_elf = env.BuildFirmware([target_corelib, "c", "gcc", "m"])
#
# Target: Build the .bin file
#
target_bin = env.ElfToBin(join("$BUILD_DIR", "firmware"), target_elf)
#
# Target: Upload firmware
#
upload = env.Alias("upload", target_bin, ["$UPLOADCMD"])
AlwaysBuild(upload)
#
# Target: Define targets
#
Default([target_corelib, target_elf, target_bin])
+2
View File
@@ -0,0 +1,2 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
+98
View File
@@ -0,0 +1,98 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
from os import walk
from os.path import isfile, join
from time import sleep
from serial import Serial
def BuildCoreLibrary(env):
corelib = env.Clone()
vdirs = corelib.VariantDirRecursive("$BUILDCORE_DIR", "$PLATFORMCORE_DIR")
return corelib.Library(
corelib.subst("$BUILDCORE_DIR"),
[corelib.GlobCXXFiles(vdir) for vdir in vdirs]
)
def BuildFirmware(env, liblist):
src = env.Clone()
vdirs = src.VariantDirRecursive("$BUILDSRC_DIR",
join("$PROJECT_DIR", "src"))
return src.Program(
join("$BUILD_DIR", "firmware"),
[src.GlobCXXFiles(vdir) for vdir in vdirs],
LIBS=liblist,
LIBPATH="$BUILD_DIR",
PROGSUFFIX=".elf")
def GlobCXXFiles(env, path):
files = []
for suff in ["*.c", "*.cpp", "*.S"]:
_list = env.Glob(join(path, suff))
if _list:
files += _list
return files
def VariantDirRecursive(env, variant_dir, src_dir, duplicate=True):
# add root dir by default
variants = [variant_dir]
env.VariantDir(variant_dir, src_dir, duplicate)
for root, dirnames, filenames in walk(env.subst(src_dir)):
if not dirnames:
continue
for dn in dirnames:
env.VariantDir(join(variant_dir, dn), join(root, dn), duplicate)
variants.append(join(variant_dir, dn))
return variants
def ParseBoardOptions(env, path, name):
path = env.subst(path)
name = env.subst(name)
if not isfile(path):
env.Exit("Invalid path to boards.txt -> %s" % path)
data = {}
_namelen = len(name) + 1
with open(path) as f:
for line in f:
if line[0:_namelen] != name + ".":
continue
line = line[_namelen:].strip()
opt, value = line.split("=", 1)
data[opt] = value
if not data:
env.Exit("Unknown Board '%s'" % name)
else:
return data
def ResetDevice(env):
""" Pulse the DTR line and flush serial buffer """
s = Serial(env.subst("$UPLOAD_PORT"))
s.flushInput()
s.setDTR(False)
s.setRTS(False)
sleep(0.1)
s.setDTR(True)
s.setRTS(True)
s.close()
def exists(env):
return True
def generate(env):
env.AddMethod(BuildCoreLibrary)
env.AddMethod(BuildFirmware)
env.AddMethod(GlobCXXFiles)
env.AddMethod(VariantDirRecursive)
env.AddMethod(ParseBoardOptions)
env.AddMethod(ResetDevice)
return env