1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/cpu/stm32/dist/irqs/gen_vectors.py
Gilles DOFFE 91a12c200c cpu/stm32: do not retrieve cmsis headers
Normally, CMSIS headers are retrieved as package from ST git repository
for each stm32.
However stm32mp1 family does not have a CMSIS headers repository but
have been included into RIOT source code in a previous commit.
For stm32mp1, CMSIS headers package must then not be retrieved and
vectors have to be generated from already in-source CMSIS headers.

Signed-off-by: Gilles DOFFE <gilles.doffe@savoirfairelinux.com>
2020-11-13 10:43:08 +01:00

148 lines
4.1 KiB
Python
Executable File

#!/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()))
elif cpu_line.startswith("STM32MP1"):
# STM32MP157Cxx is provided in the RIOT codebase in a different location
cpu_line_cmsis = os.path.join(
STM32_VENDOR_DIR, "{}_cm4.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 "typedef enum" in line:
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())