Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rpc_classes.py Source File

rpc_classes.py

00001 """
00002 mbed SDK
00003 Copyright (c) 2011-2013 ARM Limited
00004 
00005 Licensed under the Apache License, Version 2.0 (the "License");
00006 you may not use this file except in compliance with the License.
00007 You may obtain a copy of the License at
00008 
00009     http://www.apache.org/licenses/LICENSE-2.0
00010 
00011 Unless required by applicable law or agreed to in writing, software
00012 distributed under the License is distributed on an "AS IS" BASIS,
00013 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014 See the License for the specific language governing permissions and
00015 limitations under the License.
00016 """
00017 from os.path import join
00018 from jinja2 import Template
00019 
00020 from tools.paths import TOOLS_DATA, MBED_RPC
00021 
00022 RPC_TEMPLATES_PATH = join(TOOLS_DATA, "rpc")
00023 
00024 RPC_TEMPLATE = "RPCClasses.h"
00025 CLASS_TEMPLATE = "class.cpp"
00026 RPC_CLASSES_PATH = join(MBED_RPC, RPC_TEMPLATE)
00027 
00028 
00029 def get_template(name):
00030     return Template(open(join(RPC_TEMPLATES_PATH, name)).read())
00031 
00032 
00033 def write_rpc_classes(classes):
00034     template = get_template(RPC_TEMPLATE)
00035     open(RPC_CLASSES_PATH, "w").write(template.render({"classes":classes}))
00036 
00037 
00038 RPC_CLASSES = (
00039     {
00040         "name": "DigitalOut",
00041         "cons_args": ["PinName"],
00042         "methods": [
00043             (None , "write", ["int"]),
00044             ("int", "read" , []),
00045         ]
00046     },
00047     {
00048         "name": "DigitalIn",
00049         "cons_args": ["PinName"],
00050         "methods": [
00051             ("int", "read" , []),
00052         ]
00053     },
00054     {
00055         "name": "DigitalInOut",
00056         "cons_args": ["PinName"],
00057         "methods": [
00058             ("int", "read"  , []),
00059             (None , "write" , ["int"]),
00060             (None , "input" , []),
00061             (None , "output", []),
00062         ]
00063     },
00064     {
00065         "name": "AnalogIn",
00066         "required": "ANALOGIN",
00067         "cons_args": ["PinName"],
00068         "methods": [
00069             ("float"         , "read"    , []),
00070             ("unsigned short", "read_u16", []),
00071         ]
00072     },
00073     {
00074         "name": "AnalogOut",
00075         "required": "ANALOGOUT",
00076         "cons_args": ["PinName"],
00077         "methods": [
00078             ("float", "read"     , []),
00079             (None   , "write"    , ["float"]),
00080             (None   , "write_u16", ["unsigned short"]),
00081         ]
00082     },
00083     {
00084         "name": "PwmOut",
00085         "required": "PWMOUT",
00086         "cons_args": ["PinName"],
00087         "methods": [
00088             ("float", "read"         , []),
00089             (None   , "write"        , ["float"]),
00090             (None   , "period"       , ["float"]),
00091             (None   , "period_ms"    , ["int"]),
00092             (None   , "pulsewidth"   , ["float"]),
00093             (None   , "pulsewidth_ms", ["int"]),
00094         ]
00095     },
00096     {
00097         "name": "SPI",
00098         "required": "SPI",
00099         "cons_args": ["PinName", "PinName", "PinName"],
00100         "methods": [
00101             (None , "format"   , ["int", "int"]),
00102             (None , "frequency", ["int"]),
00103             ("int", "write"    , ["int"]),
00104         ]
00105     },
00106     {
00107         "name": "Serial",
00108         "required": "SERIAL",
00109         "cons_args": ["PinName", "PinName"],
00110         "methods": [
00111             (None , "baud"     , ["int"]),
00112             ("int", "readable" , []),
00113             ("int", "writeable", []),
00114             ("int", "putc"     , ["int"]),
00115             ("int", "getc"     , []),
00116             ("int", "puts"     , ["const char *"]),
00117         ]
00118     },
00119     {
00120         "name": "Timer",
00121         "cons_args": [],
00122         "methods": [
00123             (None   , "start"  , []),
00124             (None   , "stop"   , []),
00125             (None   , "reset"  , []),
00126             ("float", "read"   , []),
00127             ("int"  , "read_ms", []),
00128             ("int"  , "read_us", []),
00129         ]
00130     }
00131 )
00132 
00133 
00134 def get_args_proto(args_types, extra=None):
00135     args = ["%s a%d" % (s, n) for n, s in enumerate(args_types)]
00136     if extra:
00137         args.extend(extra)
00138     return ', '.join(args)
00139 
00140 
00141 def get_args_call(args):
00142     return ', '.join(["a%d"    % (n)    for n in range(len(args))])
00143 
00144 
00145 classes = []
00146 class_template = get_template(CLASS_TEMPLATE)
00147 
00148 for c in RPC_CLASSES:
00149     c_args = c['cons_args']
00150     data = {
00151         'name': c['name'],
00152         'cons_type': ', '.join(c_args + ['const char*']),
00153         "cons_proto": get_args_proto(c_args, ["const char *name=NULL"]),
00154         "cons_call": get_args_call(c_args)
00155     }
00156 
00157     c_name = "Rpc" +  c['name']
00158 
00159     methods = []
00160     rpc_methods = []
00161     for r, m, a in c['methods']:
00162         ret_proto = r if r else "void"
00163         args_proto = "void"
00164 
00165         ret_defin = "return " if r else ""
00166         args_defin = ""
00167 
00168         if a:
00169             args_proto = get_args_proto(a)
00170             args_defin = get_args_call(a)
00171 
00172         proto = "%s %s(%s)"   % (ret_proto, m, args_proto)
00173         defin = "{%so.%s(%s);}" % (ret_defin, m, args_defin)
00174         methods.append("%s %s" % (proto, defin))
00175 
00176         rpc_method_type = [r] if r else []
00177         rpc_method_type.append(c_name)
00178         rpc_method_type.extend(a)
00179         rpc_methods.append('{"%s", rpc_method_caller<%s, &%s::%s>}' % (m, ', '.join(rpc_method_type), c_name, m))
00180 
00181     data['methods'] = "\n    ".join(methods)
00182     data['rpc_methods'] = ",\n            ".join(rpc_methods)
00183 
00184     class_decl = class_template.render(data)
00185     if 'required' in c:
00186         class_decl = "#if DEVICE_%s\n%s\n#endif" % (c['required'], class_decl)
00187 
00188     classes.append(class_decl)
00189 
00190 write_rpc_classes('\n\n'.join(classes))