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
|
// llgo build
|
||||||
var Cmd = &base.Command{
|
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",
|
Short: "Compile packages and dependencies",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,6 +50,7 @@ func runCmd(cmd *base.Command, args []string) {
|
|||||||
conf.Tags = flags.Tags
|
conf.Tags = flags.Tags
|
||||||
conf.Verbose = flags.Verbose
|
conf.Verbose = flags.Verbose
|
||||||
conf.OutFile = flags.OutputFile
|
conf.OutFile = flags.OutputFile
|
||||||
|
conf.Target = flags.Target
|
||||||
|
|
||||||
args = cmd.Flag.Args()
|
args = cmd.Flag.Args()
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ func AddOutputFlags(fs *flag.FlagSet) {
|
|||||||
var Verbose bool
|
var Verbose bool
|
||||||
var BuildEnv string
|
var BuildEnv string
|
||||||
var Tags string
|
var Tags string
|
||||||
|
var Target string
|
||||||
|
|
||||||
func AddBuildFlags(fs *flag.FlagSet) {
|
func AddBuildFlags(fs *flag.FlagSet) {
|
||||||
fs.BoolVar(&Verbose, "v", false, "Verbose mode")
|
fs.BoolVar(&Verbose, "v", false, "Verbose mode")
|
||||||
fs.StringVar(&Tags, "tags", "", "Build tags")
|
fs.StringVar(&Tags, "tags", "", "Build tags")
|
||||||
fs.StringVar(&BuildEnv, "buildenv", "", "Build environment")
|
fs.StringVar(&BuildEnv, "buildenv", "", "Build environment")
|
||||||
|
fs.StringVar(&Target, "target", "", "Target platform (e.g., rp2040, wasi)")
|
||||||
}
|
}
|
||||||
|
|
||||||
var Gen bool
|
var Gen bool
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ var (
|
|||||||
|
|
||||||
// llgo run
|
// llgo run
|
||||||
var Cmd = &base.Command{
|
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",
|
Short: "Compile and run Go program",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,11 +54,11 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runCmd(cmd *base.Command, args []string) {
|
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) {
|
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) {
|
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.Tags = flags.Tags
|
||||||
conf.Verbose = flags.Verbose
|
conf.Verbose = flags.Verbose
|
||||||
conf.GenExpect = flags.Gen
|
conf.GenExpect = flags.Gen
|
||||||
|
conf.Target = flags.Target
|
||||||
|
|
||||||
args = cmd.Flag.Args()
|
args = cmd.Flag.Args()
|
||||||
args, runArgs, err := parseRunArgs(args)
|
args, runArgs, err := parseRunArgs(args)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
// llgo test
|
// llgo test
|
||||||
var Cmd = &base.Command{
|
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",
|
Short: "Compile and run Go test",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@ func runCmd(cmd *base.Command, args []string) {
|
|||||||
conf := build.NewDefaultConf(build.ModeTest)
|
conf := build.NewDefaultConf(build.ModeTest)
|
||||||
conf.Tags = flags.Tags
|
conf.Tags = flags.Tags
|
||||||
conf.Verbose = flags.Verbose
|
conf.Verbose = flags.Verbose
|
||||||
|
conf.Target = flags.Target
|
||||||
|
|
||||||
args = cmd.Flag.Args()
|
args = cmd.Flag.Args()
|
||||||
_, err := build.Do(args, conf)
|
_, err := build.Do(args, conf)
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ const (
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Goos string
|
Goos string
|
||||||
Goarch string
|
Goarch string
|
||||||
|
Target string // target name (e.g., "rp2040", "wasi") - takes precedence over Goos/Goarch
|
||||||
BinPath string
|
BinPath string
|
||||||
AppExt string // ".exe" on Windows, empty on Unix
|
AppExt string // ".exe" on Windows, empty on Unix
|
||||||
OutFile string // only valid for ModeBuild when len(pkgs) == 1
|
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 == "" {
|
if conf.Goarch == "" {
|
||||||
conf.Goarch = runtime.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
|
verbose := conf.Verbose
|
||||||
patterns := args
|
patterns := args
|
||||||
tags := "llgo"
|
tags := "llgo"
|
||||||
@@ -160,6 +175,7 @@ func Do(args []string, conf *Config) ([]Package, error) {
|
|||||||
BuildFlags: []string{"-tags=" + tags},
|
BuildFlags: []string{"-tags=" + tags},
|
||||||
Fset: token.NewFileSet(),
|
Fset: token.NewFileSet(),
|
||||||
Tests: conf.Mode == ModeTest,
|
Tests: conf.Mode == ModeTest,
|
||||||
|
Env: append(slices.Clone(os.Environ()), "GOOS="+conf.Goos, "GOARCH="+conf.Goarch),
|
||||||
}
|
}
|
||||||
if conf.Mode == ModeTest {
|
if conf.Mode == ModeTest {
|
||||||
cfg.Mode |= packages.NeedForTest
|
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
|
os.Setenv("PATH", env.BinDir()+":"+os.Getenv("PATH")) // TODO(xsw): check windows
|
||||||
|
|
||||||
output := conf.OutFile != ""
|
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,
|
ctx := &context{env: env, conf: cfg, progSSA: progSSA, prog: prog, dedup: dedup,
|
||||||
patches: patches, built: make(map[string]none), initial: initial, mode: mode,
|
patches: patches, built: make(map[string]none), initial: initial, mode: mode,
|
||||||
output: output,
|
output: output,
|
||||||
@@ -370,6 +384,15 @@ func (c *context) compiler() *clang.Cmd {
|
|||||||
return 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) {
|
func buildAllPkgs(ctx *context, initial []*packages.Package, verbose bool) (pkgs []*aPackage, err error) {
|
||||||
pkgs, errPkgs := allPkgs(ctx, initial, verbose)
|
pkgs, errPkgs := allPkgs(ctx, initial, verbose)
|
||||||
for _, errPkg := range errPkgs {
|
for _, errPkg := range errPkgs {
|
||||||
@@ -540,14 +563,14 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, global l
|
|||||||
pkgsMap[v.Package] = v
|
pkgsMap[v.Package] = v
|
||||||
allPkgs = append(allPkgs, v.Package)
|
allPkgs = append(allPkgs, v.Package)
|
||||||
}
|
}
|
||||||
var llFiles []string
|
var objFiles []string
|
||||||
var linkArgs []string
|
var linkArgs []string
|
||||||
packages.Visit(allPkgs, nil, func(p *packages.Package) {
|
packages.Visit(allPkgs, nil, func(p *packages.Package) {
|
||||||
aPkg := pkgsMap[p]
|
aPkg := pkgsMap[p]
|
||||||
if p.ExportFile != "" && aPkg != nil { // skip packages that only contain declarations
|
if p.ExportFile != "" && aPkg != nil { // skip packages that only contain declarations
|
||||||
linkArgs = append(linkArgs, aPkg.LinkArgs...)
|
linkArgs = append(linkArgs, aPkg.LinkArgs...)
|
||||||
llFiles = append(llFiles, aPkg.LLFiles...)
|
objFiles = append(objFiles, aPkg.LLFiles...)
|
||||||
llFiles = append(llFiles, aPkg.ExportFile)
|
objFiles = append(objFiles, aPkg.ExportFile)
|
||||||
need1, need2 := isNeedRuntimeOrPyInit(ctx, p)
|
need1, need2 := isNeedRuntimeOrPyInit(ctx, p)
|
||||||
if !needRuntime {
|
if !needRuntime {
|
||||||
needRuntime = need1
|
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)
|
check(err)
|
||||||
// defer os.Remove(entryLLFile)
|
// defer os.Remove(entryLLFile)
|
||||||
llFiles = append(llFiles, entryLLFile)
|
objFiles = append(objFiles, entryObjFile)
|
||||||
|
|
||||||
if global != nil {
|
if global != nil {
|
||||||
export, err := exportObject(ctx, pkg.PkgPath+".global", pkg.ExportFile+"-global", []byte(global.String()))
|
export, err := exportObject(ctx, pkg.PkgPath+".global", pkg.ExportFile+"-global", []byte(global.String()))
|
||||||
check(err)
|
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)
|
check(err)
|
||||||
|
|
||||||
switch mode {
|
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 := []string{"-o", app}
|
||||||
buildArgs = append(buildArgs, linkArgs...)
|
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, "-gdwarf-4")
|
||||||
}
|
}
|
||||||
|
|
||||||
buildArgs = append(buildArgs, ctx.crossCompile.CCFLAGS...)
|
|
||||||
buildArgs = append(buildArgs, ctx.crossCompile.LDFLAGS...)
|
buildArgs = append(buildArgs, ctx.crossCompile.LDFLAGS...)
|
||||||
buildArgs = append(buildArgs, ctx.crossCompile.EXTRAFLAGS...)
|
buildArgs = append(buildArgs, ctx.crossCompile.EXTRAFLAGS...)
|
||||||
buildArgs = append(buildArgs, llFiles...)
|
buildArgs = append(buildArgs, objFiles...)
|
||||||
if verbose {
|
|
||||||
buildArgs = append(buildArgs, "-v")
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := ctx.compiler()
|
cmd := ctx.linker()
|
||||||
cmd.Verbose = verbose
|
cmd.Verbose = verbose
|
||||||
return cmd.Link(buildArgs...)
|
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)
|
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"
|
mainDefine := "define i32 @main(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr"
|
||||||
if isWasmTarget(ctx.buildConf.Goos) {
|
if isWasmTarget(ctx.buildConf.Goos) {
|
||||||
mainDefine = "define hidden noundef i32 @__main_argc_argv(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr"
|
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'
|
mainCode := fmt.Sprintf(`; ModuleID = 'main'
|
||||||
source_filename = "main"
|
source_filename = "main"
|
||||||
@@ -714,6 +748,8 @@ define weak void @"syscall.init"() {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%s
|
||||||
|
|
||||||
%s {
|
%s {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
store i32 %%0, ptr @__llgo_argc, align 4
|
store i32 %%0, ptr @__llgo_argc, align 4
|
||||||
@@ -728,7 +764,7 @@ _llgo_0:
|
|||||||
}
|
}
|
||||||
`, declSizeT, stdioDecl,
|
`, declSizeT, stdioDecl,
|
||||||
pyInitDecl, rtInitDecl, mainPkgPath, mainPkgPath,
|
pyInitDecl, rtInitDecl, mainPkgPath, mainPkgPath,
|
||||||
mainDefine, stdioNobuf,
|
startDefine, mainDefine, stdioNobuf,
|
||||||
pyInit, rtInit, mainPkgPath, mainPkgPath)
|
pyInit, rtInit, mainPkgPath, mainPkgPath)
|
||||||
|
|
||||||
return exportObject(ctx, pkg.PkgPath+".main", pkg.ExportFile+"-main", []byte(mainCode))
|
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"
|
exportFile += ".o"
|
||||||
args := []string{"-o", exportFile, "-c", f.Name(), "-Wno-override-module"}
|
args := []string{"-o", exportFile, "-c", f.Name(), "-Wno-override-module"}
|
||||||
args = append(args, ctx.crossCompile.CCFLAGS...)
|
args = append(args, ctx.crossCompile.CCFLAGS...)
|
||||||
|
args = append(args, ctx.crossCompile.CFLAGS...)
|
||||||
if ctx.buildConf.Verbose {
|
if ctx.buildConf.Verbose {
|
||||||
fmt.Fprintln(os.Stderr, "clang", args)
|
fmt.Fprintln(os.Stderr, "clang", args)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ package crosscompile
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/goplus/llgo/internal/env"
|
"github.com/goplus/llgo/internal/env"
|
||||||
|
"github.com/goplus/llgo/internal/targets"
|
||||||
"github.com/goplus/llgo/internal/xtool/llvm"
|
"github.com/goplus/llgo/internal/xtool/llvm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,6 +20,15 @@ type Export struct {
|
|||||||
CFLAGS []string
|
CFLAGS []string
|
||||||
LDFLAGS []string
|
LDFLAGS []string
|
||||||
EXTRAFLAGS []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"
|
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,
|
"-I" + includeDir,
|
||||||
}
|
}
|
||||||
// Add WebAssembly linker flags
|
// Add WebAssembly linker flags
|
||||||
export.LDFLAGS = []string{
|
export.LDFLAGS = append(export.LDFLAGS, export.CCFLAGS...)
|
||||||
"-target", targetTriple,
|
export.LDFLAGS = append(export.LDFLAGS, []string{
|
||||||
"-Wno-override-module",
|
"-Wno-override-module",
|
||||||
"-Wl,--error-limit=0",
|
"-Wl,--error-limit=0",
|
||||||
"-L" + libDir,
|
"-L" + libDir,
|
||||||
@@ -134,18 +146,18 @@ func Use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
|||||||
"-lwasi-emulated-signal",
|
"-lwasi-emulated-signal",
|
||||||
"-fwasm-exceptions",
|
"-fwasm-exceptions",
|
||||||
"-mllvm", "-wasm-enable-sjlj",
|
"-mllvm", "-wasm-enable-sjlj",
|
||||||
}
|
}...)
|
||||||
// Add thread support if enabled
|
// Add thread support if enabled
|
||||||
if wasiThreads {
|
if wasiThreads {
|
||||||
export.CCFLAGS = append(
|
export.CCFLAGS = append(
|
||||||
export.CCFLAGS,
|
export.CCFLAGS,
|
||||||
"-pthread",
|
"-pthread",
|
||||||
)
|
)
|
||||||
|
export.LDFLAGS = append(export.LDFLAGS, export.CCFLAGS...)
|
||||||
export.LDFLAGS = append(
|
export.LDFLAGS = append(
|
||||||
export.LDFLAGS,
|
export.LDFLAGS,
|
||||||
"-lwasi-emulated-pthread",
|
"-lwasi-emulated-pthread",
|
||||||
"-lpthread",
|
"-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
|
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 (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"slices"
|
||||||
"testing"
|
"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