zephyr: first attempt
This commit is contained in:
committed by
alexander-gorshenev
parent
a5bc23d706
commit
d968fafec0
@@ -331,3 +331,16 @@ llcOptFlags.wasm32 = -O3
|
|||||||
llcDebugFlags.wasm32 = -O0
|
llcDebugFlags.wasm32 = -O0
|
||||||
# The stack size is in bytes.
|
# The stack size is in bytes.
|
||||||
s2wasmFlags.wasm32 = --allocate-stack 1048576 --import-memory
|
s2wasmFlags.wasm32 = --allocate-stack 1048576 --import-memory
|
||||||
|
|
||||||
|
# Zephyr RTOS.
|
||||||
|
targetToolchain.linux-zephyr = target-gcc-toolchain-6-2017q2-linux-armemb/arm-none-eabi
|
||||||
|
dependencies.linux-zephyr = \
|
||||||
|
clang-llvm-5.0.0-linux-x86-64 \
|
||||||
|
target-gcc-toolchain-6-2017q2-linux-armemb \
|
||||||
|
target-sysroot-2-wasm \
|
||||||
|
zephyr-host-tools-1-linux \
|
||||||
|
zephyr-zephyr-v1.10.0
|
||||||
|
|
||||||
|
quadruple.zephyr = armv7m-none-eabi
|
||||||
|
targetSysRoot.zephyr = target-sysroot-2-wasm
|
||||||
|
entrySelector.zephyr = --defsym main=Konan_main
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#define KONAN_NEED_ASINH_ACOSH 0
|
#define KONAN_NEED_ASINH_ACOSH 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef KONAN_WASM
|
#if KONAN_WASM || __ZEPHYR__
|
||||||
#define KONAN_NO_MATH 1
|
#define KONAN_NO_MATH 1
|
||||||
#else
|
#else
|
||||||
#define KONAN_NO_MATH 0
|
#define KONAN_NO_MATH 0
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
#include "Porting.h"
|
#include "Porting.h"
|
||||||
|
|
||||||
#ifdef KONAN_WASM
|
#if KONAN_WASM || __ZEPHYR__
|
||||||
extern "C" void Konan_abort(const char*);
|
extern "C" void Konan_abort(const char*);
|
||||||
extern "C" void Konan_exit(int32_t status);
|
extern "C" void Konan_exit(int32_t status);
|
||||||
#endif
|
#endif
|
||||||
@@ -124,7 +124,7 @@ static void onThreadExitInit() {
|
|||||||
|
|
||||||
void onThreadExit(void (*destructor)()) {
|
void onThreadExit(void (*destructor)()) {
|
||||||
#if KONAN_NO_THREADS
|
#if KONAN_NO_THREADS
|
||||||
#ifdef KONAN_WASM
|
#if KONAN_WASM || __ZEPHYR__
|
||||||
// No way to do that.
|
// No way to do that.
|
||||||
#else
|
#else
|
||||||
#error "How to do onThreadExit()?"
|
#error "How to do onThreadExit()?"
|
||||||
@@ -145,7 +145,7 @@ void abort() {
|
|||||||
::abort();
|
::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KONAN_WASM
|
#if KONAN_WASM || __ZEPHYR__
|
||||||
void exit(int32_t status) {
|
void exit(int32_t status) {
|
||||||
Konan_exit(status);
|
Konan_exit(status);
|
||||||
}
|
}
|
||||||
@@ -159,7 +159,7 @@ void exit(int32_t status) {
|
|||||||
// memcpy/memmove are not here intentionally, as frequently implemented/optimized
|
// memcpy/memmove are not here intentionally, as frequently implemented/optimized
|
||||||
// by C compiler.
|
// by C compiler.
|
||||||
void* memmem(const void *big, size_t bigLen, const void *little, size_t littleLen) {
|
void* memmem(const void *big, size_t bigLen, const void *little, size_t littleLen) {
|
||||||
#if KONAN_WINDOWS || KONAN_WASM
|
#if KONAN_WINDOWS || KONAN_WASM || __ZEPHYR__
|
||||||
for (size_t i = 0; i + littleLen <= bigLen; ++i) {
|
for (size_t i = 0; i + littleLen <= bigLen; ++i) {
|
||||||
void* pos = ((char*)big) + i;
|
void* pos = ((char*)big) + i;
|
||||||
if (::memcmp(little, pos, littleLen) == 0) return pos;
|
if (::memcmp(little, pos, littleLen) == 0) return pos;
|
||||||
@@ -180,9 +180,11 @@ int snprintf(char* buffer, size_t size, const char* format, ...) {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !__ZEPHYR__
|
||||||
size_t strnlen(const char* buffer, size_t maxSize) {
|
size_t strnlen(const char* buffer, size_t maxSize) {
|
||||||
return ::strnlen(buffer, maxSize);
|
return ::strnlen(buffer, maxSize);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Memory operations.
|
// Memory operations.
|
||||||
#if KONAN_INTERNAL_DLMALLOC
|
#if KONAN_INTERNAL_DLMALLOC
|
||||||
@@ -241,7 +243,7 @@ uint64_t getTimeMicros() {
|
|||||||
#if KONAN_INTERNAL_DLMALLOC
|
#if KONAN_INTERNAL_DLMALLOC
|
||||||
// This function is being called when memory allocator needs more RAM.
|
// This function is being called when memory allocator needs more RAM.
|
||||||
|
|
||||||
#ifdef KONAN_WASM
|
#if KONAN_WASM || __ZEPHYR__
|
||||||
|
|
||||||
// This one is an interface to query module.env.memory.buffer.byteLength
|
// This one is an interface to query module.env.memory.buffer.byteLength
|
||||||
extern "C" unsigned long Konan_heap_upper();
|
extern "C" unsigned long Konan_heap_upper();
|
||||||
@@ -302,7 +304,7 @@ long getpagesize() {
|
|||||||
} // namespace konan
|
} // namespace konan
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#ifdef KONAN_WASM
|
#if KONAN_WASM || __ZEPHYR__
|
||||||
|
|
||||||
// TODO: get rid of these.
|
// TODO: get rid of these.
|
||||||
void _ZNKSt3__220__vector_base_commonILb1EE20__throw_length_errorEv(void) {
|
void _ZNKSt3__220__vector_base_commonILb1EE20__throw_length_errorEv(void) {
|
||||||
@@ -399,4 +401,60 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __ZEPHYR__
|
||||||
|
|
||||||
|
/* Support the alias for the __aeabi_memcpy which may
|
||||||
|
assume memory alignment. */
|
||||||
|
void __aeabi_memcpy4 (void *dest, const void *source, size_t n)
|
||||||
|
__attribute__ ((alias ("memcpy")));
|
||||||
|
|
||||||
|
void __aeabi_memcpy8 (void *dest, const void *source, size_t n)
|
||||||
|
__attribute__ ((alias ("memcpy")));
|
||||||
|
|
||||||
|
void __aeabi_memcpy (void *dest, const void *source, size_t n)
|
||||||
|
__attribute__ ((alias ("memcpy")));
|
||||||
|
|
||||||
|
/* Support the alias for the __aeabi_memmove which may
|
||||||
|
assume memory alignment. */
|
||||||
|
void __aeabi_memmove4 (void *dest, const void *source, size_t n)
|
||||||
|
__attribute__ ((alias ("memmove")));
|
||||||
|
|
||||||
|
void __aeabi_memmove8 (void *dest, const void *source, size_t n)
|
||||||
|
__attribute__ ((alias ("memmove")));
|
||||||
|
|
||||||
|
void __aeabi_memmove (void *dest, const void *source, size_t n)
|
||||||
|
__attribute__ ((alias ("memmove")));
|
||||||
|
|
||||||
|
/* Support the alias for the __aeabi_memset which may
|
||||||
|
assume memory alignment. */
|
||||||
|
void __aeabi_memset4 (void *dest, size_t n, int c)
|
||||||
|
__attribute__ ((alias ("__aeabi_memset")));
|
||||||
|
|
||||||
|
void __aeabi_memset8 (void *dest, size_t n, int c)
|
||||||
|
__attribute__ ((alias ("__aeabi_memset")));
|
||||||
|
|
||||||
|
/* Support the routine __aeabi_memset. Can't alias to memset
|
||||||
|
because it's not defined in the same translation unit. */
|
||||||
|
void __aeabi_memset (void *dest, size_t n, int c)
|
||||||
|
{
|
||||||
|
/*Note that relative to ANSI memset, __aeabi_memset hase the order
|
||||||
|
of its second and third arguments reversed. */
|
||||||
|
memset (dest, c, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Support the alias for the __aeabi_memclr which may
|
||||||
|
assume memory alignment. */
|
||||||
|
void __aeabi_memclr4 (void *dest, size_t n)
|
||||||
|
__attribute__ ((alias ("__aeabi_memclr")));
|
||||||
|
|
||||||
|
void __aeabi_memclr8 (void *dest, size_t n)
|
||||||
|
__attribute__ ((alias ("__aeabi_memclr")));
|
||||||
|
|
||||||
|
/* Support the routine __aeabi_memclr. */
|
||||||
|
void __aeabi_memclr (void *dest, size_t n)
|
||||||
|
{
|
||||||
|
__aeabi_memset (dest, n, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#if KONAN_WASM && !defined(assert)
|
#if (KONAN_WASM || __ZEPHYR__) && !defined(assert)
|
||||||
// assert() is needed by WASM STL.
|
// assert() is needed by WASM STL.
|
||||||
#define assert(cond) if (!(cond)) abort()
|
#define assert(cond) if (!(cond)) abort()
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -525,13 +525,13 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP
|
|||||||
|
|
||||||
/**** Start of Konan-specific dlmalloc configuration. ****/
|
/**** Start of Konan-specific dlmalloc configuration. ****/
|
||||||
#define USE_DL_PREFIX 1
|
#define USE_DL_PREFIX 1
|
||||||
#if KONAN_WASM
|
#if KONAN_WASM || __ZEPHYR__
|
||||||
#define USE_LOCKS 0
|
#define USE_LOCKS 0
|
||||||
#define LACKS_TIME_H 1
|
#define LACKS_TIME_H 1
|
||||||
#define NO_MALLOC_STATS 1
|
#define NO_MALLOC_STATS 1
|
||||||
#define HAVE_MMAP 0 // don't try to allocate large chunks of memory using mmap().
|
#define HAVE_MMAP 0 // don't try to allocate large chunks of memory using mmap().
|
||||||
// It will go to malloc->calloc->sbrk->morecore chain anyways.
|
// It will go to malloc->calloc->sbrk->morecore chain anyways.
|
||||||
#else
|
#else
|
||||||
#define USE_LOCKS 1
|
#define USE_LOCKS 1
|
||||||
#endif
|
#endif
|
||||||
#define DLMALLOC_EXPORT extern "C"
|
#define DLMALLOC_EXPORT extern "C"
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||||
|
project(NONE)
|
||||||
|
|
||||||
|
target_sources(app PRIVATE build/program.o)
|
||||||
Executable
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||||
|
|
||||||
|
source "$DIR/../konan.sh"
|
||||||
|
|
||||||
|
mkdir -p $DIR/build && cd $DIR/build
|
||||||
|
|
||||||
|
konanc $DIR/src/main.kt -target zephyr
|
||||||
|
|
||||||
|
DEP="$HOME/.konan/dependencies"
|
||||||
|
export ZEPHYR_BASE="$DEP/zephyr-zephyr-v1.10.0"
|
||||||
|
export ZEPHYR_GCC_VARIANT=gccarmemb
|
||||||
|
export GCCARMEMB_TOOLCHAIN_PATH="$DEP/target-gcc-toolchain-6-2017q2-linux-armemb/"
|
||||||
|
export PATH="$DEP/zephyr-host-tools-1-linux/bin:$PATH"
|
||||||
|
|
||||||
|
[ -f CMakeCache.txt ] || cmake -DBOARD=qemu_cortex_m3 ..
|
||||||
|
make run
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
CONFIG_CPLUSPLUS=y
|
||||||
|
CONFIG_PRINTK=y
|
||||||
|
CONFIG_BOOT_BANNER=y
|
||||||
|
CONFIG_BUILD_OUTPUT_BIN=y
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr.h>
|
||||||
|
#include <misc/printk.h>
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
printk("Hello World! %s\n", CONFIG_ARCH);
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
println("Hello World!")
|
||||||
|
}
|
||||||
@@ -81,6 +81,20 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
|
|||||||
"-nostdinc", "-Xclang", "-nobuiltininc", "-Xclang", "-nostdsysteminc",
|
"-nostdinc", "-Xclang", "-nobuiltininc", "-Xclang", "-nostdsysteminc",
|
||||||
"-Xclang", "-isystem$absoluteTargetSysRoot/include/libcxx", "-Xclang", "-isystem$absoluteTargetSysRoot/lib/libcxxabi/include",
|
"-Xclang", "-isystem$absoluteTargetSysRoot/include/libcxx", "-Xclang", "-isystem$absoluteTargetSysRoot/lib/libcxxabi/include",
|
||||||
"-Xclang", "-isystem$absoluteTargetSysRoot/include/compat", "-Xclang", "-isystem$absoluteTargetSysRoot/include/libc")
|
"-Xclang", "-isystem$absoluteTargetSysRoot/include/compat", "-Xclang", "-isystem$absoluteTargetSysRoot/include/libc")
|
||||||
|
KonanTarget.ZEPHYR ->
|
||||||
|
listOf("-target", targetArg!!, "-mabi=aapcs", "-mthumb", "-mcpu=cortex-m3",
|
||||||
|
"-Os", "-g",
|
||||||
|
"-fno-rtti",
|
||||||
|
"-fno-exceptions",
|
||||||
|
"-fno-asynchronous-unwind-tables",
|
||||||
|
"-fno-pie",
|
||||||
|
"-fno-pic",
|
||||||
|
"-nostdinc",
|
||||||
|
"-isystem$sysRoot/include/libcxx",
|
||||||
|
"-isystem$sysRoot/lib/libcxxabi/include",
|
||||||
|
"-isystem$sysRoot/include/compat",
|
||||||
|
"-isystem$sysRoot/include/libc")
|
||||||
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -120,6 +134,9 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
|
|||||||
KonanTarget.WASM32 ->
|
KonanTarget.WASM32 ->
|
||||||
listOf("-DKONAN_WASM=1", "-DKONAN_NO_FFI=1", "-DKONAN_NO_THREADS=1", "-DKONAN_NO_EXCEPTIONS=1",
|
listOf("-DKONAN_WASM=1", "-DKONAN_NO_FFI=1", "-DKONAN_NO_THREADS=1", "-DKONAN_NO_EXCEPTIONS=1",
|
||||||
"-DKONAN_INTERNAL_DLMALLOC=1", "-DKONAN_INTERNAL_SNPRINTF=1", "-DKONAN_INTERNAL_NOW=1")
|
"-DKONAN_INTERNAL_DLMALLOC=1", "-DKONAN_INTERNAL_SNPRINTF=1", "-DKONAN_INTERNAL_NOW=1")
|
||||||
|
KonanTarget.ZEPHYR ->
|
||||||
|
listOf( "-D__ZEPHYR__=1", "-DKONAN_NO_FFI=1", "-DKONAN_NO_THREADS=1", "-DKONAN_NO_EXCEPTIONS=1",
|
||||||
|
"-DKONAN_INTERNAL_DLMALLOC=1", "-DKONAN_INTERNAL_SNPRINTF=1", "-DKONAN_INTERNAL_NOW=1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val host = TargetManager.host
|
private val host = TargetManager.host
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ enum class Family(val exeSuffix:String, val dynamicPrefix: String, val dynamicSu
|
|||||||
LINUX ("kexe", "lib", "so" ),
|
LINUX ("kexe", "lib", "so" ),
|
||||||
WINDOWS ("exe" , "" , "dll" ),
|
WINDOWS ("exe" , "" , "dll" ),
|
||||||
ANDROID ("so" , "lib", "so" ),
|
ANDROID ("so" , "lib", "so" ),
|
||||||
WASM ("wasm", "" , "wasm" )
|
WASM ("wasm", "" , "wasm" ),
|
||||||
|
ZEPHYR ("o" , "lib", "a" )
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Architecture(val bitness: Int) {
|
enum class Architecture(val bitness: Int) {
|
||||||
@@ -50,6 +51,8 @@ sealed class KonanTarget(override val name: String, val family: Family, val arch
|
|||||||
object LINUX_MIPS32 : KonanTarget( "linux_mips32", Family.LINUX, Architecture.MIPS32, "linux_mips32")
|
object LINUX_MIPS32 : KonanTarget( "linux_mips32", Family.LINUX, Architecture.MIPS32, "linux_mips32")
|
||||||
object LINUX_MIPSEL32 : KonanTarget( "linux_mipsel32", Family.LINUX, Architecture.MIPSEL32, "linux_mipsel32")
|
object LINUX_MIPSEL32 : KonanTarget( "linux_mipsel32", Family.LINUX, Architecture.MIPSEL32, "linux_mipsel32")
|
||||||
object WASM32 : KonanTarget( "wasm32", Family.WASM, Architecture.WASM32, "wasm32")
|
object WASM32 : KonanTarget( "wasm32", Family.WASM, Architecture.WASM32, "wasm32")
|
||||||
|
// Tunable targets
|
||||||
|
class ZEPHYR(val subName: String) : KonanTarget("$zephyr_$subName", Family.ZEPHYR, Architecture.ARM32, "$zephyr_$subName")
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
protected val memberObjects = mutableListOf<KonanTarget>()
|
protected val memberObjects = mutableListOf<KonanTarget>()
|
||||||
@@ -59,6 +62,12 @@ sealed class KonanTarget(override val name: String, val family: Family, val arch
|
|||||||
init {
|
init {
|
||||||
memberObjects.add(this)
|
memberObjects.add(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun generateZephyrTargets(subtargets: List<String>) {
|
||||||
|
subtargets.forEach {
|
||||||
|
object : ZEPHYR(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hostTargetSuffix(host: KonanTarget, target: KonanTarget) =
|
fun hostTargetSuffix(host: KonanTarget, target: KonanTarget) =
|
||||||
@@ -179,12 +188,13 @@ class TargetManager(val userRequest: String? = null) {
|
|||||||
when (host) {
|
when (host) {
|
||||||
KonanTarget.LINUX -> {
|
KonanTarget.LINUX -> {
|
||||||
KonanTarget.LINUX.enabled = true
|
KonanTarget.LINUX.enabled = true
|
||||||
KonanTarget.RASPBERRYPI.enabled = true
|
/*KonanTarget.RASPBERRYPI.enabled = true
|
||||||
KonanTarget.LINUX_MIPS32.enabled = true
|
KonanTarget.LINUX_MIPS32.enabled = true
|
||||||
KonanTarget.LINUX_MIPSEL32.enabled = true
|
KonanTarget.LINUX_MIPSEL32.enabled = true
|
||||||
KonanTarget.ANDROID_ARM32.enabled = true
|
KonanTarget.ANDROID_ARM32.enabled = true
|
||||||
KonanTarget.ANDROID_ARM64.enabled = true
|
KonanTarget.ANDROID_ARM64.enabled = true
|
||||||
KonanTarget.WASM32.enabled = true
|
KonanTarget.WASM32.enabled = true*/
|
||||||
|
KonanTarget.ZEPHYR.enabled = true
|
||||||
}
|
}
|
||||||
KonanTarget.MINGW -> {
|
KonanTarget.MINGW -> {
|
||||||
KonanTarget.MINGW.enabled = true
|
KonanTarget.MINGW.enabled = true
|
||||||
|
|||||||
@@ -285,6 +285,25 @@ open class WasmLinker(targetProperties: WasmConfigurables)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class ZephyrLinker(targetProperties: ZephyrConfigurables)
|
||||||
|
: LinkerFlags(targetProperties), ZephyrConfigurables by targetProperties {
|
||||||
|
|
||||||
|
private val linker = "$targetToolchain/bin/ld"
|
||||||
|
|
||||||
|
override val useCompilerDriverAsLinker: Boolean get() = false
|
||||||
|
|
||||||
|
override fun filterStaticLibraries(binaries: List<String>)
|
||||||
|
= emptyList<String>()
|
||||||
|
|
||||||
|
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
||||||
|
return Command(linker).apply {
|
||||||
|
+ listOf("-r", "--gc-sections", "--entry", "main")
|
||||||
|
+ listOf("-o", executable)
|
||||||
|
+ objectFiles
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun linker(configurables: Configurables): LinkerFlags =
|
fun linker(configurables: Configurables): LinkerFlags =
|
||||||
when (configurables.target) {
|
when (configurables.target) {
|
||||||
KonanTarget.LINUX, KonanTarget.RASPBERRYPI ->
|
KonanTarget.LINUX, KonanTarget.RASPBERRYPI ->
|
||||||
|
|||||||
Reference in New Issue
Block a user