tools: added tool for auto-generating ISR vectors#7553
tools: added tool for auto-generating ISR vectors#7553haukepetersen wants to merge 4 commits intoRIOT-OS:masterfrom
Conversation
aabadie
left a comment
There was a problem hiding this comment.
Looks quite good. This tool is definitely useful.
I pointed to mainly small python style issues.
I'll test it when time permits.
dist/tools/isrvecgen/isrvecgen.py
Outdated
| "isr_exti[_\d+]+": "isr_exti" | ||
| } | ||
|
|
||
| def parse_cpuconf( cpuconf ): |
There was a problem hiding this comment.
PEP8, no space around parameter, here and below
There was a problem hiding this comment.
good to know, will fix.
| @@ -0,0 +1,200 @@ | |||
| #!/usr/bin/env python3 | |||
There was a problem hiding this comment.
why making this only python 3 ?
There was a problem hiding this comment.
no idea, thought I'll try to be 'modern' :-)
There was a problem hiding this comment.
Are there still major distros or OSs that do not supply python 3 (it has not to be the default)? Even the grand old ladies Debian and CentOS have python 3 now.
There was a problem hiding this comment.
I don't think mac OS users have python3 installed by default
There was a problem hiding this comment.
As this is not needed for building, having python3 as dependency should be fine.
dist/tools/isrvecgen/isrvecgen.py
Outdated
| pat_cpu = re.compile("CPU_MODEL_([0-9A-Z]+)") | ||
|
|
||
| for m in pat_line.finditer(buf): | ||
| header = ("%s/%s" % (path, m.group(5))) |
There was a problem hiding this comment.
parenthesis are useless. Prefer using format
dist/tools/isrvecgen/isrvecgen.py
Outdated
| m = re.match(" +([_0-9A-Za-z]+)_IRQn += (-?\d+),? +(/\*!<|/\*\*<) (.+[a-zA-Z0-9]) +\*/", line) | ||
| if m: | ||
| num = int(m.group(2)) | ||
| name = ("isr_%s" % (m.group(1).lower())) |
There was a problem hiding this comment.
parenthesis, here and the line below
dist/tools/isrvecgen/isrvecgen.py
Outdated
| headermap = dict() | ||
|
|
||
| alias = { | ||
| "isr_exti[_\d+]+": "isr_exti" |
There was a problem hiding this comment.
could, but as this list is meant to be extended, I figured to start with a good style right away. I am thinking about even putting the filters in some external config file in the future...
dist/tools/isrvecgen/isrvecgen.py
Outdated
|
|
||
| def parse_header( file, cpus ): | ||
| filename = os.path.basename(file) | ||
| res = { "cpus": cpus, "vec": {} }; |
There was a problem hiding this comment.
no space after { and before }, here and in other places
dist/tools/isrvecgen/isrvecgen.py
Outdated
| for num in common: | ||
| for a in alias: | ||
| m = re.match(a, common[num]["name"]) | ||
| if m: |
There was a problem hiding this comment.
are you sure m is mandatory ?
if re.match(a, common[num]["name"]):
common[num]["name"] = alias[a]There was a problem hiding this comment.
nope, will fix
dist/tools/isrvecgen/isrvecgen.py
Outdated
| for num in cl["vec"]: | ||
| for a in alias: | ||
| m = re.match(a, cl["vec"][num]["name"]) | ||
| if m: |
dist/tools/isrvecgen/isrvecgen.py
Outdated
| res += " || \\\n " | ||
| elif i & 0x1: | ||
| res += " ||" | ||
| res += (" defined(%s)" % (cpu)) |
dist/tools/isrvecgen/isrvecgen.py
Outdated
| # read through file and find all lines | ||
| with open(file, 'r', encoding = "ISO-8859-1") as f: | ||
| for line in f: | ||
| m = re.match(" +([_0-9A-Za-z]+)_IRQn += (-?\d+),? +(/\*!<|/\*\*<) (.+[a-zA-Z0-9]) +\*/", line) |
There was a problem hiding this comment.
This line is too long (PEP8), it should be 80 characters long max.
|
I started toying with the idea of unifying the Kinetis K CPUs (k60, k64f, K22f) as a single CPU directory |
|
nice, sharing your starters won't hurt. Would be interesting to see what else we could generate to make porting even more simple |
|
Some interesting work in the same area: https://github.com/posborne/cmsis-svd |
|
@haukepetersen this is my WIP/experiment branch: https://github.com/gebart/RIOT/commits/wip/kinetis-k not much there so far, other than a sed version of the ISR vector generator and some makefile magic for splitting the model number into separate properties for family, subfamily, memory size, etc. |
9fbcf01 to
87dd773
Compare
|
fixed python style issues. |
|
Sure. Also found some other minor things, will push later today |
aabadie
left a comment
There was a problem hiding this comment.
Re-read the script and found other things:
- one typo
- missing docstring
- some refactoring is needed
A general comment: try to use variables with explicit names. It helps understand the code by improving readability.
| @@ -0,0 +1,18 @@ | |||
| Overivew | |||
| from operator import itemgetter | ||
|
|
||
| cpulist = set() | ||
| headermap = dict() |
There was a problem hiding this comment.
The scope of variable can be reduced: the function parse_cpuconf can return this dict.
| import copy | ||
| from operator import itemgetter | ||
|
|
||
| cpulist = set() |
There was a problem hiding this comment.
Same comment for this global variable. By the way, the same variable name is used internally in other functions, this looks weird:
for cpulist in specific:
...for example
|
|
||
| alias = {"isr_exti[_\d+]+": "isr_exti"} | ||
|
|
||
| def parse_cpuconf(cpuconf): |
There was a problem hiding this comment.
Adding some docstrings won't hurt
|
|
||
|
|
||
| def parse_header(file, cpus): | ||
| filename = os.path.basename(file) |
| cl["vec"][num]["name"] = alias[a] | ||
|
|
||
|
|
||
| def depstr(cpus, prefix): |
There was a problem hiding this comment.
docstring missing + try to be explicit with function names. We are not writing C code
| return res + "\n" | ||
|
|
||
|
|
||
| def pull_common_vectors(specific): |
| specific.append(parse_header(h, headermap[h])) | ||
|
|
||
| # list items by CPU name | ||
| specific = sorted(specific, key=lambda k: sorted(list(k["cpus"]))[0]) |
There was a problem hiding this comment.
This is personal opinion but in general I tend to avoid this kind of oneliner, for code readability reasons.
There was a problem hiding this comment.
I think this is perfectly readable and one very good example why lamdas are so useful :-)
|
|
||
| if __name__ == "__main__": | ||
| # Define some command line args | ||
| p = argparse.ArgumentParser() |
| return table | ||
|
|
||
|
|
||
| if __name__ == "__main__": |
There was a problem hiding this comment.
There is a lot of code in this block, adding a main function is required:
def main(args):
...
# call it with:
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("cpu_conf", help="path to a cpu_conf.h file")
main(parser.parse_args())|
Hm, this is getting too cumbersome for me, don't see myself putting so much effort into a small helper tool... Will put this tool in its own repo. I welcome anyone to beautify it and move it to the RIOT repo, but I don't see myself spending so much time on this... |
|
The current version of the tool resides now here: So as said, feel free to copy/adapt/move to RIOT... |
Creating the ISR vector tables is error prone and cumbersome, so why don't we just do it automatically?!
This PR proposes a tool that parses CMSIS-style header files and outputs a compact version of vector table(s), for a single CPU or a group of CPU models. I parses the list of CPU(s) from the
cpu_conf.hfiles, using the `#include' statements in those files to find the header files.The output table style depends on #7535.
I tested the tools for all the STM and the Kinetis CPUs, and the results are valid as far as I can see and test it. But as I am a poor python noob, the code of the tool might be far from perfect... But instead of having a thousand change requests, I would prefer to merge it in the current state and improve it with separate PRs: this way we can already use the tool for cleaning up existing vector definitions while tuning the tool itself...