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:
xushiwei
2025-08-02 06:09:52 +08:00
committed by GitHub
287 changed files with 8817 additions and 26 deletions

180
.github/workflows/targets.yml vendored Normal file
View 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
View File

@@ -0,0 +1,4 @@
package main
func main() {
}

View File

@@ -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()

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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])
}
}
})
}
}

View 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
}

View 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
View 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
}

View 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
}

View 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
View 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.

View File

@@ -0,0 +1,4 @@
{
"inherits": ["esp32"],
"build-tags": ["adafruit_esp32_feather_v2"]
}

14
targets/ae-rp2040.json Normal file
View 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"
]
}

View 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 {}"
}

View 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"
}

View 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"
}

View 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"
}

View 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"
}

View 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
View 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 {}"
}

View 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"
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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"
}

View 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
View 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
View 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"

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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"
]
}

View File

@@ -0,0 +1,6 @@
{
"inherits": ["nrf52840", "nrf52840-s140v6-uf2"],
"build-tags": ["bluemicro840"],
"serial-port": ["1d50:6161"],
"msd-volume-name": ["BLUEMICRO"]
}

View File

@@ -0,0 +1,4 @@
{
"inherits": ["bluepill"],
"openocd-commands": ["set CPUTAPID 0x2ba01477"]
}

12
targets/bluepill.json Normal file
View 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
View 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"
]
}

View 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"
]
}

View File

@@ -0,0 +1,6 @@
{
"inherits": ["nrf52840", "nrf52840-s140v6-uf2"],
"build-tags": ["circuitplay_bluefruit"],
"serial-port": ["239a:8045"],
"msd-volume-name": ["CPLAYBTBOOT"]
}

View 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
View 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
View File

@@ -0,0 +1,3 @@
{
"inherits": ["clue-alpha"]
}

View 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
View 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
View 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
View 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"
}

View 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
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1,3 @@
{
"inherits": ["nodemcu"]
}

10
targets/digispark.json Normal file
View 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 {}"
}

View 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"
]
}

View 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"
]
}

View File

@@ -0,0 +1,5 @@
{
"inherits": ["esp32c3"],
"build-tags": ["esp_c3_32s_kit"],
"serial-port": ["1a86:7523"]
}

View File

@@ -0,0 +1,4 @@
{
"inherits": ["esp32c3"],
"build-tags": ["esp32_c3_devkit_rust_1"]
}

View File

@@ -0,0 +1,4 @@
{
"inherits": ["esp32"],
"build-tags": ["esp32_coreboard_v2"]
}

View File

@@ -0,0 +1,3 @@
{
"inherits": ["esp32-coreboard-v2"]
}

21
targets/esp32.json Normal file
View 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
View 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
View File

@@ -0,0 +1,5 @@
{
"inherits": ["esp32c3"],
"build-tags": ["esp32c312f"]
}

View File

@@ -0,0 +1,4 @@
{
"inherits": ["esp32c3"],
"build-tags": ["esp32c3_supermini"]
}

23
targets/esp32c3.json Normal file
View 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

File diff suppressed because it is too large Load Diff

18
targets/esp8266.json Normal file
View 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
View 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
View 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"]
}

View 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
View 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"
}

View 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
View 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"
}

View 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