esp32: add support for running and debuggin using qemu-esp32
Этот коммит содержится в:
родитель
bd56636d58
коммит
8568d4f625
5 изменённых файлов: 57 добавлений и 9 удалений
|
@ -37,8 +37,14 @@ import (
|
|||
// BuildResult is the output of a build. This includes the binary itself and
|
||||
// some other metadata that is obtained while building the binary.
|
||||
type BuildResult struct {
|
||||
// The executable directly from the linker, usually including debug
|
||||
// information. Used for GDB for example.
|
||||
Executable string
|
||||
|
||||
// A path to the output binary. It will be removed after Build returns, so
|
||||
// if it should be kept it must be copied or moved away.
|
||||
// It is often the same as Executable, but differs if the output format is
|
||||
// .hex for example (instead of the usual ELF).
|
||||
Binary string
|
||||
|
||||
// The directory of the main package. This is useful for testing as the test
|
||||
|
@ -835,7 +841,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "esp32", "esp32c3", "esp8266":
|
||||
case "esp32", "esp32-img", "esp32c3", "esp8266":
|
||||
// Special format for the ESP family of chips (parsed by the ROM
|
||||
// bootloader).
|
||||
tmppath = filepath.Join(dir, "main"+outext)
|
||||
|
@ -867,6 +873,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
|
|||
}
|
||||
|
||||
return action(BuildResult{
|
||||
Executable: executable,
|
||||
Binary: tmppath,
|
||||
MainDir: lprogram.MainPkg().Dir,
|
||||
ModuleRoot: moduleroot,
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type espImageSegment struct {
|
||||
|
@ -78,15 +79,31 @@ func makeESPFirmareImage(infile, outfile, format string) error {
|
|||
// 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,
|
||||
}[format]
|
||||
}[chip]
|
||||
|
||||
// Image header.
|
||||
switch format {
|
||||
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
|
||||
|
@ -155,12 +172,22 @@ func makeESPFirmareImage(infile, outfile, format string) error {
|
|||
outf.Write(make([]byte, 15-outf.Len()%16))
|
||||
outf.WriteByte(checksum)
|
||||
|
||||
if format != "esp8266" {
|
||||
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 ioutil.WriteFile(outfile, outf.Bytes(), 0666)
|
||||
}
|
||||
|
|
|
@ -395,6 +395,13 @@ func (c *Config) BinaryFormat(ext string) string {
|
|||
return c.Target.BinaryFormat
|
||||
}
|
||||
return "bin"
|
||||
case ".img":
|
||||
// Image file. Only defined for the ESP32 at the moment, where it is a
|
||||
// full (runnable) image that can be used in the Espressif QEMU fork.
|
||||
if c.Target.BinaryFormat != "" {
|
||||
return c.Target.BinaryFormat + "-img"
|
||||
}
|
||||
return "bin"
|
||||
case ".hex":
|
||||
// Similar to bin, but includes the start address and is thus usually a
|
||||
// better format.
|
||||
|
@ -507,9 +514,14 @@ func (c *Config) EmulatorName() string {
|
|||
|
||||
// EmulatorFormat returns the binary format for the emulator and the associated
|
||||
// file extension. An empty string means to pass directly whatever the linker
|
||||
// produces directly without conversion.
|
||||
// produces directly without conversion (usually ELF format).
|
||||
func (c *Config) EmulatorFormat() (format, fileExt string) {
|
||||
return "", ""
|
||||
switch {
|
||||
case strings.Contains(c.Target.Emulator, "{img}"):
|
||||
return "img", ".img"
|
||||
default:
|
||||
return "", ""
|
||||
}
|
||||
}
|
||||
|
||||
// Emulator returns a ready-to-run command to run the given binary in an
|
||||
|
|
4
main.go
4
main.go
|
@ -634,7 +634,7 @@ func Debug(debugger, pkgName string, ocdOutput bool, options *compileopts.Option
|
|||
// Construct and execute a gdb or lldb command.
|
||||
// By default: gdb -ex run <binary>
|
||||
// Exit the debugger with Ctrl-D.
|
||||
params := []string{result.Binary}
|
||||
params := []string{result.Executable}
|
||||
switch debugger {
|
||||
case "gdb":
|
||||
if port != "" {
|
||||
|
@ -668,7 +668,7 @@ func Debug(debugger, pkgName string, ocdOutput bool, options *compileopts.Option
|
|||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return &commandError{"failed to run " + cmdName + " with", result.Binary, err}
|
||||
return &commandError{"failed to run " + cmdName + " with", result.Executable, err}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
|
|
@ -15,5 +15,7 @@
|
|||
"src/internal/task/task_stack_esp32.S"
|
||||
],
|
||||
"binary-format": "esp32",
|
||||
"flash-command": "esptool.py --chip=esp32 --port {port} write_flash 0x1000 {bin} -ff 80m -fm dout"
|
||||
"flash-command": "esptool.py --chip=esp32 --port {port} write_flash 0x1000 {bin} -ff 80m -fm dout",
|
||||
"emulator": "qemu-system-xtensa -machine esp32 -nographic -drive file={img},if=mtd,format=raw",
|
||||
"gdb": ["xtensa-esp32-elf-gdb"]
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче