Merge pull request #1193 from cpunion/targets-refactor-1176
Build targets task 1: Basic Target Parameter Support for llgo build/run/test commands
This commit is contained in:
180
.github/workflows/targets.yml
vendored
Normal file
180
.github/workflows/targets.yml
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
|
||||
name: Targets
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["**"]
|
||||
pull_request:
|
||||
branches: ["**"]
|
||||
|
||||
jobs:
|
||||
llgo:
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- macos-latest
|
||||
- ubuntu-24.04
|
||||
llvm: [19]
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/setup-deps
|
||||
with:
|
||||
llvm-version: ${{matrix.llvm}}
|
||||
|
||||
- name: Set up Go for build
|
||||
uses: ./.github/actions/setup-go
|
||||
with:
|
||||
go-version: "1.24.2"
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
go install ./...
|
||||
echo "LLGO_ROOT=$GITHUB_WORKSPACE" >> $GITHUB_ENV
|
||||
|
||||
- name: Build targets
|
||||
run: |
|
||||
cd _demo/empty
|
||||
for target in \
|
||||
ae-rp2040 \
|
||||
arduino-leonardo \
|
||||
arduino-mega1280 \
|
||||
arduino-mega2560 \
|
||||
arduino-mkr1000 \
|
||||
arduino-mkrwifi1010 \
|
||||
arduino-nano-new \
|
||||
arduino-nano \
|
||||
arduino-nano33 \
|
||||
arduino-zero \
|
||||
arduino \
|
||||
atmega1280 \
|
||||
atmega1284p \
|
||||
atmega2560 \
|
||||
atmega328p \
|
||||
atmega328pb \
|
||||
atmega32u4 \
|
||||
atsamd21e18a \
|
||||
atsamd21g18a \
|
||||
atsamd51g19a \
|
||||
atsamd51j19a \
|
||||
atsamd51j20a \
|
||||
atsamd51p19a \
|
||||
atsamd51p20a \
|
||||
atsame51j19a \
|
||||
atsame54-xpro \
|
||||
atsame54p20a \
|
||||
attiny1616 \
|
||||
attiny85 \
|
||||
badger2040-w \
|
||||
badger2040 \
|
||||
bluepill-clone \
|
||||
bluepill \
|
||||
btt-skr-pico \
|
||||
challenger-rp2040 \
|
||||
circuitplay-express \
|
||||
cortex-m-qemu \
|
||||
cortex-m0 \
|
||||
cortex-m0plus \
|
||||
cortex-m3 \
|
||||
cortex-m33 \
|
||||
cortex-m4 \
|
||||
cortex-m7 \
|
||||
digispark \
|
||||
elecrow-rp2040 \
|
||||
elecrow-rp2350 \
|
||||
esp-c3-32s-kit \
|
||||
esp32-c3-devkit-rust-1 \
|
||||
esp32c3-12f \
|
||||
esp32c3-supermini \
|
||||
esp32c3 \
|
||||
fe310 \
|
||||
feather-m0-express \
|
||||
feather-m0 \
|
||||
feather-m4-can \
|
||||
feather-m4 \
|
||||
feather-rp2040 \
|
||||
feather-stm32f405 \
|
||||
gameboy-advance \
|
||||
gemma-m0 \
|
||||
gnse \
|
||||
gobadge \
|
||||
gopher-badge \
|
||||
gopherbot \
|
||||
grandcentral-m4 \
|
||||
hifive1b \
|
||||
itsybitsy-m0 \
|
||||
itsybitsy-m4 \
|
||||
k210 \
|
||||
kb2040 \
|
||||
lgt92 \
|
||||
lorae5 \
|
||||
m5stamp-c3 \
|
||||
macropad-rp2040 \
|
||||
maixbit \
|
||||
makerfabs-esp32c3spi35 \
|
||||
matrixportal-m4 \
|
||||
metro-m4-airlift \
|
||||
mksnanov3 \
|
||||
nano-rp2040 \
|
||||
nintendoswitch \
|
||||
nucleo-f103rb \
|
||||
nucleo-f722ze \
|
||||
nucleo-l031k6 \
|
||||
nucleo-l432kc \
|
||||
nucleo-l476rg \
|
||||
nucleo-l552ze \
|
||||
nucleo-wl55jc \
|
||||
p1am-100 \
|
||||
pga2350 \
|
||||
pico-plus2 \
|
||||
pico-w \
|
||||
pico \
|
||||
pico2-w \
|
||||
pico2 \
|
||||
pybadge \
|
||||
pygamer \
|
||||
pyportal \
|
||||
qtpy-esp32c3 \
|
||||
qtpy-rp2040 \
|
||||
qtpy \
|
||||
riscv-qemu \
|
||||
riscv32 \
|
||||
riscv64 \
|
||||
rp2040 \
|
||||
rp2350 \
|
||||
rp2350b \
|
||||
simavr \
|
||||
stm32f469disco \
|
||||
stm32f4disco-1 \
|
||||
stm32f4disco \
|
||||
stm32l0x2 \
|
||||
stm32wl5x_cm4 \
|
||||
stm32wle5 \
|
||||
swan \
|
||||
teensy36 \
|
||||
teensy40 \
|
||||
teensy41 \
|
||||
thingplus-rp2040 \
|
||||
thumby \
|
||||
tiny2350 \
|
||||
tkey \
|
||||
trinket-m0 \
|
||||
trinkey-qt2040 \
|
||||
tufty2040 \
|
||||
wasip2 \
|
||||
wasm-unknown \
|
||||
waveshare-rp2040-tiny \
|
||||
waveshare-rp2040-zero \
|
||||
wioterminal \
|
||||
xiao-esp32c3 \
|
||||
xiao-rp2040 \
|
||||
xiao; do
|
||||
../../llgo.sh build -v -target $target -o hello.out . >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ✅ $target `file hello.out`
|
||||
else
|
||||
echo ❌ $target
|
||||
fi
|
||||
done
|
||||
4
_demo/empty/empty.go
Normal file
4
_demo/empty/empty.go
Normal file
@@ -0,0 +1,4 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
}
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
|
||||
// llgo build
|
||||
var Cmd = &base.Command{
|
||||
UsageLine: "llgo build [-o output] [build flags] [packages]",
|
||||
UsageLine: "llgo build [-o output] [-target platform] [build flags] [packages]",
|
||||
Short: "Compile packages and dependencies",
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ func runCmd(cmd *base.Command, args []string) {
|
||||
conf.Tags = flags.Tags
|
||||
conf.Verbose = flags.Verbose
|
||||
conf.OutFile = flags.OutputFile
|
||||
conf.Target = flags.Target
|
||||
|
||||
args = cmd.Flag.Args()
|
||||
|
||||
|
||||
@@ -13,11 +13,13 @@ func AddOutputFlags(fs *flag.FlagSet) {
|
||||
var Verbose bool
|
||||
var BuildEnv string
|
||||
var Tags string
|
||||
var Target string
|
||||
|
||||
func AddBuildFlags(fs *flag.FlagSet) {
|
||||
fs.BoolVar(&Verbose, "v", false, "Verbose mode")
|
||||
fs.StringVar(&Tags, "tags", "", "Build tags")
|
||||
fs.StringVar(&BuildEnv, "buildenv", "", "Build environment")
|
||||
fs.StringVar(&Target, "target", "", "Target platform (e.g., rp2040, wasi)")
|
||||
}
|
||||
|
||||
var Gen bool
|
||||
|
||||
@@ -34,7 +34,7 @@ var (
|
||||
|
||||
// llgo run
|
||||
var Cmd = &base.Command{
|
||||
UsageLine: "llgo run [build flags] package [arguments...]",
|
||||
UsageLine: "llgo run [-target platform] [build flags] package [arguments...]",
|
||||
Short: "Compile and run Go program",
|
||||
}
|
||||
|
||||
@@ -54,11 +54,11 @@ func init() {
|
||||
}
|
||||
|
||||
func runCmd(cmd *base.Command, args []string) {
|
||||
runCmdEx(cmd, args, build.ModeRun)
|
||||
runCmdEx(cmd, args, build.ModeRun) // support target
|
||||
}
|
||||
|
||||
func runCmpTest(cmd *base.Command, args []string) {
|
||||
runCmdEx(cmd, args, build.ModeCmpTest)
|
||||
runCmdEx(cmd, args, build.ModeCmpTest) // no target support
|
||||
}
|
||||
|
||||
func runCmdEx(cmd *base.Command, args []string, mode build.Mode) {
|
||||
@@ -71,6 +71,7 @@ func runCmdEx(cmd *base.Command, args []string, mode build.Mode) {
|
||||
conf.Tags = flags.Tags
|
||||
conf.Verbose = flags.Verbose
|
||||
conf.GenExpect = flags.Gen
|
||||
conf.Target = flags.Target
|
||||
|
||||
args = cmd.Flag.Args()
|
||||
args, runArgs, err := parseRunArgs(args)
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
// llgo test
|
||||
var Cmd = &base.Command{
|
||||
UsageLine: "llgo test [build flags] package [arguments...]",
|
||||
UsageLine: "llgo test [-target platform] [build flags] package [arguments...]",
|
||||
Short: "Compile and run Go test",
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ func runCmd(cmd *base.Command, args []string) {
|
||||
conf := build.NewDefaultConf(build.ModeTest)
|
||||
conf.Tags = flags.Tags
|
||||
conf.Verbose = flags.Verbose
|
||||
conf.Target = flags.Target
|
||||
|
||||
args = cmd.Flag.Args()
|
||||
_, err := build.Do(args, conf)
|
||||
|
||||
@@ -70,6 +70,7 @@ const (
|
||||
type Config struct {
|
||||
Goos string
|
||||
Goarch string
|
||||
Target string // target name (e.g., "rp2040", "wasi") - takes precedence over Goos/Goarch
|
||||
BinPath string
|
||||
AppExt string // ".exe" on Windows, empty on Unix
|
||||
OutFile string // only valid for ModeBuild when len(pkgs) == 1
|
||||
@@ -149,6 +150,20 @@ func Do(args []string, conf *Config) ([]Package, error) {
|
||||
if conf.Goarch == "" {
|
||||
conf.Goarch = runtime.GOARCH
|
||||
}
|
||||
// Handle crosscompile configuration first to set correct GOOS/GOARCH
|
||||
export, err := crosscompile.UseWithTarget(conf.Goos, conf.Goarch, IsWasiThreadsEnabled(), conf.Target)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to setup crosscompile: %w", err)
|
||||
}
|
||||
|
||||
// Update GOOS/GOARCH from export if target was used
|
||||
if conf.Target != "" && export.GOOS != "" {
|
||||
conf.Goos = export.GOOS
|
||||
}
|
||||
if conf.Target != "" && export.GOARCH != "" {
|
||||
conf.Goarch = export.GOARCH
|
||||
}
|
||||
|
||||
verbose := conf.Verbose
|
||||
patterns := args
|
||||
tags := "llgo"
|
||||
@@ -160,6 +175,7 @@ func Do(args []string, conf *Config) ([]Package, error) {
|
||||
BuildFlags: []string{"-tags=" + tags},
|
||||
Fset: token.NewFileSet(),
|
||||
Tests: conf.Mode == ModeTest,
|
||||
Env: append(slices.Clone(os.Environ()), "GOOS="+conf.Goos, "GOARCH="+conf.Goarch),
|
||||
}
|
||||
if conf.Mode == ModeTest {
|
||||
cfg.Mode |= packages.NeedForTest
|
||||
@@ -251,8 +267,6 @@ func Do(args []string, conf *Config) ([]Package, error) {
|
||||
os.Setenv("PATH", env.BinDir()+":"+os.Getenv("PATH")) // TODO(xsw): check windows
|
||||
|
||||
output := conf.OutFile != ""
|
||||
export, err := crosscompile.Use(conf.Goos, conf.Goarch, IsWasiThreadsEnabled())
|
||||
check(err)
|
||||
ctx := &context{env: env, conf: cfg, progSSA: progSSA, prog: prog, dedup: dedup,
|
||||
patches: patches, built: make(map[string]none), initial: initial, mode: mode,
|
||||
output: output,
|
||||
@@ -370,6 +384,15 @@ func (c *context) compiler() *clang.Cmd {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *context) linker() *clang.Cmd {
|
||||
cmd := c.env.Clang()
|
||||
if c.crossCompile.Linker != "" {
|
||||
cmd = clang.New(c.crossCompile.Linker)
|
||||
}
|
||||
cmd.Verbose = c.buildConf.Verbose
|
||||
return cmd
|
||||
}
|
||||
|
||||
func buildAllPkgs(ctx *context, initial []*packages.Package, verbose bool) (pkgs []*aPackage, err error) {
|
||||
pkgs, errPkgs := allPkgs(ctx, initial, verbose)
|
||||
for _, errPkg := range errPkgs {
|
||||
@@ -540,14 +563,14 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, global l
|
||||
pkgsMap[v.Package] = v
|
||||
allPkgs = append(allPkgs, v.Package)
|
||||
}
|
||||
var llFiles []string
|
||||
var objFiles []string
|
||||
var linkArgs []string
|
||||
packages.Visit(allPkgs, nil, func(p *packages.Package) {
|
||||
aPkg := pkgsMap[p]
|
||||
if p.ExportFile != "" && aPkg != nil { // skip packages that only contain declarations
|
||||
linkArgs = append(linkArgs, aPkg.LinkArgs...)
|
||||
llFiles = append(llFiles, aPkg.LLFiles...)
|
||||
llFiles = append(llFiles, aPkg.ExportFile)
|
||||
objFiles = append(objFiles, aPkg.LLFiles...)
|
||||
objFiles = append(objFiles, aPkg.ExportFile)
|
||||
need1, need2 := isNeedRuntimeOrPyInit(ctx, p)
|
||||
if !needRuntime {
|
||||
needRuntime = need1
|
||||
@@ -557,18 +580,19 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, global l
|
||||
}
|
||||
}
|
||||
})
|
||||
entryLLFile, err := genMainModuleFile(ctx, llssa.PkgRuntime, pkg, needRuntime, needPyInit)
|
||||
entryObjFile, err := genMainModuleFile(ctx, llssa.PkgRuntime, pkg, needRuntime, needPyInit)
|
||||
check(err)
|
||||
// defer os.Remove(entryLLFile)
|
||||
llFiles = append(llFiles, entryLLFile)
|
||||
objFiles = append(objFiles, entryObjFile)
|
||||
|
||||
if global != nil {
|
||||
export, err := exportObject(ctx, pkg.PkgPath+".global", pkg.ExportFile+"-global", []byte(global.String()))
|
||||
check(err)
|
||||
llFiles = append(llFiles, export)
|
||||
objFiles = append(objFiles, export)
|
||||
}
|
||||
|
||||
err = compileAndLinkLLFiles(ctx, app, llFiles, linkArgs, verbose)
|
||||
err = linkObjFiles(ctx, app, objFiles, linkArgs, verbose)
|
||||
err = linkObjFiles(ctx, app, objFiles, linkArgs, verbose)
|
||||
check(err)
|
||||
|
||||
switch mode {
|
||||
@@ -625,7 +649,7 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, global l
|
||||
}
|
||||
}
|
||||
|
||||
func compileAndLinkLLFiles(ctx *context, app string, llFiles, linkArgs []string, verbose bool) error {
|
||||
func linkObjFiles(ctx *context, app string, objFiles, linkArgs []string, verbose bool) error {
|
||||
buildArgs := []string{"-o", app}
|
||||
buildArgs = append(buildArgs, linkArgs...)
|
||||
|
||||
@@ -634,15 +658,11 @@ func compileAndLinkLLFiles(ctx *context, app string, llFiles, linkArgs []string,
|
||||
buildArgs = append(buildArgs, "-gdwarf-4")
|
||||
}
|
||||
|
||||
buildArgs = append(buildArgs, ctx.crossCompile.CCFLAGS...)
|
||||
buildArgs = append(buildArgs, ctx.crossCompile.LDFLAGS...)
|
||||
buildArgs = append(buildArgs, ctx.crossCompile.EXTRAFLAGS...)
|
||||
buildArgs = append(buildArgs, llFiles...)
|
||||
if verbose {
|
||||
buildArgs = append(buildArgs, "-v")
|
||||
}
|
||||
buildArgs = append(buildArgs, objFiles...)
|
||||
|
||||
cmd := ctx.compiler()
|
||||
cmd := ctx.linker()
|
||||
cmd.Verbose = verbose
|
||||
return cmd.Link(buildArgs...)
|
||||
}
|
||||
@@ -691,9 +711,23 @@ call i32 @setvbuf(ptr %stdout_ptr, ptr null, i32 2, %size_t 0)
|
||||
call i32 @setvbuf(ptr %stderr_ptr, ptr null, i32 2, %size_t 0)
|
||||
`
|
||||
}
|
||||
// TODO(lijie): workaround for libc-free
|
||||
// Remove main/_start when -buildmode and libc are ready
|
||||
startDefine := `
|
||||
define weak void @_start() {
|
||||
; argc = 0
|
||||
%argc_val = icmp eq i32 0, 0
|
||||
%argc = zext i1 %argc_val to i32
|
||||
; argv = null
|
||||
%argv = inttoptr i64 0 to i8**
|
||||
call i32 @main(i32 %argc, i8** %argv)
|
||||
ret void
|
||||
}
|
||||
`
|
||||
mainDefine := "define i32 @main(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr"
|
||||
if isWasmTarget(ctx.buildConf.Goos) {
|
||||
mainDefine = "define hidden noundef i32 @__main_argc_argv(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr"
|
||||
startDefine = ""
|
||||
}
|
||||
mainCode := fmt.Sprintf(`; ModuleID = 'main'
|
||||
source_filename = "main"
|
||||
@@ -714,6 +748,8 @@ define weak void @"syscall.init"() {
|
||||
ret void
|
||||
}
|
||||
|
||||
%s
|
||||
|
||||
%s {
|
||||
_llgo_0:
|
||||
store i32 %%0, ptr @__llgo_argc, align 4
|
||||
@@ -728,7 +764,7 @@ _llgo_0:
|
||||
}
|
||||
`, declSizeT, stdioDecl,
|
||||
pyInitDecl, rtInitDecl, mainPkgPath, mainPkgPath,
|
||||
mainDefine, stdioNobuf,
|
||||
startDefine, mainDefine, stdioNobuf,
|
||||
pyInit, rtInit, mainPkgPath, mainPkgPath)
|
||||
|
||||
return exportObject(ctx, pkg.PkgPath+".main", pkg.ExportFile+"-main", []byte(mainCode))
|
||||
@@ -819,6 +855,7 @@ func exportObject(ctx *context, pkgPath string, exportFile string, data []byte)
|
||||
exportFile += ".o"
|
||||
args := []string{"-o", exportFile, "-c", f.Name(), "-Wno-override-module"}
|
||||
args = append(args, ctx.crossCompile.CCFLAGS...)
|
||||
args = append(args, ctx.crossCompile.CFLAGS...)
|
||||
if ctx.buildConf.Verbose {
|
||||
fmt.Fprintln(os.Stderr, "clang", args)
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@ package crosscompile
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/goplus/llgo/internal/env"
|
||||
"github.com/goplus/llgo/internal/targets"
|
||||
"github.com/goplus/llgo/internal/xtool/llvm"
|
||||
)
|
||||
|
||||
@@ -17,6 +20,15 @@ type Export struct {
|
||||
CFLAGS []string
|
||||
LDFLAGS []string
|
||||
EXTRAFLAGS []string
|
||||
|
||||
// Additional fields from target configuration
|
||||
LLVMTarget string
|
||||
CPU string
|
||||
Features string
|
||||
BuildTags []string
|
||||
GOOS string
|
||||
GOARCH string
|
||||
Linker string // Linker to use (e.g., "ld.lld", "avr-ld")
|
||||
}
|
||||
|
||||
const wasiSdkUrl = "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-x86_64-macos.tar.gz"
|
||||
@@ -109,8 +121,8 @@ func Use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
||||
"-I" + includeDir,
|
||||
}
|
||||
// Add WebAssembly linker flags
|
||||
export.LDFLAGS = []string{
|
||||
"-target", targetTriple,
|
||||
export.LDFLAGS = append(export.LDFLAGS, export.CCFLAGS...)
|
||||
export.LDFLAGS = append(export.LDFLAGS, []string{
|
||||
"-Wno-override-module",
|
||||
"-Wl,--error-limit=0",
|
||||
"-L" + libDir,
|
||||
@@ -134,18 +146,18 @@ func Use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
||||
"-lwasi-emulated-signal",
|
||||
"-fwasm-exceptions",
|
||||
"-mllvm", "-wasm-enable-sjlj",
|
||||
}
|
||||
}...)
|
||||
// Add thread support if enabled
|
||||
if wasiThreads {
|
||||
export.CCFLAGS = append(
|
||||
export.CCFLAGS,
|
||||
"-pthread",
|
||||
)
|
||||
export.LDFLAGS = append(export.LDFLAGS, export.CCFLAGS...)
|
||||
export.LDFLAGS = append(
|
||||
export.LDFLAGS,
|
||||
"-lwasi-emulated-pthread",
|
||||
"-lpthread",
|
||||
"-pthread", // global is immutable if -pthread is not specified
|
||||
)
|
||||
}
|
||||
|
||||
@@ -194,3 +206,114 @@ func Use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// useTarget loads configuration from a target name (e.g., "rp2040", "wasi")
|
||||
func useTarget(targetName string) (export Export, err error) {
|
||||
resolver := targets.NewDefaultResolver()
|
||||
|
||||
config, err := resolver.Resolve(targetName)
|
||||
if err != nil {
|
||||
return export, fmt.Errorf("failed to resolve target %s: %w", targetName, err)
|
||||
}
|
||||
|
||||
// Convert target config to Export - only export necessary fields
|
||||
export.BuildTags = config.BuildTags
|
||||
export.GOOS = config.GOOS
|
||||
export.GOARCH = config.GOARCH
|
||||
|
||||
// Convert LLVMTarget, CPU, Features to CCFLAGS/LDFLAGS
|
||||
var ccflags []string
|
||||
var ldflags []string
|
||||
|
||||
target := config.LLVMTarget
|
||||
if target == "" {
|
||||
target = llvm.GetTargetTriple(config.GOOS, config.GOARCH)
|
||||
}
|
||||
|
||||
ccflags = append(ccflags, "-Wno-override-module", "--target="+config.LLVMTarget)
|
||||
|
||||
// Inspired by tinygo
|
||||
cpu := config.CPU
|
||||
if cpu != "" {
|
||||
if strings.HasPrefix(target, "i386") || strings.HasPrefix(target, "x86_64") {
|
||||
ccflags = append(ccflags, "-march="+cpu)
|
||||
} else if strings.HasPrefix(target, "avr") {
|
||||
ccflags = append(ccflags, "-mmcu="+cpu)
|
||||
} else {
|
||||
ccflags = append(ccflags, "-mcpu="+cpu)
|
||||
}
|
||||
// Only add -mllvm flags for non-WebAssembly linkers
|
||||
if config.Linker == "ld.lld" {
|
||||
ldflags = append(ldflags, "-mllvm", "-mcpu="+cpu)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Features
|
||||
if config.Features != "" {
|
||||
// Only add -mllvm flags for non-WebAssembly linkers
|
||||
if config.Linker == "ld.lld" {
|
||||
ldflags = append(ldflags, "-mllvm", "-mattr="+config.Features)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Linker - keep it for external usage
|
||||
export.Linker = config.Linker
|
||||
|
||||
// Combine with config flags
|
||||
export.CFLAGS = config.CFlags
|
||||
export.CCFLAGS = ccflags
|
||||
export.LDFLAGS = append(ldflags, filterCompatibleLDFlags(config.LDFlags)...)
|
||||
export.EXTRAFLAGS = []string{}
|
||||
|
||||
return export, nil
|
||||
}
|
||||
|
||||
// UseWithTarget extends the original Use function to support target-based configuration
|
||||
// If targetName is provided, it takes precedence over goos/goarch
|
||||
func UseWithTarget(goos, goarch string, wasiThreads bool, targetName string) (export Export, err error) {
|
||||
if targetName != "" {
|
||||
return useTarget(targetName)
|
||||
}
|
||||
return Use(goos, goarch, wasiThreads)
|
||||
}
|
||||
|
||||
// filterCompatibleLDFlags filters out linker flags that are incompatible with clang/lld
|
||||
func filterCompatibleLDFlags(ldflags []string) []string {
|
||||
if len(ldflags) == 0 {
|
||||
return ldflags
|
||||
}
|
||||
|
||||
var filtered []string
|
||||
|
||||
incompatiblePrefixes := []string{
|
||||
"--defsym=", // Use -Wl,--defsym= instead
|
||||
"-T", // Linker script, needs special handling
|
||||
}
|
||||
|
||||
i := 0
|
||||
for i < len(ldflags) {
|
||||
flag := ldflags[i]
|
||||
|
||||
// Check incompatible prefixes
|
||||
skip := false
|
||||
for _, prefix := range incompatiblePrefixes {
|
||||
if strings.HasPrefix(flag, prefix) {
|
||||
skip = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if skip {
|
||||
// Skip -T and its argument if separate
|
||||
if flag == "-T" && i+1 < len(ldflags) {
|
||||
i += 2 // Skip both -T and the script path
|
||||
} else {
|
||||
i++
|
||||
}
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, flag)
|
||||
i++
|
||||
}
|
||||
|
||||
return filtered
|
||||
}
|
||||
@@ -6,6 +6,7 @@ package crosscompile
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"slices"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -154,3 +155,181 @@ func TestUseCrossCompileSDK(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUseTarget(t *testing.T) {
|
||||
// Test cases for target-based configuration
|
||||
testCases := []struct {
|
||||
name string
|
||||
targetName string
|
||||
expectError bool
|
||||
expectLLVM string
|
||||
expectCPU string
|
||||
}{
|
||||
{
|
||||
name: "WASI Target",
|
||||
targetName: "wasi",
|
||||
expectError: false,
|
||||
expectLLVM: "",
|
||||
expectCPU: "generic",
|
||||
},
|
||||
{
|
||||
name: "RP2040 Target",
|
||||
targetName: "rp2040",
|
||||
expectError: false,
|
||||
expectLLVM: "thumbv6m-unknown-unknown-eabi",
|
||||
expectCPU: "cortex-m0plus",
|
||||
},
|
||||
{
|
||||
name: "Cortex-M Target",
|
||||
targetName: "cortex-m",
|
||||
expectError: false,
|
||||
expectLLVM: "",
|
||||
expectCPU: "",
|
||||
},
|
||||
{
|
||||
name: "Arduino Target (with filtered flags)",
|
||||
targetName: "arduino",
|
||||
expectError: false,
|
||||
expectLLVM: "avr",
|
||||
expectCPU: "atmega328p",
|
||||
},
|
||||
{
|
||||
name: "Nonexistent Target",
|
||||
targetName: "nonexistent-target",
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
export, err := useTarget(tc.targetName)
|
||||
|
||||
if tc.expectError {
|
||||
if err == nil {
|
||||
t.Errorf("Expected error for target %s, but got none", tc.targetName)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error for target %s: %v", tc.targetName, err)
|
||||
}
|
||||
|
||||
// Check if LLVM target is in CCFLAGS
|
||||
if tc.expectLLVM != "" {
|
||||
found := false
|
||||
expectedFlag := "--target=" + tc.expectLLVM
|
||||
for _, flag := range export.CCFLAGS {
|
||||
if flag == expectedFlag {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Expected LLVM target %s in CCFLAGS, got %v", expectedFlag, export.CCFLAGS)
|
||||
}
|
||||
}
|
||||
|
||||
// Check if CPU is in CCFLAGS
|
||||
if tc.expectCPU != "" {
|
||||
found := false
|
||||
expectedFlags := []string{"-mmcu=" + tc.expectCPU, "-mcpu=" + tc.expectCPU}
|
||||
for _, flag := range export.CCFLAGS {
|
||||
for _, expectedFlag := range expectedFlags {
|
||||
if flag == expectedFlag {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Expected CPU %s in CCFLAGS, got %v", tc.expectCPU, export.CCFLAGS)
|
||||
}
|
||||
}
|
||||
|
||||
t.Logf("Target %s: BuildTags=%v, CFlags=%v, CCFlags=%v, LDFlags=%v",
|
||||
tc.targetName, export.BuildTags, export.CFLAGS, export.CCFLAGS, export.LDFLAGS)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUseWithTarget(t *testing.T) {
|
||||
// Test target-based configuration takes precedence
|
||||
export, err := UseWithTarget("linux", "amd64", false, "wasi")
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
// Check if LLVM target is in CCFLAGS
|
||||
found := slices.Contains(export.CCFLAGS, "-mcpu=generic")
|
||||
if !found {
|
||||
t.Errorf("Expected CPU generic in CCFLAGS, got %v", export.CCFLAGS)
|
||||
}
|
||||
|
||||
// Test fallback to goos/goarch when no target specified
|
||||
export, err = UseWithTarget(runtime.GOOS, runtime.GOARCH, false, "")
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
// Should use native configuration (only check for macOS since that's where tests run)
|
||||
if runtime.GOOS == "darwin" && len(export.LDFLAGS) == 0 {
|
||||
t.Error("Expected LDFLAGS to be set for native build")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterCompatibleLDFlags(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input []string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "Empty flags",
|
||||
input: []string{},
|
||||
expected: []string{},
|
||||
},
|
||||
{
|
||||
name: "Compatible flags only",
|
||||
input: []string{"-lm", "-lpthread"},
|
||||
expected: []string{"-lm", "-lpthread"},
|
||||
},
|
||||
{
|
||||
name: "Incompatible flags filtered",
|
||||
input: []string{"--gc-sections", "-lm", "--emit-relocs", "-lpthread"},
|
||||
expected: []string{"--gc-sections", "-lm", "--emit-relocs", "-lpthread"},
|
||||
},
|
||||
{
|
||||
name: "Defsym flags filtered",
|
||||
input: []string{"--defsym=_stack_size=512", "-lm", "--defsym=_bootloader_size=512"},
|
||||
expected: []string{"-lm"},
|
||||
},
|
||||
{
|
||||
name: "Linker script flags filtered",
|
||||
input: []string{"-T", "script.ld", "-lm"},
|
||||
expected: []string{"-lm"},
|
||||
},
|
||||
{
|
||||
name: "Mixed compatible and incompatible",
|
||||
input: []string{"-lm", "--gc-sections", "--defsym=test=1", "-lpthread", "--no-demangle"},
|
||||
expected: []string{"-lm", "--gc-sections", "-lpthread", "--no-demangle"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
result := filterCompatibleLDFlags(tc.input)
|
||||
|
||||
if len(result) != len(tc.expected) {
|
||||
t.Errorf("Expected %d flags, got %d: %v", len(tc.expected), len(result), result)
|
||||
return
|
||||
}
|
||||
|
||||
for i, expected := range tc.expected {
|
||||
if result[i] != expected {
|
||||
t.Errorf("Expected flag[%d] = %s, got %s", i, expected, result[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
43
internal/targets/config.go
Normal file
43
internal/targets/config.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package targets
|
||||
|
||||
// Config represents a complete target configuration after inheritance resolution
|
||||
type Config struct {
|
||||
// Target identification
|
||||
Name string `json:"-"`
|
||||
|
||||
// LLVM configuration
|
||||
LLVMTarget string `json:"llvm-target"`
|
||||
CPU string `json:"cpu"`
|
||||
Features string `json:"features"`
|
||||
|
||||
// Build configuration
|
||||
BuildTags []string `json:"build-tags"`
|
||||
GOOS string `json:"goos"`
|
||||
GOARCH string `json:"goarch"`
|
||||
|
||||
// Compiler and linker configuration
|
||||
Linker string `json:"linker"`
|
||||
CFlags []string `json:"cflags"`
|
||||
LDFlags []string `json:"ldflags"`
|
||||
}
|
||||
|
||||
// RawConfig represents the raw JSON configuration before inheritance resolution
|
||||
type RawConfig struct {
|
||||
Inherits []string `json:"inherits"`
|
||||
Config
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the config appears to be uninitialized
|
||||
func (c *Config) IsEmpty() bool {
|
||||
return c.Name == "" && c.LLVMTarget == "" && c.GOOS == "" && c.GOARCH == ""
|
||||
}
|
||||
|
||||
// HasInheritance returns true if this config inherits from other configs
|
||||
func (rc *RawConfig) HasInheritance() bool {
|
||||
return len(rc.Inherits) > 0
|
||||
}
|
||||
|
||||
// GetInherits returns the list of configs this config inherits from
|
||||
func (rc *RawConfig) GetInherits() []string {
|
||||
return rc.Inherits
|
||||
}
|
||||
73
internal/targets/example_test.go
Normal file
73
internal/targets/example_test.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package targets_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sort"
|
||||
|
||||
"github.com/goplus/llgo/internal/targets"
|
||||
)
|
||||
|
||||
func ExampleResolver_Resolve() {
|
||||
resolver := targets.NewDefaultResolver()
|
||||
|
||||
// Resolve a specific target
|
||||
config, err := resolver.Resolve("rp2040")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Target: %s\n", config.Name)
|
||||
fmt.Printf("LLVM Target: %s\n", config.LLVMTarget)
|
||||
fmt.Printf("CPU: %s\n", config.CPU)
|
||||
fmt.Printf("GOOS: %s\n", config.GOOS)
|
||||
fmt.Printf("GOARCH: %s\n", config.GOARCH)
|
||||
if len(config.BuildTags) > 0 {
|
||||
fmt.Printf("Build Tags: %v\n", config.BuildTags)
|
||||
}
|
||||
if len(config.CFlags) > 0 {
|
||||
fmt.Printf("C Flags: %v\n", config.CFlags)
|
||||
}
|
||||
if len(config.LDFlags) > 0 {
|
||||
fmt.Printf("LD Flags: %v\n", config.LDFlags)
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleResolver_ListAvailableTargets() {
|
||||
resolver := targets.NewDefaultResolver()
|
||||
|
||||
targets, err := resolver.ListAvailableTargets()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Show first 10 targets
|
||||
sort.Strings(targets)
|
||||
fmt.Printf("Available targets (first 10 of %d):\n", len(targets))
|
||||
for i, target := range targets[:10] {
|
||||
fmt.Printf("%d. %s\n", i+1, target)
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleResolver_ResolveAll() {
|
||||
resolver := targets.NewDefaultResolver()
|
||||
|
||||
configs, err := resolver.ResolveAll()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Count targets by GOOS
|
||||
goosCounts := make(map[string]int)
|
||||
for _, config := range configs {
|
||||
if config.GOOS != "" {
|
||||
goosCounts[config.GOOS]++
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Loaded %d target configurations\n", len(configs))
|
||||
fmt.Printf("GOOS distribution:\n")
|
||||
for goos, count := range goosCounts {
|
||||
fmt.Printf(" %s: %d targets\n", goos, count)
|
||||
}
|
||||
}
|
||||
176
internal/targets/loader.go
Normal file
176
internal/targets/loader.go
Normal file
@@ -0,0 +1,176 @@
|
||||
package targets
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Loader handles loading and parsing target configurations
|
||||
type Loader struct {
|
||||
targetsDir string
|
||||
cache map[string]*RawConfig
|
||||
}
|
||||
|
||||
// NewLoader creates a new target configuration loader
|
||||
func NewLoader(targetsDir string) *Loader {
|
||||
return &Loader{
|
||||
targetsDir: targetsDir,
|
||||
cache: make(map[string]*RawConfig),
|
||||
}
|
||||
}
|
||||
|
||||
// LoadRaw loads a raw configuration without resolving inheritance
|
||||
func (l *Loader) LoadRaw(name string) (*RawConfig, error) {
|
||||
// Check cache first
|
||||
if config, exists := l.cache[name]; exists {
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// Construct file path
|
||||
configPath := filepath.Join(l.targetsDir, name+".json")
|
||||
|
||||
// Read file
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read target config %s: %w", name, err)
|
||||
}
|
||||
|
||||
// Parse JSON
|
||||
var config RawConfig
|
||||
if err := json.Unmarshal(data, &config); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse target config %s: %w", name, err)
|
||||
}
|
||||
|
||||
// Set the name
|
||||
config.Name = name
|
||||
|
||||
// Cache the result
|
||||
l.cache[name] = &config
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
// Load loads a target configuration with inheritance resolved
|
||||
func (l *Loader) Load(name string) (*Config, error) {
|
||||
raw, err := l.LoadRaw(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return l.resolveInheritance(raw)
|
||||
}
|
||||
|
||||
// LoadAll loads all target configurations in the targets directory
|
||||
func (l *Loader) LoadAll() (map[string]*Config, error) {
|
||||
entries, err := os.ReadDir(l.targetsDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read targets directory: %w", err)
|
||||
}
|
||||
|
||||
configs := make(map[string]*Config)
|
||||
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".json") {
|
||||
continue
|
||||
}
|
||||
|
||||
name := strings.TrimSuffix(entry.Name(), ".json")
|
||||
config, err := l.Load(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load target %s: %w", name, err)
|
||||
}
|
||||
|
||||
configs[name] = config
|
||||
}
|
||||
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
// resolveInheritance resolves inheritance chain for a configuration
|
||||
func (l *Loader) resolveInheritance(raw *RawConfig) (*Config, error) {
|
||||
if !raw.HasInheritance() {
|
||||
// No inheritance, return as-is
|
||||
return &raw.Config, nil
|
||||
}
|
||||
|
||||
// Start with base config
|
||||
result := &Config{Name: raw.Name}
|
||||
|
||||
// Apply inheritance in order
|
||||
for _, parentName := range raw.GetInherits() {
|
||||
parent, err := l.Load(parentName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load parent config %s: %w", parentName, err)
|
||||
}
|
||||
|
||||
// Merge parent into result
|
||||
l.mergeConfig(result, parent)
|
||||
}
|
||||
|
||||
// Finally, apply current config on top
|
||||
l.mergeConfig(result, &raw.Config)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// mergeConfig merges source config into destination config
|
||||
// Non-empty values in source override those in destination
|
||||
func (l *Loader) mergeConfig(dst, src *Config) {
|
||||
if src.LLVMTarget != "" {
|
||||
dst.LLVMTarget = src.LLVMTarget
|
||||
}
|
||||
if src.CPU != "" {
|
||||
dst.CPU = src.CPU
|
||||
}
|
||||
if src.Features != "" {
|
||||
dst.Features = src.Features
|
||||
}
|
||||
if src.GOOS != "" {
|
||||
dst.GOOS = src.GOOS
|
||||
}
|
||||
if src.GOARCH != "" {
|
||||
dst.GOARCH = src.GOARCH
|
||||
}
|
||||
if src.Linker != "" {
|
||||
dst.Linker = src.Linker
|
||||
}
|
||||
|
||||
// Merge slices (append, don't replace)
|
||||
if len(src.BuildTags) > 0 {
|
||||
dst.BuildTags = append(dst.BuildTags, src.BuildTags...)
|
||||
}
|
||||
if len(src.CFlags) > 0 {
|
||||
dst.CFlags = append(dst.CFlags, src.CFlags...)
|
||||
}
|
||||
if len(src.LDFlags) > 0 {
|
||||
dst.LDFlags = append(dst.LDFlags, src.LDFlags...)
|
||||
}
|
||||
}
|
||||
|
||||
// GetTargetsDir returns the targets directory path
|
||||
func (l *Loader) GetTargetsDir() string {
|
||||
return l.targetsDir
|
||||
}
|
||||
|
||||
// ListTargets returns a list of all available target names
|
||||
func (l *Loader) ListTargets() ([]string, error) {
|
||||
entries, err := os.ReadDir(l.targetsDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read targets directory: %w", err)
|
||||
}
|
||||
|
||||
var targets []string
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".json") {
|
||||
continue
|
||||
}
|
||||
|
||||
name := strings.TrimSuffix(entry.Name(), ".json")
|
||||
targets = append(targets, name)
|
||||
}
|
||||
|
||||
return targets, nil
|
||||
}
|
||||
77
internal/targets/resolver.go
Normal file
77
internal/targets/resolver.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package targets
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Resolver provides high-level interface for target configuration resolution
|
||||
type Resolver struct {
|
||||
loader *Loader
|
||||
}
|
||||
|
||||
// NewResolver creates a new target resolver
|
||||
func NewResolver(targetsDir string) *Resolver {
|
||||
return &Resolver{
|
||||
loader: NewLoader(targetsDir),
|
||||
}
|
||||
}
|
||||
|
||||
// NewDefaultResolver creates a resolver with default targets directory
|
||||
func NewDefaultResolver() *Resolver {
|
||||
// Assume targets directory is relative to this package
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
projectRoot := filepath.Dir(filepath.Dir(filepath.Dir(filename)))
|
||||
targetsDir := filepath.Join(projectRoot, "targets")
|
||||
|
||||
return NewResolver(targetsDir)
|
||||
}
|
||||
|
||||
// Resolve resolves a target configuration by name
|
||||
func (r *Resolver) Resolve(targetName string) (*Config, error) {
|
||||
config, err := r.loader.Load(targetName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve target %s: %w", targetName, err)
|
||||
}
|
||||
|
||||
// Validate required fields
|
||||
if err := r.validateConfig(config); err != nil {
|
||||
return nil, fmt.Errorf("invalid target config %s: %w", targetName, err)
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// ResolveAll resolves all available target configurations
|
||||
func (r *Resolver) ResolveAll() (map[string]*Config, error) {
|
||||
return r.loader.LoadAll()
|
||||
}
|
||||
|
||||
// ListAvailableTargets returns a list of all available target names
|
||||
func (r *Resolver) ListAvailableTargets() ([]string, error) {
|
||||
return r.loader.ListTargets()
|
||||
}
|
||||
|
||||
// validateConfig validates that a resolved config has required fields
|
||||
func (r *Resolver) validateConfig(config *Config) error {
|
||||
if config.Name == "" {
|
||||
return fmt.Errorf("target name is required")
|
||||
}
|
||||
|
||||
// For now, we don't require any specific fields since different targets
|
||||
// may have different requirements. This can be extended in the future.
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTargetsDirectory returns the path to the targets directory
|
||||
func (r *Resolver) GetTargetsDirectory() string {
|
||||
return r.loader.GetTargetsDir()
|
||||
}
|
||||
|
||||
// HasTarget checks if a target with the given name exists
|
||||
func (r *Resolver) HasTarget(name string) bool {
|
||||
_, err := r.loader.LoadRaw(name)
|
||||
return err == nil
|
||||
}
|
||||
322
internal/targets/targets_test.go
Normal file
322
internal/targets/targets_test.go
Normal file
@@ -0,0 +1,322 @@
|
||||
//go:build !llgo
|
||||
|
||||
package targets
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConfigBasics(t *testing.T) {
|
||||
config := &Config{
|
||||
Name: "test",
|
||||
LLVMTarget: "arm-none-eabi",
|
||||
GOOS: "linux",
|
||||
GOARCH: "arm",
|
||||
}
|
||||
|
||||
if config.IsEmpty() {
|
||||
t.Error("Config should not be empty when fields are set")
|
||||
}
|
||||
|
||||
empty := &Config{}
|
||||
if !empty.IsEmpty() {
|
||||
t.Error("Empty config should report as empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawConfigInheritance(t *testing.T) {
|
||||
raw := &RawConfig{
|
||||
Inherits: []string{"parent1", "parent2"},
|
||||
Config: Config{
|
||||
Name: "child",
|
||||
},
|
||||
}
|
||||
|
||||
if !raw.HasInheritance() {
|
||||
t.Error("RawConfig should report having inheritance")
|
||||
}
|
||||
|
||||
inherits := raw.GetInherits()
|
||||
if len(inherits) != 2 || inherits[0] != "parent1" || inherits[1] != "parent2" {
|
||||
t.Errorf("Expected inheritance list [parent1, parent2], got %v", inherits)
|
||||
}
|
||||
|
||||
noInherit := &RawConfig{}
|
||||
if noInherit.HasInheritance() {
|
||||
t.Error("RawConfig with no inherits should not report having inheritance")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoaderLoadRaw(t *testing.T) {
|
||||
// Create a temporary directory for test configs
|
||||
tempDir := t.TempDir()
|
||||
|
||||
// Create a test config file
|
||||
testConfig := `{
|
||||
"llvm-target": "thumbv6m-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m0plus",
|
||||
"goos": "linux",
|
||||
"goarch": "arm",
|
||||
"build-tags": ["test", "embedded"],
|
||||
"cflags": ["-Os", "-g"],
|
||||
"ldflags": ["--gc-sections"]
|
||||
}`
|
||||
|
||||
configPath := filepath.Join(tempDir, "test-target.json")
|
||||
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
||||
t.Fatalf("Failed to write test config: %v", err)
|
||||
}
|
||||
|
||||
loader := NewLoader(tempDir)
|
||||
config, err := loader.LoadRaw("test-target")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to load raw config: %v", err)
|
||||
}
|
||||
|
||||
if config.Name != "test-target" {
|
||||
t.Errorf("Expected name 'test-target', got '%s'", config.Name)
|
||||
}
|
||||
if config.LLVMTarget != "thumbv6m-unknown-unknown-eabi" {
|
||||
t.Errorf("Expected llvm-target 'thumbv6m-unknown-unknown-eabi', got '%s'", config.LLVMTarget)
|
||||
}
|
||||
if config.CPU != "cortex-m0plus" {
|
||||
t.Errorf("Expected cpu 'cortex-m0plus', got '%s'", config.CPU)
|
||||
}
|
||||
if len(config.BuildTags) != 2 || config.BuildTags[0] != "test" || config.BuildTags[1] != "embedded" {
|
||||
t.Errorf("Expected build-tags [test, embedded], got %v", config.BuildTags)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoaderInheritance(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
// Create parent config
|
||||
parentConfig := `{
|
||||
"llvm-target": "thumbv6m-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m0plus",
|
||||
"goos": "linux",
|
||||
"goarch": "arm",
|
||||
"cflags": ["-Os"],
|
||||
"ldflags": ["--gc-sections"]
|
||||
}`
|
||||
|
||||
// Create child config that inherits from parent
|
||||
childConfig := `{
|
||||
"inherits": ["parent"],
|
||||
"cpu": "cortex-m4",
|
||||
"build-tags": ["child"],
|
||||
"cflags": ["-O2"],
|
||||
"ldflags": ["-g"]
|
||||
}`
|
||||
|
||||
parentPath := filepath.Join(tempDir, "parent.json")
|
||||
childPath := filepath.Join(tempDir, "child.json")
|
||||
|
||||
if err := os.WriteFile(parentPath, []byte(parentConfig), 0644); err != nil {
|
||||
t.Fatalf("Failed to write parent config: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(childPath, []byte(childConfig), 0644); err != nil {
|
||||
t.Fatalf("Failed to write child config: %v", err)
|
||||
}
|
||||
|
||||
loader := NewLoader(tempDir)
|
||||
config, err := loader.Load("child")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to load child config: %v", err)
|
||||
}
|
||||
|
||||
// Check inherited values
|
||||
if config.LLVMTarget != "thumbv6m-unknown-unknown-eabi" {
|
||||
t.Errorf("Expected inherited llvm-target 'thumbv6m-unknown-unknown-eabi', got '%s'", config.LLVMTarget)
|
||||
}
|
||||
if config.GOOS != "linux" {
|
||||
t.Errorf("Expected inherited goos 'linux', got '%s'", config.GOOS)
|
||||
}
|
||||
if config.GOARCH != "arm" {
|
||||
t.Errorf("Expected inherited goarch 'arm', got '%s'", config.GOARCH)
|
||||
}
|
||||
|
||||
// Check overridden values
|
||||
if config.CPU != "cortex-m4" {
|
||||
t.Errorf("Expected overridden cpu 'cortex-m4', got '%s'", config.CPU)
|
||||
}
|
||||
|
||||
// Check merged arrays
|
||||
expectedCFlags := []string{"-Os", "-O2"}
|
||||
if len(config.CFlags) != 2 || config.CFlags[0] != "-Os" || config.CFlags[1] != "-O2" {
|
||||
t.Errorf("Expected merged cflags %v, got %v", expectedCFlags, config.CFlags)
|
||||
}
|
||||
|
||||
expectedLDFlags := []string{"--gc-sections", "-g"}
|
||||
if len(config.LDFlags) != 2 || config.LDFlags[0] != "--gc-sections" || config.LDFlags[1] != "-g" {
|
||||
t.Errorf("Expected merged ldflags %v, got %v", expectedLDFlags, config.LDFlags)
|
||||
}
|
||||
|
||||
// Check child-specific values
|
||||
if len(config.BuildTags) != 1 || config.BuildTags[0] != "child" {
|
||||
t.Errorf("Expected build-tags [child], got %v", config.BuildTags)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoaderListTargets(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
// Create some test config files
|
||||
configs := []string{"target1.json", "target2.json", "not-a-target.txt"}
|
||||
for _, config := range configs {
|
||||
configPath := filepath.Join(tempDir, config)
|
||||
if err := os.WriteFile(configPath, []byte("{}"), 0644); err != nil {
|
||||
t.Fatalf("Failed to write config %s: %v", config, err)
|
||||
}
|
||||
}
|
||||
|
||||
loader := NewLoader(tempDir)
|
||||
targets, err := loader.ListTargets()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to list targets: %v", err)
|
||||
}
|
||||
|
||||
expectedTargets := []string{"target1", "target2"}
|
||||
if len(targets) != len(expectedTargets) {
|
||||
t.Errorf("Expected %d targets, got %d", len(expectedTargets), len(targets))
|
||||
}
|
||||
|
||||
for _, expected := range expectedTargets {
|
||||
found := false
|
||||
for _, target := range targets {
|
||||
if target == expected {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Expected target %s not found in list %v", expected, targets)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolver(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
// Create a test config
|
||||
testConfig := `{
|
||||
"llvm-target": "wasm32-unknown-wasi",
|
||||
"cpu": "generic",
|
||||
"goos": "wasip1",
|
||||
"goarch": "wasm"
|
||||
}`
|
||||
|
||||
configPath := filepath.Join(tempDir, "wasi.json")
|
||||
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
||||
t.Fatalf("Failed to write test config: %v", err)
|
||||
}
|
||||
|
||||
resolver := NewResolver(tempDir)
|
||||
|
||||
// Test resolve
|
||||
config, err := resolver.Resolve("wasi")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to resolve target: %v", err)
|
||||
}
|
||||
|
||||
if config.Name != "wasi" {
|
||||
t.Errorf("Expected name 'wasi', got '%s'", config.Name)
|
||||
}
|
||||
|
||||
// Test has target
|
||||
if !resolver.HasTarget("wasi") {
|
||||
t.Error("Resolver should report having 'wasi' target")
|
||||
}
|
||||
if resolver.HasTarget("nonexistent") {
|
||||
t.Error("Resolver should not report having 'nonexistent' target")
|
||||
}
|
||||
|
||||
// Test list available targets
|
||||
targets, err := resolver.ListAvailableTargets()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to list available targets: %v", err)
|
||||
}
|
||||
|
||||
if len(targets) != 1 || targets[0] != "wasi" {
|
||||
t.Errorf("Expected targets [wasi], got %v", targets)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolverWithRealTargets(t *testing.T) {
|
||||
// Test with actual targets directory if it exists
|
||||
resolver := NewDefaultResolver()
|
||||
targetsDir := resolver.GetTargetsDirectory()
|
||||
|
||||
// Check if targets directory exists
|
||||
if _, err := os.Stat(targetsDir); os.IsNotExist(err) {
|
||||
t.Skipf("Targets directory %s does not exist, skipping real targets test", targetsDir)
|
||||
}
|
||||
|
||||
// Test listing real targets
|
||||
targets, err := resolver.ListAvailableTargets()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to list real targets: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Found %d targets in %s", len(targets), targetsDir)
|
||||
|
||||
// Test resolving some known targets
|
||||
knownTargets := []string{"wasi", "cortex-m", "rp2040"}
|
||||
for _, targetName := range knownTargets {
|
||||
if resolver.HasTarget(targetName) {
|
||||
config, err := resolver.Resolve(targetName)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to resolve known target %s: %v", targetName, err)
|
||||
continue
|
||||
}
|
||||
t.Logf("Resolved target %s: LLVM=%s, CPU=%s, GOOS=%s, GOARCH=%s",
|
||||
targetName, config.LLVMTarget, config.CPU, config.GOOS, config.GOARCH)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveAllRealTargets(t *testing.T) {
|
||||
resolver := NewDefaultResolver()
|
||||
targetsDir := resolver.GetTargetsDirectory()
|
||||
|
||||
// Check if targets directory exists
|
||||
if _, err := os.Stat(targetsDir); os.IsNotExist(err) {
|
||||
t.Skipf("Targets directory %s does not exist, skipping resolve all test", targetsDir)
|
||||
}
|
||||
|
||||
// Test resolving all targets
|
||||
configs, err := resolver.ResolveAll()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to resolve all targets: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Successfully resolved %d targets", len(configs))
|
||||
|
||||
// Check that all configs have names
|
||||
for name, config := range configs {
|
||||
if config.Name != name {
|
||||
t.Errorf("Config name mismatch: key=%s, config.Name=%s", name, config.Name)
|
||||
}
|
||||
if config.IsEmpty() {
|
||||
t.Errorf("Config %s appears to be empty", name)
|
||||
}
|
||||
}
|
||||
|
||||
// Log some statistics
|
||||
goosCounts := make(map[string]int)
|
||||
goarchCounts := make(map[string]int)
|
||||
|
||||
for _, config := range configs {
|
||||
if config.GOOS != "" {
|
||||
goosCounts[config.GOOS]++
|
||||
}
|
||||
if config.GOARCH != "" {
|
||||
goarchCounts[config.GOARCH]++
|
||||
}
|
||||
}
|
||||
|
||||
t.Logf("GOOS distribution: %v", goosCounts)
|
||||
t.Logf("GOARCH distribution: %v", goarchCounts)
|
||||
}
|
||||
61
targets/LICENSE
Normal file
61
targets/LICENSE
Normal file
@@ -0,0 +1,61 @@
|
||||
Target Configuration Files License
|
||||
=====================================
|
||||
|
||||
The target configuration files in this directory are derived from the TinyGo project
|
||||
(https://github.com/tinygo-org/tinygo/tree/release/targets) and are subject to the
|
||||
TinyGo project's license terms.
|
||||
|
||||
Original source: https://github.com/tinygo-org/tinygo/tree/release/targets
|
||||
License: BSD 3-Clause License (same as TinyGo project)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
TinyGo License (BSD 3-Clause)
|
||||
==============================
|
||||
|
||||
Copyright (c) 2018-2025 The TinyGo Authors. All rights reserved.
|
||||
|
||||
TinyGo includes portions of the Go standard library.
|
||||
Copyright (c) 2009-2024 The Go Authors. All rights reserved.
|
||||
|
||||
TinyGo includes portions of LLVM, which is under the Apache License v2.0 with
|
||||
LLVM Exceptions. See https://llvm.org/LICENSE.txt for license information.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Usage in llgo project
|
||||
======================
|
||||
|
||||
These target configuration files have been adapted for use in the llgo project
|
||||
to provide cross-compilation support for embedded platforms. The files maintain
|
||||
their original structure and content while being integrated into llgo's build
|
||||
system.
|
||||
|
||||
Any modifications or adaptations to these files for llgo-specific use are
|
||||
released under the same BSD 3-Clause license terms as the original TinyGo project.
|
||||
4
targets/adafruit-esp32-feather-v2.json
Normal file
4
targets/adafruit-esp32-feather-v2.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"inherits": ["esp32"],
|
||||
"build-tags": ["adafruit_esp32_feather_v2"]
|
||||
}
|
||||
14
targets/ae-rp2040.json
Normal file
14
targets/ae-rp2040.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"inherits": [
|
||||
"rp2040"
|
||||
],
|
||||
"build-tags": ["ae_rp2040"],
|
||||
"serial-port": ["2e8a:000A"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=2048K"
|
||||
],
|
||||
"extra-files": [
|
||||
"targets/pico-boot-stage2.S"
|
||||
]
|
||||
}
|
||||
|
||||
10
targets/arduino-leonardo.json
Normal file
10
targets/arduino-leonardo.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["atmega32u4"],
|
||||
"build-tags": ["arduino_leonardo"],
|
||||
"ldflags": [
|
||||
"--defsym=_bootloader_size=512",
|
||||
"--defsym=_stack_size=512"
|
||||
],
|
||||
"flash-command": "avrdude -c avr109 -p atmega32u4 -b 57600 -P {port} -U flash:w:{hex}:i",
|
||||
"emulator": "simavr -m atmega32u4 -f 16000000 {}"
|
||||
}
|
||||
8
targets/arduino-mega1280.json
Normal file
8
targets/arduino-mega1280.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"inherits": ["atmega1280"],
|
||||
"build-tags": ["arduino_mega1280"],
|
||||
"ldflags": [
|
||||
"--defsym=_bootloader_size=4096"
|
||||
],
|
||||
"flash-command":"avrdude -c arduino -b 57600 -p atmega1280 -P {port} -U flash:w:{hex}:i -v -D"
|
||||
}
|
||||
8
targets/arduino-mega2560.json
Normal file
8
targets/arduino-mega2560.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"inherits": ["atmega2560"],
|
||||
"build-tags": ["arduino_mega2560"],
|
||||
"ldflags": [
|
||||
"--defsym=_bootloader_size=8192"
|
||||
],
|
||||
"flash-command":"avrdude -c wiring -b 115200 -p atmega2560 -P {port} -U flash:w:{hex}:i -v -D"
|
||||
}
|
||||
7
targets/arduino-mkr1000.json
Normal file
7
targets/arduino-mkr1000.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"inherits": ["atsamd21g18a"],
|
||||
"build-tags": ["arduino_mkr1000"],
|
||||
"serial": "usb",
|
||||
"flash-command": "bossac -i -e -w -v -R -U --port={port} --offset=0x2000 {bin}",
|
||||
"flash-1200-bps-reset": "true"
|
||||
}
|
||||
8
targets/arduino-mkrwifi1010.json
Normal file
8
targets/arduino-mkrwifi1010.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"inherits": ["atsamd21g18a"],
|
||||
"build-tags": ["arduino_mkrwifi1010", "ninafw"],
|
||||
"serial": "usb",
|
||||
"serial-port": ["2341:8054", "2341:0054"],
|
||||
"flash-command": "bossac -i -e -w -v -R -U --port={port} --offset=0x2000 {bin}",
|
||||
"flash-1200-bps-reset": "true"
|
||||
}
|
||||
4
targets/arduino-nano-new.json
Normal file
4
targets/arduino-nano-new.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"inherits": ["arduino-nano"],
|
||||
"flash-command": "avrdude -c arduino -p atmega328p -b 115200 -P {port} -U flash:w:{hex}:i"
|
||||
}
|
||||
10
targets/arduino-nano.json
Normal file
10
targets/arduino-nano.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["atmega328p"],
|
||||
"build-tags": ["arduino_nano"],
|
||||
"ldflags": [
|
||||
"--defsym=_bootloader_size=512",
|
||||
"--defsym=_stack_size=512"
|
||||
],
|
||||
"flash-command": "avrdude -c arduino -p atmega328p -b 57600 -P {port} -U flash:w:{hex}:i",
|
||||
"emulator": "simavr -m atmega328p -f 16000000 {}"
|
||||
}
|
||||
7
targets/arduino-nano33.json
Normal file
7
targets/arduino-nano33.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"inherits": ["atsamd21g18a"],
|
||||
"build-tags": ["arduino_nano33", "ninafw", "ninafw_machine_init"],
|
||||
"flash-command": "bossac -i -e -w -v -R -U --port={port} --offset=0x2000 {bin}",
|
||||
"serial-port": ["2341:8057", "2341:0057"],
|
||||
"flash-1200-bps-reset": "true"
|
||||
}
|
||||
7
targets/arduino-zero.json
Normal file
7
targets/arduino-zero.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"inherits": ["atsamd21g18a"],
|
||||
"build-tags": ["arduino_zero"],
|
||||
"serial": "usb",
|
||||
"flash-command": "bossac -i -e -w -v -R -U --port={port} --offset=0x2000 {bin}",
|
||||
"flash-1200-bps-reset": "true"
|
||||
}
|
||||
11
targets/arduino.json
Normal file
11
targets/arduino.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"inherits": ["atmega328p"],
|
||||
"build-tags": ["arduino"],
|
||||
"ldflags": [
|
||||
"--defsym=_bootloader_size=512",
|
||||
"--defsym=_stack_size=512"
|
||||
],
|
||||
"flash-command": "avrdude -c arduino -p atmega328p -P {port} -U flash:w:{hex}:i",
|
||||
"serial-port": ["2341:0043", "2341:0001", "2a03:0043", "2341:0243"],
|
||||
"emulator": "simavr -m atmega328p -f 16000000 {}"
|
||||
}
|
||||
86
targets/arm.ld
Normal file
86
targets/arm.ld
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
/* Unused, but here to silence a linker warning. */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* Program code and read-only data goes to FLASH_TEXT. */
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.isr_vector))
|
||||
KEEP(*(.after_isr_vector)) /* for the RP2350 */
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
. = ALIGN(4);
|
||||
} >FLASH_TEXT
|
||||
|
||||
.tinygo_stacksizes :
|
||||
{
|
||||
*(.tinygo_stacksizes)
|
||||
} > FLASH_TEXT
|
||||
|
||||
/* Put the stack at the bottom of RAM, so that the application will
|
||||
* crash on stack overflow instead of silently corrupting memory.
|
||||
* See: http://blog.japaric.io/stack-overflow-protection/ */
|
||||
.stack (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
. += _stack_size;
|
||||
_stack_top = .;
|
||||
} >RAM
|
||||
|
||||
/* Stack for second core (core 1), if there is one. */
|
||||
.stack1 (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
. += DEFINED(__num_stacks) && __num_stacks >= 2 ? _stack_size : 0;
|
||||
_stack1_top = .;
|
||||
} >RAM
|
||||
|
||||
/* Start address (in flash) of .data, used by startup code. */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
/* Globals with initial value */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .; /* used by startup code */
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
. = ALIGN(4);
|
||||
*(.ramfuncs*) /* Functions that must execute from RAM */
|
||||
. = ALIGN(4);
|
||||
_edata = .; /* used by startup code */
|
||||
} >RAM AT>FLASH_TEXT
|
||||
|
||||
/* Zero-initialized globals */
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sbss = .; /* used by startup code */
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = .; /* used by startup code */
|
||||
} >RAM
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.ARM.exidx) /* causes 'no memory region specified' error in lld */
|
||||
*(.ARM.exidx.*) /* causes spurious 'undefined reference' errors */
|
||||
}
|
||||
}
|
||||
|
||||
/* For the memory allocator. */
|
||||
_heap_start = _ebss;
|
||||
_heap_end = ORIGIN(RAM) + LENGTH(RAM);
|
||||
_globals_start = _sdata;
|
||||
_globals_end = _ebss;
|
||||
|
||||
/* For the flash API */
|
||||
__flash_data_start = LOADADDR(.data) + SIZEOF(.data);
|
||||
__flash_data_end = ORIGIN(FLASH_TEXT) + LENGTH(FLASH_TEXT);
|
||||
14
targets/atmega1280.json
Normal file
14
targets/atmega1280.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"inherits": ["avr"],
|
||||
"cpu": "atmega1280",
|
||||
"build-tags": ["atmega1280", "atmega"],
|
||||
"serial": "uart",
|
||||
"ldflags": [
|
||||
"--defsym=_stack_size=512"
|
||||
],
|
||||
"linkerscript": "src/device/avr/atmega1280.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega1280.s"
|
||||
]
|
||||
}
|
||||
16
targets/atmega1284p.json
Normal file
16
targets/atmega1284p.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"inherits": ["avr"],
|
||||
"cpu": "atmega1284p",
|
||||
"build-tags": ["atmega1284p", "atmega"],
|
||||
"serial": "uart",
|
||||
"ldflags": [
|
||||
"--defsym=_bootloader_size=0",
|
||||
"--defsym=_stack_size=512"
|
||||
],
|
||||
"linkerscript": "src/device/avr/atmega1284p.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega1284p.s"
|
||||
],
|
||||
"emulator": "simavr -m atmega1284p -f 20000000 {}"
|
||||
}
|
||||
14
targets/atmega2560.json
Normal file
14
targets/atmega2560.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"inherits": ["avr"],
|
||||
"cpu": "atmega2560",
|
||||
"build-tags": ["atmega2560", "atmega"],
|
||||
"serial": "uart",
|
||||
"ldflags": [
|
||||
"--defsym=_stack_size=512"
|
||||
],
|
||||
"linkerscript": "src/device/avr/atmega2560.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega2560.s"
|
||||
]
|
||||
}
|
||||
11
targets/atmega328p.json
Normal file
11
targets/atmega328p.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"inherits": ["avr"],
|
||||
"cpu": "atmega328p",
|
||||
"build-tags": ["atmega328p", "atmega", "avr5"],
|
||||
"serial": "uart",
|
||||
"linkerscript": "src/device/avr/atmega328p.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega328p.s"
|
||||
]
|
||||
}
|
||||
15
targets/atmega328pb.json
Normal file
15
targets/atmega328pb.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"inherits": ["avr"],
|
||||
"cpu": "atmega328pb",
|
||||
"build-tags": ["atmega328pb", "atmega", "avr5"],
|
||||
"ldflags": [
|
||||
"--defsym=_bootloader_size=512",
|
||||
"--defsym=_stack_size=512"
|
||||
],
|
||||
"serial": "uart",
|
||||
"linkerscript": "src/device/avr/atmega328pb.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega328pb.s"
|
||||
]
|
||||
}
|
||||
11
targets/atmega32u4.json
Normal file
11
targets/atmega32u4.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"inherits": ["avr"],
|
||||
"cpu": "atmega32u4",
|
||||
"build-tags": ["atmega32u4", "avr5"],
|
||||
"serial": "none",
|
||||
"linkerscript": "src/device/avr/atmega32u4.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega32u4.s"
|
||||
]
|
||||
}
|
||||
10
targets/atsamd21.ld
Normal file
10
targets/atsamd21.ld
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x00008000
|
||||
}
|
||||
|
||||
_stack_size = 2K;
|
||||
|
||||
INCLUDE "targets/arm.ld"
|
||||
11
targets/atsamd21e18a.json
Normal file
11
targets/atsamd21e18a.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"inherits": ["cortex-m0plus"],
|
||||
"build-tags": ["atsamd21e18a", "atsamd21e18", "atsamd21", "sam"],
|
||||
"serial": "usb",
|
||||
"linkerscript": "targets/atsamd21.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd21e18a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "at91samdXX"
|
||||
}
|
||||
11
targets/atsamd21g18a.json
Normal file
11
targets/atsamd21g18a.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"inherits": ["cortex-m0plus"],
|
||||
"build-tags": ["atsamd21g18a", "atsamd21g18", "atsamd21", "sam"],
|
||||
"serial": "usb",
|
||||
"linkerscript": "targets/atsamd21.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd21g18a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "at91samdXX"
|
||||
}
|
||||
10
targets/atsamd51.ld
Normal file
10
targets/atsamd51.ld
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x00030000
|
||||
}
|
||||
|
||||
_stack_size = 4K;
|
||||
|
||||
INCLUDE "targets/arm.ld"
|
||||
10
targets/atsamd51g19a.json
Normal file
10
targets/atsamd51g19a.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["cortex-m4"],
|
||||
"build-tags": ["atsamd51g19a", "atsamd51g19", "atsamd51", "sam"],
|
||||
"linkerscript": "targets/atsamd51.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd51g19a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
}
|
||||
10
targets/atsamd51j19a.json
Normal file
10
targets/atsamd51j19a.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["cortex-m4"],
|
||||
"build-tags": ["atsamd51j19a", "atsamd51j19", "atsamd51", "sam"],
|
||||
"linkerscript": "targets/atsamd51.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd51j19a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
}
|
||||
10
targets/atsamd51j20a.json
Normal file
10
targets/atsamd51j20a.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["cortex-m4"],
|
||||
"build-tags": ["sam", "atsamd51", "atsamd51j20", "atsamd51j20a"],
|
||||
"linkerscript": "targets/atsamd51j20a.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd51j20a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
}
|
||||
10
targets/atsamd51j20a.ld
Normal file
10
targets/atsamd51j20a.ld
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00100000-0x4000 /* First 16KB used by bootloader */
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x00040000
|
||||
}
|
||||
|
||||
_stack_size = 4K;
|
||||
|
||||
INCLUDE "targets/arm.ld"
|
||||
10
targets/atsamd51p19a.json
Normal file
10
targets/atsamd51p19a.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["cortex-m4"],
|
||||
"build-tags": ["atsamd51p19a", "atsamd51p19", "atsamd51", "sam"],
|
||||
"linkerscript": "targets/atsamd51.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd51p19a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
}
|
||||
10
targets/atsamd51p20a.json
Normal file
10
targets/atsamd51p20a.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["cortex-m4"],
|
||||
"build-tags": ["sam", "atsamd51", "atsamd51p20", "atsamd51p20a"],
|
||||
"linkerscript": "targets/atsamd51p20a.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd51p20a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
}
|
||||
10
targets/atsamd51p20a.ld
Normal file
10
targets/atsamd51p20a.ld
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00100000-0x4000 /* First 16KB used by bootloader */
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x00040000
|
||||
}
|
||||
|
||||
_stack_size = 4K;
|
||||
|
||||
INCLUDE "targets/arm.ld"
|
||||
10
targets/atsame51j19a.json
Normal file
10
targets/atsame51j19a.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["cortex-m4"],
|
||||
"build-tags": ["atsame51j19a", "atsame51j19", "atsame51", "atsame5x", "sam"],
|
||||
"linkerscript": "targets/atsame5xx19.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsame51j19a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
}
|
||||
7
targets/atsame54-xpro.json
Normal file
7
targets/atsame54-xpro.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"inherits": ["atsame54p20a"],
|
||||
"build-tags": ["atsame54_xpro"],
|
||||
"serial": "usb",
|
||||
"flash-method": "openocd",
|
||||
"openocd-interface": "cmsis-dap"
|
||||
}
|
||||
10
targets/atsame54p20a.json
Normal file
10
targets/atsame54p20a.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["cortex-m4"],
|
||||
"build-tags": ["sam", "atsame5x", "atsame54", "atsame54p20", "atsame54p20a"],
|
||||
"linkerscript": "targets/atsame5xx20-no-bootloader.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsame54p20a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
}
|
||||
10
targets/atsame5xx19.ld
Normal file
10
targets/atsame5xx19.ld
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x00030000
|
||||
}
|
||||
|
||||
_stack_size = 4K;
|
||||
|
||||
INCLUDE "targets/arm.ld"
|
||||
10
targets/atsame5xx20-no-bootloader.ld
Normal file
10
targets/atsame5xx20-no-bootloader.ld
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x0000, LENGTH = 0x00100000-0x0000
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x00040000
|
||||
}
|
||||
|
||||
_stack_size = 4K;
|
||||
|
||||
INCLUDE "targets/arm.ld"
|
||||
14
targets/attiny1616.json
Normal file
14
targets/attiny1616.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"inherits": ["avrtiny"],
|
||||
"cpu": "attiny1616",
|
||||
"build-tags": ["attiny1616"],
|
||||
"gc": "none",
|
||||
"cflags": [
|
||||
"-D__AVR_ARCH__=103"
|
||||
],
|
||||
"linkerscript": "src/device/avr/attiny1616.ld",
|
||||
"extra-files": [
|
||||
"src/device/avr/attiny1616.s"
|
||||
],
|
||||
"flash-command": "pymcuprog write -f {hex} --erase --verify -d attiny1616 -t uart -u {port}"
|
||||
}
|
||||
13
targets/attiny85.json
Normal file
13
targets/attiny85.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"inherits": ["avr"],
|
||||
"cpu": "attiny85",
|
||||
"build-tags": ["attiny85", "attiny", "avr2", "avr25"],
|
||||
"cflags": [
|
||||
"-D__AVR_ARCH__=25"
|
||||
],
|
||||
"linkerscript": "src/device/avr/attiny85.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/attiny85.s"
|
||||
]
|
||||
}
|
||||
84
targets/avr.S
Normal file
84
targets/avr.S
Normal file
@@ -0,0 +1,84 @@
|
||||
; This file provides common code across AVRs that cannot be implemented directly
|
||||
; in Go.
|
||||
; The reset vector is device-specific and is generated by tools/gen-device-avr.py.
|
||||
|
||||
; These definitions are necessary because LLVM does not yet know these register
|
||||
; aliases. See: https://reviews.llvm.org/D96492
|
||||
#define xl r26
|
||||
#define xh r27
|
||||
#define yl r28
|
||||
#define yh r29
|
||||
#define zl r30
|
||||
#define zh r31
|
||||
|
||||
; Ugly hack until https://reviews.llvm.org/D137572 is merged.
|
||||
#if !defined(__AVR_HAVE_ELPM__) && defined(__flash1)
|
||||
#define __AVR_HAVE_ELPM__
|
||||
#endif
|
||||
|
||||
; Startup code
|
||||
.section .text.__vector_RESET
|
||||
.global __vector_RESET
|
||||
__vector_RESET:
|
||||
clr r1 ; r1 is expected to be 0 by the C calling convention
|
||||
|
||||
; Set up the stack pointer.
|
||||
ldi xl, lo8(_stack_top)
|
||||
ldi xh, hi8(_stack_top)
|
||||
out 0x3d, xl; SPL
|
||||
out 0x3e, xh; SPH
|
||||
|
||||
; Subtract one from the stack pointer, so it doesn't point in the .data section.
|
||||
push r0
|
||||
|
||||
; Initialize .data
|
||||
init_data:
|
||||
ldi xl, lo8(_sdata)
|
||||
ldi xh, hi8(_sdata)
|
||||
ldi yl, lo8(_edata)
|
||||
ldi yh, hi8(_edata)
|
||||
ldi zl, lo8(_sidata)
|
||||
ldi zh, hi8(_sidata)
|
||||
#ifdef __AVR_HAVE_ELPM__
|
||||
ldi r16, hh8(_sidata) ; RAMPZ = hh8(_sidata)
|
||||
out 0x3b, r16
|
||||
#endif
|
||||
init_data_loop:
|
||||
cp xl, yl ; if x == y
|
||||
cpc xh, yh
|
||||
breq init_data_end ; goto main
|
||||
#ifdef __AVR_HAVE_ELPM__
|
||||
elpm r0, Z+ ; r0 = *(z++)
|
||||
#else
|
||||
lpm r0, Z+ ; r0 = *(z++)
|
||||
#endif
|
||||
st X+, r0 ; *(x++) = r0
|
||||
rjmp init_data_loop ; goto init_data_loop
|
||||
init_data_end:
|
||||
|
||||
; main will be placed right after here by the linker script so there's no
|
||||
; need to jump.
|
||||
|
||||
|
||||
; The only thing this WDT handler really does is disable itself, to get out of
|
||||
; sleep mode.
|
||||
.section .text.__vector_WDT
|
||||
.global __vector_WDT
|
||||
__vector_WDT:
|
||||
push r16
|
||||
|
||||
clr r16
|
||||
wdr ; Reset watchdog
|
||||
out 0x34, r16 ; Clear reset reason (MCUSR)
|
||||
|
||||
; part 1: set WDCE and WDE to enable editing WDTCSR
|
||||
lds r16, 0x60 ; r16 = WDTCSR
|
||||
ori r16, 0x18 ; r16 |= WDCE | WDE
|
||||
sts 0x60, r16 ; WDTCSR = r16
|
||||
|
||||
; part 2: within 4 clock cycles, set the new value for WDTCSR
|
||||
clr r16
|
||||
sts 0x60, r16 ; WDTCSR = 0
|
||||
|
||||
pop r16
|
||||
reti
|
||||
24
targets/avr.json
Normal file
24
targets/avr.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"llvm-target": "avr",
|
||||
"build-tags": ["avr", "baremetal", "linux", "arm"],
|
||||
"goos": "linux",
|
||||
"goarch": "arm",
|
||||
"gc": "conservative",
|
||||
"linker": "ld.lld",
|
||||
"scheduler": "none",
|
||||
"rtlib": "compiler-rt",
|
||||
"libc": "picolibc",
|
||||
"default-stack-size": 256,
|
||||
"cflags": [
|
||||
"-Werror"
|
||||
],
|
||||
"ldflags": [
|
||||
"-T", "targets/avr.ld",
|
||||
"--gc-sections"
|
||||
],
|
||||
"extra-files": [
|
||||
"src/internal/task/task_stack_avr.S",
|
||||
"src/runtime/asm_avr.S"
|
||||
],
|
||||
"gdb": ["avr-gdb"]
|
||||
}
|
||||
56
targets/avr.ld
Normal file
56
targets/avr.ld
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rw) : ORIGIN = 0, LENGTH = __flash_size - _bootloader_size
|
||||
RAM (xrw) : ORIGIN = 0x800000 + __ram_start, LENGTH = __ram_size
|
||||
}
|
||||
|
||||
ENTRY(main)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.vectors))
|
||||
KEEP(*(.text.__vector_RESET))
|
||||
KEEP(*(.text.main)) /* main must follow the reset handler */
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.progmem)
|
||||
*(.progmem.*)
|
||||
. = ALIGN(16); /* needed with ld.lld for some reasoon */
|
||||
}
|
||||
|
||||
.stack (NOLOAD) :
|
||||
{
|
||||
. += _stack_size;
|
||||
_stack_top = .;
|
||||
} >RAM
|
||||
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
.data :
|
||||
{
|
||||
_sdata = .; /* used by startup code */
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.data)
|
||||
*(.data*)
|
||||
_edata = .; /* used by startup code */
|
||||
} >RAM AT>FLASH_TEXT
|
||||
|
||||
.bss :
|
||||
{
|
||||
_sbss = .; /* used by startup code */
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
_ebss = .; /* used by startup code */
|
||||
} >RAM
|
||||
}
|
||||
|
||||
/* For the memory allocator. */
|
||||
_heap_start = _ebss;
|
||||
_heap_end = ORIGIN(RAM) + LENGTH(RAM);
|
||||
_globals_start = _sdata;
|
||||
_globals_end = _ebss;
|
||||
43
targets/avrtiny.S
Normal file
43
targets/avrtiny.S
Normal file
@@ -0,0 +1,43 @@
|
||||
#define __tmp_reg__ r16
|
||||
#define __zero_reg__ r17
|
||||
|
||||
; Startup code
|
||||
.section .text.__vector_RESET
|
||||
.global __vector_RESET
|
||||
__vector_RESET:
|
||||
clr __zero_reg__ ; this register is expected to be 0 by the C calling convention
|
||||
|
||||
; Keep the stack pointer at the default location, which is RAMEND.
|
||||
|
||||
; Initialize .data section.
|
||||
.section .text.__do_copy_data,"ax",@progbits
|
||||
.global __do_copy_data
|
||||
__do_copy_data:
|
||||
ldi xl, lo8(__data_start)
|
||||
ldi xh, hi8(__data_start)
|
||||
ldi yl, lo8(__data_end)
|
||||
ldi yh, hi8(__data_end)
|
||||
ldi zl, lo8(__data_load_start)
|
||||
ldi zh, hi8(__data_load_start)
|
||||
1: ; loop
|
||||
cp xl, yl ; if x == y
|
||||
cpc xh, yh
|
||||
breq 2f ; goto end
|
||||
ld r16, Z+ ; r0 = *(z++)
|
||||
st X+, r16 ; *(x++) = r0
|
||||
rjmp 1b ; goto loop
|
||||
2: ; end
|
||||
|
||||
; Initialize .bss section.
|
||||
.section .text.__do_clear_bss,"ax",@progbits
|
||||
.global __do_clear_bss
|
||||
__do_clear_bss:
|
||||
ldi xl, lo8(__bss_start)
|
||||
ldi xh, hi8(__bss_start)
|
||||
ldi yl, lo8(__bss_end)
|
||||
1: ; loop
|
||||
cp xl, yl ; if x == y
|
||||
breq 2f ; goto end
|
||||
st X+, __zero_reg__ ; *(x++) = 0
|
||||
rjmp 1b ; goto loop
|
||||
2: ; end
|
||||
25
targets/avrtiny.json
Normal file
25
targets/avrtiny.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"llvm-target": "avr",
|
||||
"build-tags": ["avr", "avrtiny", "baremetal", "linux", "arm"],
|
||||
"goos": "linux",
|
||||
"goarch": "arm",
|
||||
"gc": "conservative",
|
||||
"linker": "ld.lld",
|
||||
"scheduler": "none",
|
||||
"rtlib": "compiler-rt",
|
||||
"libc": "picolibc",
|
||||
"default-stack-size": 256,
|
||||
"cflags": [
|
||||
"-Werror"
|
||||
],
|
||||
"ldflags": [
|
||||
"-T", "targets/avrtiny.ld",
|
||||
"--gc-sections"
|
||||
],
|
||||
"extra-files": [
|
||||
"src/internal/task/task_stack_avr.S",
|
||||
"src/runtime/asm_avr.S",
|
||||
"targets/avrtiny.S"
|
||||
],
|
||||
"gdb": ["avr-gdb"]
|
||||
}
|
||||
58
targets/avrtiny.ld
Normal file
58
targets/avrtiny.ld
Normal file
@@ -0,0 +1,58 @@
|
||||
/* Linker script for AVRs with a unified flash and RAM address space. This
|
||||
* includes the ATtiny10 and the ATtiny1616.
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (x) : ORIGIN = 0, LENGTH = __flash_size
|
||||
FLASH_DATA (r) : ORIGIN = __mapped_flash_start, LENGTH = __flash_size
|
||||
RAM (xrw) : ORIGIN = __ram_start, LENGTH = __ram_size
|
||||
}
|
||||
|
||||
ENTRY(main)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.vectors))
|
||||
*(.text.__vector_RESET)
|
||||
KEEP(*(.text.__do_copy_data)) /* TODO: only use when __do_copy_data is requested */
|
||||
KEEP(*(.text.__do_clear_bss))
|
||||
KEEP(*(.text.main)) /* main must follow the reset handler */
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
} > FLASH_TEXT
|
||||
|
||||
/* Read-only data is stored in flash, but is read from an offset (0x4000 or
|
||||
* 0x8000 depending on the chip). This requires some weird math to get it in
|
||||
* the right place.
|
||||
*/
|
||||
.rodata ORIGIN(FLASH_DATA) + ADDR(.text) + SIZEOF(.text):
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
} AT>FLASH_TEXT
|
||||
|
||||
/* The address to which the data section should be copied by the startup
|
||||
* code.
|
||||
*/
|
||||
__data_load_start = ORIGIN(FLASH_DATA) + LOADADDR(.data);
|
||||
|
||||
.data :
|
||||
{
|
||||
__data_start = .; /* used by startup code */
|
||||
*(.data)
|
||||
*(.data*)
|
||||
__data_end = .; /* used by startup code */
|
||||
} >RAM AT>FLASH_TEXT
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start = .; /* used by startup code */
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
__bss_end = .; /* used by startup code */
|
||||
} >RAM
|
||||
}
|
||||
13
targets/badger2040-w.json
Normal file
13
targets/badger2040-w.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"inherits": [
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2e8a:0003"],
|
||||
"build-tags": ["badger2040_w", "cyw43439"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=1020K"
|
||||
],
|
||||
"extra-files": [
|
||||
"targets/pico-boot-stage2.S"
|
||||
]
|
||||
}
|
||||
13
targets/badger2040.json
Normal file
13
targets/badger2040.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"inherits": [
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2e8a:0003"],
|
||||
"build-tags": ["badger2040"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=1020K"
|
||||
],
|
||||
"extra-files": [
|
||||
"targets/pico-boot-stage2.S"
|
||||
]
|
||||
}
|
||||
6
targets/bluemicro840.json
Normal file
6
targets/bluemicro840.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inherits": ["nrf52840", "nrf52840-s140v6-uf2"],
|
||||
"build-tags": ["bluemicro840"],
|
||||
"serial-port": ["1d50:6161"],
|
||||
"msd-volume-name": ["BLUEMICRO"]
|
||||
}
|
||||
4
targets/bluepill-clone.json
Normal file
4
targets/bluepill-clone.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"inherits": ["bluepill"],
|
||||
"openocd-commands": ["set CPUTAPID 0x2ba01477"]
|
||||
}
|
||||
12
targets/bluepill.json
Normal file
12
targets/bluepill.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"inherits": ["cortex-m3"],
|
||||
"build-tags": ["bluepill", "stm32f103", "stm32f1", "stm32"],
|
||||
"serial": "uart",
|
||||
"linkerscript": "targets/stm32.ld",
|
||||
"extra-files": [
|
||||
"src/device/stm32/stm32f103.s"
|
||||
],
|
||||
"flash-method": "openocd",
|
||||
"openocd-interface": "stlink-v2",
|
||||
"openocd-target": "stm32f1x"
|
||||
}
|
||||
13
targets/btt-skr-pico.json
Normal file
13
targets/btt-skr-pico.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"inherits": [
|
||||
"rp2040"
|
||||
],
|
||||
"build-tags": ["btt_skr_pico"],
|
||||
"serial-port": ["2e8a:000A"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=16M"
|
||||
],
|
||||
"extra-files": [
|
||||
"targets/pico-boot-stage2.S"
|
||||
]
|
||||
}
|
||||
13
targets/challenger-rp2040.json
Normal file
13
targets/challenger-rp2040.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"inherits": [
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2e8a:1023"],
|
||||
"build-tags": ["challenger_rp2040"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=8M"
|
||||
],
|
||||
"extra-files": [
|
||||
"targets/feather-rp2040-boot-stage2.S"
|
||||
]
|
||||
}
|
||||
6
targets/circuitplay-bluefruit.json
Normal file
6
targets/circuitplay-bluefruit.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inherits": ["nrf52840", "nrf52840-s140v6-uf2"],
|
||||
"build-tags": ["circuitplay_bluefruit"],
|
||||
"serial-port": ["239a:8045"],
|
||||
"msd-volume-name": ["CPLAYBTBOOT"]
|
||||
}
|
||||
9
targets/circuitplay-express.json
Normal file
9
targets/circuitplay-express.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"inherits": ["atsamd21g18a"],
|
||||
"build-tags": ["circuitplay_express"],
|
||||
"flash-1200-bps-reset": "true",
|
||||
"flash-method": "msd",
|
||||
"serial-port": ["239a:8018"],
|
||||
"msd-volume-name": ["CPLAYBOOT"],
|
||||
"msd-firmware-name": "firmware.uf2"
|
||||
}
|
||||
6
targets/clue-alpha.json
Normal file
6
targets/clue-alpha.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inherits": ["nrf52840", "nrf52840-s140v6-uf2"],
|
||||
"build-tags": ["clue_alpha"],
|
||||
"serial-port": ["239a:8072", "239a:8071"],
|
||||
"msd-volume-name": ["CLUEBOOT"]
|
||||
}
|
||||
3
targets/clue.json
Normal file
3
targets/clue.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"inherits": ["clue-alpha"]
|
||||
}
|
||||
10
targets/cortex-m-qemu.json
Normal file
10
targets/cortex-m-qemu.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["cortex-m3"],
|
||||
"build-tags": ["qemu", "lm3s6965"],
|
||||
"linkerscript": "targets/lm3s6965.ld",
|
||||
"default-stack-size": 4096,
|
||||
"extra-files": [
|
||||
"targets/cortex-m-qemu.s"
|
||||
],
|
||||
"emulator": "qemu-system-arm -machine lm3s6965evb -semihosting -nographic -kernel {}"
|
||||
}
|
||||
59
targets/cortex-m-qemu.s
Normal file
59
targets/cortex-m-qemu.s
Normal file
@@ -0,0 +1,59 @@
|
||||
// Generic Cortex-M interrupt vector.
|
||||
// This vector is used by the Cortex-M QEMU target.
|
||||
|
||||
.cfi_sections .debug_frame
|
||||
.syntax unified
|
||||
|
||||
// This is the default handler for interrupts, if triggered but not defined.
|
||||
.section .text.Default_Handler
|
||||
.global Default_Handler
|
||||
.type Default_Handler, %function
|
||||
Default_Handler:
|
||||
.cfi_startproc
|
||||
wfe
|
||||
b Default_Handler
|
||||
.cfi_endproc
|
||||
.size Default_Handler, .-Default_Handler
|
||||
|
||||
// Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, Default_Handler
|
||||
.endm
|
||||
|
||||
.section .isr_vector, "a", %progbits
|
||||
.global __isr_vector
|
||||
__isr_vector:
|
||||
// Interrupt vector as defined by Cortex-M, starting with the stack top.
|
||||
// On reset, SP is initialized with *0x0 and PC is loaded with *0x4, loading
|
||||
// _stack_top and Reset_Handler.
|
||||
.long _stack_top
|
||||
.long Reset_Handler
|
||||
.long NMI_Handler
|
||||
.long HardFault_Handler
|
||||
.long MemoryManagement_Handler
|
||||
.long BusFault_Handler
|
||||
.long UsageFault_Handler
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long SVC_Handler
|
||||
.long DebugMon_Handler
|
||||
.long 0
|
||||
.long PendSV_Handler
|
||||
.long SysTick_Handler
|
||||
|
||||
// Define default implementations for interrupts, redirecting to
|
||||
// Default_Handler when not implemented.
|
||||
IRQ NMI_Handler
|
||||
IRQ HardFault_Handler
|
||||
IRQ MemoryManagement_Handler
|
||||
IRQ BusFault_Handler
|
||||
IRQ UsageFault_Handler
|
||||
IRQ SVC_Handler
|
||||
IRQ DebugMon_Handler
|
||||
IRQ PendSV_Handler
|
||||
IRQ SysTick_Handler
|
||||
|
||||
.size __isr_vector, .-__isr_vector
|
||||
30
targets/cortex-m.json
Normal file
30
targets/cortex-m.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"build-tags": ["cortexm", "baremetal", "linux", "arm"],
|
||||
"goos": "linux",
|
||||
"goarch": "arm",
|
||||
"gc": "conservative",
|
||||
"scheduler": "tasks",
|
||||
"linker": "ld.lld",
|
||||
"rtlib": "compiler-rt",
|
||||
"libc": "picolibc",
|
||||
"automatic-stack-size": true,
|
||||
"default-stack-size": 2048,
|
||||
"cflags": [
|
||||
"-Werror",
|
||||
"-fshort-enums",
|
||||
"-fomit-frame-pointer",
|
||||
"-mfloat-abi=soft",
|
||||
"-fno-exceptions", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables",
|
||||
"-ffunction-sections", "-fdata-sections"
|
||||
],
|
||||
"ldflags": [
|
||||
"--emit-relocs",
|
||||
"--gc-sections"
|
||||
],
|
||||
"extra-files": [
|
||||
"src/device/arm/cortexm.S",
|
||||
"src/internal/task/task_stack_cortexm.S",
|
||||
"src/runtime/asm_arm.S"
|
||||
],
|
||||
"gdb": ["gdb-multiarch", "arm-none-eabi-gdb", "gdb"]
|
||||
}
|
||||
6
targets/cortex-m0.json
Normal file
6
targets/cortex-m0.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "thumbv6m-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m0",
|
||||
"features": "+armv6-m,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
}
|
||||
6
targets/cortex-m0plus.json
Normal file
6
targets/cortex-m0plus.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "thumbv6m-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m0plus",
|
||||
"features": "+armv6-m,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
}
|
||||
6
targets/cortex-m3.json
Normal file
6
targets/cortex-m3.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "thumbv7m-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m3",
|
||||
"features": "+armv7-m,+hwdiv,+soft-float,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
}
|
||||
6
targets/cortex-m33.json
Normal file
6
targets/cortex-m33.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "thumbv8m.main-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m33",
|
||||
"features": "+armv8-m.main,+dsp,+hwdiv,+soft-float,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
}
|
||||
6
targets/cortex-m4.json
Normal file
6
targets/cortex-m4.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "thumbv7em-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m4",
|
||||
"features": "+armv7e-m,+dsp,+hwdiv,+soft-float,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
}
|
||||
6
targets/cortex-m7.json
Normal file
6
targets/cortex-m7.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "thumbv7em-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m7",
|
||||
"features": "+armv7e-m,+dsp,+hwdiv,+soft-float,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
}
|
||||
3
targets/d1mini.json
Normal file
3
targets/d1mini.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"inherits": ["nodemcu"]
|
||||
}
|
||||
10
targets/digispark.json
Normal file
10
targets/digispark.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["attiny85"],
|
||||
"build-tags": ["digispark"],
|
||||
"ldflags": [
|
||||
"--defsym=_bootloader_size=2180",
|
||||
"--defsym=_stack_size=128"
|
||||
],
|
||||
"flash-command": "micronucleus --run {hex}",
|
||||
"emulator": "simavr -m attiny85 -f 16000000 {}"
|
||||
}
|
||||
12
targets/elecrow-rp2040.json
Normal file
12
targets/elecrow-rp2040.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"inherits": ["rp2040"],
|
||||
"build-tags": ["elecrow_rp2040", "comboat_fw"],
|
||||
"serial-port": ["2e8a:000a"],
|
||||
"default-stack-size": 8192,
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=8M"
|
||||
],
|
||||
"extra-files": [
|
||||
"targets/pico-boot-stage2.S"
|
||||
]
|
||||
}
|
||||
12
targets/elecrow-rp2350.json
Normal file
12
targets/elecrow-rp2350.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"inherits": ["rp2350"],
|
||||
"build-tags": ["elecrow_rp2350", "comboat_fw"],
|
||||
"serial-port": ["2e8a:000f"],
|
||||
"default-stack-size": 8192,
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=8M"
|
||||
],
|
||||
"extra-files": [
|
||||
"targets/pico-boot-stage2.S"
|
||||
]
|
||||
}
|
||||
5
targets/esp-c3-32s-kit.json
Normal file
5
targets/esp-c3-32s-kit.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"inherits": ["esp32c3"],
|
||||
"build-tags": ["esp_c3_32s_kit"],
|
||||
"serial-port": ["1a86:7523"]
|
||||
}
|
||||
4
targets/esp32-c3-devkit-rust-1.json
Normal file
4
targets/esp32-c3-devkit-rust-1.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"inherits": ["esp32c3"],
|
||||
"build-tags": ["esp32_c3_devkit_rust_1"]
|
||||
}
|
||||
4
targets/esp32-coreboard-v2.json
Normal file
4
targets/esp32-coreboard-v2.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"inherits": ["esp32"],
|
||||
"build-tags": ["esp32_coreboard_v2"]
|
||||
}
|
||||
3
targets/esp32-mini32.json
Normal file
3
targets/esp32-mini32.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"inherits": ["esp32-coreboard-v2"]
|
||||
}
|
||||
21
targets/esp32.json
Normal file
21
targets/esp32.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"inherits": ["xtensa"],
|
||||
"cpu": "esp32",
|
||||
"features": "+atomctl,+bool,+clamps,+coprocessor,+debug,+density,+dfpaccel,+div32,+exception,+fp,+highpriinterrupts,+interrupt,+loop,+mac16,+memctl,+minmax,+miscsr,+mul32,+mul32high,+nsa,+prid,+regprotect,+rvector,+s32c1i,+sext,+threadptr,+timerint,+windowed",
|
||||
"build-tags": ["esp32", "esp"],
|
||||
"scheduler": "tasks",
|
||||
"serial": "uart",
|
||||
"linker": "ld.lld",
|
||||
"default-stack-size": 2048,
|
||||
"rtlib": "compiler-rt",
|
||||
"libc": "picolibc",
|
||||
"linkerscript": "targets/esp32.ld",
|
||||
"extra-files": [
|
||||
"src/device/esp/esp32.S",
|
||||
"src/internal/task/task_stack_esp32.S"
|
||||
],
|
||||
"binary-format": "esp32",
|
||||
"flash-command": "esptool.py --chip=esp32 --port {port} write_flash 0x1000 {bin} -ff 80m -fm dout",
|
||||
"emulator": "qemu-system-xtensa -machine esp32 -nographic -drive file={img},if=mtd,format=raw",
|
||||
"gdb": ["xtensa-esp32-elf-gdb"]
|
||||
}
|
||||
202
targets/esp32.ld
Normal file
202
targets/esp32.ld
Normal file
@@ -0,0 +1,202 @@
|
||||
/* Linker script for the ESP32 */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/* Data RAM. Allows byte access.
|
||||
* There are various data RAM regions:
|
||||
* SRAM2: 0x3FFA_E000..0x3FFD_FFFF (72 + 128 = 200K)
|
||||
* SRAM1: 0x3FFE_0000..0x3FFF_FFFF (128K)
|
||||
* This gives us 328K of contiguous RAM, which is the largest span possible.
|
||||
* SRAM1 has other addresses as well but the datasheet seems to indicate
|
||||
* these are aliases.
|
||||
*/
|
||||
DRAM (rw) : ORIGIN = 0x3FFAE000, LENGTH = 200K + 128K /* Internal SRAM 1 + 2 */
|
||||
|
||||
/* Instruction RAM. */
|
||||
IRAM (x) : ORIGIN = 0x40080000, LENGTH = 128K /* Internal SRAM 0 */
|
||||
}
|
||||
|
||||
/* The entry point. It is set in the image flashed to the chip, so must be
|
||||
* defined.
|
||||
*/
|
||||
ENTRY(call_start_cpu0)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Constant literals and code. Loaded into IRAM for now. Eventually, most
|
||||
* code should be executed directly from flash.
|
||||
* Note that literals must be before code for the l32r instruction to work.
|
||||
*/
|
||||
.text : ALIGN(4)
|
||||
{
|
||||
*(.literal.call_start_cpu0)
|
||||
*(.text.call_start_cpu0)
|
||||
*(.literal .text)
|
||||
*(.literal.* .text.*)
|
||||
} >IRAM
|
||||
|
||||
/* Put the stack at the bottom of DRAM, so that the application will
|
||||
* crash on stack overflow instead of silently corrupting memory.
|
||||
* See: http://blog.japaric.io/stack-overflow-protection/ */
|
||||
.stack (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(16);
|
||||
. += _stack_size;
|
||||
_stack_top = .;
|
||||
} >DRAM
|
||||
|
||||
/* Constant global variables.
|
||||
* They are loaded in DRAM for ease of use. Eventually they should be stored
|
||||
* in flash and loaded directly from there but they're kept in RAM to make
|
||||
* sure they can always be accessed (even in interrupts).
|
||||
*/
|
||||
.rodata : ALIGN(4)
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
} >DRAM
|
||||
|
||||
/* Mutable global variables.
|
||||
*/
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_sdata = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
_edata = ABSOLUTE(.);
|
||||
} >DRAM
|
||||
|
||||
/* Check that the boot ROM stack (for the APP CPU) does not overlap with the
|
||||
* data that is loaded by the boot ROM. There may be ways to avoid this
|
||||
* issue if it occurs in practice.
|
||||
* The magic value here is _stack_sentry in the boot ROM ELF file.
|
||||
*/
|
||||
ASSERT(_edata < 0x3ffe1320, "the .data section overlaps with the stack used by the boot ROM, possibly causing corruption at startup")
|
||||
|
||||
/* Global variables that are mutable and zero-initialized.
|
||||
* These must be zeroed at startup (unlike data, which is loaded by the
|
||||
* bootloader).
|
||||
*/
|
||||
.bss (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
. = ALIGN (4);
|
||||
_sbss = ABSOLUTE(.);
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
. = ALIGN (4);
|
||||
_ebss = ABSOLUTE(.);
|
||||
} >DRAM
|
||||
}
|
||||
|
||||
/* For the garbage collector.
|
||||
*/
|
||||
_globals_start = _sdata;
|
||||
_globals_end = _ebss;
|
||||
_heap_start = _ebss;
|
||||
_heap_end = ORIGIN(DRAM) + LENGTH(DRAM);
|
||||
|
||||
_stack_size = 4K;
|
||||
|
||||
/* From ESP-IDF:
|
||||
* components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld
|
||||
* This is the subset that is sometimes used by LLVM during codegen, and thus
|
||||
* must always be present.
|
||||
*/
|
||||
memcpy = 0x4000c2c8;
|
||||
memmove = 0x4000c3c0;
|
||||
memset = 0x4000c44c;
|
||||
|
||||
/* From ESP-IDF:
|
||||
* components/esp_rom/esp32/ld/esp32.rom.libgcc.ld
|
||||
* These are called from LLVM during codegen. The original license is Apache
|
||||
* 2.0, but I believe that a list of function names and addresses can't really
|
||||
* be copyrighted.
|
||||
*/
|
||||
__absvdi2 = 0x4006387c;
|
||||
__absvsi2 = 0x40063868;
|
||||
__adddf3 = 0x40002590;
|
||||
__addsf3 = 0x400020e8;
|
||||
__addvdi3 = 0x40002cbc;
|
||||
__addvsi3 = 0x40002c98;
|
||||
__ashldi3 = 0x4000c818;
|
||||
__ashrdi3 = 0x4000c830;
|
||||
__bswapdi2 = 0x40064b08;
|
||||
__bswapsi2 = 0x40064ae0;
|
||||
__clrsbdi2 = 0x40064b7c;
|
||||
__clrsbsi2 = 0x40064b64;
|
||||
__clzdi2 = 0x4000ca50;
|
||||
__clzsi2 = 0x4000c7e8;
|
||||
__cmpdi2 = 0x40063820;
|
||||
__ctzdi2 = 0x4000ca64;
|
||||
__ctzsi2 = 0x4000c7f0;
|
||||
__divdc3 = 0x400645a4;
|
||||
__divdf3 = 0x40002954;
|
||||
__divdi3 = 0x4000ca84;
|
||||
__divsi3 = 0x4000c7b8;
|
||||
__eqdf2 = 0x400636a8;
|
||||
__eqsf2 = 0x40063374;
|
||||
__extendsfdf2 = 0x40002c34;
|
||||
__ffsdi2 = 0x4000ca2c;
|
||||
__ffssi2 = 0x4000c804;
|
||||
__fixdfdi = 0x40002ac4;
|
||||
__fixdfsi = 0x40002a78;
|
||||
__fixsfdi = 0x4000244c;
|
||||
__fixsfsi = 0x4000240c;
|
||||
__fixunsdfsi = 0x40002b30;
|
||||
__fixunssfdi = 0x40002504;
|
||||
__fixunssfsi = 0x400024ac;
|
||||
__floatdidf = 0x4000c988;
|
||||
__floatdisf = 0x4000c8c0;
|
||||
__floatsidf = 0x4000c944;
|
||||
__floatsisf = 0x4000c870;
|
||||
__floatundidf = 0x4000c978;
|
||||
__floatundisf = 0x4000c8b0;
|
||||
__floatunsidf = 0x4000c938;
|
||||
__floatunsisf = 0x4000c864;
|
||||
__gcc_bcmp = 0x40064a70;
|
||||
__gedf2 = 0x40063768;
|
||||
__gesf2 = 0x4006340c;
|
||||
__gtdf2 = 0x400636dc;
|
||||
__gtsf2 = 0x400633a0;
|
||||
__ledf2 = 0x40063704;
|
||||
__lesf2 = 0x400633c0;
|
||||
__lshrdi3 = 0x4000c84c;
|
||||
__ltdf2 = 0x40063790;
|
||||
__ltsf2 = 0x4006342c;
|
||||
__moddi3 = 0x4000cd4c;
|
||||
__modsi3 = 0x4000c7c0;
|
||||
__muldc3 = 0x40063c90;
|
||||
__muldf3 = 0x4006358c;
|
||||
__muldi3 = 0x4000c9fc;
|
||||
__mulsf3 = 0x400632c8;
|
||||
__mulsi3 = 0x4000c7b0;
|
||||
__mulvdi3 = 0x40002d78;
|
||||
__mulvsi3 = 0x40002d60;
|
||||
__nedf2 = 0x400636a8;
|
||||
__negdf2 = 0x400634a0;
|
||||
__negdi2 = 0x4000ca14;
|
||||
__negsf2 = 0x400020c0;
|
||||
__negvdi2 = 0x40002e98;
|
||||
__negvsi2 = 0x40002e78;
|
||||
__nesf2 = 0x40063374;
|
||||
__nsau_data = 0x3ff96544;
|
||||
__paritysi2 = 0x40002f3c;
|
||||
__popcount_tab = 0x3ff96544;
|
||||
__popcountdi2 = 0x40002ef8;
|
||||
__popcountsi2 = 0x40002ed0;
|
||||
__powidf2 = 0x400638e4;
|
||||
__subdf3 = 0x400026e4;
|
||||
__subsf3 = 0x400021d0;
|
||||
__subvdi3 = 0x40002d20;
|
||||
__subvsi3 = 0x40002cf8;
|
||||
__truncdfsf2 = 0x40002b90;
|
||||
__ucmpdi2 = 0x40063840;
|
||||
__udiv_w_sdiv = 0x40064bec;
|
||||
__udivdi3 = 0x4000cff8;
|
||||
__udivmoddi4 = 0x40064bf4;
|
||||
__udivsi3 = 0x4000c7c8;
|
||||
__umoddi3 = 0x4000d280;
|
||||
__umodsi3 = 0x4000c7d0;
|
||||
__umulsidi3 = 0x4000c7d8;
|
||||
__unorddf2 = 0x400637f4;
|
||||
__unordsf2 = 0x40063478;
|
||||
5
targets/esp32c3-12f.json
Normal file
5
targets/esp32c3-12f.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"inherits": ["esp32c3"],
|
||||
"build-tags": ["esp32c312f"]
|
||||
}
|
||||
|
||||
4
targets/esp32c3-supermini.json
Normal file
4
targets/esp32c3-supermini.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"inherits": ["esp32c3"],
|
||||
"build-tags": ["esp32c3_supermini"]
|
||||
}
|
||||
23
targets/esp32c3.json
Normal file
23
targets/esp32c3.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"inherits": ["riscv32"],
|
||||
"features": "+32bit,+c,+m,+zmmul,-a,-b,-d,-e,-experimental-smmpm,-experimental-smnpm,-experimental-ssnpm,-experimental-sspm,-experimental-ssqosid,-experimental-supm,-experimental-zacas,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-f,-h,-relax,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smepmp,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
||||
"build-tags": ["esp32c3", "esp"],
|
||||
"serial": "usb",
|
||||
"rtlib": "compiler-rt",
|
||||
"libc": "picolibc",
|
||||
"cflags": [
|
||||
"-march=rv32imc"
|
||||
],
|
||||
"linkerscript": "targets/esp32c3.ld",
|
||||
"extra-files": [
|
||||
"src/device/esp/esp32c3.S"
|
||||
],
|
||||
"binary-format": "esp32c3",
|
||||
"flash-command": "esptool.py --chip=esp32c3 --port {port} write_flash 0x0 {bin}",
|
||||
"serial-port": ["303a:1001"],
|
||||
"openocd-interface": "esp_usb_jtag",
|
||||
"openocd-target": "esp32c3",
|
||||
"openocd-commands": ["gdb_memory_map disable"],
|
||||
"gdb": ["riscv32-esp-elf-gdb"]
|
||||
}
|
||||
|
||||
2238
targets/esp32c3.ld
Normal file
2238
targets/esp32c3.ld
Normal file
File diff suppressed because it is too large
Load Diff
18
targets/esp8266.json
Normal file
18
targets/esp8266.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"inherits": ["xtensa"],
|
||||
"cpu": "esp8266",
|
||||
"features": "+debug,+density,+exception,+extendedl32r,+highpriinterrupts,+interrupt,+mul32,+nsa,+prid,+regprotect,+rvector,+timerint",
|
||||
"build-tags": ["esp8266", "esp"],
|
||||
"scheduler": "tasks",
|
||||
"linker": "ld.lld",
|
||||
"default-stack-size": 2048,
|
||||
"rtlib": "compiler-rt",
|
||||
"libc": "picolibc",
|
||||
"linkerscript": "targets/esp8266.ld",
|
||||
"extra-files": [
|
||||
"src/device/esp/esp8266.S",
|
||||
"src/internal/task/task_stack_esp8266.S"
|
||||
],
|
||||
"binary-format": "esp8266",
|
||||
"flash-command": "esptool.py --chip=esp8266 --port {port} write_flash 0x00000 {bin} -fm qio"
|
||||
}
|
||||
109
targets/esp8266.ld
Normal file
109
targets/esp8266.ld
Normal file
@@ -0,0 +1,109 @@
|
||||
/* Linker script for the ESP8266 */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/* Data RAM. Allows byte access. */
|
||||
DRAM (rw) : ORIGIN = 0x3FFE8000, LENGTH = 80K
|
||||
/* Instruction RAM. */
|
||||
IRAM (x) : ORIGIN = 0x40100000, LENGTH = 32K
|
||||
}
|
||||
|
||||
/* The entry point. It is set in the image flashed to the chip, so must be
|
||||
* defined.
|
||||
*/
|
||||
ENTRY(main)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Mutable global variables.
|
||||
*/
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_sdata = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
} >DRAM
|
||||
|
||||
/* Constant global variables.
|
||||
* Note that they still need to be loaded in RAM because the ESP8266 doesn't
|
||||
* allow byte access to flash.
|
||||
*/
|
||||
.rodata : ALIGN(4)
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
} >DRAM
|
||||
|
||||
/* Global variables that are mutable and zero-initialized.
|
||||
*/
|
||||
.bss (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
. = ALIGN (4);
|
||||
_sbss = ABSOLUTE(.);
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
. = ALIGN (4);
|
||||
_ebss = ABSOLUTE(.);
|
||||
} >DRAM
|
||||
|
||||
/* Constant literals and code. Loaded into IRAM for now. Eventually, most
|
||||
* code should be executed directly from flash.
|
||||
* Note that literals must be before code for the l32r instruction to work.
|
||||
*/
|
||||
.text : ALIGN(4)
|
||||
{
|
||||
*(.literal .text)
|
||||
*(.literal.* .text.*)
|
||||
} >IRAM
|
||||
}
|
||||
|
||||
_globals_start = _sdata;
|
||||
_globals_end = _ebss;
|
||||
_heap_start = _ebss;
|
||||
_heap_end = ORIGIN(DRAM) + LENGTH(DRAM);
|
||||
|
||||
/* It appears that the stack is set to 0x3ffffff0 when main is called.
|
||||
* Be conservative and scan all the way up to the end of the RAM.
|
||||
*/
|
||||
_stack_top = 0x40000000;
|
||||
|
||||
/* Functions normally provided by a libc.
|
||||
* Source:
|
||||
* https://github.com/espressif/ESP8266_NONOS_SDK/blob/master/ld/eagle.rom.addr.v6.ld
|
||||
*/
|
||||
memcpy = 0x4000df48;
|
||||
memmove = 0x4000e04c;
|
||||
memset = 0x4000e190;
|
||||
|
||||
/* Compiler runtime functions provided by the ROM.
|
||||
* Source:
|
||||
* https://github.com/espressif/ESP8266_NONOS_SDK/blob/master/ld/eagle.rom.addr.v6.ld
|
||||
*/
|
||||
__adddf3 = 0x4000c538;
|
||||
__addsf3 = 0x4000c180;
|
||||
__divdf3 = 0x4000cb94;
|
||||
__divdi3 = 0x4000ce60;
|
||||
__divsi3 = 0x4000dc88;
|
||||
__extendsfdf2 = 0x4000cdfc;
|
||||
__fixdfsi = 0x4000ccb8;
|
||||
__fixunsdfsi = 0x4000cd00;
|
||||
__fixunssfsi = 0x4000c4c4;
|
||||
__floatsidf = 0x4000e2f0;
|
||||
__floatsisf = 0x4000e2ac;
|
||||
__floatunsidf = 0x4000e2e8;
|
||||
__floatunsisf = 0x4000e2a4;
|
||||
__muldf3 = 0x4000c8f0;
|
||||
__muldi3 = 0x40000650;
|
||||
__mulsf3 = 0x4000c3dc;
|
||||
__subdf3 = 0x4000c688;
|
||||
__subsf3 = 0x4000c268;
|
||||
__truncdfsf2 = 0x4000cd5c;
|
||||
__udivdi3 = 0x4000d310;
|
||||
__udivsi3 = 0x4000e21c;
|
||||
__umoddi3 = 0x4000d770;
|
||||
__umodsi3 = 0x4000e268;
|
||||
__umulsidi3 = 0x4000dcf0;
|
||||
|
||||
/* Proprietary ROM function needed for proper clock configuration.
|
||||
*/
|
||||
rom_i2c_writeReg = 0x400072d8;
|
||||
6
targets/fe310.json
Normal file
6
targets/fe310.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inherits": ["riscv32"],
|
||||
"cpu": "sifive-e31",
|
||||
"features": "+32bit,+a,+c,+m,+zmmul,-b,-d,-e,-experimental-smmpm,-experimental-smnpm,-experimental-ssnpm,-experimental-sspm,-experimental-ssqosid,-experimental-supm,-experimental-zacas,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-f,-h,-relax,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smepmp,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
||||
"build-tags": ["fe310", "sifive"]
|
||||
}
|
||||
10
targets/feather-m0-express.json
Normal file
10
targets/feather-m0-express.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["atsamd21g18a"],
|
||||
"build-tags": ["feather_m0_express"],
|
||||
"serial": "usb",
|
||||
"serial-port": ["239a:801b"],
|
||||
"flash-1200-bps-reset": "true",
|
||||
"flash-method": "msd",
|
||||
"msd-volume-name": ["FEATHERBOOT"],
|
||||
"msd-firmware-name": "firmware.uf2"
|
||||
}
|
||||
10
targets/feather-m0.json
Normal file
10
targets/feather-m0.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["atsamd21g18a"],
|
||||
"build-tags": ["feather_m0"],
|
||||
"serial": "usb",
|
||||
"serial-port": ["239a:801b", "239a:800b"],
|
||||
"flash-1200-bps-reset": "true",
|
||||
"flash-method": "msd",
|
||||
"msd-volume-name": ["FEATHERBOOT"],
|
||||
"msd-firmware-name": "firmware.uf2"
|
||||
}
|
||||
10
targets/feather-m4-can.json
Normal file
10
targets/feather-m4-can.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["atsame51j19a"],
|
||||
"build-tags": ["feather_m4_can"],
|
||||
"serial": "usb",
|
||||
"serial-port": ["239a:80cd"],
|
||||
"flash-1200-bps-reset": "true",
|
||||
"flash-method": "msd",
|
||||
"msd-volume-name": ["FTHRCANBOOT"],
|
||||
"msd-firmware-name": "firmware.uf2"
|
||||
}
|
||||
10
targets/feather-m4.json
Normal file
10
targets/feather-m4.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"inherits": ["atsamd51j19a"],
|
||||
"build-tags": ["feather_m4"],
|
||||
"serial": "usb",
|
||||
"serial-port": ["239a:8022"],
|
||||
"flash-1200-bps-reset": "true",
|
||||
"flash-method": "msd",
|
||||
"msd-volume-name": ["FEATHERBOOT"],
|
||||
"msd-firmware-name": "firmware.uf2"
|
||||
}
|
||||
6
targets/feather-nrf52840-sense.json
Normal file
6
targets/feather-nrf52840-sense.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"inherits": ["nrf52840", "nrf52840-s140v6-uf2"],
|
||||
"build-tags": ["feather_nrf52840_sense"],
|
||||
"serial-port": ["239a:8087", "239a:8088"],
|
||||
"msd-volume-name": ["FTHRSNSBOOT"]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user