Merge pull request #1203 from cpunion/esp-llvm
Build Target Task 2: Multi-Platform LLVM Support and Bootable Code Generation
This commit is contained in:
1
.github/codecov.yml
vendored
1
.github/codecov.yml
vendored
@@ -9,4 +9,5 @@ coverage:
|
||||
- "internal/packages"
|
||||
- "internal/typepatch"
|
||||
- "internal/github"
|
||||
- "internal/firmware"
|
||||
- "xtool"
|
||||
|
||||
144
.github/workflows/targets.yml
vendored
144
.github/workflows/targets.yml
vendored
@@ -36,145 +36,5 @@ jobs:
|
||||
|
||||
- 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
|
||||
cd _demo/targetsbuild
|
||||
bash build.sh
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
}
|
||||
21
_demo/targetsbuild/C/c.go
Normal file
21
_demo/targetsbuild/C/c.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package C
|
||||
|
||||
func XhandleHardFault() {
|
||||
|
||||
}
|
||||
|
||||
func Reset_Handler() {
|
||||
|
||||
}
|
||||
|
||||
func XhandleInterrupt() {
|
||||
|
||||
}
|
||||
|
||||
type dyn64 struct {
|
||||
// Fields for dynamic loader
|
||||
}
|
||||
|
||||
// For nintendo switch
|
||||
func X__dynamic_loader(base uintptr, dyn *dyn64) {
|
||||
}
|
||||
180
_demo/targetsbuild/build.sh
Normal file
180
_demo/targetsbuild/build.sh
Normal file
@@ -0,0 +1,180 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Function to display usage information
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $(basename "$0") [OPTIONS] [TARGET_FILE]
|
||||
|
||||
Build targets for llgo across multiple platforms.
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Show this help message and exit
|
||||
|
||||
ARGUMENTS:
|
||||
TARGET_FILE Optional. A text file containing target names, one per line.
|
||||
Lines starting with # are treated as comments and ignored.
|
||||
Empty lines are also ignored.
|
||||
|
||||
BEHAVIOR:
|
||||
Without TARGET_FILE:
|
||||
- Automatically discovers all targets from ../../targets/*.json files
|
||||
- Extracts target names from JSON filenames
|
||||
|
||||
With TARGET_FILE:
|
||||
- Reads target names from the specified file
|
||||
- Supports comments (lines starting with #)
|
||||
- Ignores empty lines and whitespace
|
||||
|
||||
IGNORED TARGETS:
|
||||
The following targets are automatically ignored and not built:
|
||||
atmega1280, atmega2560, atmega328p, atmega32u4, attiny85,
|
||||
fe310, k210, riscv32, riscv64, rp2040
|
||||
|
||||
RESULT CATEGORIES:
|
||||
✅ Successful: Build completed successfully
|
||||
🔕 Ignored: Target is in the ignore list
|
||||
⚠️ Warned: Build failed with configuration warnings
|
||||
❌ Failed: Build failed with errors
|
||||
|
||||
EXIT CODES:
|
||||
0 All builds successful, ignored, or warned only
|
||||
1 One or more builds failed with errors
|
||||
|
||||
EXAMPLES:
|
||||
$(basename "$0") # Build all targets from JSON files
|
||||
$(basename "$0") my-targets.txt # Build targets from file
|
||||
$(basename "$0") --help # Show this help
|
||||
|
||||
TARGET FILE FORMAT:
|
||||
# This is a comment
|
||||
esp32
|
||||
cortex-m4
|
||||
|
||||
# Another comment
|
||||
riscv64
|
||||
EOF
|
||||
}
|
||||
|
||||
# Check for help flag
|
||||
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
||||
show_usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check for invalid number of arguments
|
||||
if [ $# -gt 1 ]; then
|
||||
echo "Error: Too many arguments."
|
||||
echo "Use '$(basename "$0") --help' for usage information."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Initialize arrays to store results
|
||||
successful_targets=()
|
||||
ignored_targets=()
|
||||
warned_targets=()
|
||||
failed_targets=()
|
||||
targets_to_build=()
|
||||
|
||||
# Define ignore list
|
||||
ignore_list=(
|
||||
"atmega1280"
|
||||
"atmega2560"
|
||||
"atmega328p"
|
||||
"atmega32u4"
|
||||
"attiny85"
|
||||
"fe310"
|
||||
"k210"
|
||||
"riscv32"
|
||||
"riscv64"
|
||||
"rp2040"
|
||||
)
|
||||
|
||||
# Build the targets list based on input method
|
||||
if [ $# -eq 1 ]; then
|
||||
# Read targets from file
|
||||
target_file="$1"
|
||||
if [ ! -f "$target_file" ]; then
|
||||
echo "Error: Target file '$target_file' not found."
|
||||
echo "Use '$(basename "$0") --help' for usage information."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while IFS= read -r target || [[ -n "$target" ]]; do
|
||||
# Skip empty lines and comments
|
||||
if [[ -z "$target" || "$target" =~ ^[[:space:]]*# ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Trim whitespace
|
||||
target=$(echo "$target" | xargs)
|
||||
targets_to_build+=("$target")
|
||||
done < "$target_file"
|
||||
else
|
||||
# Use targets from *.json files
|
||||
for target_file in ../../targets/*.json; do
|
||||
# Extract target name from filename (remove path and .json extension)
|
||||
target=$(basename "$target_file" .json)
|
||||
targets_to_build+=("$target")
|
||||
done
|
||||
fi
|
||||
|
||||
# Process each target
|
||||
for target in "${targets_to_build[@]}"; do
|
||||
# Check if target is in ignore list
|
||||
if [[ " ${ignore_list[@]} " =~ " ${target} " ]]; then
|
||||
echo 🔕 $target "(ignored)"
|
||||
ignored_targets+=("$target")
|
||||
continue
|
||||
fi
|
||||
|
||||
output=$(../../llgo.sh build -target $target -o hello.out . 2>&1)
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ✅ $target `file hello.out`
|
||||
successful_targets+=("$target")
|
||||
else
|
||||
# Check if output contains warning messages
|
||||
if echo "$output" | grep -q "does not have a valid LLVM target triple\|does not have a valid CPU configuration"; then
|
||||
echo ⚠️ $target
|
||||
echo "$output"
|
||||
warned_targets+=("$target")
|
||||
else
|
||||
echo ❌ $target
|
||||
echo "$output"
|
||||
failed_targets+=("$target")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "----------------------------------------"
|
||||
|
||||
# Output successful targets
|
||||
echo "Successful targets (${#successful_targets[@]} total):"
|
||||
for target in "${successful_targets[@]}"; do
|
||||
echo "$target"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Ignored targets (${#ignored_targets[@]} total):"
|
||||
for target in "${ignored_targets[@]}"; do
|
||||
echo "$target"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Warned targets (${#warned_targets[@]} total):"
|
||||
for target in "${warned_targets[@]}"; do
|
||||
echo "$target"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Failed targets (${#failed_targets[@]} total):"
|
||||
for target in "${failed_targets[@]}"; do
|
||||
echo "$target"
|
||||
done
|
||||
|
||||
# Exit with error code if there are any failed targets
|
||||
if [ ${#failed_targets[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
echo "Build failed with ${#failed_targets[@]} failed targets."
|
||||
exit 1
|
||||
fi
|
||||
6
_demo/targetsbuild/empty.go
Normal file
6
_demo/targetsbuild/empty.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package main
|
||||
|
||||
import _ "github.com/goplus/llgo/_demo/targetsbuild/C"
|
||||
|
||||
func main() {
|
||||
}
|
||||
2
go.mod
2
go.mod
@@ -15,6 +15,8 @@ require (
|
||||
golang.org/x/tools v0.36.0
|
||||
)
|
||||
|
||||
require github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1
|
||||
|
||||
require (
|
||||
golang.org/x/mod v0.27.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
|
||||
2
go.sum
2
go.sum
@@ -12,6 +12,8 @@ github.com/goplus/mod v0.17.1 h1:ITovxDcc5zbURV/Wrp3/SBsYLgC1KrxY6pq1zMM2V94=
|
||||
github.com/goplus/mod v0.17.1/go.mod h1:iXEszBKqi38BAyQApBPyQeurLHmQN34YMgC2ZNdap50=
|
||||
github.com/qiniu/x v1.15.1 h1:avE+YQaowp8ZExjylOeSM73rUo3MQKBAYVxh4NJ8dY8=
|
||||
github.com/qiniu/x v1.15.1/go.mod h1:AiovSOCaRijaf3fj+0CBOpR1457pn24b0Vdb1JpwhII=
|
||||
github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1 h1:NVK+OqnavpyFmUiKfUMHrpvbCi2VFoWTrcpI7aDaJ2I=
|
||||
github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
|
||||
@@ -39,13 +39,14 @@ import (
|
||||
|
||||
"github.com/goplus/llgo/cl"
|
||||
"github.com/goplus/llgo/internal/cabi"
|
||||
"github.com/goplus/llgo/internal/clang"
|
||||
"github.com/goplus/llgo/internal/crosscompile"
|
||||
"github.com/goplus/llgo/internal/env"
|
||||
"github.com/goplus/llgo/internal/firmware"
|
||||
"github.com/goplus/llgo/internal/mockable"
|
||||
"github.com/goplus/llgo/internal/packages"
|
||||
"github.com/goplus/llgo/internal/typepatch"
|
||||
"github.com/goplus/llgo/ssa/abi"
|
||||
"github.com/goplus/llgo/xtool/clang"
|
||||
xenv "github.com/goplus/llgo/xtool/env"
|
||||
"github.com/goplus/llgo/xtool/env/llvm"
|
||||
|
||||
@@ -156,7 +157,7 @@ func Do(args []string, conf *Config) ([]Package, error) {
|
||||
conf.Goarch = runtime.GOARCH
|
||||
}
|
||||
// Handle crosscompile configuration first to set correct GOOS/GOARCH
|
||||
export, err := crosscompile.UseWithTarget(conf.Goos, conf.Goarch, IsWasiThreadsEnabled(), conf.Target)
|
||||
export, err := crosscompile.Use(conf.Goos, conf.Goarch, IsWasiThreadsEnabled(), conf.Target)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to setup crosscompile: %w", err)
|
||||
}
|
||||
@@ -389,19 +390,27 @@ type context struct {
|
||||
}
|
||||
|
||||
func (c *context) compiler() *clang.Cmd {
|
||||
cmd := c.env.Clang()
|
||||
if c.crossCompile.CC != "" {
|
||||
cmd = clang.New(c.crossCompile.CC)
|
||||
}
|
||||
config := clang.NewConfig(
|
||||
c.crossCompile.CC,
|
||||
c.crossCompile.CCFLAGS,
|
||||
c.crossCompile.CFLAGS,
|
||||
c.crossCompile.LDFLAGS,
|
||||
c.crossCompile.Linker,
|
||||
)
|
||||
cmd := clang.NewCompiler(config)
|
||||
cmd.Verbose = c.buildConf.Verbose
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *context) linker() *clang.Cmd {
|
||||
cmd := c.env.Clang()
|
||||
if c.crossCompile.Linker != "" {
|
||||
cmd = clang.New(c.crossCompile.Linker)
|
||||
}
|
||||
config := clang.NewConfig(
|
||||
c.crossCompile.CC,
|
||||
c.crossCompile.CCFLAGS,
|
||||
c.crossCompile.CFLAGS,
|
||||
c.crossCompile.LDFLAGS,
|
||||
c.crossCompile.Linker,
|
||||
)
|
||||
cmd := clang.NewLinker(config)
|
||||
cmd.Verbose = c.buildConf.Verbose
|
||||
return cmd
|
||||
}
|
||||
@@ -552,23 +561,145 @@ func createGlobals(ctx *context, prog llssa.Program, pkgs []*aPackage) (llssa.Pa
|
||||
return global, nil
|
||||
}
|
||||
|
||||
func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, global llssa.Package, conf *Config, mode Mode, verbose bool) {
|
||||
pkgPath := pkg.PkgPath
|
||||
name := path.Base(pkgPath)
|
||||
app := conf.OutFile
|
||||
if app == "" {
|
||||
if mode == ModeBuild && len(ctx.initial) > 1 {
|
||||
// compileExtraFiles compiles extra files (.s/.c) from target configuration and returns object files
|
||||
func compileExtraFiles(ctx *context, verbose bool) ([]string, error) {
|
||||
if len(ctx.crossCompile.ExtraFiles) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var objFiles []string
|
||||
llgoRoot := env.LLGoROOT()
|
||||
|
||||
for _, extraFile := range ctx.crossCompile.ExtraFiles {
|
||||
// Resolve the file path relative to llgo root
|
||||
srcFile := filepath.Join(llgoRoot, extraFile)
|
||||
|
||||
// Check if file exists
|
||||
if _, err := os.Stat(srcFile); os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("extra file not found: %s", srcFile)
|
||||
}
|
||||
|
||||
// Generate output file name
|
||||
objFile, err := os.CreateTemp("", "extra-*"+filepath.Base(extraFile))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create temp file for %s: %w", extraFile, err)
|
||||
}
|
||||
objFile.Close()
|
||||
|
||||
var outputFile string
|
||||
ext := filepath.Ext(srcFile)
|
||||
|
||||
if ctx.buildConf.GenLL {
|
||||
outputFile = objFile.Name() + ".ll"
|
||||
} else {
|
||||
outputFile = objFile.Name() + ".o"
|
||||
}
|
||||
|
||||
// Prepare compilation arguments
|
||||
var args []string
|
||||
|
||||
// Handle different file types
|
||||
switch ext {
|
||||
case ".c":
|
||||
args = append(args, "-x", "c")
|
||||
case ".S", ".s":
|
||||
args = append(args, "-x", "assembler-with-cpp")
|
||||
}
|
||||
|
||||
// Add output flags
|
||||
if ctx.buildConf.GenLL {
|
||||
args = append(args, "-emit-llvm", "-S", "-o", outputFile, "-c", srcFile)
|
||||
} else {
|
||||
args = append(args, "-o", outputFile, "-c", srcFile)
|
||||
}
|
||||
|
||||
if verbose {
|
||||
fmt.Fprintf(os.Stderr, "Compiling extra file: clang %s\n", strings.Join(args, " "))
|
||||
}
|
||||
|
||||
// Compile the file
|
||||
cmd := ctx.compiler()
|
||||
if err := cmd.Compile(args...); err != nil {
|
||||
return nil, fmt.Errorf("failed to compile extra file %s: %w", srcFile, err)
|
||||
}
|
||||
|
||||
objFiles = append(objFiles, outputFile)
|
||||
os.Remove(objFile.Name()) // Remove the temp file we created for naming
|
||||
}
|
||||
|
||||
return objFiles, nil
|
||||
}
|
||||
|
||||
// generateOutputFilenames generates the final output filename (app) and intermediate filename (orgApp)
|
||||
// based on configuration and build context.
|
||||
func generateOutputFilenames(outFile, binPath, appExt, binExt, pkgName string, mode Mode, isMultiplePkgs bool) (app, orgApp string, err error) {
|
||||
if outFile == "" {
|
||||
if mode == ModeBuild && isMultiplePkgs {
|
||||
// For multiple packages in ModeBuild mode, use temporary file
|
||||
tmpFile, err := os.CreateTemp("", name+"*"+conf.AppExt)
|
||||
check(err)
|
||||
name := pkgName
|
||||
if binExt != "" {
|
||||
name += "*" + binExt
|
||||
} else {
|
||||
name += "*" + appExt
|
||||
}
|
||||
tmpFile, err := os.CreateTemp("", name)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
app = tmpFile.Name()
|
||||
tmpFile.Close()
|
||||
} else {
|
||||
app = filepath.Join(conf.BinPath, name+conf.AppExt)
|
||||
app = filepath.Join(binPath, pkgName+appExt)
|
||||
}
|
||||
} else if filepath.Ext(app) == "" {
|
||||
app += conf.AppExt
|
||||
orgApp = app
|
||||
} else {
|
||||
// outFile is not empty, use it as base part
|
||||
base := outFile
|
||||
if binExt != "" {
|
||||
// If binExt has value, use temporary file as orgApp for firmware conversion
|
||||
tmpFile, err := os.CreateTemp("", "llgo-*"+appExt)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
orgApp = tmpFile.Name()
|
||||
tmpFile.Close()
|
||||
// Check if base already ends with binExt, if so, don't add it again
|
||||
if strings.HasSuffix(base, binExt) {
|
||||
app = base
|
||||
} else {
|
||||
app = base + binExt
|
||||
}
|
||||
} else {
|
||||
// No binExt, use base + AppExt directly
|
||||
if filepath.Ext(base) == "" {
|
||||
app = base + appExt
|
||||
} else {
|
||||
app = base
|
||||
}
|
||||
orgApp = app
|
||||
}
|
||||
}
|
||||
return app, orgApp, nil
|
||||
}
|
||||
|
||||
func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, global llssa.Package, conf *Config, mode Mode, verbose bool) {
|
||||
pkgPath := pkg.PkgPath
|
||||
name := path.Base(pkgPath)
|
||||
binFmt := ctx.crossCompile.BinaryFormat
|
||||
binExt := firmware.BinaryExt(binFmt)
|
||||
|
||||
// app: converted firmware output file or executable file
|
||||
// orgApp: before converted output file
|
||||
app, orgApp, err := generateOutputFilenames(
|
||||
conf.OutFile,
|
||||
conf.BinPath,
|
||||
conf.AppExt,
|
||||
binExt,
|
||||
name,
|
||||
mode,
|
||||
len(ctx.initial) > 1,
|
||||
)
|
||||
check(err)
|
||||
|
||||
needRuntime := false
|
||||
needPyInit := false
|
||||
@@ -600,6 +731,11 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, global l
|
||||
// defer os.Remove(entryLLFile)
|
||||
objFiles = append(objFiles, entryObjFile)
|
||||
|
||||
// Compile extra files from target configuration
|
||||
extraObjFiles, err := compileExtraFiles(ctx, verbose)
|
||||
check(err)
|
||||
objFiles = append(objFiles, extraObjFiles...)
|
||||
|
||||
if global != nil {
|
||||
export, err := exportObject(ctx, pkg.PkgPath+".global", pkg.ExportFile+"-global", []byte(global.String()))
|
||||
check(err)
|
||||
@@ -619,9 +755,15 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, global l
|
||||
linkArgs = append(linkArgs, exargs...)
|
||||
}
|
||||
|
||||
err = linkObjFiles(ctx, app, objFiles, linkArgs, verbose)
|
||||
err = linkObjFiles(ctx, orgApp, objFiles, linkArgs, verbose)
|
||||
check(err)
|
||||
|
||||
if orgApp != app {
|
||||
fmt.Printf("cross compile: %#v\n", ctx.crossCompile)
|
||||
err = firmware.MakeFirmwareImage(orgApp, app, ctx.crossCompile.BinaryFormat, ctx.crossCompile.FormatDetail)
|
||||
check(err)
|
||||
}
|
||||
|
||||
switch mode {
|
||||
case ModeTest:
|
||||
cmd := exec.Command(app, conf.RunArgs...)
|
||||
@@ -685,8 +827,6 @@ func linkObjFiles(ctx *context, app string, objFiles, linkArgs []string, verbose
|
||||
buildArgs = append(buildArgs, "-gdwarf-4")
|
||||
}
|
||||
|
||||
buildArgs = append(buildArgs, ctx.crossCompile.LDFLAGS...)
|
||||
buildArgs = append(buildArgs, ctx.crossCompile.EXTRAFLAGS...)
|
||||
buildArgs = append(buildArgs, objFiles...)
|
||||
|
||||
cmd := ctx.linker()
|
||||
@@ -698,6 +838,18 @@ func isWasmTarget(goos string) bool {
|
||||
return slices.Contains([]string{"wasi", "js", "wasip1"}, goos)
|
||||
}
|
||||
|
||||
func needStart(conf *Config) bool {
|
||||
if conf.Target == "" {
|
||||
return !isWasmTarget(conf.Goos)
|
||||
}
|
||||
switch conf.Target {
|
||||
case "wasip2":
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func genMainModuleFile(ctx *context, rtPkgPath string, pkg *packages.Package, needRuntime, needPyInit bool) (path string, err error) {
|
||||
var (
|
||||
pyInitDecl string
|
||||
@@ -751,8 +903,10 @@ define weak void @_start() {
|
||||
}
|
||||
`
|
||||
mainDefine := "define i32 @main(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr"
|
||||
if isWasmTarget(ctx.buildConf.Goos) {
|
||||
if !needStart(ctx.buildConf) && isWasmTarget(ctx.buildConf.Goos) {
|
||||
mainDefine = "define hidden noundef i32 @__main_argc_argv(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr"
|
||||
}
|
||||
if !needStart(ctx.buildConf) {
|
||||
startDefine = ""
|
||||
}
|
||||
mainCode := fmt.Sprintf(`; ModuleID = 'main'
|
||||
@@ -883,8 +1037,6 @@ func exportObject(ctx *context, pkgPath string, exportFile string, data []byte)
|
||||
}
|
||||
exportFile += ".o"
|
||||
args := []string{"-o", exportFile, "-c", f.Name(), "-Wno-override-module"}
|
||||
args = append(args, ctx.crossCompile.CCFLAGS...)
|
||||
args = append(args, ctx.crossCompile.CFLAGS...)
|
||||
if ctx.buildConf.Verbose {
|
||||
fmt.Fprintln(os.Stderr, "clang", args)
|
||||
}
|
||||
@@ -1126,8 +1278,6 @@ func clFile(ctx *context, args []string, cFile, expFile string, procFile func(li
|
||||
llFile += ".o"
|
||||
args = append(args, "-o", llFile, "-c", cFile)
|
||||
}
|
||||
args = append(args, ctx.crossCompile.CCFLAGS...)
|
||||
args = append(args, ctx.crossCompile.CFLAGS...)
|
||||
if verbose {
|
||||
fmt.Fprintln(os.Stderr, "clang", args)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/goplus/llgo/internal/mockable"
|
||||
@@ -93,3 +94,173 @@ func TestExtest(t *testing.T) {
|
||||
func TestCmpTest(t *testing.T) {
|
||||
mockRun([]string{"../../cl/_testgo/runtest"}, &Config{Mode: ModeCmpTest})
|
||||
}
|
||||
|
||||
func TestGenerateOutputFilenames(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
outFile string
|
||||
binPath string
|
||||
appExt string
|
||||
binExt string
|
||||
pkgName string
|
||||
mode Mode
|
||||
isMultiplePkgs bool
|
||||
wantAppSuffix string
|
||||
wantOrgAppDiff bool // true if orgApp should be different from app
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "empty outFile, single package",
|
||||
outFile: "",
|
||||
binPath: "/usr/local/bin",
|
||||
appExt: "",
|
||||
binExt: "",
|
||||
pkgName: "hello",
|
||||
mode: ModeBuild,
|
||||
isMultiplePkgs: false,
|
||||
wantAppSuffix: "/usr/local/bin/hello",
|
||||
wantOrgAppDiff: false,
|
||||
},
|
||||
{
|
||||
name: "empty outFile with appExt",
|
||||
outFile: "",
|
||||
binPath: "/usr/local/bin",
|
||||
appExt: ".exe",
|
||||
binExt: "",
|
||||
pkgName: "hello",
|
||||
mode: ModeBuild,
|
||||
isMultiplePkgs: false,
|
||||
wantAppSuffix: "/usr/local/bin/hello.exe",
|
||||
wantOrgAppDiff: false,
|
||||
},
|
||||
{
|
||||
name: "outFile without binExt",
|
||||
outFile: "myapp",
|
||||
binPath: "/usr/local/bin",
|
||||
appExt: ".exe",
|
||||
binExt: "",
|
||||
pkgName: "hello",
|
||||
mode: ModeBuild,
|
||||
isMultiplePkgs: false,
|
||||
wantAppSuffix: "myapp.exe",
|
||||
wantOrgAppDiff: false,
|
||||
},
|
||||
{
|
||||
name: "outFile with existing extension, no binExt",
|
||||
outFile: "myapp.exe",
|
||||
binPath: "/usr/local/bin",
|
||||
appExt: ".exe",
|
||||
binExt: "",
|
||||
pkgName: "hello",
|
||||
mode: ModeBuild,
|
||||
isMultiplePkgs: false,
|
||||
wantAppSuffix: "myapp.exe",
|
||||
wantOrgAppDiff: false,
|
||||
},
|
||||
{
|
||||
name: "outFile with binExt, different from existing extension",
|
||||
outFile: "myapp",
|
||||
binPath: "/usr/local/bin",
|
||||
appExt: ".exe",
|
||||
binExt: ".bin",
|
||||
pkgName: "hello",
|
||||
mode: ModeBuild,
|
||||
isMultiplePkgs: false,
|
||||
wantAppSuffix: "myapp.bin",
|
||||
wantOrgAppDiff: true,
|
||||
},
|
||||
{
|
||||
name: "outFile already ends with binExt",
|
||||
outFile: "t.bin",
|
||||
binPath: "/usr/local/bin",
|
||||
appExt: ".exe",
|
||||
binExt: ".bin",
|
||||
pkgName: "hello",
|
||||
mode: ModeBuild,
|
||||
isMultiplePkgs: false,
|
||||
wantAppSuffix: "t.bin",
|
||||
wantOrgAppDiff: true,
|
||||
},
|
||||
{
|
||||
name: "outFile with full path already ends with binExt",
|
||||
outFile: "/path/to/t.bin",
|
||||
binPath: "/usr/local/bin",
|
||||
appExt: ".exe",
|
||||
binExt: ".bin",
|
||||
pkgName: "hello",
|
||||
mode: ModeBuild,
|
||||
isMultiplePkgs: false,
|
||||
wantAppSuffix: "/path/to/t.bin",
|
||||
wantOrgAppDiff: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
app, orgApp, err := generateOutputFilenames(
|
||||
tt.outFile,
|
||||
tt.binPath,
|
||||
tt.appExt,
|
||||
tt.binExt,
|
||||
tt.pkgName,
|
||||
tt.mode,
|
||||
tt.isMultiplePkgs,
|
||||
)
|
||||
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("generateOutputFilenames() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
if tt.wantAppSuffix != "" {
|
||||
if app != tt.wantAppSuffix {
|
||||
t.Errorf("generateOutputFilenames() app = %v, want %v", app, tt.wantAppSuffix)
|
||||
}
|
||||
}
|
||||
|
||||
if tt.wantOrgAppDiff {
|
||||
if app == orgApp {
|
||||
t.Errorf("generateOutputFilenames() orgApp should be different from app, but both are %v", app)
|
||||
}
|
||||
// Clean up temp file
|
||||
if orgApp != "" && strings.Contains(orgApp, "llgo-") {
|
||||
os.Remove(orgApp)
|
||||
}
|
||||
} else {
|
||||
if app != orgApp {
|
||||
t.Errorf("generateOutputFilenames() orgApp = %v, want %v (same as app)", orgApp, app)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateOutputFilenames_EdgeCases(t *testing.T) {
|
||||
// Test case where outFile has same extension as binExt
|
||||
app, orgApp, err := generateOutputFilenames(
|
||||
"firmware.bin",
|
||||
"/usr/local/bin",
|
||||
".exe",
|
||||
".bin",
|
||||
"esp32app",
|
||||
ModeBuild,
|
||||
false,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if app != "firmware.bin" {
|
||||
t.Errorf("Expected app to be 'firmware.bin', got '%s'", app)
|
||||
}
|
||||
|
||||
if app == orgApp {
|
||||
t.Errorf("Expected orgApp to be different from app when binExt is present, but both are '%s'", app)
|
||||
}
|
||||
|
||||
// Clean up temp file
|
||||
if orgApp != "" && strings.Contains(orgApp, "llgo-") {
|
||||
os.Remove(orgApp)
|
||||
}
|
||||
}
|
||||
|
||||
202
internal/clang/clang.go
Normal file
202
internal/clang/clang.go
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package clang
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/goplus/llgo/xtool/safesplit"
|
||||
)
|
||||
|
||||
// Config represents clang configuration parameters.
|
||||
type Config struct {
|
||||
CC string // Compiler to use (e.g., "clang", "clang++")
|
||||
CCFLAGS []string // Compiler flags for C/C++ compilation
|
||||
CFLAGS []string // C-specific flags
|
||||
LDFLAGS []string // Linker flags
|
||||
Linker string // Linker to use (e.g., "ld.lld", "avr-ld")
|
||||
}
|
||||
|
||||
// NewConfig creates a new Config with the specified parameters.
|
||||
func NewConfig(cc string, ccflags, cflags, ldflags []string, linker string) Config {
|
||||
return Config{
|
||||
CC: cc,
|
||||
CCFLAGS: ccflags,
|
||||
CFLAGS: cflags,
|
||||
LDFLAGS: ldflags,
|
||||
Linker: linker,
|
||||
}
|
||||
}
|
||||
|
||||
// Cmd represents a clang command with environment and configuration support.
|
||||
type Cmd struct {
|
||||
app string
|
||||
config Config
|
||||
Env []string
|
||||
Verbose bool
|
||||
Stdin io.Reader
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
}
|
||||
|
||||
// New creates a new clang command with configuration.
|
||||
func New(app string, config Config) *Cmd {
|
||||
if app == "" {
|
||||
app = "clang"
|
||||
}
|
||||
return &Cmd{
|
||||
app: app,
|
||||
config: config,
|
||||
Env: nil,
|
||||
Verbose: false,
|
||||
Stdin: nil,
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
}
|
||||
}
|
||||
|
||||
// NewCompiler creates a compiler command with proper flag merging.
|
||||
func NewCompiler(config Config) *Cmd {
|
||||
app := "clang"
|
||||
if config.CC != "" {
|
||||
app = config.CC
|
||||
}
|
||||
return New(app, config)
|
||||
}
|
||||
|
||||
// NewLinker creates a linker command with proper flag merging.
|
||||
func NewLinker(config Config) *Cmd {
|
||||
app := "clang"
|
||||
if config.Linker != "" {
|
||||
app = config.Linker
|
||||
} else if config.CC != "" {
|
||||
app = config.CC
|
||||
}
|
||||
return New(app, config)
|
||||
}
|
||||
|
||||
// Compile executes a compilation command with merged flags.
|
||||
func (c *Cmd) Compile(args ...string) error {
|
||||
flags := c.mergeCompilerFlags()
|
||||
allArgs := make([]string, 0, len(flags)+len(args))
|
||||
allArgs = append(allArgs, flags...)
|
||||
allArgs = append(allArgs, args...)
|
||||
return c.exec(allArgs...)
|
||||
}
|
||||
|
||||
// Link executes a linking command with merged flags.
|
||||
func (c *Cmd) Link(args ...string) error {
|
||||
flags := c.mergeLinkerFlags()
|
||||
allArgs := make([]string, 0, len(flags)+len(args))
|
||||
allArgs = append(allArgs, flags...)
|
||||
allArgs = append(allArgs, args...)
|
||||
return c.exec(allArgs...)
|
||||
}
|
||||
|
||||
// mergeCompilerFlags merges environment CCFLAGS/CFLAGS with config flags.
|
||||
func (c *Cmd) mergeCompilerFlags() []string {
|
||||
var flags []string
|
||||
|
||||
// Add environment CCFLAGS
|
||||
if envCCFlags := os.Getenv("CCFLAGS"); envCCFlags != "" {
|
||||
flags = append(flags, safesplit.SplitPkgConfigFlags(envCCFlags)...)
|
||||
}
|
||||
|
||||
// Add environment CFLAGS
|
||||
if envCFlags := os.Getenv("CFLAGS"); envCFlags != "" {
|
||||
flags = append(flags, safesplit.SplitPkgConfigFlags(envCFlags)...)
|
||||
}
|
||||
|
||||
// Add config CCFLAGS
|
||||
flags = append(flags, c.config.CCFLAGS...)
|
||||
|
||||
// Add config CFLAGS
|
||||
flags = append(flags, c.config.CFLAGS...)
|
||||
|
||||
return flags
|
||||
}
|
||||
|
||||
// mergeLinkerFlags merges environment CCFLAGS/LDFLAGS with config flags.
|
||||
func (c *Cmd) mergeLinkerFlags() []string {
|
||||
var flags []string
|
||||
|
||||
// Add environment CCFLAGS (for linker)
|
||||
if envCCFlags := os.Getenv("CCFLAGS"); envCCFlags != "" {
|
||||
flags = append(flags, safesplit.SplitPkgConfigFlags(envCCFlags)...)
|
||||
}
|
||||
|
||||
// Add environment LDFLAGS
|
||||
if envLDFlags := os.Getenv("LDFLAGS"); envLDFlags != "" {
|
||||
flags = append(flags, safesplit.SplitPkgConfigFlags(envLDFlags)...)
|
||||
}
|
||||
|
||||
// Add config LDFLAGS
|
||||
flags = append(flags, c.config.LDFLAGS...)
|
||||
|
||||
return flags
|
||||
}
|
||||
|
||||
// exec executes the clang command with given arguments.
|
||||
func (c *Cmd) exec(args ...string) error {
|
||||
cmd := exec.Command(c.app, args...)
|
||||
if c.Verbose {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", cmd)
|
||||
}
|
||||
cmd.Stdin = c.Stdin
|
||||
cmd.Stdout = c.Stdout
|
||||
cmd.Stderr = c.Stderr
|
||||
if c.Env != nil {
|
||||
cmd.Env = c.Env
|
||||
}
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// CheckLinkArgs validates linking arguments by attempting a test compile.
|
||||
func (c *Cmd) CheckLinkArgs(cmdArgs []string, wasm bool) error {
|
||||
// Create a temporary file with appropriate extension
|
||||
extension := ""
|
||||
if wasm {
|
||||
extension = ".wasm"
|
||||
} else if runtime.GOOS == "windows" {
|
||||
extension = ".exe"
|
||||
}
|
||||
|
||||
tmpFile, err := os.CreateTemp("", "llgo_check*"+extension)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create temporary file: %w", err)
|
||||
}
|
||||
tmpFile.Close()
|
||||
tmpPath := tmpFile.Name()
|
||||
|
||||
// Make sure to delete the temporary file when done
|
||||
defer os.Remove(tmpPath)
|
||||
|
||||
// Set up compilation arguments
|
||||
args := append([]string{}, cmdArgs...)
|
||||
args = append(args, []string{"-x", "c", "-o", tmpPath, "-"}...)
|
||||
src := "int main() {return 0;}"
|
||||
srcIn := strings.NewReader(src)
|
||||
c.Stdin = srcIn
|
||||
|
||||
// Execute the command with linker flags
|
||||
return c.Link(args...)
|
||||
}
|
||||
513
internal/clang/clang_test.go
Normal file
513
internal/clang/clang_test.go
Normal file
@@ -0,0 +1,513 @@
|
||||
//go:build !llgo
|
||||
// +build !llgo
|
||||
|
||||
/*
|
||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package clang
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConfig(t *testing.T) {
|
||||
t.Run("NewConfig", func(t *testing.T) {
|
||||
ccflags := []string{"-O2", "-g"}
|
||||
cflags := []string{"-std=c99"}
|
||||
ldflags := []string{"-lm"}
|
||||
|
||||
config := NewConfig("clang++", ccflags, cflags, ldflags, "ld.lld")
|
||||
|
||||
if config.CC != "clang++" {
|
||||
t.Errorf("Expected CC to be 'clang++', got %q", config.CC)
|
||||
}
|
||||
if !reflect.DeepEqual(config.CCFLAGS, ccflags) {
|
||||
t.Errorf("Expected CCFLAGS %v, got %v", ccflags, config.CCFLAGS)
|
||||
}
|
||||
if !reflect.DeepEqual(config.CFLAGS, cflags) {
|
||||
t.Errorf("Expected CFLAGS %v, got %v", cflags, config.CFLAGS)
|
||||
}
|
||||
if !reflect.DeepEqual(config.LDFLAGS, ldflags) {
|
||||
t.Errorf("Expected LDFLAGS %v, got %v", ldflags, config.LDFLAGS)
|
||||
}
|
||||
if config.Linker != "ld.lld" {
|
||||
t.Errorf("Expected Linker to be 'ld.lld', got %q", config.Linker)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
t.Run("WithApp", func(t *testing.T) {
|
||||
config := Config{CC: "gcc"}
|
||||
cmd := New("clang++", config)
|
||||
|
||||
if cmd.app != "clang++" {
|
||||
t.Errorf("Expected app to be 'clang++', got %q", cmd.app)
|
||||
}
|
||||
if !reflect.DeepEqual(cmd.config, config) {
|
||||
t.Errorf("Expected config %+v, got %+v", config, cmd.config)
|
||||
}
|
||||
if cmd.Stdout != os.Stdout {
|
||||
t.Error("Expected Stdout to be os.Stdout")
|
||||
}
|
||||
if cmd.Stderr != os.Stderr {
|
||||
t.Error("Expected Stderr to be os.Stderr")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithoutApp", func(t *testing.T) {
|
||||
config := Config{}
|
||||
cmd := New("", config)
|
||||
|
||||
if cmd.app != "clang" {
|
||||
t.Errorf("Expected app to be 'clang', got %q", cmd.app)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewCompiler(t *testing.T) {
|
||||
t.Run("WithCC", func(t *testing.T) {
|
||||
config := Config{CC: "gcc"}
|
||||
cmd := NewCompiler(config)
|
||||
|
||||
if cmd.app != "gcc" {
|
||||
t.Errorf("Expected app to be 'gcc', got %q", cmd.app)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithoutCC", func(t *testing.T) {
|
||||
config := Config{}
|
||||
cmd := NewCompiler(config)
|
||||
|
||||
if cmd.app != "clang" {
|
||||
t.Errorf("Expected app to be 'clang', got %q", cmd.app)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewLinker(t *testing.T) {
|
||||
t.Run("WithLinker", func(t *testing.T) {
|
||||
config := Config{Linker: "ld.lld"}
|
||||
cmd := NewLinker(config)
|
||||
|
||||
if cmd.app != "ld.lld" {
|
||||
t.Errorf("Expected app to be 'ld.lld', got %q", cmd.app)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithoutLinkerButWithCC", func(t *testing.T) {
|
||||
config := Config{CC: "gcc"}
|
||||
cmd := NewLinker(config)
|
||||
|
||||
if cmd.app != "gcc" {
|
||||
t.Errorf("Expected app to be 'gcc', got %q", cmd.app)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithoutLinkerAndCC", func(t *testing.T) {
|
||||
config := Config{}
|
||||
cmd := NewLinker(config)
|
||||
|
||||
if cmd.app != "clang" {
|
||||
t.Errorf("Expected app to be 'clang', got %q", cmd.app)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestMergeCompilerFlags(t *testing.T) {
|
||||
// Save original environment
|
||||
origCCFlags := os.Getenv("CCFLAGS")
|
||||
origCFlags := os.Getenv("CFLAGS")
|
||||
defer func() {
|
||||
os.Setenv("CCFLAGS", origCCFlags)
|
||||
os.Setenv("CFLAGS", origCFlags)
|
||||
}()
|
||||
|
||||
t.Run("WithEnvironmentAndConfig", func(t *testing.T) {
|
||||
os.Setenv("CCFLAGS", "-O2 -g")
|
||||
os.Setenv("CFLAGS", "-std=c99")
|
||||
|
||||
config := Config{
|
||||
CCFLAGS: []string{"-Wall"},
|
||||
CFLAGS: []string{"-pedantic"},
|
||||
}
|
||||
cmd := New("clang", config)
|
||||
|
||||
flags := cmd.mergeCompilerFlags()
|
||||
expected := []string{"-O2", "-g", "-std=c99", "-Wall", "-pedantic"}
|
||||
|
||||
if !reflect.DeepEqual(flags, expected) {
|
||||
t.Errorf("Expected flags %v, got %v", expected, flags)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithOnlyConfig", func(t *testing.T) {
|
||||
os.Unsetenv("CCFLAGS")
|
||||
os.Unsetenv("CFLAGS")
|
||||
|
||||
config := Config{
|
||||
CCFLAGS: []string{"-Wall"},
|
||||
CFLAGS: []string{"-pedantic"},
|
||||
}
|
||||
cmd := New("clang", config)
|
||||
|
||||
flags := cmd.mergeCompilerFlags()
|
||||
expected := []string{"-Wall", "-pedantic"}
|
||||
|
||||
if !reflect.DeepEqual(flags, expected) {
|
||||
t.Errorf("Expected flags %v, got %v", expected, flags)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithOnlyEnvironment", func(t *testing.T) {
|
||||
os.Setenv("CCFLAGS", "-O3")
|
||||
os.Setenv("CFLAGS", "-fPIC")
|
||||
|
||||
config := Config{}
|
||||
cmd := New("clang", config)
|
||||
|
||||
flags := cmd.mergeCompilerFlags()
|
||||
expected := []string{"-O3", "-fPIC"}
|
||||
|
||||
if !reflect.DeepEqual(flags, expected) {
|
||||
t.Errorf("Expected flags %v, got %v", expected, flags)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Empty", func(t *testing.T) {
|
||||
os.Unsetenv("CCFLAGS")
|
||||
os.Unsetenv("CFLAGS")
|
||||
|
||||
config := Config{}
|
||||
cmd := New("clang", config)
|
||||
|
||||
flags := cmd.mergeCompilerFlags()
|
||||
|
||||
if len(flags) != 0 {
|
||||
t.Errorf("Expected empty flags, got %v", flags)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestMergeLinkerFlags(t *testing.T) {
|
||||
// Save original environment
|
||||
origCCFlags := os.Getenv("CCFLAGS")
|
||||
origLDFlags := os.Getenv("LDFLAGS")
|
||||
defer func() {
|
||||
os.Setenv("CCFLAGS", origCCFlags)
|
||||
os.Setenv("LDFLAGS", origLDFlags)
|
||||
}()
|
||||
|
||||
t.Run("WithEnvironmentAndConfig", func(t *testing.T) {
|
||||
os.Setenv("CCFLAGS", "-O2")
|
||||
os.Setenv("LDFLAGS", "-lm -lpthread")
|
||||
|
||||
config := Config{
|
||||
LDFLAGS: []string{"-static"},
|
||||
}
|
||||
cmd := New("clang", config)
|
||||
|
||||
flags := cmd.mergeLinkerFlags()
|
||||
expected := []string{"-O2", "-lm", "-lpthread", "-static"}
|
||||
|
||||
if !reflect.DeepEqual(flags, expected) {
|
||||
t.Errorf("Expected flags %v, got %v", expected, flags)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithOnlyConfig", func(t *testing.T) {
|
||||
os.Unsetenv("CCFLAGS")
|
||||
os.Unsetenv("LDFLAGS")
|
||||
|
||||
config := Config{
|
||||
LDFLAGS: []string{"-static", "-lm"},
|
||||
}
|
||||
cmd := New("clang", config)
|
||||
|
||||
flags := cmd.mergeLinkerFlags()
|
||||
expected := []string{"-static", "-lm"}
|
||||
|
||||
if !reflect.DeepEqual(flags, expected) {
|
||||
t.Errorf("Expected flags %v, got %v", expected, flags)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestCompile(t *testing.T) {
|
||||
// This test uses echo instead of clang to avoid dependency on clang installation
|
||||
config := Config{
|
||||
CCFLAGS: []string{"-Wall"},
|
||||
CFLAGS: []string{"-std=c99"},
|
||||
}
|
||||
cmd := New("echo", config)
|
||||
|
||||
var stdout bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
|
||||
err := cmd.Compile("-c", "test.c")
|
||||
if err != nil {
|
||||
t.Errorf("Compile failed: %v", err)
|
||||
}
|
||||
|
||||
output := strings.TrimSpace(stdout.String())
|
||||
expectedArgs := "-Wall -std=c99 -c test.c"
|
||||
if output != expectedArgs {
|
||||
t.Errorf("Expected output %q, got %q", expectedArgs, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLink(t *testing.T) {
|
||||
// This test uses echo instead of clang to avoid dependency on clang installation
|
||||
config := Config{
|
||||
LDFLAGS: []string{"-lm"},
|
||||
}
|
||||
cmd := New("echo", config)
|
||||
|
||||
var stdout bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
|
||||
err := cmd.Link("test.o", "-o", "test")
|
||||
if err != nil {
|
||||
t.Errorf("Link failed: %v", err)
|
||||
}
|
||||
|
||||
output := strings.TrimSpace(stdout.String())
|
||||
expectedArgs := "-lm test.o -o test"
|
||||
if output != expectedArgs {
|
||||
t.Errorf("Expected output %q, got %q", expectedArgs, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerboseMode(t *testing.T) {
|
||||
config := Config{}
|
||||
cmd := New("echo", config)
|
||||
cmd.Verbose = true
|
||||
|
||||
// Since verbose output goes to os.Stderr directly, we'll test
|
||||
// that verbose flag is set and command executes successfully
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stderr = &stderr
|
||||
cmd.Stdout = &bytes.Buffer{} // Suppress stdout
|
||||
|
||||
err := cmd.Compile("-c", "test.c")
|
||||
if err != nil {
|
||||
t.Errorf("Compile failed: %v", err)
|
||||
}
|
||||
|
||||
// The test passes if verbose is set and no error occurred
|
||||
if !cmd.Verbose {
|
||||
t.Error("Expected Verbose to be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCmdEnvironment(t *testing.T) {
|
||||
config := Config{}
|
||||
cmd := New("echo", config)
|
||||
cmd.Env = []string{"TEST_VAR=test_value"}
|
||||
|
||||
var stdout bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
|
||||
// Use a command that will show environment variables
|
||||
// Note: This is a simplified test that just ensures the Env field is set
|
||||
err := cmd.Compile("-c", "test.c")
|
||||
if err != nil {
|
||||
t.Errorf("Compile failed: %v", err)
|
||||
}
|
||||
|
||||
if len(cmd.Env) != 1 || cmd.Env[0] != "TEST_VAR=test_value" {
|
||||
t.Errorf("Expected environment to be set correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCmdIO(t *testing.T) {
|
||||
config := Config{}
|
||||
cmd := New("cat", config) // Use cat to test stdin/stdout
|
||||
|
||||
input := "test input"
|
||||
cmd.Stdin = strings.NewReader(input)
|
||||
|
||||
var stdout bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
|
||||
// cat will read from stdin and write to stdout
|
||||
err := cmd.exec() // Call exec directly with no args
|
||||
if err != nil {
|
||||
t.Errorf("exec failed: %v", err)
|
||||
}
|
||||
|
||||
output := stdout.String()
|
||||
if output != input {
|
||||
t.Errorf("Expected output %q, got %q", input, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckLinkArgs(t *testing.T) {
|
||||
t.Run("BasicTest", func(t *testing.T) {
|
||||
// Use echo instead of clang to avoid dependency
|
||||
config := Config{}
|
||||
cmd := New("echo", config)
|
||||
|
||||
// Redirect output to avoid clutter
|
||||
cmd.Stdout = &bytes.Buffer{}
|
||||
cmd.Stderr = &bytes.Buffer{}
|
||||
|
||||
// This should succeed with echo
|
||||
err := cmd.CheckLinkArgs([]string{"-o"}, false)
|
||||
if err != nil {
|
||||
t.Errorf("CheckLinkArgs failed: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WasmExtension", func(t *testing.T) {
|
||||
config := Config{}
|
||||
cmd := New("echo", config)
|
||||
|
||||
cmd.Stdout = &bytes.Buffer{}
|
||||
cmd.Stderr = &bytes.Buffer{}
|
||||
|
||||
// Test with wasm=true
|
||||
err := cmd.CheckLinkArgs([]string{"-o"}, true)
|
||||
if err != nil {
|
||||
t.Errorf("CheckLinkArgs with wasm failed: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Additional table-driven test for flag merging scenarios
|
||||
func TestFlagMergingScenarios(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
envCCFlags string
|
||||
envCFlags string
|
||||
envLDFlags string
|
||||
config Config
|
||||
expectComp []string
|
||||
expectLink []string
|
||||
}{
|
||||
{
|
||||
name: "empty everything",
|
||||
envCCFlags: "",
|
||||
envCFlags: "",
|
||||
envLDFlags: "",
|
||||
config: Config{},
|
||||
expectComp: []string{},
|
||||
expectLink: []string{},
|
||||
},
|
||||
{
|
||||
name: "only environment flags",
|
||||
envCCFlags: "-O2",
|
||||
envCFlags: "-std=c99",
|
||||
envLDFlags: "-lm",
|
||||
config: Config{},
|
||||
expectComp: []string{"-O2", "-std=c99"},
|
||||
expectLink: []string{"-O2", "-lm"},
|
||||
},
|
||||
{
|
||||
name: "only config flags",
|
||||
envCCFlags: "",
|
||||
envCFlags: "",
|
||||
envLDFlags: "",
|
||||
config: Config{
|
||||
CCFLAGS: []string{"-Wall"},
|
||||
CFLAGS: []string{"-pedantic"},
|
||||
LDFLAGS: []string{"-static"},
|
||||
},
|
||||
expectComp: []string{"-Wall", "-pedantic"},
|
||||
expectLink: []string{"-static"},
|
||||
},
|
||||
{
|
||||
name: "mixed environment and config",
|
||||
envCCFlags: "-O3",
|
||||
envCFlags: "-fPIC",
|
||||
envLDFlags: "-lm -lpthread",
|
||||
config: Config{
|
||||
CCFLAGS: []string{"-Wall", "-Wextra"},
|
||||
CFLAGS: []string{"-std=c11"},
|
||||
LDFLAGS: []string{"-static"},
|
||||
},
|
||||
expectComp: []string{"-O3", "-fPIC", "-Wall", "-Wextra", "-std=c11"},
|
||||
expectLink: []string{"-O3", "-lm", "-lpthread", "-static"},
|
||||
},
|
||||
}
|
||||
|
||||
// Save original environment
|
||||
origCCFlags := os.Getenv("CCFLAGS")
|
||||
origCFlags := os.Getenv("CFLAGS")
|
||||
origLDFlags := os.Getenv("LDFLAGS")
|
||||
defer func() {
|
||||
os.Setenv("CCFLAGS", origCCFlags)
|
||||
os.Setenv("CFLAGS", origCFlags)
|
||||
os.Setenv("LDFLAGS", origLDFlags)
|
||||
}()
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Set environment variables
|
||||
os.Setenv("CCFLAGS", tt.envCCFlags)
|
||||
os.Setenv("CFLAGS", tt.envCFlags)
|
||||
os.Setenv("LDFLAGS", tt.envLDFlags)
|
||||
|
||||
cmd := New("clang", tt.config)
|
||||
|
||||
// Test compiler flags
|
||||
compFlags := cmd.mergeCompilerFlags()
|
||||
if len(tt.expectComp) == 0 && len(compFlags) == 0 {
|
||||
// Both are empty, consider them equal
|
||||
} else if !reflect.DeepEqual(compFlags, tt.expectComp) {
|
||||
t.Errorf("mergeCompilerFlags() = %v, want %v", compFlags, tt.expectComp)
|
||||
}
|
||||
|
||||
// Test linker flags
|
||||
linkFlags := cmd.mergeLinkerFlags()
|
||||
if len(tt.expectLink) == 0 && len(linkFlags) == 0 {
|
||||
// Both are empty, consider them equal
|
||||
} else if !reflect.DeepEqual(linkFlags, tt.expectLink) {
|
||||
t.Errorf("mergeLinkerFlags() = %v, want %v", linkFlags, tt.expectLink)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark tests
|
||||
func BenchmarkMergeCompilerFlags(b *testing.B) {
|
||||
config := Config{
|
||||
CCFLAGS: []string{"-Wall", "-O2"},
|
||||
CFLAGS: []string{"-std=c99", "-pedantic"},
|
||||
}
|
||||
cmd := New("clang", config)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = cmd.mergeCompilerFlags()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMergeLinkerFlags(b *testing.B) {
|
||||
config := Config{
|
||||
LDFLAGS: []string{"-lm", "-lpthread", "-static"},
|
||||
}
|
||||
cmd := New("clang", config)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = cmd.mergeLinkerFlags()
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -19,36 +20,257 @@ type Export struct {
|
||||
CCFLAGS []string
|
||||
CFLAGS []string
|
||||
LDFLAGS []string
|
||||
EXTRAFLAGS []string
|
||||
|
||||
// Additional fields from target configuration
|
||||
LLVMTarget string
|
||||
CPU string
|
||||
Features string
|
||||
BuildTags []string
|
||||
GOOS string
|
||||
GOARCH string
|
||||
Linker string // Linker to use (e.g., "ld.lld", "avr-ld")
|
||||
ExtraFiles []string // Extra files to compile and link (e.g., .s, .c files)
|
||||
ClangRoot string // Root directory of custom clang installation
|
||||
ClangBinPath string // Path to clang binary directory
|
||||
|
||||
BinaryFormat string // Binary format (e.g., "elf", "esp", "uf2")
|
||||
FormatDetail string // For uf2, it's uf2FamilyID
|
||||
}
|
||||
|
||||
const wasiSdkUrl = "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-x86_64-macos.tar.gz"
|
||||
// URLs and configuration that can be overridden for testing
|
||||
var (
|
||||
wasiSdkUrl = "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-x86_64-macos.tar.gz"
|
||||
wasiMacosSubdir = "wasi-sdk-25.0-x86_64-macos"
|
||||
)
|
||||
|
||||
var (
|
||||
espClangBaseUrl = "https://github.com/goplus/espressif-llvm-project-prebuilt/releases/download/19.1.2_20250820"
|
||||
espClangVersion = "19.1.2_20250820"
|
||||
)
|
||||
|
||||
// cacheRoot can be overridden for testing
|
||||
var cacheRoot = env.LLGoCacheDir
|
||||
|
||||
func cacheDir() string {
|
||||
return filepath.Join(env.LLGoCacheDir(), "crosscompile")
|
||||
return filepath.Join(cacheRoot(), "crosscompile")
|
||||
}
|
||||
|
||||
func Use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
||||
// expandEnv expands template variables in a string
|
||||
// Supports variables like {port}, {hex}, {bin}, {root}, {tmpDir}, etc.
|
||||
// Special case: {} expands to the first available file variable (hex, bin, img, zip)
|
||||
func expandEnv(template string, envs map[string]string) string {
|
||||
return expandEnvWithDefault(template, envs)
|
||||
}
|
||||
|
||||
// expandEnvWithDefault expands template variables with optional default for {}
|
||||
func expandEnvWithDefault(template string, envs map[string]string, defaultValue ...string) string {
|
||||
if template == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
result := template
|
||||
|
||||
// Handle special case of {} - use provided default or first available file variable
|
||||
if strings.Contains(result, "{}") {
|
||||
defaultVal := ""
|
||||
if len(defaultValue) > 0 && defaultValue[0] != "" {
|
||||
defaultVal = defaultValue[0]
|
||||
} else {
|
||||
// Priority order: hex, bin, img, zip
|
||||
for _, key := range []string{"hex", "bin", "img", "zip"} {
|
||||
if value, exists := envs[key]; exists && value != "" {
|
||||
defaultVal = value
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
result = strings.ReplaceAll(result, "{}", defaultVal)
|
||||
}
|
||||
|
||||
// Replace named variables
|
||||
for key, value := range envs {
|
||||
if key != "" { // Skip empty key used for {} default
|
||||
result = strings.ReplaceAll(result, "{"+key+"}", value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// expandEnvSlice expands template variables in a slice of strings
|
||||
func expandEnvSlice(templates []string, envs map[string]string) []string {
|
||||
return expandEnvSliceWithDefault(templates, envs)
|
||||
}
|
||||
|
||||
// expandEnvSliceWithDefault expands template variables in a slice with optional default for {}
|
||||
func expandEnvSliceWithDefault(templates []string, envs map[string]string, defaultValue ...string) []string {
|
||||
if len(templates) == 0 {
|
||||
return templates
|
||||
}
|
||||
|
||||
result := make([]string, len(templates))
|
||||
for i, template := range templates {
|
||||
result[i] = expandEnvWithDefault(template, envs, defaultValue...)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// buildEnvMap creates a map of template variables for the current context
|
||||
func buildEnvMap(llgoRoot string) map[string]string {
|
||||
envs := make(map[string]string)
|
||||
|
||||
// Basic paths
|
||||
envs["root"] = llgoRoot
|
||||
envs["tmpDir"] = os.TempDir()
|
||||
|
||||
// These will typically be set by calling code when actual values are known
|
||||
// envs["port"] = "" // Serial port (e.g., "/dev/ttyUSB0", "COM3")
|
||||
// envs["hex"] = "" // Path to hex file
|
||||
// envs["bin"] = "" // Path to binary file
|
||||
// envs["img"] = "" // Path to image file
|
||||
// envs["zip"] = "" // Path to zip file
|
||||
|
||||
return envs
|
||||
}
|
||||
|
||||
// getCanonicalArchName returns the canonical architecture name for a target triple
|
||||
func getCanonicalArchName(triple string) string {
|
||||
arch := strings.Split(triple, "-")[0]
|
||||
if arch == "arm64" {
|
||||
return "aarch64"
|
||||
}
|
||||
if strings.HasPrefix(arch, "arm") || strings.HasPrefix(arch, "thumb") {
|
||||
return "arm"
|
||||
}
|
||||
if arch == "mipsel" {
|
||||
return "mips"
|
||||
}
|
||||
return arch
|
||||
}
|
||||
|
||||
// getMacOSSysroot returns the macOS SDK path using xcrun
|
||||
func getMacOSSysroot() (string, error) {
|
||||
cmd := exec.Command("xcrun", "--sdk", "macosx", "--show-sdk-path")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSpace(string(output)), nil
|
||||
}
|
||||
|
||||
// getESPClangRoot returns the ESP Clang root directory, checking LLGoROOT first,
|
||||
// then downloading if needed and platform is supported
|
||||
func getESPClangRoot() (clangRoot string, err error) {
|
||||
llgoRoot := env.LLGoROOT()
|
||||
|
||||
// First check if clang exists in LLGoROOT
|
||||
espClangRoot := filepath.Join(llgoRoot, "crosscompile", "clang")
|
||||
if _, err = os.Stat(espClangRoot); err == nil {
|
||||
clangRoot = espClangRoot
|
||||
return
|
||||
}
|
||||
|
||||
// Try to download ESP Clang if platform is supported
|
||||
platformSuffix := getESPClangPlatform(runtime.GOOS, runtime.GOARCH)
|
||||
if platformSuffix != "" {
|
||||
cacheClangDir := filepath.Join(cacheRoot(), "crosscompile", "esp-clang-"+espClangVersion)
|
||||
if _, err = os.Stat(cacheClangDir); err != nil {
|
||||
if !errors.Is(err, fs.ErrNotExist) {
|
||||
return
|
||||
}
|
||||
fmt.Fprintln(os.Stderr, "ESP Clang not found in LLGO_ROOT or cache, will download.")
|
||||
if err = checkDownloadAndExtractESPClang(platformSuffix, cacheClangDir); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
clangRoot = cacheClangDir
|
||||
return
|
||||
}
|
||||
|
||||
err = fmt.Errorf("ESP Clang not found in LLGoROOT and platform %s/%s is not supported for download", runtime.GOOS, runtime.GOARCH)
|
||||
return
|
||||
}
|
||||
|
||||
// getESPClangPlatform returns the platform suffix for ESP Clang downloads
|
||||
func getESPClangPlatform(goos, goarch string) string {
|
||||
switch goos {
|
||||
case "darwin":
|
||||
switch goarch {
|
||||
case "amd64":
|
||||
return "x86_64-apple-darwin"
|
||||
case "arm64":
|
||||
return "aarch64-apple-darwin"
|
||||
}
|
||||
case "linux":
|
||||
switch goarch {
|
||||
case "amd64":
|
||||
return "x86_64-linux-gnu"
|
||||
case "arm64":
|
||||
return "aarch64-linux-gnu"
|
||||
case "arm":
|
||||
return "arm-linux-gnueabihf"
|
||||
}
|
||||
case "windows":
|
||||
switch goarch {
|
||||
case "amd64":
|
||||
return "x86_64-w64-mingw32"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
||||
targetTriple := llvm.GetTargetTriple(goos, goarch)
|
||||
llgoRoot := env.LLGoROOT()
|
||||
|
||||
// Check for ESP Clang support for target-based builds
|
||||
clangRoot, err := getESPClangRoot()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Set ClangRoot and CC if clang is available
|
||||
export.ClangRoot = clangRoot
|
||||
export.CC = filepath.Join(clangRoot, "bin", "clang++")
|
||||
|
||||
if runtime.GOOS == goos && runtime.GOARCH == goarch {
|
||||
clangLib := filepath.Join(clangRoot, "lib")
|
||||
clangInc := filepath.Join(clangRoot, "include")
|
||||
// not cross compile
|
||||
// Set up basic flags for non-cross-compile
|
||||
export.LDFLAGS = []string{
|
||||
"-L" + clangLib,
|
||||
"-target", targetTriple,
|
||||
"-Wno-override-module",
|
||||
"-Qunused-arguments",
|
||||
"-Wno-unused-command-line-argument",
|
||||
"-Wl,--error-limit=0",
|
||||
"-fuse-ld=lld",
|
||||
}
|
||||
export.CFLAGS = append(export.CFLAGS, "-I"+clangInc)
|
||||
export.CCFLAGS = []string{
|
||||
"-Qunused-arguments",
|
||||
"-Wno-unused-command-line-argument",
|
||||
}
|
||||
|
||||
// Add platform-specific rpath flags
|
||||
switch goos {
|
||||
case "darwin":
|
||||
export.LDFLAGS = append(export.LDFLAGS, "-Wl,-rpath,"+clangLib)
|
||||
case "linux":
|
||||
export.LDFLAGS = append(export.LDFLAGS, "-Wl,-rpath,"+clangLib)
|
||||
case "windows":
|
||||
// Windows doesn't support rpath, DLLs should be in PATH or same directory
|
||||
default:
|
||||
// For other Unix-like systems, try the generic rpath
|
||||
export.LDFLAGS = append(export.LDFLAGS, "-Wl,-rpath,"+clangLib)
|
||||
}
|
||||
|
||||
// Add sysroot for macOS only
|
||||
if goos == "darwin" {
|
||||
sysrootPath, sysrootErr := getMacOSSysroot()
|
||||
if sysrootErr != nil {
|
||||
err = fmt.Errorf("failed to get macOS SDK path: %w", sysrootErr)
|
||||
return
|
||||
}
|
||||
export.CCFLAGS = append(export.CCFLAGS, []string{"--sysroot=" + sysrootPath}...)
|
||||
export.LDFLAGS = append(export.LDFLAGS, []string{"--sysroot=" + sysrootPath}...)
|
||||
}
|
||||
|
||||
// Add OS-specific flags
|
||||
switch goos {
|
||||
@@ -85,13 +307,13 @@ func Use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
||||
// Configure based on GOOS
|
||||
switch goos {
|
||||
case "wasip1":
|
||||
sdkDir := filepath.Join(cacheDir(), llvm.GetTargetTriple(goos, goarch))
|
||||
if _, err = os.Stat(sdkDir); err != nil {
|
||||
if !errors.Is(err, fs.ErrNotExist) {
|
||||
return
|
||||
}
|
||||
// Set wasiSdkRoot path
|
||||
wasiSdkRoot := filepath.Join(llgoRoot, "crosscompile", "wasi-libc")
|
||||
|
||||
if err = downloadAndExtract(wasiSdkUrl, sdkDir); err != nil {
|
||||
// If not exists in LLGoROOT, download and use cached wasiSdkRoot
|
||||
if _, err = os.Stat(wasiSdkRoot); err != nil {
|
||||
sdkDir := filepath.Join(cacheDir(), llvm.GetTargetTriple(goos, goarch))
|
||||
if wasiSdkRoot, err = checkDownloadAndExtractWasiSDK(sdkDir); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -101,8 +323,7 @@ func Use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
||||
triple = "wasm32-wasip1-threads"
|
||||
}
|
||||
|
||||
// Set up flags for the WASI-SDK
|
||||
wasiSdkRoot := filepath.Join(sdkDir, "wasi-sdk-25.0-x86_64-macos")
|
||||
// Set up flags for the WASI-SDK or wasi-libc
|
||||
sysrootDir := filepath.Join(wasiSdkRoot, "share", "wasi-sysroot")
|
||||
libclangDir := filepath.Join(wasiSdkRoot, "lib", "clang", "19")
|
||||
includeDir := filepath.Join(sysrootDir, "include", triple)
|
||||
@@ -119,6 +340,8 @@ func Use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
||||
}
|
||||
export.CFLAGS = []string{
|
||||
"-I" + includeDir,
|
||||
"-Qunused-arguments",
|
||||
"-Wno-unused-command-line-argument",
|
||||
}
|
||||
// Add WebAssembly linker flags
|
||||
export.LDFLAGS = append(export.LDFLAGS, export.CCFLAGS...)
|
||||
@@ -169,6 +392,8 @@ func Use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
||||
// Add compiler flags
|
||||
export.CCFLAGS = []string{
|
||||
"-target", targetTriple,
|
||||
"-Qunused-arguments",
|
||||
"-Wno-unused-command-line-argument",
|
||||
}
|
||||
export.CFLAGS = []string{}
|
||||
// Add WebAssembly linker flags for Emscripten
|
||||
@@ -186,7 +411,7 @@ func Use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
||||
// "-z", "stack-size=10485760", // 10MB
|
||||
// "-Wl,--export=malloc", "-Wl,--export=free",
|
||||
}
|
||||
export.EXTRAFLAGS = []string{
|
||||
export.LDFLAGS = append(export.LDFLAGS, []string{
|
||||
"-sENVIRONMENT=web,worker",
|
||||
"-DPLATFORM_WEB",
|
||||
"-sEXPORT_KEEPALIVE=1",
|
||||
@@ -198,7 +423,7 @@ func Use(goos, goarch string, wasiThreads bool) (export Export, err error) {
|
||||
"-sEXPORT_ALL=1",
|
||||
"-sASYNCIFY=1",
|
||||
"-sSTACK_SIZE=5242880", // 50MB
|
||||
}
|
||||
}...)
|
||||
|
||||
default:
|
||||
err = errors.New("unsupported GOOS for WebAssembly: " + goos)
|
||||
@@ -216,25 +441,55 @@ func useTarget(targetName string) (export Export, err error) {
|
||||
return export, fmt.Errorf("failed to resolve target %s: %w", targetName, err)
|
||||
}
|
||||
|
||||
target := config.LLVMTarget
|
||||
if target == "" {
|
||||
return export, fmt.Errorf("target '%s' does not have a valid LLVM target triple", targetName)
|
||||
}
|
||||
|
||||
cpu := config.CPU
|
||||
if cpu == "" {
|
||||
return export, fmt.Errorf("target '%s' does not have a valid CPU configuration", targetName)
|
||||
}
|
||||
|
||||
// Check for ESP Clang support for target-based builds
|
||||
clangRoot, err := getESPClangRoot()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Set ClangRoot and CC if clang is available
|
||||
export.ClangRoot = clangRoot
|
||||
export.CC = filepath.Join(clangRoot, "bin", "clang++")
|
||||
|
||||
// Convert target config to Export - only export necessary fields
|
||||
export.BuildTags = config.BuildTags
|
||||
export.GOOS = config.GOOS
|
||||
export.GOARCH = config.GOARCH
|
||||
export.ExtraFiles = config.ExtraFiles
|
||||
export.BinaryFormat = config.BinaryFormat
|
||||
export.FormatDetail = config.FormatDetail()
|
||||
|
||||
// Build environment map for template variable expansion
|
||||
envs := buildEnvMap(env.LLGoROOT())
|
||||
|
||||
// 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)
|
||||
cflags := []string{"-Wno-override-module", "-Qunused-arguments", "-Wno-unused-command-line-argument"}
|
||||
if config.LLVMTarget != "" {
|
||||
cflags = append(cflags, "--target="+config.LLVMTarget)
|
||||
ccflags = append(ccflags, "--target="+config.LLVMTarget)
|
||||
}
|
||||
// Expand template variables in cflags
|
||||
expandedCFlags := expandEnvSlice(config.CFlags, envs)
|
||||
cflags = append(cflags, expandedCFlags...)
|
||||
|
||||
ccflags = append(ccflags, "-Wno-override-module", "--target="+config.LLVMTarget)
|
||||
|
||||
// Inspired by tinygo
|
||||
cpu := config.CPU
|
||||
// The following parameters are inspired by tinygo/builder/library.go
|
||||
// Handle CPU configuration
|
||||
if cpu != "" {
|
||||
// X86 has deprecated the -mcpu flag, so we need to use -march instead.
|
||||
// However, ARM has not done this.
|
||||
if strings.HasPrefix(target, "i386") || strings.HasPrefix(target, "x86_64") {
|
||||
ccflags = append(ccflags, "-march="+cpu)
|
||||
} else if strings.HasPrefix(target, "avr") {
|
||||
@@ -242,12 +497,50 @@ func useTarget(targetName string) (export Export, err error) {
|
||||
} else {
|
||||
ccflags = append(ccflags, "-mcpu="+cpu)
|
||||
}
|
||||
// Only add -mllvm flags for non-WebAssembly linkers
|
||||
|
||||
// For ld.lld linker, also add CPU info to linker flags
|
||||
if config.Linker == "ld.lld" {
|
||||
ldflags = append(ldflags, "-mllvm", "-mcpu="+cpu)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle architecture-specific flags
|
||||
canonicalArch := getCanonicalArchName(target)
|
||||
switch canonicalArch {
|
||||
case "arm":
|
||||
if strings.Split(target, "-")[2] == "linux" {
|
||||
ccflags = append(ccflags, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
|
||||
} else {
|
||||
ccflags = append(ccflags, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
|
||||
}
|
||||
case "avr":
|
||||
// AVR defaults to C float and double both being 32-bit. This deviates
|
||||
// from what most code (and certainly compiler-rt) expects. So we need
|
||||
// to force the compiler to use 64-bit floating point numbers for
|
||||
// double.
|
||||
ccflags = append(ccflags, "-mdouble=64")
|
||||
case "riscv32":
|
||||
ccflags = append(ccflags, "-march=rv32imac", "-fforce-enable-int128")
|
||||
case "riscv64":
|
||||
ccflags = append(ccflags, "-march=rv64gc")
|
||||
case "mips":
|
||||
ccflags = append(ccflags, "-fno-pic")
|
||||
}
|
||||
|
||||
// Handle soft float
|
||||
if strings.Contains(config.Features, "soft-float") || strings.Contains(strings.Join(config.CFlags, " "), "soft-float") {
|
||||
// Use softfloat instead of floating point instructions. This is
|
||||
// supported on many architectures.
|
||||
ccflags = append(ccflags, "-msoft-float")
|
||||
} else {
|
||||
if strings.HasPrefix(target, "armv5") {
|
||||
// On ARMv5 we need to explicitly enable hardware floating point
|
||||
// instructions: Clang appears to assume the hardware doesn't have a
|
||||
// FPU otherwise.
|
||||
ccflags = append(ccflags, "-mfpu=vfpv2")
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Features
|
||||
if config.Features != "" {
|
||||
// Only add -mllvm flags for non-WebAssembly linkers
|
||||
@@ -256,64 +549,45 @@ func useTarget(targetName string) (export Export, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Linker - keep it for external usage
|
||||
export.Linker = config.Linker
|
||||
// Handle code generation configuration
|
||||
if config.CodeModel != "" {
|
||||
ccflags = append(ccflags, "-mcmodel="+config.CodeModel)
|
||||
}
|
||||
if config.TargetABI != "" {
|
||||
ccflags = append(ccflags, "-mabi="+config.TargetABI)
|
||||
}
|
||||
if config.RelocationModel != "" {
|
||||
switch config.RelocationModel {
|
||||
case "pic":
|
||||
ccflags = append(ccflags, "-fPIC")
|
||||
case "static":
|
||||
ccflags = append(ccflags, "-fno-pic")
|
||||
}
|
||||
}
|
||||
|
||||
// Combine with config flags
|
||||
export.CFLAGS = config.CFlags
|
||||
// Handle Linker - keep it for external usage
|
||||
if config.Linker != "" {
|
||||
export.Linker = filepath.Join(clangRoot, "bin", config.Linker)
|
||||
}
|
||||
if config.LinkerScript != "" {
|
||||
ldflags = append(ldflags, "-T", config.LinkerScript)
|
||||
}
|
||||
ldflags = append(ldflags, "-L", env.LLGoROOT()) // search targets/*.ld
|
||||
|
||||
// Combine with config flags and expand template variables
|
||||
export.CFLAGS = cflags
|
||||
export.CCFLAGS = ccflags
|
||||
export.LDFLAGS = append(ldflags, filterCompatibleLDFlags(config.LDFlags)...)
|
||||
export.EXTRAFLAGS = []string{}
|
||||
expandedLDFlags := expandEnvSlice(config.LDFlags, envs)
|
||||
export.LDFLAGS = append(ldflags, expandedLDFlags...)
|
||||
|
||||
return export, nil
|
||||
}
|
||||
|
||||
// UseWithTarget extends the original Use function to support target-based configuration
|
||||
// Use 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) {
|
||||
func Use(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
|
||||
return use(goos, goarch, wasiThreads)
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ func TestUseCrossCompileSDK(t *testing.T) {
|
||||
name: "Same Platform",
|
||||
goos: runtime.GOOS,
|
||||
goarch: runtime.GOARCH,
|
||||
expectSDK: false,
|
||||
expectCCFlags: false,
|
||||
expectCFlags: false,
|
||||
expectLDFlags: false,
|
||||
expectSDK: true, // Changed: now we expect flags even for same platform
|
||||
expectCCFlags: true, // Changed: CCFLAGS will contain sysroot
|
||||
expectCFlags: true, // Changed: CFLAGS will contain include paths
|
||||
expectLDFlags: true, // Changed: LDFLAGS will contain library paths
|
||||
},
|
||||
{
|
||||
name: "WASM Target",
|
||||
@@ -55,10 +55,10 @@ func TestUseCrossCompileSDK(t *testing.T) {
|
||||
name: "Unsupported Target",
|
||||
goos: "windows",
|
||||
goarch: "amd64",
|
||||
expectSDK: false,
|
||||
expectCCFlags: false,
|
||||
expectCFlags: false,
|
||||
expectLDFlags: false,
|
||||
expectSDK: false, // Still false as it won't set up specific SDK
|
||||
expectCCFlags: false, // No cross-compile specific flags
|
||||
expectCFlags: false, // No cross-compile specific flags
|
||||
expectLDFlags: false, // No cross-compile specific flags
|
||||
},
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ func TestUseCrossCompileSDK(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
export, err := Use(tc.goos, tc.goarch, false)
|
||||
export, err := use(tc.goos, tc.goarch, false)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
@@ -111,12 +111,21 @@ func TestUseCrossCompileSDK(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// For WASM target, both sysroot and resource-dir are expected
|
||||
if tc.name == "WASM Target" {
|
||||
if !hasSysroot {
|
||||
t.Error("Missing --sysroot flag in CCFLAGS")
|
||||
}
|
||||
if !hasResourceDir {
|
||||
t.Error("Missing -resource-dir flag in CCFLAGS")
|
||||
}
|
||||
} else if tc.name == "Same Platform" {
|
||||
// For same platform, we expect sysroot only on macOS
|
||||
if runtime.GOOS == "darwin" && !hasSysroot {
|
||||
t.Error("Missing --sysroot flag in CCFLAGS on macOS")
|
||||
}
|
||||
// On Linux and other platforms, sysroot is not necessarily required
|
||||
}
|
||||
}
|
||||
|
||||
if tc.expectCFlags {
|
||||
@@ -147,9 +156,11 @@ func TestUseCrossCompileSDK(t *testing.T) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if /*len(export.CCFLAGS) != 0 ||*/ len(export.CFLAGS) != 0 {
|
||||
t.Errorf("Expected empty export, got CCFLAGS=%v, CFLAGS=%v, LDFLAGS=%v",
|
||||
export.CCFLAGS, export.CFLAGS, export.LDFLAGS)
|
||||
// For unsupported targets, we still expect some basic flags to be set
|
||||
// since the implementation now always sets up ESP Clang environment
|
||||
// Only check that we don't have specific SDK-related flags for unsupported targets
|
||||
if tc.name == "Unsupported Target" && len(export.CFLAGS) != 0 {
|
||||
t.Errorf("Expected empty CFLAGS for unsupported target, got CFLAGS=%v", export.CFLAGS)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -182,7 +193,7 @@ func TestUseTarget(t *testing.T) {
|
||||
{
|
||||
name: "Cortex-M Target",
|
||||
targetName: "cortex-m",
|
||||
expectError: false,
|
||||
expectError: true,
|
||||
expectLLVM: "",
|
||||
expectCPU: "",
|
||||
},
|
||||
@@ -230,9 +241,21 @@ func TestUseTarget(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if CPU is in CCFLAGS
|
||||
// Check if CPU is in LDFLAGS (for ld.lld linker) or CCFLAGS (for other cases)
|
||||
if tc.expectCPU != "" {
|
||||
found := false
|
||||
// First check LDFLAGS for -mllvm -mcpu= pattern
|
||||
for i, flag := range export.LDFLAGS {
|
||||
if flag == "-mllvm" && i+1 < len(export.LDFLAGS) {
|
||||
nextFlag := export.LDFLAGS[i+1]
|
||||
if nextFlag == "-mcpu="+tc.expectCPU {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// If not found in LDFLAGS, check CCFLAGS for direct CPU flags
|
||||
if !found {
|
||||
expectedFlags := []string{"-mmcu=" + tc.expectCPU, "-mcpu=" + tc.expectCPU}
|
||||
for _, flag := range export.CCFLAGS {
|
||||
for _, expectedFlag := range expectedFlags {
|
||||
@@ -242,8 +265,9 @@ func TestUseTarget(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Expected CPU %s in CCFLAGS, got %v", tc.expectCPU, export.CCFLAGS)
|
||||
t.Errorf("Expected CPU %s in LDFLAGS or CCFLAGS, got LDFLAGS=%v, CCFLAGS=%v", tc.expectCPU, export.LDFLAGS, export.CCFLAGS)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +279,7 @@ func TestUseTarget(t *testing.T) {
|
||||
|
||||
func TestUseWithTarget(t *testing.T) {
|
||||
// Test target-based configuration takes precedence
|
||||
export, err := UseWithTarget("linux", "amd64", false, "wasi")
|
||||
export, err := Use("linux", "amd64", false, "wasi")
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -267,7 +291,7 @@ func TestUseWithTarget(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test fallback to goos/goarch when no target specified
|
||||
export, err = UseWithTarget(runtime.GOOS, runtime.GOARCH, false, "")
|
||||
export, err = Use(runtime.GOOS, runtime.GOARCH, false, "")
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -278,58 +302,125 @@ func TestUseWithTarget(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterCompatibleLDFlags(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input []string
|
||||
expected []string
|
||||
func TestExpandEnv(t *testing.T) {
|
||||
envs := map[string]string{
|
||||
"port": "/dev/ttyUSB0",
|
||||
"hex": "firmware.hex",
|
||||
"bin": "firmware.bin",
|
||||
"root": "/usr/local/llgo",
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
template string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "Empty flags",
|
||||
input: []string{},
|
||||
expected: []string{},
|
||||
"avrdude -c arduino -p atmega328p -P {port} -U flash:w:{hex}:i",
|
||||
"avrdude -c arduino -p atmega328p -P /dev/ttyUSB0 -U flash:w:firmware.hex:i",
|
||||
},
|
||||
{
|
||||
name: "Compatible flags only",
|
||||
input: []string{"-lm", "-lpthread"},
|
||||
expected: []string{"-lm", "-lpthread"},
|
||||
"simavr -m atmega328p -f 16000000 {}",
|
||||
"simavr -m atmega328p -f 16000000 firmware.hex", // {} expands to hex (first priority)
|
||||
},
|
||||
{
|
||||
name: "Incompatible flags filtered",
|
||||
input: []string{"--gc-sections", "-lm", "--emit-relocs", "-lpthread"},
|
||||
expected: []string{"--gc-sections", "-lm", "--emit-relocs", "-lpthread"},
|
||||
"-I{root}/lib/CMSIS/CMSIS/Include",
|
||||
"-I/usr/local/llgo/lib/CMSIS/CMSIS/Include",
|
||||
},
|
||||
{
|
||||
name: "Defsym flags filtered",
|
||||
input: []string{"--defsym=_stack_size=512", "-lm", "--defsym=_bootloader_size=512"},
|
||||
expected: []string{"-lm"},
|
||||
"no variables here",
|
||||
"no variables here",
|
||||
},
|
||||
{
|
||||
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 _, test := range tests {
|
||||
result := expandEnv(test.template, envs)
|
||||
if result != test.expected {
|
||||
t.Errorf("expandEnv(%q) = %q, want %q", test.template, result, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i, expected := range tc.expected {
|
||||
if result[i] != expected {
|
||||
t.Errorf("Expected flag[%d] = %s, got %s", i, expected, result[i])
|
||||
func TestExpandEnvSlice(t *testing.T) {
|
||||
envs := map[string]string{
|
||||
"root": "/usr/local/llgo",
|
||||
"port": "/dev/ttyUSB0",
|
||||
}
|
||||
|
||||
input := []string{
|
||||
"-I{root}/include",
|
||||
"-DPORT={port}",
|
||||
"static-flag",
|
||||
}
|
||||
|
||||
expected := []string{
|
||||
"-I/usr/local/llgo/include",
|
||||
"-DPORT=/dev/ttyUSB0",
|
||||
"static-flag",
|
||||
}
|
||||
|
||||
result := expandEnvSlice(input, envs)
|
||||
|
||||
if len(result) != len(expected) {
|
||||
t.Fatalf("expandEnvSlice length mismatch: got %d, want %d", len(result), len(expected))
|
||||
}
|
||||
|
||||
for i, exp := range expected {
|
||||
if result[i] != exp {
|
||||
t.Errorf("expandEnvSlice[%d] = %q, want %q", i, result[i], exp)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestExpandEnvWithDefault(t *testing.T) {
|
||||
envs := map[string]string{
|
||||
"port": "/dev/ttyUSB0",
|
||||
"hex": "firmware.hex",
|
||||
"bin": "firmware.bin",
|
||||
"img": "image.img",
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
template string
|
||||
defaultValue string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
"simavr {}",
|
||||
"", // No default - should use hex (priority)
|
||||
"simavr firmware.hex",
|
||||
},
|
||||
{
|
||||
"simavr {}",
|
||||
"custom.elf", // Explicit default
|
||||
"simavr custom.elf",
|
||||
},
|
||||
{
|
||||
"qemu -kernel {}",
|
||||
"vmlinux", // Custom kernel
|
||||
"qemu -kernel vmlinux",
|
||||
},
|
||||
{
|
||||
"no braces here",
|
||||
"ignored",
|
||||
"no braces here",
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var result string
|
||||
if test.defaultValue == "" {
|
||||
result = expandEnvWithDefault(test.template, envs)
|
||||
} else {
|
||||
result = expandEnvWithDefault(test.template, envs, test.defaultValue)
|
||||
}
|
||||
|
||||
if result != test.expected {
|
||||
t.Errorf("Test %d: expandEnvWithDefault(%q, envs, %q) = %q, want %q",
|
||||
i, test.template, test.defaultValue, result, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,39 +7,149 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func downloadAndExtract(url, dir string) (err error) {
|
||||
if _, err = os.Stat(dir); err == nil {
|
||||
os.RemoveAll(dir)
|
||||
}
|
||||
tempDir := dir + ".temp"
|
||||
os.RemoveAll(tempDir)
|
||||
if err = os.MkdirAll(tempDir, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create temporary directory: %w", err)
|
||||
// checkDownloadAndExtractWasiSDK downloads and extracts WASI SDK
|
||||
func checkDownloadAndExtractWasiSDK(dir string) (wasiSdkRoot string, err error) {
|
||||
wasiSdkRoot = filepath.Join(dir, wasiMacosSubdir)
|
||||
|
||||
// Check if already exists
|
||||
if _, err := os.Stat(wasiSdkRoot); err == nil {
|
||||
return wasiSdkRoot, nil
|
||||
}
|
||||
|
||||
// Create lock file path for the parent directory (dir) since that's what we're operating on
|
||||
lockPath := dir + ".lock"
|
||||
lockFile, err := acquireLock(lockPath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to acquire lock: %w", err)
|
||||
}
|
||||
defer releaseLock(lockFile)
|
||||
|
||||
// Double-check after acquiring lock
|
||||
if _, err := os.Stat(wasiSdkRoot); err == nil {
|
||||
return wasiSdkRoot, nil
|
||||
}
|
||||
|
||||
err = downloadAndExtractArchive(wasiSdkUrl, dir, "WASI SDK")
|
||||
return wasiSdkRoot, err
|
||||
}
|
||||
|
||||
// checkDownloadAndExtractESPClang downloads and extracts ESP Clang binaries and libraries
|
||||
func checkDownloadAndExtractESPClang(platformSuffix, dir string) error {
|
||||
// Check if already exists
|
||||
if _, err := os.Stat(dir); err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create lock file path for the final destination
|
||||
lockPath := dir + ".lock"
|
||||
lockFile, err := acquireLock(lockPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to acquire lock: %w", err)
|
||||
}
|
||||
defer releaseLock(lockFile)
|
||||
|
||||
// Double-check after acquiring lock
|
||||
if _, err := os.Stat(dir); err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
clangUrl := fmt.Sprintf("%s/clang-esp-%s-%s.tar.xz", espClangBaseUrl, espClangVersion, platformSuffix)
|
||||
description := fmt.Sprintf("ESP Clang %s-%s", espClangVersion, platformSuffix)
|
||||
|
||||
// Use temporary extraction directory for ESP Clang special handling
|
||||
tempExtractDir := dir + ".extract"
|
||||
if err := downloadAndExtractArchive(clangUrl, tempExtractDir, description); err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tempExtractDir)
|
||||
|
||||
// ESP Clang needs special handling: move esp-clang subdirectory to final destination
|
||||
espClangDir := filepath.Join(tempExtractDir, "esp-clang")
|
||||
if err := os.Rename(espClangDir, dir); err != nil {
|
||||
return fmt.Errorf("failed to rename esp-clang directory: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// acquireLock creates and locks a file to prevent concurrent operations
|
||||
func acquireLock(lockPath string) (*os.File, error) {
|
||||
// Ensure the parent directory exists
|
||||
if err := os.MkdirAll(filepath.Dir(lockPath), 0755); err != nil {
|
||||
return nil, fmt.Errorf("failed to create lock directory: %w", err)
|
||||
}
|
||||
|
||||
lockFile, err := os.OpenFile(lockPath, os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create lock file: %w", err)
|
||||
}
|
||||
if err := syscall.Flock(int(lockFile.Fd()), syscall.LOCK_EX); err != nil {
|
||||
lockFile.Close()
|
||||
return nil, fmt.Errorf("failed to acquire lock: %w", err)
|
||||
}
|
||||
return lockFile, nil
|
||||
}
|
||||
|
||||
// releaseLock unlocks and removes the lock file
|
||||
func releaseLock(lockFile *os.File) error {
|
||||
if lockFile == nil {
|
||||
return nil
|
||||
}
|
||||
lockPath := lockFile.Name()
|
||||
syscall.Flock(int(lockFile.Fd()), syscall.LOCK_UN)
|
||||
lockFile.Close()
|
||||
os.Remove(lockPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
// downloadAndExtractArchive downloads and extracts an archive to the destination directory (without locking)
|
||||
func downloadAndExtractArchive(url, destDir, description string) error {
|
||||
fmt.Fprintf(os.Stderr, "Downloading %s...\n", description)
|
||||
|
||||
// Use temporary extraction directory
|
||||
tempDir := destDir + ".temp"
|
||||
os.RemoveAll(tempDir)
|
||||
if err := os.MkdirAll(tempDir, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create temporary directory: %w", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// Download the archive
|
||||
urlPath := strings.Split(url, "/")
|
||||
filename := urlPath[len(urlPath)-1]
|
||||
localFile := filepath.Join(tempDir, filename)
|
||||
if err = downloadFile(url, localFile); err != nil {
|
||||
return fmt.Errorf("failed to download file: %w", err)
|
||||
if err := downloadFile(url, localFile); err != nil {
|
||||
return fmt.Errorf("failed to download %s from %s: %w", description, url, err)
|
||||
}
|
||||
defer os.Remove(localFile)
|
||||
|
||||
// Extract the archive
|
||||
fmt.Fprintf(os.Stderr, "Extracting %s...\n", description)
|
||||
if strings.HasSuffix(filename, ".tar.gz") || strings.HasSuffix(filename, ".tgz") {
|
||||
err = extractTarGz(localFile, tempDir)
|
||||
err := extractTarGz(localFile, tempDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to extract %s archive: %w", description, err)
|
||||
}
|
||||
} else if strings.HasSuffix(filename, ".tar.xz") {
|
||||
err := extractTarXz(localFile, tempDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to extract %s archive: %w", description, err)
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("unsupported archive format: %s", filename)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to extract archive: %w", err)
|
||||
}
|
||||
if err = os.Rename(tempDir, dir); err != nil {
|
||||
|
||||
// Rename temp directory to target directory
|
||||
if err := os.Rename(tempDir, destDir); err != nil {
|
||||
return fmt.Errorf("failed to rename directory: %w", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "%s downloaded and extracted successfully.\n", description)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -107,3 +217,9 @@ func extractTarGz(tarGzFile, dest string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractTarXz(tarXzFile, dest string) error {
|
||||
// Use external tar command to extract .tar.xz files
|
||||
cmd := exec.Command("tar", "-xf", tarXzFile, "-C", dest)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
492
internal/crosscompile/fetch_test.go
Normal file
492
internal/crosscompile/fetch_test.go
Normal file
@@ -0,0 +1,492 @@
|
||||
//go:build !llgo
|
||||
// +build !llgo
|
||||
|
||||
package crosscompile
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Helper function to create a test tar.gz archive
|
||||
func createTestTarGz(t *testing.T, files map[string]string) string {
|
||||
tempFile, err := os.CreateTemp("", "test*.tar.gz")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp file: %v", err)
|
||||
}
|
||||
defer tempFile.Close()
|
||||
|
||||
gzw := gzip.NewWriter(tempFile)
|
||||
defer gzw.Close()
|
||||
|
||||
tw := tar.NewWriter(gzw)
|
||||
defer tw.Close()
|
||||
|
||||
for name, content := range files {
|
||||
hdr := &tar.Header{
|
||||
Name: name,
|
||||
Mode: 0644,
|
||||
Size: int64(len(content)),
|
||||
}
|
||||
if err := tw.WriteHeader(hdr); err != nil {
|
||||
t.Fatalf("Failed to write tar header: %v", err)
|
||||
}
|
||||
if _, err := tw.Write([]byte(content)); err != nil {
|
||||
t.Fatalf("Failed to write tar content: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return tempFile.Name()
|
||||
}
|
||||
|
||||
// Helper function to create a test HTTP server
|
||||
func createTestServer(t *testing.T, files map[string]string) *httptest.Server {
|
||||
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
path := strings.TrimPrefix(r.URL.Path, "/")
|
||||
if content, exists := files[path]; exists {
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
w.Write([]byte(content))
|
||||
} else {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
func TestAcquireAndReleaseLock(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
lockPath := filepath.Join(tempDir, "test.lock")
|
||||
|
||||
// Test acquiring lock
|
||||
lockFile, err := acquireLock(lockPath)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to acquire lock: %v", err)
|
||||
}
|
||||
|
||||
// Check lock file exists
|
||||
if _, err := os.Stat(lockPath); os.IsNotExist(err) {
|
||||
t.Error("Lock file should exist")
|
||||
}
|
||||
|
||||
// Test releasing lock
|
||||
if err := releaseLock(lockFile); err != nil {
|
||||
t.Errorf("Failed to release lock: %v", err)
|
||||
}
|
||||
|
||||
// Check lock file is removed
|
||||
if _, err := os.Stat(lockPath); !os.IsNotExist(err) {
|
||||
t.Error("Lock file should be removed after release")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAcquireLockConcurrency(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
lockPath := filepath.Join(tempDir, "concurrent.lock")
|
||||
|
||||
var wg sync.WaitGroup
|
||||
var results []int
|
||||
var resultsMu sync.Mutex
|
||||
|
||||
// Start multiple goroutines trying to acquire the same lock
|
||||
for i := 0; i < 5; i++ {
|
||||
wg.Add(1)
|
||||
go func(id int) {
|
||||
defer wg.Done()
|
||||
|
||||
lockFile, err := acquireLock(lockPath)
|
||||
if err != nil {
|
||||
t.Errorf("Goroutine %d failed to acquire lock: %v", id, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Hold the lock for a short time
|
||||
resultsMu.Lock()
|
||||
results = append(results, id)
|
||||
resultsMu.Unlock()
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
if err := releaseLock(lockFile); err != nil {
|
||||
t.Errorf("Goroutine %d failed to release lock: %v", id, err)
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
// All goroutines should have successfully acquired and released the lock
|
||||
if len(results) != 5 {
|
||||
t.Errorf("Expected 5 successful lock acquisitions, got %d", len(results))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDownloadFile(t *testing.T) {
|
||||
// Create test server
|
||||
testContent := "test file content"
|
||||
server := createTestServer(t, map[string]string{
|
||||
"test.txt": testContent,
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
tempDir := t.TempDir()
|
||||
targetFile := filepath.Join(tempDir, "downloaded.txt")
|
||||
|
||||
// Test successful download
|
||||
err := downloadFile(server.URL+"/test.txt", targetFile)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to download file: %v", err)
|
||||
}
|
||||
|
||||
// Check file content
|
||||
content, err := os.ReadFile(targetFile)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read downloaded file: %v", err)
|
||||
}
|
||||
|
||||
if string(content) != testContent {
|
||||
t.Errorf("Expected content %q, got %q", testContent, string(content))
|
||||
}
|
||||
|
||||
// Test download failure (404)
|
||||
err = downloadFile(server.URL+"/nonexistent.txt", targetFile)
|
||||
if err == nil {
|
||||
t.Error("Expected error for non-existent file, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractTarGz(t *testing.T) {
|
||||
// Create test archive
|
||||
files := map[string]string{
|
||||
"test-dir/file1.txt": "content of file1",
|
||||
"test-dir/file2.txt": "content of file2",
|
||||
"file3.txt": "content of file3",
|
||||
}
|
||||
|
||||
archivePath := createTestTarGz(t, files)
|
||||
defer os.Remove(archivePath)
|
||||
|
||||
// Extract to temp directory
|
||||
tempDir := t.TempDir()
|
||||
err := extractTarGz(archivePath, tempDir)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to extract tar.gz: %v", err)
|
||||
}
|
||||
|
||||
// Check extracted files
|
||||
for name, expectedContent := range files {
|
||||
filePath := filepath.Join(tempDir, name)
|
||||
content, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to read extracted file %s: %v", name, err)
|
||||
continue
|
||||
}
|
||||
if string(content) != expectedContent {
|
||||
t.Errorf("File %s: expected content %q, got %q", name, expectedContent, string(content))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractTarGzPathTraversal(t *testing.T) {
|
||||
// Create a malicious archive with path traversal
|
||||
tempFile, err := os.CreateTemp("", "malicious*.tar.gz")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp file: %v", err)
|
||||
}
|
||||
defer tempFile.Close()
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
gzw := gzip.NewWriter(tempFile)
|
||||
tw := tar.NewWriter(gzw)
|
||||
|
||||
// Add a file with path traversal attack
|
||||
hdr := &tar.Header{
|
||||
Name: "../../../etc/passwd",
|
||||
Mode: 0644,
|
||||
Size: 5,
|
||||
Typeflag: tar.TypeReg,
|
||||
}
|
||||
if err := tw.WriteHeader(hdr); err != nil {
|
||||
t.Fatalf("Failed to write tar header: %v", err)
|
||||
}
|
||||
if _, err := tw.Write([]byte("pwned")); err != nil {
|
||||
t.Fatalf("Failed to write tar content: %v", err)
|
||||
}
|
||||
|
||||
// Close writers to flush all data
|
||||
if err := tw.Close(); err != nil {
|
||||
t.Fatalf("Failed to close tar writer: %v", err)
|
||||
}
|
||||
if err := gzw.Close(); err != nil {
|
||||
t.Fatalf("Failed to close gzip writer: %v", err)
|
||||
}
|
||||
if err := tempFile.Close(); err != nil {
|
||||
t.Fatalf("Failed to close temp file: %v", err)
|
||||
}
|
||||
|
||||
tempDir := t.TempDir()
|
||||
err = extractTarGz(tempFile.Name(), tempDir)
|
||||
if err == nil {
|
||||
t.Error("Expected error for path traversal attack, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "illegal file path") {
|
||||
t.Errorf("Expected 'illegal file path' error, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDownloadAndExtractArchive(t *testing.T) {
|
||||
// Create test archive
|
||||
files := map[string]string{
|
||||
"test-app/bin/app": "#!/bin/bash\necho hello",
|
||||
"test-app/lib/lib.so": "fake library content",
|
||||
"test-app/README": "This is a test application",
|
||||
}
|
||||
|
||||
archivePath := createTestTarGz(t, files)
|
||||
defer os.Remove(archivePath)
|
||||
|
||||
// Create test server to serve the archive
|
||||
archiveContent, err := os.ReadFile(archivePath)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read test archive: %v", err)
|
||||
}
|
||||
|
||||
server := createTestServer(t, map[string]string{
|
||||
"test-app.tar.gz": string(archiveContent),
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
// Test download and extract
|
||||
tempDir := t.TempDir()
|
||||
destDir := filepath.Join(tempDir, "extracted")
|
||||
|
||||
err = downloadAndExtractArchive(server.URL+"/test-app.tar.gz", destDir, "Test App")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to download and extract: %v", err)
|
||||
}
|
||||
|
||||
// Check extracted files
|
||||
for name, expectedContent := range files {
|
||||
filePath := filepath.Join(destDir, name)
|
||||
content, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to read extracted file %s: %v", name, err)
|
||||
continue
|
||||
}
|
||||
if string(content) != expectedContent {
|
||||
t.Errorf("File %s: expected content %q, got %q", name, expectedContent, string(content))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDownloadAndExtractArchiveUnsupportedFormat(t *testing.T) {
|
||||
server := createTestServer(t, map[string]string{
|
||||
"test.zip": "fake zip content",
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
tempDir := t.TempDir()
|
||||
destDir := filepath.Join(tempDir, "extracted")
|
||||
|
||||
err := downloadAndExtractArchive(server.URL+"/test.zip", destDir, "Test Archive")
|
||||
if err == nil {
|
||||
t.Error("Expected error for unsupported format, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "unsupported archive format") {
|
||||
t.Errorf("Expected 'unsupported archive format' error, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Mock test for WASI SDK (without actual download)
|
||||
func TestWasiSDKExtractionLogic(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
// Create fake WASI SDK directory structure
|
||||
wasiSdkDir := filepath.Join(tempDir, wasiMacosSubdir)
|
||||
binDir := filepath.Join(wasiSdkDir, "bin")
|
||||
err := os.MkdirAll(binDir, 0755)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create fake WASI SDK structure: %v", err)
|
||||
}
|
||||
|
||||
// Create fake clang binary
|
||||
clangPath := filepath.Join(binDir, "clang")
|
||||
err = os.WriteFile(clangPath, []byte("fake clang"), 0755)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create fake clang: %v", err)
|
||||
}
|
||||
|
||||
// Test that function returns correct path for existing SDK
|
||||
sdkRoot, err := checkDownloadAndExtractWasiSDK(tempDir)
|
||||
if err != nil {
|
||||
t.Fatalf("checkDownloadAndExtractWasiSDK failed: %v", err)
|
||||
}
|
||||
|
||||
expectedRoot := filepath.Join(tempDir, wasiMacosSubdir)
|
||||
if sdkRoot != expectedRoot {
|
||||
t.Errorf("Expected SDK root %q, got %q", expectedRoot, sdkRoot)
|
||||
}
|
||||
}
|
||||
|
||||
// Test ESP Clang extraction logic with existing directory
|
||||
func TestESPClangExtractionLogic(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
espClangDir := filepath.Join(tempDir, "esp-clang")
|
||||
|
||||
// Create fake ESP Clang directory structure
|
||||
binDir := filepath.Join(espClangDir, "bin")
|
||||
err := os.MkdirAll(binDir, 0755)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create fake ESP Clang structure: %v", err)
|
||||
}
|
||||
|
||||
// Create fake clang binary
|
||||
clangPath := filepath.Join(binDir, "clang")
|
||||
err = os.WriteFile(clangPath, []byte("fake esp clang"), 0755)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create fake esp clang: %v", err)
|
||||
}
|
||||
|
||||
// Test that function skips download for existing directory
|
||||
err = checkDownloadAndExtractESPClang("linux", espClangDir)
|
||||
if err != nil {
|
||||
t.Fatalf("checkDownloadAndExtractESPClang failed: %v", err)
|
||||
}
|
||||
|
||||
// Check that the directory still exists and has the right content
|
||||
if _, err := os.Stat(clangPath); os.IsNotExist(err) {
|
||||
t.Error("ESP Clang binary should exist")
|
||||
}
|
||||
}
|
||||
|
||||
// Test WASI SDK download and extraction when directory doesn't exist
|
||||
func TestWasiSDKDownloadWhenNotExists(t *testing.T) {
|
||||
// Create fake WASI SDK archive with proper structure
|
||||
files := map[string]string{
|
||||
"wasi-sdk-25.0-x86_64-macos/bin/clang": "fake wasi clang binary",
|
||||
"wasi-sdk-25.0-x86_64-macos/lib/libm.a": "fake math library",
|
||||
"wasi-sdk-25.0-x86_64-macos/include/stdio.h": "#include <stdio.h>",
|
||||
}
|
||||
|
||||
archivePath := createTestTarGz(t, files)
|
||||
defer os.Remove(archivePath)
|
||||
|
||||
// Create test server to serve the archive
|
||||
archiveContent, err := os.ReadFile(archivePath)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read test archive: %v", err)
|
||||
}
|
||||
|
||||
server := createTestServer(t, map[string]string{
|
||||
"wasi-sdk-25.0-x86_64-macos.tar.gz": string(archiveContent),
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
// Override cacheRoot to use a temporary directory
|
||||
tempCacheRoot := t.TempDir()
|
||||
originalCacheRoot := cacheRoot
|
||||
cacheRoot = func() string { return tempCacheRoot }
|
||||
defer func() { cacheRoot = originalCacheRoot }()
|
||||
|
||||
// Override wasiSdkUrl to use our test server
|
||||
originalWasiSdkUrl := wasiSdkUrl
|
||||
wasiSdkUrl = server.URL + "/wasi-sdk-25.0-x86_64-macos.tar.gz"
|
||||
defer func() { wasiSdkUrl = originalWasiSdkUrl }()
|
||||
|
||||
// Use the cache directory structure
|
||||
extractDir := filepath.Join(tempCacheRoot, "crosscompile", "wasi")
|
||||
|
||||
// Test download and extract when directory doesn't exist
|
||||
sdkRoot, err := checkDownloadAndExtractWasiSDK(extractDir)
|
||||
if err != nil {
|
||||
t.Fatalf("checkDownloadAndExtractWasiSDK failed: %v", err)
|
||||
}
|
||||
|
||||
expectedRoot := filepath.Join(extractDir, wasiMacosSubdir)
|
||||
if sdkRoot != expectedRoot {
|
||||
t.Errorf("Expected SDK root %q, got %q", expectedRoot, sdkRoot)
|
||||
}
|
||||
|
||||
// Check that files were extracted correctly
|
||||
for name, expectedContent := range files {
|
||||
filePath := filepath.Join(extractDir, name)
|
||||
content, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to read extracted file %s: %v", name, err)
|
||||
continue
|
||||
}
|
||||
if string(content) != expectedContent {
|
||||
t.Errorf("File %s: expected content %q, got %q", name, expectedContent, string(content))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test ESP Clang download and extraction when directory doesn't exist
|
||||
func TestESPClangDownloadWhenNotExists(t *testing.T) {
|
||||
// Create fake ESP Clang archive with proper structure
|
||||
files := map[string]string{
|
||||
"esp-clang/bin/clang": "fake esp clang binary",
|
||||
"esp-clang/lib/libc.a": "fake c library",
|
||||
"esp-clang/include/esp32.h": "#define ESP32 1",
|
||||
}
|
||||
|
||||
archivePath := createTestTarGz(t, files)
|
||||
defer os.Remove(archivePath)
|
||||
|
||||
// Read the archive content
|
||||
archiveContent, err := os.ReadFile(archivePath)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read test archive: %v", err)
|
||||
}
|
||||
|
||||
server := createTestServer(t, map[string]string{
|
||||
"clang-esp-19.1.2_20250820-linux.tar.xz": string(archiveContent),
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
// Override cacheRoot to use a temporary directory
|
||||
tempCacheRoot := t.TempDir()
|
||||
originalCacheRoot := cacheRoot
|
||||
cacheRoot = func() string { return tempCacheRoot }
|
||||
defer func() { cacheRoot = originalCacheRoot }()
|
||||
|
||||
// Override espClangBaseUrl to use our test server
|
||||
originalEspClangBaseUrl := espClangBaseUrl
|
||||
espClangBaseUrl = server.URL
|
||||
defer func() { espClangBaseUrl = originalEspClangBaseUrl }()
|
||||
|
||||
// Use a fresh temp directory that doesn't have ESP Clang
|
||||
espClangDir := filepath.Join(tempCacheRoot, "esp-clang-test")
|
||||
|
||||
// Test download and extract when directory doesn't exist
|
||||
err = checkDownloadAndExtractESPClang("linux", espClangDir)
|
||||
if err != nil {
|
||||
t.Fatalf("checkDownloadAndExtractESPClang failed: %v", err)
|
||||
}
|
||||
|
||||
// Check that the target directory exists
|
||||
if _, err := os.Stat(espClangDir); os.IsNotExist(err) {
|
||||
t.Error("ESP Clang directory should exist after extraction")
|
||||
}
|
||||
|
||||
// Check that files were extracted correctly to the final destination
|
||||
for name, expectedContent := range files {
|
||||
// Remove "esp-clang/" prefix since it gets moved to the final destination
|
||||
relativePath := strings.TrimPrefix(name, "esp-clang/")
|
||||
filePath := filepath.Join(espClangDir, relativePath)
|
||||
content, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to read extracted file %s: %v", relativePath, err)
|
||||
continue
|
||||
}
|
||||
if string(content) != expectedContent {
|
||||
t.Errorf("File %s: expected content %q, got %q", relativePath, expectedContent, string(content))
|
||||
}
|
||||
}
|
||||
}
|
||||
188
internal/firmware/esp.go
Normal file
188
internal/firmware/esp.go
Normal file
@@ -0,0 +1,188 @@
|
||||
// From tinygo/builder/esp.go
|
||||
|
||||
package firmware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"debug/elf"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type espImageSegment struct {
|
||||
addr uint32
|
||||
data []byte
|
||||
}
|
||||
|
||||
// makeESPFirmareImage converts an input ELF file to an image file for an ESP32 or
|
||||
// ESP8266 chip. This is a special purpose image format just for the ESP chip
|
||||
// family, and is parsed by the on-chip mask ROM bootloader.
|
||||
//
|
||||
// The following documentation has been used:
|
||||
// https://github.com/espressif/esptool/wiki/Firmware-Image-Format
|
||||
// https://github.com/espressif/esp-idf/blob/8fbb63c2a701c22ccf4ce249f43aded73e134a34/components/bootloader_support/include/esp_image_format.h#L58
|
||||
// https://github.com/espressif/esptool/blob/master/esptool.py
|
||||
func makeESPFirmareImage(infile, outfile, format string) error {
|
||||
inf, err := elf.Open(infile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer inf.Close()
|
||||
|
||||
// Load all segments to be written to the image. These are actually ELF
|
||||
// sections, not true ELF segments (similar to how esptool does it).
|
||||
var segments []*espImageSegment
|
||||
for _, section := range inf.Sections {
|
||||
if section.Type != elf.SHT_PROGBITS || section.Size == 0 || section.Flags&elf.SHF_ALLOC == 0 {
|
||||
continue
|
||||
}
|
||||
data, err := section.Data()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read section data: %w", err)
|
||||
}
|
||||
for len(data)%4 != 0 {
|
||||
// Align segment to 4 bytes.
|
||||
data = append(data, 0)
|
||||
}
|
||||
if uint64(uint32(section.Addr)) != section.Addr {
|
||||
return fmt.Errorf("section address too big: 0x%x", section.Addr)
|
||||
}
|
||||
segments = append(segments, &espImageSegment{
|
||||
addr: uint32(section.Addr),
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
|
||||
// Sort the segments by address. This is what esptool does too.
|
||||
sort.SliceStable(segments, func(i, j int) bool { return segments[i].addr < segments[j].addr })
|
||||
|
||||
// Calculate checksum over the segment data. This is used in the image
|
||||
// footer.
|
||||
checksum := uint8(0xef)
|
||||
for _, segment := range segments {
|
||||
for _, b := range segment.data {
|
||||
checksum ^= b
|
||||
}
|
||||
}
|
||||
|
||||
// Write first to an in-memory buffer, primarily so that we can easily
|
||||
// calculate a hash over the entire image.
|
||||
// An added benefit is that we don't need to check for errors all the time.
|
||||
outf := &bytes.Buffer{}
|
||||
|
||||
// Separate esp32 and esp32-img. The -img suffix indicates we should make an
|
||||
// image, not just a binary to be flashed at 0x1000 for example.
|
||||
chip := format
|
||||
makeImage := false
|
||||
if strings.HasSuffix(format, "-img") {
|
||||
makeImage = true
|
||||
chip = format[:len(format)-len("-img")]
|
||||
}
|
||||
|
||||
if makeImage {
|
||||
// The bootloader starts at 0x1000, or 4096.
|
||||
// TinyGo doesn't use a separate bootloader and runs the entire
|
||||
// application in the bootloader location.
|
||||
outf.Write(make([]byte, 4096))
|
||||
}
|
||||
|
||||
// Chip IDs. Source:
|
||||
// https://github.com/espressif/esp-idf/blob/v4.3/components/bootloader_support/include/esp_app_format.h#L22
|
||||
chip_id := map[string]uint16{
|
||||
"esp32": 0x0000,
|
||||
"esp32c3": 0x0005,
|
||||
}[chip]
|
||||
|
||||
// Image header.
|
||||
switch chip {
|
||||
case "esp32", "esp32c3":
|
||||
// Header format:
|
||||
// https://github.com/espressif/esp-idf/blob/v4.3/components/bootloader_support/include/esp_app_format.h#L71
|
||||
// Note: not adding a SHA256 hash as the binary is modified by
|
||||
// esptool.py while flashing and therefore the hash won't be valid
|
||||
// anymore.
|
||||
binary.Write(outf, binary.LittleEndian, struct {
|
||||
magic uint8
|
||||
segment_count uint8
|
||||
spi_mode uint8
|
||||
spi_speed_size uint8
|
||||
entry_addr uint32
|
||||
wp_pin uint8
|
||||
spi_pin_drv [3]uint8
|
||||
chip_id uint16
|
||||
min_chip_rev uint8
|
||||
reserved [8]uint8
|
||||
hash_appended bool
|
||||
}{
|
||||
magic: 0xE9,
|
||||
segment_count: byte(len(segments)),
|
||||
spi_mode: 2, // ESP_IMAGE_SPI_MODE_DIO
|
||||
spi_speed_size: 0x1f, // ESP_IMAGE_SPI_SPEED_80M, ESP_IMAGE_FLASH_SIZE_2MB
|
||||
entry_addr: uint32(inf.Entry),
|
||||
wp_pin: 0xEE, // disable WP pin
|
||||
chip_id: chip_id,
|
||||
hash_appended: true, // add a SHA256 hash
|
||||
})
|
||||
case "esp8266":
|
||||
// Header format:
|
||||
// https://github.com/espressif/esptool/wiki/Firmware-Image-Format
|
||||
// Basically a truncated version of the ESP32 header.
|
||||
binary.Write(outf, binary.LittleEndian, struct {
|
||||
magic uint8
|
||||
segment_count uint8
|
||||
spi_mode uint8
|
||||
spi_speed_size uint8
|
||||
entry_addr uint32
|
||||
}{
|
||||
magic: 0xE9,
|
||||
segment_count: byte(len(segments)),
|
||||
spi_mode: 0, // irrelevant, replaced by esptool when flashing
|
||||
spi_speed_size: 0x20, // spi_speed, spi_size: replaced by esptool when flashing
|
||||
entry_addr: uint32(inf.Entry),
|
||||
})
|
||||
default:
|
||||
return fmt.Errorf("builder: unknown binary format %#v, expected esp32 or esp8266", format)
|
||||
}
|
||||
|
||||
// Write all segments to the image.
|
||||
// https://github.com/espressif/esptool/wiki/Firmware-Image-Format#segment
|
||||
for _, segment := range segments {
|
||||
binary.Write(outf, binary.LittleEndian, struct {
|
||||
addr uint32
|
||||
length uint32
|
||||
}{
|
||||
addr: segment.addr,
|
||||
length: uint32(len(segment.data)),
|
||||
})
|
||||
outf.Write(segment.data)
|
||||
}
|
||||
|
||||
// Footer, including checksum.
|
||||
// The entire image size must be a multiple of 16, so pad the image to one
|
||||
// byte less than that before writing the checksum.
|
||||
outf.Write(make([]byte, 15-outf.Len()%16))
|
||||
outf.WriteByte(checksum)
|
||||
|
||||
if chip != "esp8266" {
|
||||
// SHA256 hash (to protect against image corruption, not for security).
|
||||
hash := sha256.Sum256(outf.Bytes())
|
||||
outf.Write(hash[:])
|
||||
}
|
||||
|
||||
// QEMU (or more precisely, qemu-system-xtensa from Espressif) expects the
|
||||
// image to be a certain size.
|
||||
if makeImage {
|
||||
// Use a default image size of 4MB.
|
||||
grow := 4096*1024 - outf.Len()
|
||||
if grow > 0 {
|
||||
outf.Write(make([]byte, grow))
|
||||
}
|
||||
}
|
||||
|
||||
// Write the image to the output file.
|
||||
return os.WriteFile(outfile, outf.Bytes(), 0666)
|
||||
}
|
||||
16
internal/firmware/ext.go
Normal file
16
internal/firmware/ext.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package firmware
|
||||
|
||||
import "strings"
|
||||
|
||||
// BinaryExt returns the binary file extension based on the binary format
|
||||
// Returns ".bin" for ESP-based formats, "" for others
|
||||
func BinaryExt(binaryFormat string) string {
|
||||
if strings.HasPrefix(binaryFormat, "esp") {
|
||||
return ".bin"
|
||||
} else if strings.HasPrefix(binaryFormat, "uf2") {
|
||||
return ".uf2"
|
||||
} else if strings.HasPrefix(binaryFormat, "nrf-dfu") {
|
||||
return ".zip"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
31
internal/firmware/ext_test.go
Normal file
31
internal/firmware/ext_test.go
Normal file
@@ -0,0 +1,31 @@
|
||||
//go:build !llgo
|
||||
// +build !llgo
|
||||
|
||||
package firmware
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestBinaryExt(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
binaryFormat string
|
||||
expected string
|
||||
}{
|
||||
{"ESP32", "esp32", ".bin"},
|
||||
{"ESP8266", "esp8266", ".bin"},
|
||||
{"ESP32C3", "esp32c3", ".bin"},
|
||||
{"UF2", "uf2", ".uf2"},
|
||||
{"ELF", "elf", ""},
|
||||
{"Empty", "", ""},
|
||||
{"NRF-DFU", "nrf-dfu", ".zip"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := BinaryExt(tt.binaryFormat)
|
||||
if result != tt.expected {
|
||||
t.Errorf("BinaryExt() = %q, want %q", result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
19
internal/firmware/firmware.go
Normal file
19
internal/firmware/firmware.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package firmware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MakeFirmwareImage creates a firmware image from the given input file.
|
||||
func MakeFirmwareImage(infile, outfile, format, fmtDetail string) error {
|
||||
if strings.HasPrefix(format, "esp") {
|
||||
return makeESPFirmareImage(infile, outfile, format)
|
||||
} else if format == "uf2" {
|
||||
uf2Family := fmtDetail
|
||||
return convertELFFileToUF2File(infile, outfile, uf2Family)
|
||||
} else if format == "nrf-dfu" {
|
||||
return makeDFUFirmwareImage(infile, outfile)
|
||||
}
|
||||
return fmt.Errorf("unsupported firmware format: %s", format)
|
||||
}
|
||||
118
internal/firmware/nrfutil.go
Normal file
118
internal/firmware/nrfutil.go
Normal file
@@ -0,0 +1,118 @@
|
||||
// From tinygo/builder/nrfutil.go
|
||||
|
||||
package firmware
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"github.com/sigurn/crc16"
|
||||
)
|
||||
|
||||
// Structure of the manifest.json file.
|
||||
type jsonManifest struct {
|
||||
Manifest struct {
|
||||
Application struct {
|
||||
BinaryFile string `json:"bin_file"`
|
||||
DataFile string `json:"dat_file"`
|
||||
InitPacketData nrfInitPacket `json:"init_packet_data"`
|
||||
} `json:"application"`
|
||||
DFUVersion float64 `json:"dfu_version"` // yes, this is a JSON number, not a string
|
||||
} `json:"manifest"`
|
||||
}
|
||||
|
||||
// Structure of the init packet.
|
||||
// Source:
|
||||
// https://github.com/adafruit/Adafruit_nRF52_Bootloader/blob/master/lib/sdk11/components/libraries/bootloader_dfu/dfu_init.h#L47-L57
|
||||
type nrfInitPacket struct {
|
||||
ApplicationVersion uint32 `json:"application_version"`
|
||||
DeviceRevision uint16 `json:"device_revision"`
|
||||
DeviceType uint16 `json:"device_type"`
|
||||
FirmwareCRC16 uint16 `json:"firmware_crc16"`
|
||||
SoftDeviceRequired []uint16 `json:"softdevice_req"` // this is actually a variable length array
|
||||
}
|
||||
|
||||
// Create the init packet (the contents of application.dat).
|
||||
func (p nrfInitPacket) createInitPacket() []byte {
|
||||
buf := &bytes.Buffer{}
|
||||
binary.Write(buf, binary.LittleEndian, p.DeviceType) // uint16_t device_type;
|
||||
binary.Write(buf, binary.LittleEndian, p.DeviceRevision) // uint16_t device_rev;
|
||||
binary.Write(buf, binary.LittleEndian, p.ApplicationVersion) // uint32_t app_version;
|
||||
binary.Write(buf, binary.LittleEndian, uint16(len(p.SoftDeviceRequired))) // uint16_t softdevice_len;
|
||||
binary.Write(buf, binary.LittleEndian, p.SoftDeviceRequired) // uint16_t softdevice[1];
|
||||
binary.Write(buf, binary.LittleEndian, p.FirmwareCRC16)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// Make a Nordic DFU firmware image from an ELF file.
|
||||
func makeDFUFirmwareImage(infile, outfile string) error {
|
||||
// Read ELF file as input and convert it to a binary image file.
|
||||
_, data, err := extractROM(infile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the zip file in memory.
|
||||
// It won't be very large anyway.
|
||||
buf := &bytes.Buffer{}
|
||||
w := zip.NewWriter(buf)
|
||||
|
||||
// Write the application binary to the zip file.
|
||||
binw, err := w.Create("application.bin")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = binw.Write(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the init packet.
|
||||
initPacket := nrfInitPacket{
|
||||
ApplicationVersion: 0xffff_ffff, // appears to be unused by the Adafruit bootloader
|
||||
DeviceRevision: 0xffff, // DFU_DEVICE_REVISION_EMPTY
|
||||
DeviceType: 0x0052, // ADAFRUIT_DEVICE_TYPE
|
||||
FirmwareCRC16: crc16.Checksum(data, crc16.MakeTable(crc16.CRC16_CCITT_FALSE)),
|
||||
SoftDeviceRequired: []uint16{0xfffe}, // DFU_SOFTDEVICE_ANY
|
||||
}
|
||||
|
||||
// Write the init packet to the zip file.
|
||||
datw, err := w.Create("application.dat")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = datw.Write(initPacket.createInitPacket())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the JSON manifest.
|
||||
manifest := &jsonManifest{}
|
||||
manifest.Manifest.Application.BinaryFile = "application.bin"
|
||||
manifest.Manifest.Application.DataFile = "application.dat"
|
||||
manifest.Manifest.Application.InitPacketData = initPacket
|
||||
manifest.Manifest.DFUVersion = 0.5
|
||||
|
||||
// Write the JSON manifest to the file.
|
||||
jsonw, err := w.Create("manifest.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
enc := json.NewEncoder(jsonw)
|
||||
enc.SetIndent("", " ")
|
||||
err = enc.Encode(manifest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Finish the zip file.
|
||||
err = w.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.WriteFile(outfile, buf.Bytes(), 0o666)
|
||||
}
|
||||
133
internal/firmware/objcopy.go
Normal file
133
internal/firmware/objcopy.go
Normal file
@@ -0,0 +1,133 @@
|
||||
// From tinygo/builder/objcopy.go
|
||||
|
||||
package firmware
|
||||
|
||||
import (
|
||||
"debug/elf"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// maxPadBytes is the maximum allowed bytes to be padded in a rom extraction
|
||||
// this value is currently defined by Nintendo Switch Page Alignment (4096 bytes)
|
||||
const maxPadBytes = 4095
|
||||
|
||||
// objcopyError is an error returned by functions that act like objcopy.
|
||||
type objcopyError struct {
|
||||
Op string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e objcopyError) Error() string {
|
||||
if e.Err == nil {
|
||||
return e.Op
|
||||
}
|
||||
return e.Op + ": " + e.Err.Error()
|
||||
}
|
||||
|
||||
type progSlice []*elf.Prog
|
||||
|
||||
func (s progSlice) Len() int { return len(s) }
|
||||
func (s progSlice) Less(i, j int) bool { return s[i].Paddr < s[j].Paddr }
|
||||
func (s progSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// extractROM extracts a firmware image and the first load address from the
|
||||
// given ELF file. It tries to emulate the behavior of objcopy.
|
||||
func extractROM(path string) (uint64, []byte, error) {
|
||||
f, err := elf.Open(path)
|
||||
if err != nil {
|
||||
return 0, nil, objcopyError{"failed to open ELF file to extract text segment", err}
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// The GNU objcopy command does the following for firmware extraction (from
|
||||
// the man page):
|
||||
// > When objcopy generates a raw binary file, it will essentially produce a
|
||||
// > memory dump of the contents of the input object file. All symbols and
|
||||
// > relocation information will be discarded. The memory dump will start at
|
||||
// > the load address of the lowest section copied into the output file.
|
||||
|
||||
// Find the lowest section address.
|
||||
startAddr := ^uint64(0)
|
||||
for _, section := range f.Sections {
|
||||
if section.Type != elf.SHT_PROGBITS || section.Flags&elf.SHF_ALLOC == 0 {
|
||||
continue
|
||||
}
|
||||
if section.Addr < startAddr {
|
||||
startAddr = section.Addr
|
||||
}
|
||||
}
|
||||
|
||||
progs := make(progSlice, 0, 2)
|
||||
for _, prog := range f.Progs {
|
||||
if prog.Type != elf.PT_LOAD || prog.Filesz == 0 || prog.Off == 0 {
|
||||
continue
|
||||
}
|
||||
progs = append(progs, prog)
|
||||
}
|
||||
if len(progs) == 0 {
|
||||
return 0, nil, objcopyError{"file does not contain ROM segments: " + path, nil}
|
||||
}
|
||||
sort.Sort(progs)
|
||||
|
||||
var rom []byte
|
||||
for _, prog := range progs {
|
||||
romEnd := progs[0].Paddr + uint64(len(rom))
|
||||
if prog.Paddr > romEnd && prog.Paddr < romEnd+16 {
|
||||
// Sometimes, the linker seems to insert a bit of padding between
|
||||
// segments. Simply zero-fill these parts.
|
||||
rom = append(rom, make([]byte, prog.Paddr-romEnd)...)
|
||||
}
|
||||
if prog.Paddr != progs[0].Paddr+uint64(len(rom)) {
|
||||
diff := prog.Paddr - (progs[0].Paddr + uint64(len(rom)))
|
||||
if diff > maxPadBytes {
|
||||
return 0, nil, objcopyError{"ROM segments are non-contiguous: " + path, nil}
|
||||
}
|
||||
// Pad the difference
|
||||
rom = append(rom, make([]byte, diff)...)
|
||||
}
|
||||
data, err := io.ReadAll(prog.Open())
|
||||
if err != nil {
|
||||
return 0, nil, objcopyError{"failed to extract segment from ELF file: " + path, err}
|
||||
}
|
||||
rom = append(rom, data...)
|
||||
}
|
||||
if progs[0].Paddr < startAddr {
|
||||
// The lowest memory address is before the first section. This means
|
||||
// that there is some extra data loaded at the start of the image that
|
||||
// should be discarded.
|
||||
// Example: ELF files where .text doesn't start at address 0 because
|
||||
// there is a bootloader at the start.
|
||||
return startAddr, rom[startAddr-progs[0].Paddr:], nil
|
||||
} else {
|
||||
return progs[0].Paddr, rom, nil
|
||||
}
|
||||
}
|
||||
|
||||
// objcopy converts an ELF file to a different (simpler) output file format:
|
||||
// .bin or .hex. It extracts only the .text section.
|
||||
func objcopy(infile, outfile, binaryFormat string) error {
|
||||
f, err := os.OpenFile(outfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Read the .text segment.
|
||||
_, data, err := extractROM(infile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write to the file, in the correct format.
|
||||
switch binaryFormat {
|
||||
case "bin":
|
||||
// The start address is not stored in raw firmware files (therefore you
|
||||
// should use .hex files in most cases).
|
||||
_, err := f.Write(data)
|
||||
return err
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
155
internal/firmware/uf2.go
Normal file
155
internal/firmware/uf2.go
Normal file
@@ -0,0 +1,155 @@
|
||||
// From tinygo/builder/uf2.go
|
||||
|
||||
package firmware
|
||||
|
||||
// This file converts firmware files from BIN to UF2 format before flashing.
|
||||
//
|
||||
// For more information about the UF2 firmware file format, please see:
|
||||
// https://github.com/Microsoft/uf2
|
||||
//
|
||||
//
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// convertELFFileToUF2File converts an ELF file to a UF2 file.
|
||||
func convertELFFileToUF2File(infile, outfile string, uf2FamilyID string) error {
|
||||
// Read the .text segment.
|
||||
targetAddress, data, err := extractROM(infile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
output, _, err := convertBinToUF2(data, uint32(targetAddress), uf2FamilyID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(outfile, output, 0644)
|
||||
}
|
||||
|
||||
// convertBinToUF2 converts the binary bytes in input to UF2 formatted data.
|
||||
func convertBinToUF2(input []byte, targetAddr uint32, uf2FamilyID string) ([]byte, int, error) {
|
||||
blocks := split(input, 256)
|
||||
output := make([]byte, 0)
|
||||
|
||||
bl, err := newUF2Block(targetAddr, uf2FamilyID)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
bl.SetNumBlocks(len(blocks))
|
||||
|
||||
for i := 0; i < len(blocks); i++ {
|
||||
bl.SetBlockNo(i)
|
||||
bl.SetData(blocks[i])
|
||||
|
||||
output = append(output, bl.Bytes()...)
|
||||
bl.IncrementAddress(bl.payloadSize)
|
||||
}
|
||||
|
||||
return output, len(blocks), nil
|
||||
}
|
||||
|
||||
const (
|
||||
uf2MagicStart0 = 0x0A324655 // "UF2\n"
|
||||
uf2MagicStart1 = 0x9E5D5157 // Randomly selected
|
||||
uf2MagicEnd = 0x0AB16F30 // Ditto
|
||||
)
|
||||
|
||||
// uf2Block is the structure used for each UF2 code block sent to device.
|
||||
type uf2Block struct {
|
||||
magicStart0 uint32
|
||||
magicStart1 uint32
|
||||
flags uint32
|
||||
targetAddr uint32
|
||||
payloadSize uint32
|
||||
blockNo uint32
|
||||
numBlocks uint32
|
||||
familyID uint32
|
||||
data []uint8
|
||||
magicEnd uint32
|
||||
}
|
||||
|
||||
// newUF2Block returns a new uf2Block struct that has been correctly populated
|
||||
func newUF2Block(targetAddr uint32, uf2FamilyID string) (*uf2Block, error) {
|
||||
var flags uint32
|
||||
var familyID uint32
|
||||
if uf2FamilyID != "" {
|
||||
flags |= flagFamilyIDPresent
|
||||
v, err := strconv.ParseUint(uf2FamilyID, 0, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
familyID = uint32(v)
|
||||
}
|
||||
return &uf2Block{magicStart0: uf2MagicStart0,
|
||||
magicStart1: uf2MagicStart1,
|
||||
magicEnd: uf2MagicEnd,
|
||||
targetAddr: targetAddr,
|
||||
flags: flags,
|
||||
familyID: familyID,
|
||||
payloadSize: 256,
|
||||
data: make([]byte, 476),
|
||||
}, nil
|
||||
}
|
||||
|
||||
const (
|
||||
flagFamilyIDPresent = 0x00002000
|
||||
)
|
||||
|
||||
// Bytes converts the uf2Block to a slice of bytes that can be written to file.
|
||||
func (b *uf2Block) Bytes() []byte {
|
||||
buf := bytes.NewBuffer(make([]byte, 0, 512))
|
||||
binary.Write(buf, binary.LittleEndian, b.magicStart0)
|
||||
binary.Write(buf, binary.LittleEndian, b.magicStart1)
|
||||
binary.Write(buf, binary.LittleEndian, b.flags)
|
||||
binary.Write(buf, binary.LittleEndian, b.targetAddr)
|
||||
binary.Write(buf, binary.LittleEndian, b.payloadSize)
|
||||
binary.Write(buf, binary.LittleEndian, b.blockNo)
|
||||
binary.Write(buf, binary.LittleEndian, b.numBlocks)
|
||||
binary.Write(buf, binary.LittleEndian, b.familyID)
|
||||
binary.Write(buf, binary.LittleEndian, b.data)
|
||||
binary.Write(buf, binary.LittleEndian, b.magicEnd)
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// IncrementAddress moves the target address pointer forward by count bytes.
|
||||
func (b *uf2Block) IncrementAddress(count uint32) {
|
||||
b.targetAddr += b.payloadSize
|
||||
}
|
||||
|
||||
// SetData sets the data to be used for the current block.
|
||||
func (b *uf2Block) SetData(d []byte) {
|
||||
b.data = make([]byte, 476)
|
||||
copy(b.data[:], d)
|
||||
}
|
||||
|
||||
// SetBlockNo sets the current block number to be used.
|
||||
func (b *uf2Block) SetBlockNo(bn int) {
|
||||
b.blockNo = uint32(bn)
|
||||
}
|
||||
|
||||
// SetNumBlocks sets the total number of blocks for this UF2 file.
|
||||
func (b *uf2Block) SetNumBlocks(total int) {
|
||||
b.numBlocks = uint32(total)
|
||||
}
|
||||
|
||||
// split splits a slice of bytes into a slice of byte slices of a specific size limit.
|
||||
func split(input []byte, limit int) [][]byte {
|
||||
var block []byte
|
||||
output := make([][]byte, 0, len(input)/limit+1)
|
||||
for len(input) >= limit {
|
||||
// add all blocks
|
||||
block, input = input[:limit], input[limit:]
|
||||
output = append(output, block)
|
||||
}
|
||||
if len(input) > 0 {
|
||||
// add remaining block (that isn't full sized)
|
||||
output = append(output, input)
|
||||
}
|
||||
return output
|
||||
}
|
||||
@@ -17,8 +17,41 @@ type Config struct {
|
||||
|
||||
// Compiler and linker configuration
|
||||
Linker string `json:"linker"`
|
||||
LinkerScript string `json:"linkerscript"`
|
||||
CFlags []string `json:"cflags"`
|
||||
LDFlags []string `json:"ldflags"`
|
||||
ExtraFiles []string `json:"extra-files"`
|
||||
|
||||
// Code generation configuration
|
||||
CodeModel string `json:"code-model"`
|
||||
TargetABI string `json:"target-abi"`
|
||||
RelocationModel string `json:"relocation-model"`
|
||||
|
||||
// Binary and firmware configuration
|
||||
BinaryFormat string `json:"binary-format"`
|
||||
// UF2 configuration
|
||||
UF2FamilyID string `json:"uf2-family-id"`
|
||||
|
||||
// Flash and deployment configuration
|
||||
FlashCommand string `json:"flash-command"`
|
||||
FlashMethod string `json:"flash-method"`
|
||||
Flash1200BpsReset string `json:"flash-1200-bps-reset"`
|
||||
|
||||
// Mass storage device configuration
|
||||
MSDVolumeName []string `json:"msd-volume-name"`
|
||||
MSDFirmwareName string `json:"msd-firmware-name"`
|
||||
|
||||
// Device-specific configuration
|
||||
RP2040BootPatch bool `json:"rp2040-boot-patch"`
|
||||
|
||||
// Debug and emulation configuration
|
||||
Emulator string `json:"emulator"`
|
||||
GDB []string `json:"gdb"`
|
||||
|
||||
// OpenOCD configuration
|
||||
OpenOCDInterface string `json:"openocd-interface"`
|
||||
OpenOCDTransport string `json:"openocd-transport"`
|
||||
OpenOCDTarget string `json:"openocd-target"`
|
||||
}
|
||||
|
||||
// RawConfig represents the raw JSON configuration before inheritance resolution
|
||||
@@ -32,6 +65,13 @@ func (c *Config) IsEmpty() bool {
|
||||
return c.Name == "" && c.LLVMTarget == "" && c.GOOS == "" && c.GOARCH == ""
|
||||
}
|
||||
|
||||
func (c *Config) FormatDetail() string {
|
||||
if c.BinaryFormat == "uf2" {
|
||||
return c.UF2FamilyID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// HasInheritance returns true if this config inherits from other configs
|
||||
func (rc *RawConfig) HasInheritance() bool {
|
||||
return len(rc.Inherits) > 0
|
||||
|
||||
@@ -137,6 +137,51 @@ func (l *Loader) mergeConfig(dst, src *Config) {
|
||||
if src.Linker != "" {
|
||||
dst.Linker = src.Linker
|
||||
}
|
||||
if src.LinkerScript != "" {
|
||||
dst.LinkerScript = src.LinkerScript
|
||||
}
|
||||
if src.CodeModel != "" {
|
||||
dst.CodeModel = src.CodeModel
|
||||
}
|
||||
if src.TargetABI != "" {
|
||||
dst.TargetABI = src.TargetABI
|
||||
}
|
||||
if src.RelocationModel != "" {
|
||||
dst.RelocationModel = src.RelocationModel
|
||||
}
|
||||
if src.BinaryFormat != "" {
|
||||
dst.BinaryFormat = src.BinaryFormat
|
||||
}
|
||||
if src.FlashCommand != "" {
|
||||
dst.FlashCommand = src.FlashCommand
|
||||
}
|
||||
if src.FlashMethod != "" {
|
||||
dst.FlashMethod = src.FlashMethod
|
||||
}
|
||||
if src.Flash1200BpsReset != "" {
|
||||
dst.Flash1200BpsReset = src.Flash1200BpsReset
|
||||
}
|
||||
if src.MSDFirmwareName != "" {
|
||||
dst.MSDFirmwareName = src.MSDFirmwareName
|
||||
}
|
||||
if src.UF2FamilyID != "" {
|
||||
dst.UF2FamilyID = src.UF2FamilyID
|
||||
}
|
||||
if src.RP2040BootPatch {
|
||||
dst.RP2040BootPatch = src.RP2040BootPatch
|
||||
}
|
||||
if src.Emulator != "" {
|
||||
dst.Emulator = src.Emulator
|
||||
}
|
||||
if src.OpenOCDInterface != "" {
|
||||
dst.OpenOCDInterface = src.OpenOCDInterface
|
||||
}
|
||||
if src.OpenOCDTransport != "" {
|
||||
dst.OpenOCDTransport = src.OpenOCDTransport
|
||||
}
|
||||
if src.OpenOCDTarget != "" {
|
||||
dst.OpenOCDTarget = src.OpenOCDTarget
|
||||
}
|
||||
|
||||
// Merge slices (append, don't replace)
|
||||
if len(src.BuildTags) > 0 {
|
||||
@@ -148,6 +193,15 @@ func (l *Loader) mergeConfig(dst, src *Config) {
|
||||
if len(src.LDFlags) > 0 {
|
||||
dst.LDFlags = append(dst.LDFlags, src.LDFlags...)
|
||||
}
|
||||
if len(src.ExtraFiles) > 0 {
|
||||
dst.ExtraFiles = append(dst.ExtraFiles, src.ExtraFiles...)
|
||||
}
|
||||
if len(src.MSDVolumeName) > 0 {
|
||||
dst.MSDVolumeName = append(dst.MSDVolumeName, src.MSDVolumeName...)
|
||||
}
|
||||
if len(src.GDB) > 0 {
|
||||
dst.GDB = append(dst.GDB, src.GDB...)
|
||||
}
|
||||
}
|
||||
|
||||
// GetTargetsDir returns the targets directory path
|
||||
|
||||
@@ -61,7 +61,8 @@ func TestLoaderLoadRaw(t *testing.T) {
|
||||
"goarch": "arm",
|
||||
"build-tags": ["test", "embedded"],
|
||||
"cflags": ["-Os", "-g"],
|
||||
"ldflags": ["--gc-sections"]
|
||||
"ldflags": ["--gc-sections"],
|
||||
"binary-format": "uf2"
|
||||
}`
|
||||
|
||||
configPath := filepath.Join(tempDir, "test-target.json")
|
||||
@@ -87,6 +88,9 @@ func TestLoaderLoadRaw(t *testing.T) {
|
||||
if len(config.BuildTags) != 2 || config.BuildTags[0] != "test" || config.BuildTags[1] != "embedded" {
|
||||
t.Errorf("Expected build-tags [test, embedded], got %v", config.BuildTags)
|
||||
}
|
||||
if config.BinaryFormat != "uf2" {
|
||||
t.Errorf("Expected binary-format 'uf2', got '%s'", config.BinaryFormat)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoaderInheritance(t *testing.T) {
|
||||
@@ -99,7 +103,8 @@ func TestLoaderInheritance(t *testing.T) {
|
||||
"goos": "linux",
|
||||
"goarch": "arm",
|
||||
"cflags": ["-Os"],
|
||||
"ldflags": ["--gc-sections"]
|
||||
"ldflags": ["--gc-sections"],
|
||||
"binary-format": "elf"
|
||||
}`
|
||||
|
||||
// Create child config that inherits from parent
|
||||
@@ -108,7 +113,8 @@ func TestLoaderInheritance(t *testing.T) {
|
||||
"cpu": "cortex-m4",
|
||||
"build-tags": ["child"],
|
||||
"cflags": ["-O2"],
|
||||
"ldflags": ["-g"]
|
||||
"ldflags": ["-g"],
|
||||
"binary-format": "uf2"
|
||||
}`
|
||||
|
||||
parentPath := filepath.Join(tempDir, "parent.json")
|
||||
@@ -143,6 +149,11 @@ func TestLoaderInheritance(t *testing.T) {
|
||||
t.Errorf("Expected overridden cpu 'cortex-m4', got '%s'", config.CPU)
|
||||
}
|
||||
|
||||
// Check binary-format override
|
||||
if config.BinaryFormat != "uf2" {
|
||||
t.Errorf("Expected overridden binary-format 'uf2', got '%s'", config.BinaryFormat)
|
||||
}
|
||||
|
||||
// Check merged arrays
|
||||
expectedCFlags := []string{"-Os", "-O2"}
|
||||
if len(config.CFlags) != 2 || config.CFlags[0] != "-Os" || config.CFlags[1] != "-O2" {
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
"ldflags": [
|
||||
"--defsym=_stack_size=512"
|
||||
],
|
||||
"linkerscript": "src/device/avr/atmega1280.ld",
|
||||
"linkerscript": "targets/device/avr/atmega1280.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega1280.s"
|
||||
"targets/device/avr/atmega1280.s"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
"--defsym=_bootloader_size=0",
|
||||
"--defsym=_stack_size=512"
|
||||
],
|
||||
"linkerscript": "src/device/avr/atmega1284p.ld",
|
||||
"linkerscript": "targets/device/avr/atmega1284p.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega1284p.s"
|
||||
"targets/device/avr/atmega1284p.s"
|
||||
],
|
||||
"emulator": "simavr -m atmega1284p -f 20000000 {}"
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
"ldflags": [
|
||||
"--defsym=_stack_size=512"
|
||||
],
|
||||
"linkerscript": "src/device/avr/atmega2560.ld",
|
||||
"linkerscript": "targets/device/avr/atmega2560.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega2560.s"
|
||||
"targets/device/avr/atmega2560.s"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
"cpu": "atmega328p",
|
||||
"build-tags": ["atmega328p", "atmega", "avr5"],
|
||||
"serial": "uart",
|
||||
"linkerscript": "src/device/avr/atmega328p.ld",
|
||||
"linkerscript": "targets/device/avr/atmega328p.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega328p.s"
|
||||
"targets/device/avr/atmega328p.s"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
"--defsym=_stack_size=512"
|
||||
],
|
||||
"serial": "uart",
|
||||
"linkerscript": "src/device/avr/atmega328pb.ld",
|
||||
"linkerscript": "targets/device/avr/atmega328pb.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega328pb.s"
|
||||
"targets/device/avr/atmega328pb.s"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
"cpu": "atmega32u4",
|
||||
"build-tags": ["atmega32u4", "avr5"],
|
||||
"serial": "none",
|
||||
"linkerscript": "src/device/avr/atmega32u4.ld",
|
||||
"linkerscript": "targets/device/avr/atmega32u4.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/atmega32u4.s"
|
||||
"targets/device/avr/atmega32u4.s"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"serial": "usb",
|
||||
"linkerscript": "targets/atsamd21.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd21e18a.s"
|
||||
"targets/device/sam/atsamd21e18a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "at91samdXX"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"serial": "usb",
|
||||
"linkerscript": "targets/atsamd21.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd21g18a.s"
|
||||
"targets/device/sam/atsamd21g18a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "at91samdXX"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"build-tags": ["atsamd51g19a", "atsamd51g19", "atsamd51", "sam"],
|
||||
"linkerscript": "targets/atsamd51.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd51g19a.s"
|
||||
"targets/device/sam/atsamd51g19a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"build-tags": ["atsamd51j19a", "atsamd51j19", "atsamd51", "sam"],
|
||||
"linkerscript": "targets/atsamd51.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd51j19a.s"
|
||||
"targets/device/sam/atsamd51j19a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"build-tags": ["sam", "atsamd51", "atsamd51j20", "atsamd51j20a"],
|
||||
"linkerscript": "targets/atsamd51j20a.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd51j20a.s"
|
||||
"targets/device/sam/atsamd51j20a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"build-tags": ["atsamd51p19a", "atsamd51p19", "atsamd51", "sam"],
|
||||
"linkerscript": "targets/atsamd51.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd51p19a.s"
|
||||
"targets/device/sam/atsamd51p19a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"build-tags": ["sam", "atsamd51", "atsamd51p20", "atsamd51p20a"],
|
||||
"linkerscript": "targets/atsamd51p20a.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd51p20a.s"
|
||||
"targets/device/sam/atsamd51p20a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"build-tags": ["atsame51j19a", "atsame51j19", "atsame51", "atsame5x", "sam"],
|
||||
"linkerscript": "targets/atsame5xx19.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsame51j19a.s"
|
||||
"targets/device/sam/atsame51j19a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"build-tags": ["sam", "atsame5x", "atsame54", "atsame54p20", "atsame54p20a"],
|
||||
"linkerscript": "targets/atsame5xx20-no-bootloader.ld",
|
||||
"extra-files": [
|
||||
"src/device/sam/atsame54p20a.s"
|
||||
"targets/device/sam/atsame54p20a.s"
|
||||
],
|
||||
"openocd-transport": "swd",
|
||||
"openocd-target": "atsame5x"
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
"cflags": [
|
||||
"-D__AVR_ARCH__=103"
|
||||
],
|
||||
"linkerscript": "src/device/avr/attiny1616.ld",
|
||||
"linkerscript": "targets/device/avr/attiny1616.ld",
|
||||
"extra-files": [
|
||||
"src/device/avr/attiny1616.s"
|
||||
"targets/device/avr/attiny1616.s"
|
||||
],
|
||||
"flash-command": "pymcuprog write -f {hex} --erase --verify -d attiny1616 -t uart -u {port}"
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
"cflags": [
|
||||
"-D__AVR_ARCH__=25"
|
||||
],
|
||||
"linkerscript": "src/device/avr/attiny85.ld",
|
||||
"linkerscript": "targets/device/avr/attiny85.ld",
|
||||
"extra-files": [
|
||||
"targets/avr.S",
|
||||
"src/device/avr/attiny85.s"
|
||||
"targets/device/avr/attiny85.s"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -16,9 +16,5 @@
|
||||
"-T", "targets/avr.ld",
|
||||
"--gc-sections"
|
||||
],
|
||||
"extra-files": [
|
||||
"src/internal/task/task_stack_avr.S",
|
||||
"src/runtime/asm_avr.S"
|
||||
],
|
||||
"gdb": ["avr-gdb"]
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
"--gc-sections"
|
||||
],
|
||||
"extra-files": [
|
||||
"src/internal/task/task_stack_avr.S",
|
||||
"src/runtime/asm_avr.S",
|
||||
"targets/avrtiny.S"
|
||||
],
|
||||
"gdb": ["avr-gdb"]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"serial": "uart",
|
||||
"linkerscript": "targets/stm32.ld",
|
||||
"extra-files": [
|
||||
"src/device/stm32/stm32f103.s"
|
||||
"targets/device/stm32/stm32f103.s"
|
||||
],
|
||||
"flash-method": "openocd",
|
||||
"openocd-interface": "stlink-v2",
|
||||
|
||||
@@ -22,9 +22,7 @@
|
||||
"--gc-sections"
|
||||
],
|
||||
"extra-files": [
|
||||
"src/device/arm/cortexm.S",
|
||||
"src/internal/task/task_stack_cortexm.S",
|
||||
"src/runtime/asm_arm.S"
|
||||
"targets/device/arm/cortexm.S"
|
||||
],
|
||||
"gdb": ["gdb-multiarch", "arm-none-eabi-gdb", "gdb"]
|
||||
}
|
||||
|
||||
37
targets/device/arm/cortexm.S
Normal file
37
targets/device/arm/cortexm.S
Normal file
@@ -0,0 +1,37 @@
|
||||
.syntax unified
|
||||
.cfi_sections .debug_frame
|
||||
|
||||
.section .text.HardFault_Handler
|
||||
.global HardFault_Handler
|
||||
.type HardFault_Handler, %function
|
||||
HardFault_Handler:
|
||||
.cfi_startproc
|
||||
// Put the old stack pointer in the first argument, for easy debugging. This
|
||||
// is especially useful on Cortex-M0, which supports far fewer debug
|
||||
// facilities.
|
||||
mov r0, sp
|
||||
|
||||
// Load the default stack pointer from address 0 so that we can call normal
|
||||
// functions again that expect a working stack. However, it will corrupt the
|
||||
// old stack so the function below must not attempt to recover from this
|
||||
// fault.
|
||||
movs r3, #0
|
||||
ldr r3, [r3]
|
||||
mov sp, r3
|
||||
|
||||
// Continue handling this error in Go.
|
||||
bl handleHardFault
|
||||
.cfi_endproc
|
||||
.size HardFault_Handler, .-HardFault_Handler
|
||||
|
||||
// This is a convenience function for semihosting support.
|
||||
// At some point, this should be replaced by inline assembly.
|
||||
.section .text.SemihostingCall
|
||||
.global SemihostingCall
|
||||
.type SemihostingCall, %function
|
||||
SemihostingCall:
|
||||
.cfi_startproc
|
||||
bkpt 0xab
|
||||
bx lr
|
||||
.cfi_endproc
|
||||
.size SemihostingCall, .-SemihostingCall
|
||||
22
targets/device/arm/interrupts.c
Normal file
22
targets/device/arm/interrupts.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <stdint.h>
|
||||
|
||||
void EnableInterrupts(uintptr_t mask) {
|
||||
asm volatile(
|
||||
"msr PRIMASK, %0"
|
||||
:
|
||||
: "r"(mask)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
uintptr_t DisableInterrupts() {
|
||||
uintptr_t mask;
|
||||
asm volatile(
|
||||
"mrs %0, PRIMASK\n\t"
|
||||
"cpsid i"
|
||||
: "=r"(mask)
|
||||
:
|
||||
: "memory"
|
||||
);
|
||||
return mask;
|
||||
}
|
||||
7
targets/device/avr/at90can128.ld
Normal file
7
targets/device/avr/at90can128.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90CAN128.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x1000;
|
||||
__num_isrs = 37;
|
||||
98
targets/device/avr/at90can128.s
Normal file
98
targets/device/avr/at90can128.s
Normal file
@@ -0,0 +1,98 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90CAN128.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_TIMER2_COMP
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMP
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_CANIT
|
||||
jmp __vector_OVRIT
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_TIMER2_COMP
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMP
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_CANIT
|
||||
IRQ __vector_OVRIT
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90can32.ld
Normal file
7
targets/device/avr/at90can32.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90CAN32.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x8000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x800;
|
||||
__num_isrs = 37;
|
||||
98
targets/device/avr/at90can32.s
Normal file
98
targets/device/avr/at90can32.s
Normal file
@@ -0,0 +1,98 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90CAN32.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_TIMER2_COMP
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMP
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_CANIT
|
||||
jmp __vector_OVRIT
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_TIMER2_COMP
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMP
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_CANIT
|
||||
IRQ __vector_OVRIT
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90can64.ld
Normal file
7
targets/device/avr/at90can64.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90CAN64.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x10000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x1000;
|
||||
__num_isrs = 37;
|
||||
98
targets/device/avr/at90can64.s
Normal file
98
targets/device/avr/at90can64.s
Normal file
@@ -0,0 +1,98 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90CAN64.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_TIMER2_COMP
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMP
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_CANIT
|
||||
jmp __vector_OVRIT
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_TIMER2_COMP
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMP
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_CANIT
|
||||
IRQ __vector_OVRIT
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90pwm1.ld
Normal file
7
targets/device/avr/at90pwm1.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90PWM1.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x2000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x200;
|
||||
__num_isrs = 32;
|
||||
88
targets/device/avr/at90pwm1.s
Normal file
88
targets/device/avr/at90pwm1.s
Normal file
@@ -0,0 +1,88 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90PWM1.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
rjmp __vector_RESET
|
||||
rjmp __vector_PSC2_CAPT
|
||||
rjmp __vector_PSC2_EC
|
||||
rjmp __vector_PSC1_CAPT
|
||||
rjmp __vector_PSC1_EC
|
||||
rjmp __vector_PSC0_CAPT
|
||||
rjmp __vector_PSC0_EC
|
||||
rjmp __vector_ANALOG_COMP_0
|
||||
rjmp __vector_ANALOG_COMP_1
|
||||
rjmp __vector_ANALOG_COMP_2
|
||||
rjmp __vector_INT0
|
||||
rjmp __vector_TIMER1_CAPT
|
||||
rjmp __vector_TIMER1_COMPA
|
||||
rjmp __vector_TIMER1_COMPB
|
||||
rjmp __vector_RESERVED15
|
||||
rjmp __vector_TIMER1_OVF
|
||||
rjmp __vector_TIMER0_COMP_A
|
||||
rjmp __vector_TIMER0_OVF
|
||||
rjmp __vector_ADC
|
||||
rjmp __vector_INT1
|
||||
rjmp __vector_SPI_STC
|
||||
rjmp __vector_USART_RX
|
||||
rjmp __vector_USART_UDRE
|
||||
rjmp __vector_USART_TX
|
||||
rjmp __vector_INT2
|
||||
rjmp __vector_WDT
|
||||
rjmp __vector_EE_READY
|
||||
rjmp __vector_TIMER0_COMPB
|
||||
rjmp __vector_INT3
|
||||
rjmp __vector_RESERVED30
|
||||
rjmp __vector_RESERVED31
|
||||
rjmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_PSC2_CAPT
|
||||
IRQ __vector_PSC2_EC
|
||||
IRQ __vector_PSC1_CAPT
|
||||
IRQ __vector_PSC1_EC
|
||||
IRQ __vector_PSC0_CAPT
|
||||
IRQ __vector_PSC0_EC
|
||||
IRQ __vector_ANALOG_COMP_0
|
||||
IRQ __vector_ANALOG_COMP_1
|
||||
IRQ __vector_ANALOG_COMP_2
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_RESERVED15
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMP_A
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART_RX
|
||||
IRQ __vector_USART_UDRE
|
||||
IRQ __vector_USART_TX
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_RESERVED30
|
||||
IRQ __vector_RESERVED31
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90pwm161.ld
Normal file
7
targets/device/avr/at90pwm161.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90PWM161.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x4000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x400;
|
||||
__num_isrs = 20;
|
||||
64
targets/device/avr/at90pwm161.s
Normal file
64
targets/device/avr/at90pwm161.s
Normal file
@@ -0,0 +1,64 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90PWM161.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_PSC2_CAPT
|
||||
jmp __vector_PSC2_EC
|
||||
jmp __vector_PSC2_EEC
|
||||
jmp __vector_PSC0_CAPT
|
||||
jmp __vector_PSC0_EC
|
||||
jmp __vector_PSC0_EEC
|
||||
jmp __vector_ANALOG_COMP_1
|
||||
jmp __vector_ANALOG_COMP_2
|
||||
jmp __vector_ANALOG_COMP_3
|
||||
jmp __vector_INT0
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_ADC
|
||||
jmp __vector_INT1
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_INT2
|
||||
jmp __vector_WDT
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_PSC2_CAPT
|
||||
IRQ __vector_PSC2_EC
|
||||
IRQ __vector_PSC2_EEC
|
||||
IRQ __vector_PSC0_CAPT
|
||||
IRQ __vector_PSC0_EC
|
||||
IRQ __vector_PSC0_EEC
|
||||
IRQ __vector_ANALOG_COMP_1
|
||||
IRQ __vector_ANALOG_COMP_2
|
||||
IRQ __vector_ANALOG_COMP_3
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90pwm216.ld
Normal file
7
targets/device/avr/at90pwm216.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90PWM216.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x4000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x400;
|
||||
__num_isrs = 32;
|
||||
88
targets/device/avr/at90pwm216.s
Normal file
88
targets/device/avr/at90pwm216.s
Normal file
@@ -0,0 +1,88 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90PWM216.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_PSC2_CAPT
|
||||
jmp __vector_PSC2_EC
|
||||
jmp __vector_PSC1_CAPT
|
||||
jmp __vector_PSC1_EC
|
||||
jmp __vector_PSC0_CAPT
|
||||
jmp __vector_PSC0_EC
|
||||
jmp __vector_ANALOG_COMP_0
|
||||
jmp __vector_ANALOG_COMP_1
|
||||
jmp __vector_ANALOG_COMP_2
|
||||
jmp __vector_INT0
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_RESERVED15
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMP_A
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_ADC
|
||||
jmp __vector_INT1
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART_RX
|
||||
jmp __vector_USART_UDRE
|
||||
jmp __vector_USART_TX
|
||||
jmp __vector_INT2
|
||||
jmp __vector_WDT
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_INT3
|
||||
jmp __vector_RESERVED30
|
||||
jmp __vector_RESERVED31
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_PSC2_CAPT
|
||||
IRQ __vector_PSC2_EC
|
||||
IRQ __vector_PSC1_CAPT
|
||||
IRQ __vector_PSC1_EC
|
||||
IRQ __vector_PSC0_CAPT
|
||||
IRQ __vector_PSC0_EC
|
||||
IRQ __vector_ANALOG_COMP_0
|
||||
IRQ __vector_ANALOG_COMP_1
|
||||
IRQ __vector_ANALOG_COMP_2
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_RESERVED15
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMP_A
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART_RX
|
||||
IRQ __vector_USART_UDRE
|
||||
IRQ __vector_USART_TX
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_RESERVED30
|
||||
IRQ __vector_RESERVED31
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90pwm2b.ld
Normal file
7
targets/device/avr/at90pwm2b.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90PWM2B.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x2000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x200;
|
||||
__num_isrs = 32;
|
||||
88
targets/device/avr/at90pwm2b.s
Normal file
88
targets/device/avr/at90pwm2b.s
Normal file
@@ -0,0 +1,88 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90PWM2B.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
rjmp __vector_RESET
|
||||
rjmp __vector_PSC2_CAPT
|
||||
rjmp __vector_PSC2_EC
|
||||
rjmp __vector_PSC1_CAPT
|
||||
rjmp __vector_PSC1_EC
|
||||
rjmp __vector_PSC0_CAPT
|
||||
rjmp __vector_PSC0_EC
|
||||
rjmp __vector_ANALOG_COMP_0
|
||||
rjmp __vector_ANALOG_COMP_1
|
||||
rjmp __vector_ANALOG_COMP_2
|
||||
rjmp __vector_INT0
|
||||
rjmp __vector_TIMER1_CAPT
|
||||
rjmp __vector_TIMER1_COMPA
|
||||
rjmp __vector_TIMER1_COMPB
|
||||
rjmp __vector_RESERVED15
|
||||
rjmp __vector_TIMER1_OVF
|
||||
rjmp __vector_TIMER0_COMPA
|
||||
rjmp __vector_TIMER0_OVF
|
||||
rjmp __vector_ADC
|
||||
rjmp __vector_INT1
|
||||
rjmp __vector_SPI_STC
|
||||
rjmp __vector_USART_RX
|
||||
rjmp __vector_USART_UDRE
|
||||
rjmp __vector_USART_TX
|
||||
rjmp __vector_INT2
|
||||
rjmp __vector_WDT
|
||||
rjmp __vector_EE_READY
|
||||
rjmp __vector_TIMER0_COMPB
|
||||
rjmp __vector_INT3
|
||||
rjmp __vector_RESERVED30
|
||||
rjmp __vector_RESERVED31
|
||||
rjmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_PSC2_CAPT
|
||||
IRQ __vector_PSC2_EC
|
||||
IRQ __vector_PSC1_CAPT
|
||||
IRQ __vector_PSC1_EC
|
||||
IRQ __vector_PSC0_CAPT
|
||||
IRQ __vector_PSC0_EC
|
||||
IRQ __vector_ANALOG_COMP_0
|
||||
IRQ __vector_ANALOG_COMP_1
|
||||
IRQ __vector_ANALOG_COMP_2
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_RESERVED15
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART_RX
|
||||
IRQ __vector_USART_UDRE
|
||||
IRQ __vector_USART_TX
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_RESERVED30
|
||||
IRQ __vector_RESERVED31
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90pwm316.ld
Normal file
7
targets/device/avr/at90pwm316.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90PWM316.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x4000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x400;
|
||||
__num_isrs = 32;
|
||||
88
targets/device/avr/at90pwm316.s
Normal file
88
targets/device/avr/at90pwm316.s
Normal file
@@ -0,0 +1,88 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90PWM316.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_PSC2_CAPT
|
||||
jmp __vector_PSC2_EC
|
||||
jmp __vector_PSC1_CAPT
|
||||
jmp __vector_PSC1_EC
|
||||
jmp __vector_PSC0_CAPT
|
||||
jmp __vector_PSC0_EC
|
||||
jmp __vector_ANALOG_COMP_0
|
||||
jmp __vector_ANALOG_COMP_1
|
||||
jmp __vector_ANALOG_COMP_2
|
||||
jmp __vector_INT0
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_RESERVED15
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMP_A
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_ADC
|
||||
jmp __vector_INT1
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART_RX
|
||||
jmp __vector_USART_UDRE
|
||||
jmp __vector_USART_TX
|
||||
jmp __vector_INT2
|
||||
jmp __vector_WDT
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_INT3
|
||||
jmp __vector_RESERVED30
|
||||
jmp __vector_RESERVED31
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_PSC2_CAPT
|
||||
IRQ __vector_PSC2_EC
|
||||
IRQ __vector_PSC1_CAPT
|
||||
IRQ __vector_PSC1_EC
|
||||
IRQ __vector_PSC0_CAPT
|
||||
IRQ __vector_PSC0_EC
|
||||
IRQ __vector_ANALOG_COMP_0
|
||||
IRQ __vector_ANALOG_COMP_1
|
||||
IRQ __vector_ANALOG_COMP_2
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_RESERVED15
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMP_A
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART_RX
|
||||
IRQ __vector_USART_UDRE
|
||||
IRQ __vector_USART_TX
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_RESERVED30
|
||||
IRQ __vector_RESERVED31
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90pwm3b.ld
Normal file
7
targets/device/avr/at90pwm3b.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90PWM3B.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x2000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x200;
|
||||
__num_isrs = 32;
|
||||
88
targets/device/avr/at90pwm3b.s
Normal file
88
targets/device/avr/at90pwm3b.s
Normal file
@@ -0,0 +1,88 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90PWM3B.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
rjmp __vector_RESET
|
||||
rjmp __vector_PSC2_CAPT
|
||||
rjmp __vector_PSC2_EC
|
||||
rjmp __vector_PSC1_CAPT
|
||||
rjmp __vector_PSC1_EC
|
||||
rjmp __vector_PSC0_CAPT
|
||||
rjmp __vector_PSC0_EC
|
||||
rjmp __vector_ANALOG_COMP_0
|
||||
rjmp __vector_ANALOG_COMP_1
|
||||
rjmp __vector_ANALOG_COMP_2
|
||||
rjmp __vector_INT0
|
||||
rjmp __vector_TIMER1_CAPT
|
||||
rjmp __vector_TIMER1_COMPA
|
||||
rjmp __vector_TIMER1_COMPB
|
||||
rjmp __vector_RESERVED15
|
||||
rjmp __vector_TIMER1_OVF
|
||||
rjmp __vector_TIMER0_COMPA
|
||||
rjmp __vector_TIMER0_OVF
|
||||
rjmp __vector_ADC
|
||||
rjmp __vector_INT1
|
||||
rjmp __vector_SPI_STC
|
||||
rjmp __vector_USART_RX
|
||||
rjmp __vector_USART_UDRE
|
||||
rjmp __vector_USART_TX
|
||||
rjmp __vector_INT2
|
||||
rjmp __vector_WDT
|
||||
rjmp __vector_EE_READY
|
||||
rjmp __vector_TIMER0_COMPB
|
||||
rjmp __vector_INT3
|
||||
rjmp __vector_RESERVED30
|
||||
rjmp __vector_RESERVED31
|
||||
rjmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_PSC2_CAPT
|
||||
IRQ __vector_PSC2_EC
|
||||
IRQ __vector_PSC1_CAPT
|
||||
IRQ __vector_PSC1_EC
|
||||
IRQ __vector_PSC0_CAPT
|
||||
IRQ __vector_PSC0_EC
|
||||
IRQ __vector_ANALOG_COMP_0
|
||||
IRQ __vector_ANALOG_COMP_1
|
||||
IRQ __vector_ANALOG_COMP_2
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_RESERVED15
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART_RX
|
||||
IRQ __vector_USART_UDRE
|
||||
IRQ __vector_USART_TX
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_RESERVED30
|
||||
IRQ __vector_RESERVED31
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90pwm81.ld
Normal file
7
targets/device/avr/at90pwm81.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90PWM81.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x2000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x100;
|
||||
__num_isrs = 20;
|
||||
64
targets/device/avr/at90pwm81.s
Normal file
64
targets/device/avr/at90pwm81.s
Normal file
@@ -0,0 +1,64 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90PWM81.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
rjmp __vector_RESET
|
||||
rjmp __vector_PSC2_CAPT
|
||||
rjmp __vector_PSC2_EC
|
||||
rjmp __vector_PSC2_EEC
|
||||
rjmp __vector_PSC0_CAPT
|
||||
rjmp __vector_PSC0_EC
|
||||
rjmp __vector_PSC0_EEC
|
||||
rjmp __vector_ANALOG_COMP_1
|
||||
rjmp __vector_ANALOG_COMP_2
|
||||
rjmp __vector_ANALOG_COMP_3
|
||||
rjmp __vector_INT0
|
||||
rjmp __vector_TIMER1_CAPT
|
||||
rjmp __vector_TIMER1_OVF
|
||||
rjmp __vector_ADC
|
||||
rjmp __vector_INT1
|
||||
rjmp __vector_SPI_STC
|
||||
rjmp __vector_INT2
|
||||
rjmp __vector_WDT
|
||||
rjmp __vector_EE_READY
|
||||
rjmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_PSC2_CAPT
|
||||
IRQ __vector_PSC2_EC
|
||||
IRQ __vector_PSC2_EEC
|
||||
IRQ __vector_PSC0_CAPT
|
||||
IRQ __vector_PSC0_EC
|
||||
IRQ __vector_PSC0_EEC
|
||||
IRQ __vector_ANALOG_COMP_1
|
||||
IRQ __vector_ANALOG_COMP_2
|
||||
IRQ __vector_ANALOG_COMP_3
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90usb1286.ld
Normal file
7
targets/device/avr/at90usb1286.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90USB1286.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x2000;
|
||||
__num_isrs = 38;
|
||||
100
targets/device/avr/at90usb1286.s
Normal file
100
targets/device/avr/at90usb1286.s
Normal file
@@ -0,0 +1,100 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90USB1286.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_USB_GEN
|
||||
jmp __vector_USB_COM
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER2_COMPA
|
||||
jmp __vector_TIMER2_COMPB
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_USB_GEN
|
||||
IRQ __vector_USB_COM
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER2_COMPA
|
||||
IRQ __vector_TIMER2_COMPB
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90usb1287.ld
Normal file
7
targets/device/avr/at90usb1287.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90USB1287.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x2000;
|
||||
__num_isrs = 38;
|
||||
100
targets/device/avr/at90usb1287.s
Normal file
100
targets/device/avr/at90usb1287.s
Normal file
@@ -0,0 +1,100 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90USB1287.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_USB_GEN
|
||||
jmp __vector_USB_COM
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER2_COMPA
|
||||
jmp __vector_TIMER2_COMPB
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_USB_GEN
|
||||
IRQ __vector_USB_COM
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER2_COMPA
|
||||
IRQ __vector_TIMER2_COMPB
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90usb162.ld
Normal file
7
targets/device/avr/at90usb162.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90USB162.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x4000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x200;
|
||||
__num_isrs = 29;
|
||||
82
targets/device/avr/at90usb162.s
Normal file
82
targets/device/avr/at90usb162.s
Normal file
@@ -0,0 +1,82 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90USB162.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_PCINT1
|
||||
jmp __vector_USB_GEN
|
||||
jmp __vector_USB_COM
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_PCINT1
|
||||
IRQ __vector_USB_GEN
|
||||
IRQ __vector_USB_COM
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90usb646.ld
Normal file
7
targets/device/avr/at90usb646.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90USB646.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x10000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x1000;
|
||||
__num_isrs = 38;
|
||||
100
targets/device/avr/at90usb646.s
Normal file
100
targets/device/avr/at90usb646.s
Normal file
@@ -0,0 +1,100 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90USB646.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_USB_GEN
|
||||
jmp __vector_USB_COM
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER2_COMPA
|
||||
jmp __vector_TIMER2_COMPB
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_USB_GEN
|
||||
IRQ __vector_USB_COM
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER2_COMPA
|
||||
IRQ __vector_TIMER2_COMPB
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90usb647.ld
Normal file
7
targets/device/avr/at90usb647.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90USB647.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x10000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x1000;
|
||||
__num_isrs = 38;
|
||||
100
targets/device/avr/at90usb647.s
Normal file
100
targets/device/avr/at90usb647.s
Normal file
@@ -0,0 +1,100 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90USB647.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_USB_GEN
|
||||
jmp __vector_USB_COM
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER2_COMPA
|
||||
jmp __vector_TIMER2_COMPB
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_USB_GEN
|
||||
IRQ __vector_USB_COM
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER2_COMPA
|
||||
IRQ __vector_TIMER2_COMPB
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/at90usb82.ld
Normal file
7
targets/device/avr/at90usb82.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from AT90USB82.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x2000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x200;
|
||||
__num_isrs = 29;
|
||||
82
targets/device/avr/at90usb82.s
Normal file
82
targets/device/avr/at90usb82.s
Normal file
@@ -0,0 +1,82 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from AT90USB82.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
rjmp __vector_RESET
|
||||
rjmp __vector_INT0
|
||||
rjmp __vector_INT1
|
||||
rjmp __vector_INT2
|
||||
rjmp __vector_INT3
|
||||
rjmp __vector_INT4
|
||||
rjmp __vector_INT5
|
||||
rjmp __vector_INT6
|
||||
rjmp __vector_INT7
|
||||
rjmp __vector_PCINT0
|
||||
rjmp __vector_PCINT1
|
||||
rjmp __vector_USB_GEN
|
||||
rjmp __vector_USB_COM
|
||||
rjmp __vector_WDT
|
||||
rjmp __vector_TIMER1_CAPT
|
||||
rjmp __vector_TIMER1_COMPA
|
||||
rjmp __vector_TIMER1_COMPB
|
||||
rjmp __vector_TIMER1_COMPC
|
||||
rjmp __vector_TIMER1_OVF
|
||||
rjmp __vector_TIMER0_COMPA
|
||||
rjmp __vector_TIMER0_COMPB
|
||||
rjmp __vector_TIMER0_OVF
|
||||
rjmp __vector_SPI_STC
|
||||
rjmp __vector_USART1_RX
|
||||
rjmp __vector_USART1_UDRE
|
||||
rjmp __vector_USART1_TX
|
||||
rjmp __vector_ANALOG_COMP
|
||||
rjmp __vector_EE_READY
|
||||
rjmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_PCINT1
|
||||
IRQ __vector_USB_GEN
|
||||
IRQ __vector_USB_COM
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/atmega128.ld
Normal file
7
targets/device/avr/atmega128.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from ATmega128.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x1000;
|
||||
__num_isrs = 35;
|
||||
94
targets/device/avr/atmega128.s
Normal file
94
targets/device/avr/atmega128.s
Normal file
@@ -0,0 +1,94 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from ATmega128.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_TIMER2_COMP
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMP
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_TIMER2_COMP
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMP
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/atmega1280.ld
Normal file
7
targets/device/avr/atmega1280.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from ATmega1280.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x200;
|
||||
__ram_size = 0x2000;
|
||||
__num_isrs = 57;
|
||||
138
targets/device/avr/atmega1280.s
Normal file
138
targets/device/avr/atmega1280.s
Normal file
@@ -0,0 +1,138 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from ATmega1280.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_PCINT1
|
||||
jmp __vector_PCINT2
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER2_COMPA
|
||||
jmp __vector_TIMER2_COMPB
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
jmp __vector_TIMER4_CAPT
|
||||
jmp __vector_TIMER4_COMPA
|
||||
jmp __vector_TIMER4_COMPB
|
||||
jmp __vector_TIMER4_COMPC
|
||||
jmp __vector_TIMER4_OVF
|
||||
jmp __vector_TIMER5_CAPT
|
||||
jmp __vector_TIMER5_COMPA
|
||||
jmp __vector_TIMER5_COMPB
|
||||
jmp __vector_TIMER5_COMPC
|
||||
jmp __vector_TIMER5_OVF
|
||||
jmp __vector_USART2_RX
|
||||
jmp __vector_USART2_UDRE
|
||||
jmp __vector_USART2_TX
|
||||
jmp __vector_USART3_RX
|
||||
jmp __vector_USART3_UDRE
|
||||
jmp __vector_USART3_TX
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_PCINT1
|
||||
IRQ __vector_PCINT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER2_COMPA
|
||||
IRQ __vector_TIMER2_COMPB
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
IRQ __vector_TIMER4_CAPT
|
||||
IRQ __vector_TIMER4_COMPA
|
||||
IRQ __vector_TIMER4_COMPB
|
||||
IRQ __vector_TIMER4_COMPC
|
||||
IRQ __vector_TIMER4_OVF
|
||||
IRQ __vector_TIMER5_CAPT
|
||||
IRQ __vector_TIMER5_COMPA
|
||||
IRQ __vector_TIMER5_COMPB
|
||||
IRQ __vector_TIMER5_COMPC
|
||||
IRQ __vector_TIMER5_OVF
|
||||
IRQ __vector_USART2_RX
|
||||
IRQ __vector_USART2_UDRE
|
||||
IRQ __vector_USART2_TX
|
||||
IRQ __vector_USART3_RX
|
||||
IRQ __vector_USART3_UDRE
|
||||
IRQ __vector_USART3_TX
|
||||
7
targets/device/avr/atmega1281.ld
Normal file
7
targets/device/avr/atmega1281.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from ATmega1281.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x200;
|
||||
__ram_size = 0x2000;
|
||||
__num_isrs = 57;
|
||||
138
targets/device/avr/atmega1281.s
Normal file
138
targets/device/avr/atmega1281.s
Normal file
@@ -0,0 +1,138 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from ATmega1281.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_PCINT1
|
||||
jmp __vector_PCINT2
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER2_COMPA
|
||||
jmp __vector_TIMER2_COMPB
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
jmp __vector_TIMER4_CAPT
|
||||
jmp __vector_TIMER4_COMPA
|
||||
jmp __vector_TIMER4_COMPB
|
||||
jmp __vector_TIMER4_COMPC
|
||||
jmp __vector_TIMER4_OVF
|
||||
jmp __vector_TIMER5_CAPT
|
||||
jmp __vector_TIMER5_COMPA
|
||||
jmp __vector_TIMER5_COMPB
|
||||
jmp __vector_TIMER5_COMPC
|
||||
jmp __vector_TIMER5_OVF
|
||||
jmp __vector_USART2_RX
|
||||
jmp __vector_USART2_UDRE
|
||||
jmp __vector_USART2_TX
|
||||
jmp __vector_USART3_RX
|
||||
jmp __vector_USART3_UDRE
|
||||
jmp __vector_USART3_TX
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_PCINT1
|
||||
IRQ __vector_PCINT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER2_COMPA
|
||||
IRQ __vector_TIMER2_COMPB
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
IRQ __vector_TIMER4_CAPT
|
||||
IRQ __vector_TIMER4_COMPA
|
||||
IRQ __vector_TIMER4_COMPB
|
||||
IRQ __vector_TIMER4_COMPC
|
||||
IRQ __vector_TIMER4_OVF
|
||||
IRQ __vector_TIMER5_CAPT
|
||||
IRQ __vector_TIMER5_COMPA
|
||||
IRQ __vector_TIMER5_COMPB
|
||||
IRQ __vector_TIMER5_COMPC
|
||||
IRQ __vector_TIMER5_OVF
|
||||
IRQ __vector_USART2_RX
|
||||
IRQ __vector_USART2_UDRE
|
||||
IRQ __vector_USART2_TX
|
||||
IRQ __vector_USART3_RX
|
||||
IRQ __vector_USART3_UDRE
|
||||
IRQ __vector_USART3_TX
|
||||
7
targets/device/avr/atmega1284.ld
Normal file
7
targets/device/avr/atmega1284.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from ATmega1284.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x4000;
|
||||
__num_isrs = 35;
|
||||
94
targets/device/avr/atmega1284.s
Normal file
94
targets/device/avr/atmega1284.s
Normal file
@@ -0,0 +1,94 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from ATmega1284.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_PCINT1
|
||||
jmp __vector_PCINT2
|
||||
jmp __vector_PCINT3
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER2_COMPA
|
||||
jmp __vector_TIMER2_COMPB
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_OVF
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_PCINT1
|
||||
IRQ __vector_PCINT2
|
||||
IRQ __vector_PCINT3
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER2_COMPA
|
||||
IRQ __vector_TIMER2_COMPB
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_OVF
|
||||
7
targets/device/avr/atmega1284p.ld
Normal file
7
targets/device/avr/atmega1284p.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from ATmega1284P.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x4000;
|
||||
__num_isrs = 35;
|
||||
94
targets/device/avr/atmega1284p.s
Normal file
94
targets/device/avr/atmega1284p.s
Normal file
@@ -0,0 +1,94 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from ATmega1284P.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_PCINT1
|
||||
jmp __vector_PCINT2
|
||||
jmp __vector_PCINT3
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER2_COMPA
|
||||
jmp __vector_TIMER2_COMPB
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_OVF
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_PCINT1
|
||||
IRQ __vector_PCINT2
|
||||
IRQ __vector_PCINT3
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER2_COMPA
|
||||
IRQ __vector_TIMER2_COMPB
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_OVF
|
||||
7
targets/device/avr/atmega1284rfr2.ld
Normal file
7
targets/device/avr/atmega1284rfr2.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from ATmega1284RFR2.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x200;
|
||||
__ram_size = 0x4000;
|
||||
__num_isrs = 71;
|
||||
172
targets/device/avr/atmega1284rfr2.s
Normal file
172
targets/device/avr/atmega1284rfr2.s
Normal file
@@ -0,0 +1,172 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from ATmega1284RFR2.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_PCINT1
|
||||
jmp __vector_PCINT2
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER2_COMPA
|
||||
jmp __vector_TIMER2_COMPB
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
jmp __vector_TIMER4_CAPT
|
||||
jmp __vector_TIMER4_COMPA
|
||||
jmp __vector_TIMER4_COMPB
|
||||
jmp __vector_TIMER4_COMPC
|
||||
jmp __vector_TIMER4_OVF
|
||||
jmp __vector_TIMER5_CAPT
|
||||
jmp __vector_TIMER5_COMPA
|
||||
jmp __vector_TIMER5_COMPB
|
||||
jmp __vector_TIMER5_COMPC
|
||||
jmp __vector_TIMER5_OVF
|
||||
jmp __vector_default
|
||||
jmp __vector_default
|
||||
jmp __vector_default
|
||||
jmp __vector_default
|
||||
jmp __vector_default
|
||||
jmp __vector_default
|
||||
jmp __vector_TRX24_PLL_LOCK
|
||||
jmp __vector_TRX24_PLL_UNLOCK
|
||||
jmp __vector_TRX24_RX_START
|
||||
jmp __vector_TRX24_RX_END
|
||||
jmp __vector_TRX24_CCA_ED_DONE
|
||||
jmp __vector_TRX24_XAH_AMI
|
||||
jmp __vector_TRX24_TX_END
|
||||
jmp __vector_TRX24_AWAKE
|
||||
jmp __vector_SCNT_CMP1
|
||||
jmp __vector_SCNT_CMP2
|
||||
jmp __vector_SCNT_CMP3
|
||||
jmp __vector_SCNT_OVFL
|
||||
jmp __vector_SCNT_BACKOFF
|
||||
jmp __vector_AES_READY
|
||||
jmp __vector_BAT_LOW
|
||||
jmp __vector_TRX24_TX_START
|
||||
jmp __vector_TRX24_AMI0
|
||||
jmp __vector_TRX24_AMI1
|
||||
jmp __vector_TRX24_AMI2
|
||||
jmp __vector_TRX24_AMI3
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_PCINT1
|
||||
IRQ __vector_PCINT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER2_COMPA
|
||||
IRQ __vector_TIMER2_COMPB
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
IRQ __vector_TIMER4_CAPT
|
||||
IRQ __vector_TIMER4_COMPA
|
||||
IRQ __vector_TIMER4_COMPB
|
||||
IRQ __vector_TIMER4_COMPC
|
||||
IRQ __vector_TIMER4_OVF
|
||||
IRQ __vector_TIMER5_CAPT
|
||||
IRQ __vector_TIMER5_COMPA
|
||||
IRQ __vector_TIMER5_COMPB
|
||||
IRQ __vector_TIMER5_COMPC
|
||||
IRQ __vector_TIMER5_OVF
|
||||
IRQ __vector_TRX24_PLL_LOCK
|
||||
IRQ __vector_TRX24_PLL_UNLOCK
|
||||
IRQ __vector_TRX24_RX_START
|
||||
IRQ __vector_TRX24_RX_END
|
||||
IRQ __vector_TRX24_CCA_ED_DONE
|
||||
IRQ __vector_TRX24_XAH_AMI
|
||||
IRQ __vector_TRX24_TX_END
|
||||
IRQ __vector_TRX24_AWAKE
|
||||
IRQ __vector_SCNT_CMP1
|
||||
IRQ __vector_SCNT_CMP2
|
||||
IRQ __vector_SCNT_CMP3
|
||||
IRQ __vector_SCNT_OVFL
|
||||
IRQ __vector_SCNT_BACKOFF
|
||||
IRQ __vector_AES_READY
|
||||
IRQ __vector_BAT_LOW
|
||||
IRQ __vector_TRX24_TX_START
|
||||
IRQ __vector_TRX24_AMI0
|
||||
IRQ __vector_TRX24_AMI1
|
||||
IRQ __vector_TRX24_AMI2
|
||||
IRQ __vector_TRX24_AMI3
|
||||
7
targets/device/avr/atmega128a.ld
Normal file
7
targets/device/avr/atmega128a.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from ATmega128A.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x100;
|
||||
__ram_size = 0x1000;
|
||||
__num_isrs = 35;
|
||||
94
targets/device/avr/atmega128a.s
Normal file
94
targets/device/avr/atmega128a.s
Normal file
@@ -0,0 +1,94 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from ATmega128A.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_TIMER2_COMP
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMP
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_TIMER2_COMP
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMP
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
7
targets/device/avr/atmega128rfa1.ld
Normal file
7
targets/device/avr/atmega128rfa1.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from ATmega128RFA1.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x200;
|
||||
__ram_size = 0x4000;
|
||||
__num_isrs = 72;
|
||||
168
targets/device/avr/atmega128rfa1.s
Normal file
168
targets/device/avr/atmega128rfa1.s
Normal file
@@ -0,0 +1,168 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from ATmega128RFA1.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_PCINT1
|
||||
jmp __vector_PCINT2
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER2_COMPA
|
||||
jmp __vector_TIMER2_COMPB
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
jmp __vector_TIMER4_CAPT
|
||||
jmp __vector_TIMER4_COMPA
|
||||
jmp __vector_TIMER4_COMPB
|
||||
jmp __vector_TIMER4_COMPC
|
||||
jmp __vector_TIMER4_OVF
|
||||
jmp __vector_TIMER5_CAPT
|
||||
jmp __vector_TIMER5_COMPA
|
||||
jmp __vector_TIMER5_COMPB
|
||||
jmp __vector_TIMER5_COMPC
|
||||
jmp __vector_TIMER5_OVF
|
||||
jmp __vector_USART2_RX
|
||||
jmp __vector_USART2_UDRE
|
||||
jmp __vector_USART2_TX
|
||||
jmp __vector_USART3_RX
|
||||
jmp __vector_USART3_UDRE
|
||||
jmp __vector_USART3_TX
|
||||
jmp __vector_TRX24_PLL_LOCK
|
||||
jmp __vector_TRX24_PLL_UNLOCK
|
||||
jmp __vector_TRX24_RX_START
|
||||
jmp __vector_TRX24_RX_END
|
||||
jmp __vector_TRX24_CCA_ED_DONE
|
||||
jmp __vector_TRX24_XAH_AMI
|
||||
jmp __vector_TRX24_TX_END
|
||||
jmp __vector_TRX24_AWAKE
|
||||
jmp __vector_SCNT_CMP1
|
||||
jmp __vector_SCNT_CMP2
|
||||
jmp __vector_SCNT_CMP3
|
||||
jmp __vector_SCNT_OVFL
|
||||
jmp __vector_SCNT_BACKOFF
|
||||
jmp __vector_AES_READY
|
||||
jmp __vector_BAT_LOW
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_PCINT1
|
||||
IRQ __vector_PCINT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER2_COMPA
|
||||
IRQ __vector_TIMER2_COMPB
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
IRQ __vector_TIMER4_CAPT
|
||||
IRQ __vector_TIMER4_COMPA
|
||||
IRQ __vector_TIMER4_COMPB
|
||||
IRQ __vector_TIMER4_COMPC
|
||||
IRQ __vector_TIMER4_OVF
|
||||
IRQ __vector_TIMER5_CAPT
|
||||
IRQ __vector_TIMER5_COMPA
|
||||
IRQ __vector_TIMER5_COMPB
|
||||
IRQ __vector_TIMER5_COMPC
|
||||
IRQ __vector_TIMER5_OVF
|
||||
IRQ __vector_USART2_RX
|
||||
IRQ __vector_USART2_UDRE
|
||||
IRQ __vector_USART2_TX
|
||||
IRQ __vector_USART3_RX
|
||||
IRQ __vector_USART3_UDRE
|
||||
IRQ __vector_USART3_TX
|
||||
IRQ __vector_TRX24_PLL_LOCK
|
||||
IRQ __vector_TRX24_PLL_UNLOCK
|
||||
IRQ __vector_TRX24_RX_START
|
||||
IRQ __vector_TRX24_RX_END
|
||||
IRQ __vector_TRX24_CCA_ED_DONE
|
||||
IRQ __vector_TRX24_XAH_AMI
|
||||
IRQ __vector_TRX24_TX_END
|
||||
IRQ __vector_TRX24_AWAKE
|
||||
IRQ __vector_SCNT_CMP1
|
||||
IRQ __vector_SCNT_CMP2
|
||||
IRQ __vector_SCNT_CMP3
|
||||
IRQ __vector_SCNT_OVFL
|
||||
IRQ __vector_SCNT_BACKOFF
|
||||
IRQ __vector_AES_READY
|
||||
IRQ __vector_BAT_LOW
|
||||
7
targets/device/avr/atmega128rfr2.ld
Normal file
7
targets/device/avr/atmega128rfr2.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from ATmega128RFR2.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x20000;
|
||||
__ram_start = 0x200;
|
||||
__ram_size = 0x4000;
|
||||
__num_isrs = 71;
|
||||
172
targets/device/avr/atmega128rfr2.s
Normal file
172
targets/device/avr/atmega128rfr2.s
Normal file
@@ -0,0 +1,172 @@
|
||||
; Automatically generated file. DO NOT EDIT.
|
||||
; Generated by gen-device-avr.go from ATmega128RFR2.atdf, see http://packs.download.atmel.com/
|
||||
|
||||
; This is the default handler for interrupts, if triggered but not defined.
|
||||
; Sleep inside so that an accidentally triggered interrupt won't drain the
|
||||
; battery of a battery-powered device.
|
||||
.section .text.__vector_default
|
||||
.global __vector_default
|
||||
__vector_default:
|
||||
sleep
|
||||
rjmp __vector_default
|
||||
|
||||
; Avoid the need for repeated .weak and .set instructions.
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, __vector_default
|
||||
.endm
|
||||
|
||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||
.section .vectors, "a", %progbits
|
||||
.global __vectors
|
||||
jmp __vector_RESET
|
||||
jmp __vector_INT0
|
||||
jmp __vector_INT1
|
||||
jmp __vector_INT2
|
||||
jmp __vector_INT3
|
||||
jmp __vector_INT4
|
||||
jmp __vector_INT5
|
||||
jmp __vector_INT6
|
||||
jmp __vector_INT7
|
||||
jmp __vector_PCINT0
|
||||
jmp __vector_PCINT1
|
||||
jmp __vector_PCINT2
|
||||
jmp __vector_WDT
|
||||
jmp __vector_TIMER2_COMPA
|
||||
jmp __vector_TIMER2_COMPB
|
||||
jmp __vector_TIMER2_OVF
|
||||
jmp __vector_TIMER1_CAPT
|
||||
jmp __vector_TIMER1_COMPA
|
||||
jmp __vector_TIMER1_COMPB
|
||||
jmp __vector_TIMER1_COMPC
|
||||
jmp __vector_TIMER1_OVF
|
||||
jmp __vector_TIMER0_COMPA
|
||||
jmp __vector_TIMER0_COMPB
|
||||
jmp __vector_TIMER0_OVF
|
||||
jmp __vector_SPI_STC
|
||||
jmp __vector_USART0_RX
|
||||
jmp __vector_USART0_UDRE
|
||||
jmp __vector_USART0_TX
|
||||
jmp __vector_ANALOG_COMP
|
||||
jmp __vector_ADC
|
||||
jmp __vector_EE_READY
|
||||
jmp __vector_TIMER3_CAPT
|
||||
jmp __vector_TIMER3_COMPA
|
||||
jmp __vector_TIMER3_COMPB
|
||||
jmp __vector_TIMER3_COMPC
|
||||
jmp __vector_TIMER3_OVF
|
||||
jmp __vector_USART1_RX
|
||||
jmp __vector_USART1_UDRE
|
||||
jmp __vector_USART1_TX
|
||||
jmp __vector_TWI
|
||||
jmp __vector_SPM_READY
|
||||
jmp __vector_TIMER4_CAPT
|
||||
jmp __vector_TIMER4_COMPA
|
||||
jmp __vector_TIMER4_COMPB
|
||||
jmp __vector_TIMER4_COMPC
|
||||
jmp __vector_TIMER4_OVF
|
||||
jmp __vector_TIMER5_CAPT
|
||||
jmp __vector_TIMER5_COMPA
|
||||
jmp __vector_TIMER5_COMPB
|
||||
jmp __vector_TIMER5_COMPC
|
||||
jmp __vector_TIMER5_OVF
|
||||
jmp __vector_default
|
||||
jmp __vector_default
|
||||
jmp __vector_default
|
||||
jmp __vector_default
|
||||
jmp __vector_default
|
||||
jmp __vector_default
|
||||
jmp __vector_TRX24_PLL_LOCK
|
||||
jmp __vector_TRX24_PLL_UNLOCK
|
||||
jmp __vector_TRX24_RX_START
|
||||
jmp __vector_TRX24_RX_END
|
||||
jmp __vector_TRX24_CCA_ED_DONE
|
||||
jmp __vector_TRX24_XAH_AMI
|
||||
jmp __vector_TRX24_TX_END
|
||||
jmp __vector_TRX24_AWAKE
|
||||
jmp __vector_SCNT_CMP1
|
||||
jmp __vector_SCNT_CMP2
|
||||
jmp __vector_SCNT_CMP3
|
||||
jmp __vector_SCNT_OVFL
|
||||
jmp __vector_SCNT_BACKOFF
|
||||
jmp __vector_AES_READY
|
||||
jmp __vector_BAT_LOW
|
||||
jmp __vector_TRX24_TX_START
|
||||
jmp __vector_TRX24_AMI0
|
||||
jmp __vector_TRX24_AMI1
|
||||
jmp __vector_TRX24_AMI2
|
||||
jmp __vector_TRX24_AMI3
|
||||
|
||||
; Define default implementations for interrupts, redirecting to
|
||||
; __vector_default when not implemented.
|
||||
IRQ __vector_RESET
|
||||
IRQ __vector_INT0
|
||||
IRQ __vector_INT1
|
||||
IRQ __vector_INT2
|
||||
IRQ __vector_INT3
|
||||
IRQ __vector_INT4
|
||||
IRQ __vector_INT5
|
||||
IRQ __vector_INT6
|
||||
IRQ __vector_INT7
|
||||
IRQ __vector_PCINT0
|
||||
IRQ __vector_PCINT1
|
||||
IRQ __vector_PCINT2
|
||||
IRQ __vector_WDT
|
||||
IRQ __vector_TIMER2_COMPA
|
||||
IRQ __vector_TIMER2_COMPB
|
||||
IRQ __vector_TIMER2_OVF
|
||||
IRQ __vector_TIMER1_CAPT
|
||||
IRQ __vector_TIMER1_COMPA
|
||||
IRQ __vector_TIMER1_COMPB
|
||||
IRQ __vector_TIMER1_COMPC
|
||||
IRQ __vector_TIMER1_OVF
|
||||
IRQ __vector_TIMER0_COMPA
|
||||
IRQ __vector_TIMER0_COMPB
|
||||
IRQ __vector_TIMER0_OVF
|
||||
IRQ __vector_SPI_STC
|
||||
IRQ __vector_USART0_RX
|
||||
IRQ __vector_USART0_UDRE
|
||||
IRQ __vector_USART0_TX
|
||||
IRQ __vector_ANALOG_COMP
|
||||
IRQ __vector_ADC
|
||||
IRQ __vector_EE_READY
|
||||
IRQ __vector_TIMER3_CAPT
|
||||
IRQ __vector_TIMER3_COMPA
|
||||
IRQ __vector_TIMER3_COMPB
|
||||
IRQ __vector_TIMER3_COMPC
|
||||
IRQ __vector_TIMER3_OVF
|
||||
IRQ __vector_USART1_RX
|
||||
IRQ __vector_USART1_UDRE
|
||||
IRQ __vector_USART1_TX
|
||||
IRQ __vector_TWI
|
||||
IRQ __vector_SPM_READY
|
||||
IRQ __vector_TIMER4_CAPT
|
||||
IRQ __vector_TIMER4_COMPA
|
||||
IRQ __vector_TIMER4_COMPB
|
||||
IRQ __vector_TIMER4_COMPC
|
||||
IRQ __vector_TIMER4_OVF
|
||||
IRQ __vector_TIMER5_CAPT
|
||||
IRQ __vector_TIMER5_COMPA
|
||||
IRQ __vector_TIMER5_COMPB
|
||||
IRQ __vector_TIMER5_COMPC
|
||||
IRQ __vector_TIMER5_OVF
|
||||
IRQ __vector_TRX24_PLL_LOCK
|
||||
IRQ __vector_TRX24_PLL_UNLOCK
|
||||
IRQ __vector_TRX24_RX_START
|
||||
IRQ __vector_TRX24_RX_END
|
||||
IRQ __vector_TRX24_CCA_ED_DONE
|
||||
IRQ __vector_TRX24_XAH_AMI
|
||||
IRQ __vector_TRX24_TX_END
|
||||
IRQ __vector_TRX24_AWAKE
|
||||
IRQ __vector_SCNT_CMP1
|
||||
IRQ __vector_SCNT_CMP2
|
||||
IRQ __vector_SCNT_CMP3
|
||||
IRQ __vector_SCNT_OVFL
|
||||
IRQ __vector_SCNT_BACKOFF
|
||||
IRQ __vector_AES_READY
|
||||
IRQ __vector_BAT_LOW
|
||||
IRQ __vector_TRX24_TX_START
|
||||
IRQ __vector_TRX24_AMI0
|
||||
IRQ __vector_TRX24_AMI1
|
||||
IRQ __vector_TRX24_AMI2
|
||||
IRQ __vector_TRX24_AMI3
|
||||
7
targets/device/avr/atmega16.ld
Normal file
7
targets/device/avr/atmega16.ld
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Automatically generated file. DO NOT EDIT. */
|
||||
/* Generated by gen-device-avr.go from ATmega16.atdf, see http://packs.download.atmel.com/ */
|
||||
|
||||
__flash_size = 0x4000;
|
||||
__ram_start = 0x60;
|
||||
__ram_size = 0x400;
|
||||
__num_isrs = 21;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user