avr: automatically generate interrupt vectors
Этот коммит содержится в:
родитель
3850530c88
коммит
b9638315d2
5 изменённых файлов: 61 добавлений и 15 удалений
1
.gitignore
предоставленный
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)
|
||||
|
||||
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче