Separate targets into os and baremetal-sdk parts (#4842)
JerryScript-DCO-1.0-Signed-off-by: Roland Takacs roland.takacs@h-lab.eu
This commit is contained in:
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright JS Foundation and other contributors, http://js.foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# If we're checking only for global variable definitions of pins, then
|
||||
# file ordering doesn't matter. This is because:
|
||||
#
|
||||
# var a = b;
|
||||
# var b = 7;
|
||||
#
|
||||
# will be accepted by jshint, just 'a' will evaluate to 'undefined'.
|
||||
# Awkward, but at least it means we can have pins.js included at any
|
||||
# point in the clump of files and it won't give us false positives.
|
||||
|
||||
cat js/*.js | jshint -c tools/jshint.conf - | grep "not defined"
|
||||
if [ "$?" == 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
@@ -0,0 +1,17 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is intentionally blank, and is used as a dummy cmsis.h file
|
||||
* when preprocessing generate_pins.py.
|
||||
*/
|
||||
@@ -0,0 +1,221 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright JS Foundation and other contributors, http://js.foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
"""
|
||||
Generate pins.cpp for a specified target, using target definitions from the
|
||||
mbed OS source tree.
|
||||
|
||||
It's expecting to be run from the targets/os/mbedos5 directory.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import ast
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
from pycparserext.ext_c_parser import GnuCParser
|
||||
from pycparser import parse_file, c_ast
|
||||
|
||||
# import mbed tools
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'mbed-os'))
|
||||
from tools.targets import Target
|
||||
|
||||
LICENSE = '''/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the \"License\");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an \"AS IS\" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is generated by generate_pins.py. Please do not modify.
|
||||
*/
|
||||
'''
|
||||
|
||||
|
||||
def find_file(root_dir, directories, name):
|
||||
"""
|
||||
Find the first instance of file with name 'name' in the directory tree
|
||||
starting with 'root_dir'.
|
||||
|
||||
Filter out directories that are not in directories, or do not start with
|
||||
TARGET_.
|
||||
|
||||
Since this looks in (essentially )the same directories as the compiler would
|
||||
when compiling mbed OS, we should only find one PinNames.h.
|
||||
"""
|
||||
|
||||
for root, dirs, files in os.walk(root_dir, topdown=True):
|
||||
# modify dirs in place
|
||||
dirs[:] = [directory for directory in dirs if directory in directories or not directory.startswith('TARGET_')]
|
||||
|
||||
if name in files:
|
||||
return os.path.join(root, name)
|
||||
|
||||
|
||||
def enumerate_includes(root_dir, directories):
|
||||
"""
|
||||
Walk through the directory tree, starting at root_dir, and enumerate all
|
||||
valid include directories.
|
||||
"""
|
||||
for root, dirs, _ in os.walk(root_dir, topdown=True):
|
||||
# modify dirs in place
|
||||
dirs[:] = [dir_label for dir_label in dirs
|
||||
if dir_label in directories
|
||||
or (not dir_label.startswith('TARGET_')
|
||||
and not dir_label.startswith('TOOLCHAIN_'))]
|
||||
yield root
|
||||
|
||||
|
||||
class TypeDeclVisitor(c_ast.NodeVisitor):
|
||||
"""
|
||||
A TypeDecl visitor class that walks the ast and calls a visitor function for every node found.
|
||||
"""
|
||||
def __init__(self, filter_names=None):
|
||||
self.names = filter_names or []
|
||||
|
||||
def visit(self, node):
|
||||
value = None
|
||||
|
||||
if node.__class__.__name__ == "TypeDecl":
|
||||
value = self.visit_typedecl(node)
|
||||
|
||||
if value is None:
|
||||
for _, child_node in node.children():
|
||||
value = value or self.visit(child_node)
|
||||
|
||||
return value
|
||||
|
||||
def visit_typedecl(self, node):
|
||||
"""
|
||||
Visit a node.
|
||||
"""
|
||||
if node.declname in self.names:
|
||||
return [pin.name for pin in node.type.values.enumerators]
|
||||
|
||||
|
||||
def enumerate_pins(c_source_file, include_dirs, definitions):
|
||||
"""
|
||||
Enumerate pins specified in PinNames.h, by looking for a PinName enum
|
||||
typedef somewhere in the file.
|
||||
"""
|
||||
definitions += ['__attribute(x)__=', '__extension__(x)=', 'register=', '__IO=', 'uint32_t=unsigned int']
|
||||
|
||||
gcc_args = ['-E', '-fmerge-all-constants']
|
||||
gcc_args += ['-I' + directory for directory in include_dirs]
|
||||
|
||||
gcc_args += ['-D' + definition for definition in definitions]
|
||||
parsed_ast = parse_file(c_source_file,
|
||||
use_cpp=True,
|
||||
cpp_path='arm-none-eabi-gcc',
|
||||
cpp_args=gcc_args,
|
||||
parser=GnuCParser())
|
||||
|
||||
# now, walk the AST
|
||||
visitor = TypeDeclVisitor(['PinName'])
|
||||
return visitor.visit(parsed_ast)
|
||||
|
||||
|
||||
def write_pins_to_file(pins, pins_file, out_cpp_file):
|
||||
"""
|
||||
Write the generated pins for a specified mbed board into the output C++ file.
|
||||
"""
|
||||
|
||||
include = '\n#include "../{}"'.format(pins_file)
|
||||
|
||||
count = '''
|
||||
unsigned int jsmbed_js_magic_string_count = {};
|
||||
'''.format(len(pins))
|
||||
|
||||
lengths = ',\n '.join(str(len(pin)) for pin in pins)
|
||||
lenghts_source = '''
|
||||
unsigned int jsmbed_js_magic_string_lengths[] = {
|
||||
%s
|
||||
};
|
||||
''' % lengths
|
||||
|
||||
magic_values = ',\n '.join(pins)
|
||||
magic_source = '''
|
||||
int jsmbed_js_magic_string_values[] = {
|
||||
%s
|
||||
};
|
||||
''' % magic_values
|
||||
|
||||
magic_strings = ',\n '.join('"' + pin + '"' for pin in pins)
|
||||
magic_string_source = '''
|
||||
const char * jsmbed_js_magic_strings[] = {
|
||||
%s
|
||||
};
|
||||
''' % magic_strings
|
||||
|
||||
out_cpp_file.write(LICENSE + include + count + lenghts_source + magic_source + magic_string_source)
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Perform the main function of this program
|
||||
"""
|
||||
if not os.path.exists('./mbed-os'):
|
||||
print("Fatal: mbed-os directory does not exist.")
|
||||
print("Try running 'make getlibs'")
|
||||
sys.exit(1)
|
||||
|
||||
description = """
|
||||
Generate pins.cpp for a specified mbed board, using target definitions from the
|
||||
mbed OS source tree.
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser(description=description)
|
||||
|
||||
parser.add_argument('board', help='mbed board name')
|
||||
parser.add_argument('-c',
|
||||
help='Output C++ file (default: %(default)s)',
|
||||
default='source/pins.cpp',
|
||||
type=argparse.FileType('w'))
|
||||
|
||||
args = parser.parse_args()
|
||||
board_name = args.board.upper()
|
||||
|
||||
target = Target.get_target(board_name)
|
||||
|
||||
directory_labels = ['TARGET_' + label for label in target.labels] + target.macros
|
||||
|
||||
targets_dir = os.path.join('.', 'mbed-os', 'targets')
|
||||
|
||||
pins_file = find_file(targets_dir, directory_labels, 'PinNames.h')
|
||||
|
||||
includes = enumerate_includes(targets_dir, directory_labels)
|
||||
defines = list(directory_labels)
|
||||
|
||||
# enumerate pins from PinNames.h
|
||||
pins = enumerate_pins(pins_file, ['./tools'] + list(includes), defines)
|
||||
|
||||
# first sort alphabetically, then by length.
|
||||
pins = sorted(pins, key=lambda x: (len(x), x.lower()))
|
||||
|
||||
write_pins_to_file(pins, pins_file, args.c)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"undef": true,
|
||||
"predef": ["print", "BLEDevice", "BLEService", "BLECharacteristic", "DigitalOut", "I2C", "setInterval", "setTimeout", "InterruptIn", "LWIPInterface", "SimpleMbedClient", "M2MBase"]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pycparserext
|
||||
simpleeval
|
||||
Reference in New Issue
Block a user