From 5bace979ea6cee3fc64675d7ad6212547c38e7ce Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 9 Mar 2020 16:26:20 +0100 Subject: [PATCH] avr: use the correct RAM start address Previously, the RAM was set to start at address 0. This is incorrect: on AVR, the first few addresses are taken up by memory-mapped I/O. The reason this didn't lead to problems (yet) was because the stack was usually big enough to avoid real problems. --- targets/avr.ld | 4 +-- tools/gen-device-avr/gen-device-avr.go | 43 +++++++++++++++++++++----- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/targets/avr.ld b/targets/avr.ld index 0a92e5f3..7e45b533 100644 --- a/targets/avr.ld +++ b/targets/avr.ld @@ -1,8 +1,8 @@ MEMORY { - FLASH_TEXT (rw) : ORIGIN = 0, LENGTH = __flash_size - _bootloader_size - RAM (xrw) : ORIGIN = 0, LENGTH = __ram_size + FLASH_TEXT (rw) : ORIGIN = 0, LENGTH = __flash_size - _bootloader_size + RAM (xrw) : ORIGIN = __ram_start, LENGTH = __ram_size } SECTIONS diff --git a/tools/gen-device-avr/gen-device-avr.go b/tools/gen-device-avr/gen-device-avr.go index 8f9298a2..9b9c627a 100755 --- a/tools/gen-device-avr/gen-device-avr.go +++ b/tools/gen-device-avr/gen-device-avr.go @@ -24,8 +24,9 @@ type AVRToolsDeviceFile struct { Name string `xml:"name,attr"` Size string `xml:"size,attr"` MemorySegments []struct { - Name string `xml:"name,attr"` - Size string `xml:"size,attr"` + Name string `xml:"name,attr"` + Start string `xml:"start,attr"` + Size string `xml:"size,attr"` } `xml:"memory-segment"` } `xml:"address-spaces>address-space"` Interrupts []Interrupt `xml:"interrupts>interrupt"` @@ -57,9 +58,26 @@ type Device struct { peripherals []*Peripheral } +// AddressSpace is the Go version of an XML element like the following: +// +// +// +// It describes one address space in an AVR microcontroller. One address space +// may have multiple memory segments. type AddressSpace struct { Size string - Segments map[string]int + Segments map[string]MemorySegment +} + +// MemorySegment is the Go version of an XML element like the following: +// +// +// +// It describes a single contiguous area of memory in a particular address space +// (see AddressSpace). +type MemorySegment struct { + start int64 + size int64 } type Interrupt struct { @@ -115,14 +133,21 @@ func readATDF(path string) (*Device, error) { for _, el := range device.AddressSpaces { memorySizes[el.Name] = &AddressSpace{ Size: el.Size, - Segments: make(map[string]int), + Segments: make(map[string]MemorySegment), } for _, segmentEl := range el.MemorySegments { + start, err := strconv.ParseInt(segmentEl.Start, 0, 32) + if err != nil { + return nil, err + } size, err := strconv.ParseInt(segmentEl.Size, 0, 32) if err != nil { return nil, err } - memorySizes[el.Name].Segments[segmentEl.Name] = int(size) + memorySizes[el.Name].Segments[segmentEl.Name] = MemorySegment{ + start: start, + size: size, + } } } @@ -205,10 +230,12 @@ func readATDF(path string) (*Device, error) { } } - ramSize := 0 // for devices with no RAM + ramStart := int64(0) + ramSize := int64(0) // for devices with no RAM for _, ramSegmentName := range []string{"IRAM", "INTERNAL_SRAM", "SRAM"} { if segment, ok := memorySizes["data"].Segments[ramSegmentName]; ok { - ramSize = segment + ramStart = segment.start + ramSize = segment.size } } @@ -227,6 +254,7 @@ func readATDF(path string) (*Device, error) { "arch": device.Architecture, "family": device.Family, "flashSize": int(flashSize), + "ramStart": ramStart, "ramSize": ramSize, "numInterrupts": len(device.Interrupts), }, @@ -429,6 +457,7 @@ func writeLD(outdir string, device *Device) error { /* Generated by gen-device-avr.go from {{.file}}, see {{.descriptorSource}} */ __flash_size = 0x{{printf "%x" .flashSize}}; +__ram_start = 0x{{printf "%x" .ramStart}}; __ram_size = 0x{{printf "%x" .ramSize}}; __num_isrs = {{.numInterrupts}}; `))