Add initial support for ULP programming // Issue #95

This commit is contained in:
valeros
2019-06-20 13:42:21 +03:00
parent 0dbb36de4d
commit 8d08246acd
24 changed files with 1823 additions and 0 deletions
+25
View File
@@ -35,6 +35,11 @@ platform = env.PioPlatform()
env.SConscript("_bare.py", exports="env")
env.SConscript("_embedtxt_files.py", exports="env")
ulp_lib = None
ulp_dir = join(env.subst("$PROJECT_DIR"), "ulp")
if isdir(ulp_dir) and listdir(ulp_dir):
ulp_lib = env.SConscript("ulp.py", exports="env")
FRAMEWORK_DIR = platform.get_package_dir("framework-espidf")
assert FRAMEWORK_DIR and isdir(FRAMEWORK_DIR)
@@ -56,6 +61,12 @@ def get_toolchain_version():
platform.get_package_version("toolchain-xtensa32"))
def is_ulp_enabled(sdk_params):
ulp_memory = int(sdk_params.get("CONFIG_ULP_COPROC_RESERVE_MEM", 0))
ulp_enabled = int(sdk_params.get("CONFIG_ULP_COPROC_ENABLED", 0))
return ulp_memory > 0 and ulp_enabled != 0
def parse_mk(path):
result = {}
variable = None
@@ -608,6 +619,20 @@ env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", env.ElfToBin(
libs = []
if ulp_lib:
if not is_ulp_enabled(sdk_params):
print("Warning! ULP is not properly configured."
"Add next configuration lines to your sdkconfig.h:")
print (" #define CONFIG_ULP_COPROC_ENABLED 1")
print (" #define CONFIG_ULP_COPROC_RESERVE_MEM 1024")
libs.append(ulp_lib)
env.Append(
CPPPATH=[join("$BUILD_DIR", "ulp_app")],
LIBPATH=[join("$BUILD_DIR", "ulp_app")],
LINKFLAGS=["-T", "ulp_main.ld"]
)
ignore_dirs = (
"bootloader",
"esptool_py",
+171
View File
@@ -0,0 +1,171 @@
# Copyright 2019-present PlatformIO <contact@platformio.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from os import remove
from os.path import exists, join
from shutil import copyfile
from SCons.Script import Builder, Import, Return
Import("env")
ulp_env = env.Clone()
platform = ulp_env.PioPlatform()
FRAMEWORK_DIR = platform.get_package_dir("framework-espidf")
ULP_TOOLCHAIN_DIR = platform.get_package_dir("toolchain-esp32ulp")
ULP_BUILD_DIR = join("$BUILD_DIR", "ulp_app")
# ULP toolchain binaries should be in PATH
ulp_env.PrependENVPath("PATH", join(ULP_TOOLCHAIN_DIR, "bin"))
def bin_converter(target, source, env):
# A workaround that helps avoid changing working directory
# in order to generate symbols that are irrespective of path
temp_source = join(env.subst("$PROJECT_DIR"), source[0].name)
copyfile(source[0].get_path(), temp_source)
command = " ".join([
"xtensa-esp32-elf-objcopy", "--input-target",
"binary", "--output-target",
"elf32-xtensa-le", "--binary-architecture",
"xtensa", "--rename-section",
".data=.rodata.embedded",
source[0].name, target[0].get_path()
])
ulp_env.Execute(command)
if exists(temp_source):
remove(temp_source)
return None
ulp_env.Append(
CPPPATH=["$PROJECTSRC_DIR"],
BUILDERS=dict(
BuildElf=Builder(
action=ulp_env.VerboseAction(" ".join([
"esp32ulp-elf-ld",
"-o", "$TARGET",
"-A", "elf32-esp32ulp",
"-L", ULP_BUILD_DIR,
"-T", "ulp_main.common.ld",
"$SOURCES"
]), "Linking $TARGET"),
suffix=".elf"
),
UlpElfToBin=Builder(
action=ulp_env.VerboseAction(" ".join([
"esp32ulp-elf-objcopy",
"-O", "binary",
"$SOURCE", "$TARGET"
]), "Building $TARGET"),
suffix=".bin"
),
ConvertBin=Builder(
action=bin_converter,
suffix=".bin.bin.o"
),
PreprocAs=Builder(
action=ulp_env.VerboseAction(" ".join([
"xtensa-esp32-elf-gcc",
"-DESP_PLATFORM", "-MMD", "-MP", "-DGCC_NOT_5_2_0=0",
"-DWITH_POSIX", "-DHAVE_CONFIG_H",
"-MT", "${TARGET}.o",
"-DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\"",
"-I %s" % join(
FRAMEWORK_DIR, "components", "soc", "esp32", "include"),
"-E", "-P", "-xc",
"-o", "$TARGET", "-D__ASSEMBLER__", "$SOURCE"
]), "Preprocessing $TARGET"),
single_source=True,
suffix=".ulp.pS"
),
AsToObj=Builder(
action=ulp_env.VerboseAction(" ".join([
"esp32ulp-elf-as",
"-o", "$TARGET", "$SOURCE"
]), "Compiling $TARGET"),
single_source=True,
suffix=".o"
)
)
)
def preprocess_ld_script():
arguments = ("-DESP_PLATFORM", "-MMD", "-MP", "-DGCC_NOT_5_2_0=0",
"-DWITH_POSIX", "-D__ASSEMBLER__",
'-DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h"',
"-DHAVE_CONFIG_H", "-MT", "$TARGET", "-E", "-P", "-xc", "-o",
"$TARGET", "-I $PROJECTSRC_DIR", "$SOURCE")
return ulp_env.Command(
join(ULP_BUILD_DIR, "ulp_main.common.ld"),
join(FRAMEWORK_DIR, "components", "ulp", "ld", "esp32.ulp.ld"),
ulp_env.VerboseAction('xtensa-esp32-elf-gcc %s' % " ".join(arguments),
"Preprocessing linker script $TARGET"))
def collect_src_files(src_path):
return ulp_env.CollectBuildFiles(ULP_BUILD_DIR, src_path)
def generate_global_symbols(elf_file):
return ulp_env.Command(
join(ULP_BUILD_DIR, "ulp_main.sym"), elf_file,
ulp_env.VerboseAction(
"esp32ulp-elf-nm -g -f posix $SOURCE > $TARGET",
"Generating global symbols $TARGET"))
def generate_export_files(symbol_file):
# generates ld script and header file
gen_script = join(FRAMEWORK_DIR, "components", "ulp", "esp32ulp_mapgen.py")
build_suffix = join(ULP_BUILD_DIR, "ulp_main")
return ulp_env.Command(
[join(ULP_BUILD_DIR, "ulp_main.ld"),
join(ULP_BUILD_DIR, "ulp_main.h")], symbol_file,
ulp_env.VerboseAction(
'"$PYTHONEXE" "%s" -s $SOURCE -o %s' % (gen_script, build_suffix),
"Exporting ULP linker and header files"))
def create_static_lib(bin_file):
return ulp_env.StaticLibrary(join(ULP_BUILD_DIR, "ulp_main"), [bin_file])
ulp_src_files = collect_src_files(
join(ulp_env.subst("$PROJECT_DIR"), "ulp"))
objects = ulp_env.AsToObj(ulp_env.PreprocAs(ulp_src_files))
ulp_elf = ulp_env.BuildElf(join(ULP_BUILD_DIR, "ulp_main"), objects)
raw_ulp_binary = ulp_env.UlpElfToBin(ulp_elf)
ulp_bin = ulp_env.ConvertBin(raw_ulp_binary)
global_symbols = generate_global_symbols(ulp_elf)
export_files = generate_export_files(global_symbols)
ulp_lib = create_static_lib(ulp_bin)
ulp_env.Depends(ulp_lib, export_files)
ulp_env.Depends(ulp_elf, preprocess_ld_script())
# ULP sources must be built before the files in "src" folder
ulp_env.Requires(join("$BUILD_DIR", "${PROGNAME}.elf"), ulp_lib)
Return("ulp_lib")