avr: automatically generate interrupt vectors

Этот коммит содержится в:
Ayke van Laethem 2018-09-23 20:37:22 +02:00
родитель 3850530c88
коммит b9638315d2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E97FF5335DFDFDED
5 изменённых файлов: 61 добавлений и 15 удалений

1
.gitignore предоставленный
Просмотреть файл

@ -2,6 +2,7 @@ build
docs/_build
src/device/avr/*.go
src/device/avr/*.ld
src/device/avr/*.s
src/device/nrf/*.go
src/device/nrf/*.s
src/device/stm32/*.go

Просмотреть файл

@ -1,8 +1,8 @@
{
"llvm-target": "avr-atmel-none",
"build-tags": ["arduino", "atmega328p", "atmega", "avr8", "avr", "js", "wasm"],
"build-tags": ["arduino", "atmega328p", "atmega", "avr5", "avr", "js", "wasm"],
"linker": "avr-gcc",
"pre-link-args": ["-nostartfiles", "-T", "targets/avr.ld", "-Wl,--gc-sections", "targets/avr.S"],
"pre-link-args": ["-nostartfiles", "-mmcu=avr5", "-T", "targets/avr.ld", "-Wl,--gc-sections", "targets/avr.S", "src/device/avr/atmega328p.s"],
"objcopy": "avr-objcopy",
"flash": "avrdude -c arduino -p atmega328p -P {port} -U flash:w:{hex}"
}

Просмотреть файл

@ -1,14 +1,11 @@
.section .isr
isr:
rjmp reset
.org 0x18 ; WDT
rjmp wdt
; This file provides common code across AVRs that cannot be implemented directly
; in Go.
; The reset vector is device-specific and is generated by tools/gen-device-avr.py.
; Startup code
.section .reset
.org 26
reset:
.section .text.__vector_RESET
.global __vector_RESET
__vector_RESET:
clr r1 ; r1 is expected to be 0 by the C calling convention
; Set up the stack pointer.
@ -41,10 +38,21 @@ init_data_end:
; need to jump.
; 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
; The only thing this WDT handler really does is disable itself, to get out of
; sleep mode.
.section .text.wdt
wdt:
.section .text.__vector_WDT
.global __vector_WDT
__vector_WDT:
push r16
clr r16

Просмотреть файл

@ -12,8 +12,8 @@ SECTIONS
{
.text :
{
KEEP(*(.isr))
KEEP(*(.reset))
KEEP(*(.vectors))
KEEP(*(.text.__vector_RESET))
KEEP(*(.text.main)) /* main must follow the reset handler */
*(.text.*)
*(.rodata)

Просмотреть файл

@ -201,6 +201,42 @@ const (
out.write('\n')
out.write(')\n')
def writeAsm(outdir, device):
# The interrupt vector, which is hard to write directly in Go.
out = open(outdir + '/' + device.metadata['nameLower'] + '.s', 'w')
out.write('''\
; Automatically generated file. DO NOT EDIT.
; Generated by gen-device-avr.py from {file}, see {descriptorSource}
; 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
.global __vectors
'''.format(**device.metadata))
num = 0
for intr in device.interrupts:
if intr['index'] < num:
# Some devices have duplicate interrupts, probably for historical
# reasons.
continue
while intr['index'] > num:
out.write(' jmp __vector_default\n')
num += 1
num += 1
out.write(' jmp __vector_{name}\n'.format(**intr))
out.write('''
; Define default implementations for interrupts, redirecting to
; __vector_default when not implemented.
''')
for intr in device.interrupts:
out.write(' IRQ __vector_{name}\n'.format(**intr))
def writeLD(outdir, device):
# Variables for the linker script.
out = open(outdir + '/' + device.metadata['nameLower'] + '.ld', 'w')
@ -220,6 +256,7 @@ def generate(indir, outdir):
print(filepath)
device = readATDF(filepath)
writeGo(outdir, device)
writeAsm(outdir, device)
writeLD(outdir, device)