Commit 597f3103 authored by Damien George's avatar Damien George
Browse files

Update MicroPython glue and skel to handle encode/decode of ASN types.

parent 49bd33f0
...@@ -65,7 +65,6 @@ void micropython_mpy_bind_preamble(FV * fv) ...@@ -65,7 +65,6 @@ void micropython_mpy_bind_preamble(FV * fv)
if (hasparam) { if (hasparam) {
fprintf(mpy_bind_h, "#include \"C_ASN1_Types.h\"\n\n"); fprintf(mpy_bind_h, "#include \"C_ASN1_Types.h\"\n\n");
fprintf(mpy_bind_c, "#include \"MicroPython_ASN1_Types.h\"\n\n");
} }
fprintf(mpy_bind_h, fprintf(mpy_bind_h,
...@@ -83,6 +82,10 @@ void micropython_mpy_bind_preamble(FV * fv) ...@@ -83,6 +82,10 @@ void micropython_mpy_bind_preamble(FV * fv)
fprintf(mpy_bind_c, "#include \"%s_mpy_bindings.h\"\n", fv->name); fprintf(mpy_bind_c, "#include \"%s_mpy_bindings.h\"\n", fv->name);
fprintf(mpy_bind_c, "#include \"%s.mpy.h\"\n\n", fv->name); fprintf(mpy_bind_c, "#include \"%s.mpy.h\"\n\n", fv->name);
if (hasparam) {
fprintf(mpy_bind_c, "#include \"MicroPython_ASN1_Types.h\"\n\n");
}
if (has_context_param(fv)) { if (has_context_param(fv)) {
char *fv_no_underscore = char *fv_no_underscore =
underscore_to_dash(fv->name, strlen(fv->name)); underscore_to_dash(fv->name, strlen(fv->name));
...@@ -93,6 +96,28 @@ void micropython_mpy_bind_preamble(FV * fv) ...@@ -93,6 +96,28 @@ void micropython_mpy_bind_preamble(FV * fv)
free(fv_no_underscore); free(fv_no_underscore);
} }
fprintf(mpy_bind_c,
"typedef struct {\n"
" mp_obj_base_t base;\n"
" size_t len;\n"
" mp_obj_t items[2];\n"
"} mp_obj_tuple_wrap_t;\n\n");
fprintf(mpy_bind_c, "extern mp_obj_type_t mp_type_mutable_attrtuple;\n\n");
fprintf(mpy_bind_c, "static qstr wrap_fields[1] = {MP_QSTR_val};\n\n");
fprintf(mpy_bind_c,
"static mp_obj_t mp_obj_new_wrap(mp_obj_t arg) {\n"
" mp_obj_tuple_wrap_t *o = m_new_obj(mp_obj_tuple_wrap_t);\n"
" o->base.type = &mp_type_mutable_attrtuple;\n"
" o->len = 1;\n"
" o->items[0] = arg;\n"
" o->items[1] = MP_OBJ_FROM_PTR(wrap_fields);\n"
" return MP_OBJ_FROM_PTR(o);\n"
"}\n"
"MP_DEFINE_CONST_FUN_OBJ_1(mp_obj_new_wrap_obj, mp_obj_new_wrap);\n\n");
fprintf(mpy_bind_c, "mp_state_ctx_t *mp_current_ctx;\n"); // TODO there should only be one of these per executable fprintf(mpy_bind_c, "mp_state_ctx_t *mp_current_ctx;\n"); // TODO there should only be one of these per executable
fprintf(mpy_bind_c, "static mp_state_ctx_t mp_ctx;\n"); fprintf(mpy_bind_c, "static mp_state_ctx_t mp_ctx;\n");
fprintf(mpy_bind_c, "static uint64_t mp_heap[4096];\n"); fprintf(mpy_bind_c, "static uint64_t mp_heap[4096];\n");
...@@ -114,6 +139,7 @@ void micropython_mpy_bind_preamble(FV * fv) ...@@ -114,6 +139,7 @@ void micropython_mpy_bind_preamble(FV * fv)
" gc_init(mp_heap, (uint8_t*)mp_heap + sizeof(mp_heap));\n" " gc_init(mp_heap, (uint8_t*)mp_heap + sizeof(mp_heap));\n"
" mp_pystack_init(mp_pystack, (uint8_t*)mp_pystack + sizeof(mp_pystack));\n" " mp_pystack_init(mp_pystack, (uint8_t*)mp_pystack + sizeof(mp_pystack));\n"
" mp_init();\n" " mp_init();\n"
" mp_taste_types_init();\n"
" mp_exec_mpy(mpy_script_data, mpy_script_len);\n" " mp_exec_mpy(mpy_script_data, mpy_script_len);\n"
); );
...@@ -149,7 +175,6 @@ void micropython_add_PI_to_glue(Interface * i) ...@@ -149,7 +175,6 @@ void micropython_add_PI_to_glue(Interface * i)
size_t sig_len = strlen(signature); size_t sig_len = strlen(signature);
char *sep = make_string(",\n%*s", sig_len, ""); char *sep = make_string(",\n%*s", sig_len, "");
char *sep_py = make_string(",\n%*s", strlen(signature_py), "");
size_t n_args = 0; size_t n_args = 0;
fprintf(mpy_bind_h, "%s", signature); fprintf(mpy_bind_h, "%s", signature);
...@@ -190,32 +215,73 @@ void micropython_add_PI_to_glue(Interface * i) ...@@ -190,32 +215,73 @@ void micropython_add_PI_to_glue(Interface * i)
" if (nlr_push(&nlr) == 0) {\n" " if (nlr_push(&nlr) == 0) {\n"
); );
/* Convert the incoming IN parameters into MicroPython objects */ /* Encode the incoming IN data to MicroPython objects */
n_args = 0; n_args = 0;
FOREACH (p, Parameter, i->in, { FOREACH (p, Parameter, i->in, {
fprintf(mpy_bind_c, fprintf(mpy_bind_c,
" args[%u] = mp_obj_new_asn1Scc%s(IN_%s);\n", n_args, p->type, p->name); " #ifdef MICROPY_TASTE_NEED_DATA_FOR_%s\n"
" mp_obj_asn1Scc%s_t IN_%s_data;\n"
" args[%u] = mp_obj_encode_asn1Scc%s(IN_%s, &IN_%s_data);\n"
" #else\n"
" args[%u] = mp_obj_encode_asn1Scc%s(IN_%s, NULL);\n"
" #endif\n",
p->type,
p->type, p->name,
n_args, p->type, p->name, p->name,
n_args, p->type, p->name);
n_args += 1; n_args += 1;
}); });
size_t n_in_args = n_args;
/* TODO deal with out parameters */ /* Encode the incoming OUT data to MicroPython objects */
FOREACH (p, Parameter, i->out, {
fprintf(mpy_bind_c,
" mp_obj_tuple_wrap_t wrap%u = {{&mp_type_mutable_attrtuple}, 1, {MP_OBJ_NULL, MP_OBJ_FROM_PTR(wrap_fields)}};\n"
" #ifdef MICROPY_TASTE_NEED_DATA_FOR_%s\n"
" mp_obj_asn1Scc%s_t OUT_%s_data;\n"
" wrap%u.items[0] = mp_obj_encode_asn1Scc%s(OUT_%s, &OUT_%s_data);\n"
" #else\n"
" wrap%u.items[0] = mp_obj_encode_asn1Scc%s(OUT_%s, NULL);\n"
" #endif\n"
" args[%u] = &wrap%u;\n",
n_args,
p->type,
p->type, p->name,
n_args, p->type, p->name, p->name,
n_args, p->type, p->name,
n_args, n_args
);
n_args += 1;
});
/* Call the MicroPython function */ /* Call the MicroPython function */
fprintf(mpy_bind_c, fprintf(mpy_bind_c,
" mp_call_function_n_kw(mp_global_%s_PI_%s, %u, 0, args);\n" " mp_call_function_n_kw(mp_global_%s_PI_%s, %u, 0, args);\n",
i->parent_fv->name, i->name, n_args
);
/* Decode the outgoing OUT MicroPython objects to data */
n_args = n_in_args;
FOREACH (p, Parameter, i->out, {
fprintf(mpy_bind_c,
" mp_obj_decode_asn1Scc%s(wrap%u.items[0], OUT_%s);\n",
p->type, n_args, p->name);
n_args += 1;
});
/* Clean up the exception handling */
fprintf(mpy_bind_c,
" nlr_pop();\n" " nlr_pop();\n"
" } else {\n" " } else {\n"
" mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));\n" " mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));\n"
" }\n" " }\n"
"}\n" "}\n"
"\n", "\n"
i->parent_fv->name, i->name, n_args
); );
free(signature); free(signature);
free(signature_py); free(signature_py);
free(sep); free(sep);
free(sep_py);
} }
void micropython_add_RI_to_glue(Interface * i) void micropython_add_RI_to_glue(Interface * i)
...@@ -252,24 +318,32 @@ void micropython_add_RI_to_glue(Interface * i) ...@@ -252,24 +318,32 @@ void micropython_add_RI_to_glue(Interface * i)
free(sep); free(sep);
fprintf(mpy_bind_c, fprintf(mpy_bind_c,
"STATIC mp_obj_t %s_RI_%s_wrap(size_t n_args, const mp_obj_t *args)\n" "STATIC mp_obj_t %s_RI_%s_wrap(size_t n_args, const mp_obj_t *args) {\n"
"{\n", " (void)n_args;\n",
i->parent_fv->name, i->name i->parent_fv->name, i->name
); );
/* Decode the incoming IN MicroPython objects to data */
n_args = 0; n_args = 0;
FOREACH (p, Parameter, i->in, { FOREACH (p, Parameter, i->in, {
fprintf(mpy_bind_c, fprintf(mpy_bind_c,
" asn1Scc%s asn_IN_%s = mp_obj_get_int(args[%u]);\n", " asn1Scc%s asn_IN_%s;\n"
p->type, p->name, n_args); " mp_obj_decode_asn1Scc%s(args[%u], &asn_IN_%s);\n",
p->type, p->name,
p->type, n_args, p->name);
n_args += 1; n_args += 1;
}); });
n_args = 0; size_t n_in_args = n_args;
/* Create local state for the OUT data */
FOREACH (p, Parameter, i->out, { FOREACH (p, Parameter, i->out, {
fprintf(mpy_bind_c, fprintf(mpy_bind_c,
" asn1Scc%s asn_OUT_%s;\n", " asn1Scc%s asn_OUT_%s;\n",
p->type, p->name); p->type, p->name);
n_args += 1; n_args += 1;
}); });
/* Call the RI */
fprintf(mpy_bind_c, " %s_RI_%s(", i->parent_fv->name, i->name); fprintf(mpy_bind_c, " %s_RI_%s(", i->parent_fv->name, i->name);
n_args = 0; n_args = 0;
FOREACH (p, Parameter, i->in, { FOREACH (p, Parameter, i->in, {
...@@ -282,6 +356,16 @@ void micropython_add_RI_to_glue(Interface * i) ...@@ -282,6 +356,16 @@ void micropython_add_RI_to_glue(Interface * i)
}); });
fprintf(mpy_bind_c, ");\n"); fprintf(mpy_bind_c, ");\n");
/* Encode the OUT data to MicroPython objects */
n_args = n_in_args;
FOREACH (p, Parameter, i->out, {
/* TODO verify that the argument objects are of the correct type */
fprintf(mpy_bind_c,
" ((mp_obj_tuple_t*)MP_OBJ_TO_PTR(args[%u]))->items[0] = mp_obj_encode_asn1Scc%s(&asn_OUT_%s, MP_OBJ_TO_PTR(((mp_obj_tuple_t*)MP_OBJ_TO_PTR(args[%u]))->items[0]));\n",
n_args, p->type, p->name, n_args);
n_args += 1;
});
fprintf(mpy_bind_c, fprintf(mpy_bind_c,
" return mp_const_none;\n" " return mp_const_none;\n"
"}\n" "}\n"
...@@ -318,9 +402,12 @@ void End_MicroPython_Glue_Backend(FV *fv) ...@@ -318,9 +402,12 @@ void End_MicroPython_Glue_Backend(FV *fv)
{ {
// Generate the taste module // Generate the taste module
fprintf(mpy_bind_c, "MICROPY_TASTE_ASN_CONSTRUCTORS\n");
fprintf(mpy_bind_c, fprintf(mpy_bind_c,
"STATIC const mp_rom_map_elem_t taste_module_globals_table[] = {\n" "STATIC const mp_rom_map_elem_t taste_module_globals_table[] = {\n"
" { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_taste) },\n" " { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_taste) },\n"
" { MP_ROM_QSTR(MP_QSTR_Ref), MP_ROM_PTR(&mp_obj_new_wrap_obj) },\n"
); );
FOREACH(i, Interface, fv->interfaces, { FOREACH(i, Interface, fv->interfaces, {
...@@ -332,6 +419,7 @@ void End_MicroPython_Glue_Backend(FV *fv) ...@@ -332,6 +419,7 @@ void End_MicroPython_Glue_Backend(FV *fv)
); );
} }
}); });
fprintf(mpy_bind_c, "MICROPY_TASTE_ASN_MAP_ENTRIES\n");
fprintf(mpy_bind_c, fprintf(mpy_bind_c,
"};\n" "};\n"
......
...@@ -56,13 +56,13 @@ void import_RI_to_MicroPython_skel(Interface * i) ...@@ -56,13 +56,13 @@ void import_RI_to_MicroPython_skel(Interface * i)
FOREACH (p, Parameter, i->in, { FOREACH (p, Parameter, i->in, {
fprintf(user_code_py, "%sIN_%s: asn1Scc%s", fprintf(user_code_py, "%sIN_%s: asn1Scc%s",
comma ? "," : "", p->name, p->type); comma ? ", " : "", p->name, p->type);
comma = true; comma = true;
}); });
FOREACH (p, Parameter, i->out, { FOREACH (p, Parameter, i->out, {
fprintf(user_code_py,"%sOUT_%s: asn1Scc%s", fprintf(user_code_py,"%sOUT_%s: asn1Scc%s",
comma ? "," : "", p->name, p->type); comma ? ", " : "", p->name, p->type);
comma = true; comma = true;
}); });
...@@ -85,7 +85,8 @@ void micropython_skel_preamble(FV * fv) ...@@ -85,7 +85,8 @@ void micropython_skel_preamble(FV * fv)
if (NULL != user_code_py) { if (NULL != user_code_py) {
fprintf(user_code_py, fprintf(user_code_py,
"# User code: This file will not be overwritten by TASTE.\n\n"); "# User code: This file will not be overwritten by TASTE.\n\n");
fprintf(user_code_py, "import micropython\n\n"); fprintf(user_code_py, "import micropython\n");
fprintf(user_code_py, "from taste import * # import all ASN types\n\n");
FOREACH(i, Interface, fv->interfaces, { FOREACH(i, Interface, fv->interfaces, {
if (i->direction == RI && gen_this_ri(i)) { if (i->direction == RI && gen_this_ri(i)) {
...@@ -111,8 +112,10 @@ void micropython_skel_preamble(FV * fv) ...@@ -111,8 +112,10 @@ void micropython_skel_preamble(FV * fv)
fprintf(user_code_py, fprintf(user_code_py,
" # Write your initialization code here,\n" " # Write your initialization code here,\n"
" # but do not make any call to a required interface.\n" " # but do not make any call to a required interface.\n"
" pass\n" " # It's recommended to lock the heap once initialisation is done, but\n"
"\n\n"); " # note that without the heap some Python operations are not possible.\n"
" micropython.heap_lock()\n"
"\n");
} }
} }
...@@ -162,33 +165,32 @@ void add_PI_to_MicroPython_skel(Interface * i) ...@@ -162,33 +165,32 @@ void add_PI_to_MicroPython_skel(Interface * i)
char *signature_py = make_string("def %s_PI_%s(", char *signature_py = make_string("def %s_PI_%s(",
i->parent_fv->name, i->parent_fv->name,
i->name); i->name);
char *sep_py = make_string(",\n%*s", strlen(signature_py), "");
bool comma = false; bool comma = false;
fprintf(user_code_py, "%s", signature_py); fprintf(user_code_py, "%s", signature_py);
#if 0 #if 1
// This code generates type hints for the parameters, but need to have the identifiers defined as globals first... // This code generates type hints for the parameters
FOREACH (p, Parameter, i->in, { FOREACH (p, Parameter, i->in, {
fprintf(user_code_py, "%sIN_%s : asn1Scc%s", fprintf(user_code_py, "%sIN_%s: asn1Scc%s",
comma ? sep_py : "", p->name, p->type); comma ? ", " : "", p->name, p->type);
comma = true; comma = true;
}); });
FOREACH (p, Parameter, i->out, { FOREACH (p, Parameter, i->out, {
fprintf(user_code_py, "%sOUT_%s : asn1Scc%s", fprintf(user_code_py, "%sOUT_%s: asn1Scc%s",
comma ? sep_py : "", p->name, p->type); comma ? ", " : "", p->name, p->type);
comma = true; comma = true;
}); });
#else #else
// This code generates the parameter list without type hints. // This code generates the parameter list without type hints.
FOREACH (p, Parameter, i->in, { FOREACH (p, Parameter, i->in, {
fprintf(user_code_py, "%sIN_%s", comma ? sep_py : "", p->name); fprintf(user_code_py, "%sIN_%s", comma ? ", " : "", p->name);
comma = true; comma = true;
}); });
FOREACH (p, Parameter, i->out, { FOREACH (p, Parameter, i->out, {
fprintf(user_code_py, "%sOUT_%s", comma ? sep_py : "", p->name); fprintf(user_code_py, "%sOUT_%s", comma ? ", " : "", p->name);
comma = true; comma = true;
}); });
#endif #endif
...@@ -196,7 +198,6 @@ void add_PI_to_MicroPython_skel(Interface * i) ...@@ -196,7 +198,6 @@ void add_PI_to_MicroPython_skel(Interface * i)
fprintf(user_code_py, "):\n # Write your code here!\n pass\n\n"); fprintf(user_code_py, "):\n # Write your code here!\n pass\n\n");
free(signature_py); free(signature_py);
free(sep_py);
} }
/* Add timer declarations to the C code skeletons */ /* Add timer declarations to the C code skeletons */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment