mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
91a12c200c
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>
148 lines
4.1 KiB
Python
Executable File
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())
|