mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
144 lines
3.9 KiB
Python
144 lines
3.9 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
# Copyright (C) 2020 Inria
|
||
|
#
|
||
|
# This file is subject to the terms and conditions of the GNU Lesser
|
||
|
# General Public License v2.1. See the file LICENSE in the top level
|
||
|
# directory for more details.
|
||
|
|
||
|
"""Generate the vectors table for a given STM32 CPU line."""
|
||
|
|
||
|
import os
|
||
|
import argparse
|
||
|
import re
|
||
|
|
||
|
|
||
|
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||
|
RIOTBASE = os.getenv(
|
||
|
"RIOTBASE", os.path.abspath(os.path.join(CURRENT_DIR, "../../../..")))
|
||
|
STM32_VECTORS_DIR = os.path.join(RIOTBASE, "cpu/stm32/vectors")
|
||
|
STM32_VENDOR_DIR = os.path.join(RIOTBASE, "cpu/stm32/include/vendor")
|
||
|
STM32_CMSIS_FILE = os.path.join(
|
||
|
RIOTBASE, STM32_VENDOR_DIR, "cmsis/{}/Include/{}.h")
|
||
|
|
||
|
VECTORS_FORMAT = """
|
||
|
/*
|
||
|
* PLEASE DON'T EDIT
|
||
|
*
|
||
|
* This file was automatically generated by
|
||
|
* ./cpu/stm32/dist/irqs/gen_vectors.py
|
||
|
*/
|
||
|
|
||
|
#include "vectors_cortexm.h"
|
||
|
|
||
|
/* define a local dummy handler as it needs to be in the same compilation unit
|
||
|
* as the alias definition */
|
||
|
void dummy_handler(void) {{
|
||
|
dummy_handler_default();
|
||
|
}}
|
||
|
|
||
|
/* {cpu_line} specific interrupt vectors */
|
||
|
{isr_lines}
|
||
|
|
||
|
/* CPU specific interrupt vector table */
|
||
|
ISR_VECTOR(1) const isr_t vector_cpu[CPU_IRQ_NUMOF] = {{
|
||
|
{irq_lines}
|
||
|
}};
|
||
|
"""
|
||
|
|
||
|
|
||
|
def parse_cmsis(cpu_line):
|
||
|
"""Parse the CMSIS to get the list IRQs."""
|
||
|
cpu_fam = cpu_line[5:7]
|
||
|
if cpu_line == "STM32F030x4":
|
||
|
# STM32F030x4 is provided in the RIOT codebase in a different location
|
||
|
cpu_line_cmsis = os.path.join(
|
||
|
STM32_VENDOR_DIR, "{}.h".format(cpu_line.lower()))
|
||
|
else:
|
||
|
cpu_line_cmsis = STM32_CMSIS_FILE.format(
|
||
|
cpu_fam.lower(), cpu_line.lower())
|
||
|
|
||
|
with open(cpu_line_cmsis, 'rb') as cmsis:
|
||
|
cmsis_content = cmsis.readlines()
|
||
|
|
||
|
irq_lines = []
|
||
|
use_line = False
|
||
|
for line in cmsis_content:
|
||
|
try:
|
||
|
line = line.decode()
|
||
|
except UnicodeDecodeError:
|
||
|
# skip line that contains non unicode characters
|
||
|
continue
|
||
|
# start filling lines after interrupt Doxygen comment
|
||
|
if line.startswith("typedef enum"):
|
||
|
use_line = True
|
||
|
|
||
|
# use a regexp to get the available IRQs
|
||
|
match = re.match(r"[ ]+([a-zA-Z0-9_]+_IRQn)[ ]+= \d+,", line)
|
||
|
|
||
|
# Skip lines that don't match
|
||
|
if match is None:
|
||
|
continue
|
||
|
|
||
|
# Skip remapped USB interrupt
|
||
|
# (set as alias for USBWakeUp_IRQn on stm32f3)
|
||
|
if "USBWakeUp_RMP_IRQn" in line:
|
||
|
continue
|
||
|
|
||
|
# Stop at the end of the IRQn_Type enum definition
|
||
|
if "IRQn_Type" in line:
|
||
|
break
|
||
|
|
||
|
# Only append IRQ line if it should be used and is not empty
|
||
|
if use_line:
|
||
|
irq_lines.append(match.group(1).strip())
|
||
|
|
||
|
isrs = [
|
||
|
{
|
||
|
"irq": irq,
|
||
|
"func": "exti" if "EXTI" in irq else irq.lower().rsplit("_", 1)[0]
|
||
|
}
|
||
|
for irq in irq_lines
|
||
|
]
|
||
|
|
||
|
return {"isrs": isrs, "cpu_line": cpu_line}
|
||
|
|
||
|
|
||
|
def generate_vectors(context):
|
||
|
"""Use vector template string to generate the vectors C file."""
|
||
|
isr_line_format = "WEAK_DEFAULT void isr_{func}(void);"
|
||
|
irq_line_format = " [{irq:<35}] = isr_{func},"
|
||
|
|
||
|
isr_lines = []
|
||
|
irq_lines = []
|
||
|
for isr in context["isrs"]:
|
||
|
isr_line = isr_line_format.format(**isr)
|
||
|
if isr_line not in isr_lines:
|
||
|
isr_lines.append(isr_line)
|
||
|
irq_lines.append(irq_line_format.format(**isr))
|
||
|
vectors_content = VECTORS_FORMAT.format(
|
||
|
cpu_line=context["cpu_line"],
|
||
|
isr_lines="\n".join(isr_lines),
|
||
|
irq_lines="\n".join(irq_lines),
|
||
|
)
|
||
|
|
||
|
dest_file = os.path.join(
|
||
|
STM32_VECTORS_DIR, "{}.c".format(context["cpu_line"])
|
||
|
)
|
||
|
|
||
|
with open(dest_file, "w") as f_dest:
|
||
|
f_dest.write(vectors_content)
|
||
|
|
||
|
|
||
|
def main(args):
|
||
|
"""Main function."""
|
||
|
context = parse_cmsis(args.cpu_line)
|
||
|
generate_vectors(context)
|
||
|
|
||
|
|
||
|
PARSER = argparse.ArgumentParser()
|
||
|
PARSER.add_argument("cpu_line", help="STM32 CPU line")
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main(PARSER.parse_args())
|