python-on-a-chip online compiler

Dependencies:   mbed TSI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers plat.cpp Source File

plat.cpp

00001 /*
00002 # This file is Copyright 2009 Dean Hall.
00003 #
00004 # This file is part of the Python-on-a-Chip program.
00005 # Python-on-a-Chip is free software: you can redistribute it and/or modify
00006 # it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1.
00007 #
00008 # Python-on-a-Chip is distributed in the hope that it will be useful,
00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00011 # A copy of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
00012 # is seen in the file COPYING up one directory from this.
00013 */
00014 
00015 
00016 #undef __FILE_ID__
00017 #define __FILE_ID__ 0x70
00018 
00019 
00020 /** PyMite platform-specific routines for ARM7 target */
00021 
00022 
00023 #include "mbed.h"
00024 #include "pm.h"
00025 
00026 
00027 #define CALLBACK_MS 10
00028 
00029 
00030 Serial serial(USBTX, USBRX);
00031 Ticker ticker;
00032 
00033 
00034 static void
00035 ticker_callback(void)
00036 {
00037     PmReturn_t retval;
00038 
00039     retval = pm_vmPeriodic(CALLBACK_MS * 1000);
00040     PM_REPORT_IF_ERROR(retval);
00041 }
00042 
00043 
00044 PmReturn_t
00045 plat_init(void)
00046 {
00047     serial.baud(115200);
00048 
00049     ticker.attach_us(ticker_callback, CALLBACK_MS * 1000);
00050 
00051     return PM_RET_OK;
00052 }
00053 
00054 
00055 PmReturn_t
00056 plat_deinit(void)
00057 {
00058     /* Detach the callback from the ticker */
00059     ticker.detach();
00060 
00061     return PM_RET_OK;
00062 }
00063 
00064 
00065 uint8_t
00066 plat_memGetByte(PmMemSpace_t memspace, uint8_t const **paddr)
00067 {
00068     uint8_t b = 0;
00069 
00070     switch (memspace)
00071     {
00072         case MEMSPACE_RAM:
00073         case MEMSPACE_PROG:
00074             b = **paddr;
00075             *paddr += 1;
00076             return b;
00077 
00078         case MEMSPACE_EEPROM:
00079         case MEMSPACE_SEEPROM:
00080         case MEMSPACE_OTHER0:
00081         case MEMSPACE_OTHER1:
00082         case MEMSPACE_OTHER2:
00083         case MEMSPACE_OTHER3:
00084         default:
00085             return 0;
00086     }
00087 }
00088 
00089 
00090 PmReturn_t
00091 plat_getByte(uint8_t *b)
00092 {
00093     int c;
00094     PmReturn_t retval = PM_RET_OK;
00095 
00096     c = serial.getc();
00097     *b = c & 0xFF;
00098 
00099     if (c > 0xFF)
00100     {
00101         PM_RAISE(retval, PM_RET_EX_IO);
00102     }
00103 
00104     return retval;
00105 }
00106 
00107 
00108 PmReturn_t
00109 plat_putByte(uint8_t b)
00110 {
00111     while (!serial.writeable());
00112     serial.putc(b);
00113 
00114     return PM_RET_OK;
00115 }
00116 
00117 
00118 PmReturn_t
00119 plat_getMsTicks(uint32_t *r_ticks)
00120 {
00121     *r_ticks = pm_timerMsTicks;
00122 
00123     return PM_RET_OK;
00124 }
00125 
00126 
00127 void
00128 plat_reportError(PmReturn_t result)
00129 {
00130 
00131 #ifdef HAVE_DEBUG_INFO
00132 #define LEN_FNLOOKUP 26
00133 #define LEN_EXNLOOKUP 18
00134 
00135     uint8_t res;
00136     pPmFrame_t pframe;
00137     pPmObj_t pstr;
00138     PmReturn_t retval;
00139     uint16_t bcindex;
00140     uint16_t bcsum;
00141     uint16_t linesum;
00142     uint16_t len_lnotab;
00143     uint8_t const *plnotab;
00144     uint16_t i;
00145 
00146     /* This table should match src/vm/fileid.txt */
00147     char const * const fnlookup[LEN_FNLOOKUP] = {
00148         "<no file>",
00149         "codeobj.c",
00150         "dict.c",
00151         "frame.c",
00152         "func.c",
00153         "global.c",
00154         "heap.c",
00155         "img.c",
00156         "int.c",
00157         "interp.c",
00158         "pmstdlib_nat.c",
00159         "list.c",
00160         "main.c",
00161         "mem.c",
00162         "module.c",
00163         "obj.c",
00164         "seglist.c",
00165         "sli.c",
00166         "strobj.c",
00167         "tuple.c",
00168         "seq.c",
00169         "pm.c",
00170         "thread.c",
00171         "float.c",
00172         "class.c",
00173         "bytearray.c",
00174     };
00175 
00176     /* This table should match src/vm/pm.h PmReturn_t */
00177     char const * const exnlookup[LEN_EXNLOOKUP] = {
00178         "Exception",
00179         "SystemExit",
00180         "IoError",
00181         "ZeroDivisionError",
00182         "AssertionError",
00183         "AttributeError",
00184         "ImportError",
00185         "IndexError",
00186         "KeyError",
00187         "MemoryError",
00188         "NameError",
00189         "SyntaxError",
00190         "SystemError",
00191         "TypeError",
00192         "ValueError",
00193         "StopIteration",
00194         "Warning",
00195         "OverflowError",
00196     };
00197 
00198     /* Print traceback */
00199     printf("Traceback (most recent call first):\n");
00200 
00201     /* Get the top frame */
00202     pframe = gVmGlobal.pthread->pframe;
00203 
00204     /* If it's the native frame, print the native function name */
00205     if (pframe == (pPmFrame_t)&(gVmGlobal.nativeframe))
00206     {
00207 
00208         /* The last name in the names tuple of the code obj is the name */
00209         retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func->
00210                                f_co->co_names, -1, &pstr);
00211         if ((retval) != PM_RET_OK)
00212         {
00213             printf("  Unable to get native func name.\n");
00214             return;
00215         }
00216         else
00217         {
00218             printf("  %s() __NATIVE__\n", ((pPmString_t)pstr)->val);
00219         }
00220 
00221         /* Get the frame that called the native frame */
00222         pframe = (pPmFrame_t)gVmGlobal.nativeframe.nf_back;
00223     }
00224 
00225     /* Print the remaining frame stack */
00226     for (; pframe != C_NULL; pframe = pframe->fo_back)
00227     {
00228         /* The last name in the names tuple of the code obj is the name */
00229         retval = tuple_getItem((pPmObj_t)pframe->fo_func->f_co->co_names,
00230                                -1,
00231                                &pstr);
00232         if ((retval) != PM_RET_OK) break;
00233 
00234         /*
00235          * Get the line number of the current bytecode. Algorithm comes from:
00236          * http://svn.python.org/view/python/trunk/Objects/lnotab_notes.txt?view=markup
00237          */
00238         bcindex = pframe->fo_ip - pframe->fo_func->f_co->co_codeaddr;
00239         plnotab = pframe->fo_func->f_co->co_lnotab;
00240         len_lnotab = mem_getWord(MEMSPACE_PROG, &plnotab);
00241         bcsum = 0;
00242         linesum = pframe->fo_func->f_co->co_firstlineno;
00243         for (i = 0; i < len_lnotab; i += 2)
00244         {
00245             bcsum += mem_getByte(MEMSPACE_PROG, &plnotab);
00246             if (bcsum > bcindex) break;
00247             linesum += mem_getByte(MEMSPACE_PROG, &plnotab);
00248         }
00249         printf("  File \"%s\", line %d, in %s\n",
00250                ((pPmFrame_t)pframe)->fo_func->f_co->co_filename,
00251                linesum,
00252                ((pPmString_t)pstr)->val);
00253     }
00254 
00255     /* Print error */
00256     res = (uint8_t)result;
00257     if ((res > 0) && ((res - PM_RET_EX) < LEN_EXNLOOKUP))
00258     {
00259         printf("%s", exnlookup[res - PM_RET_EX]);
00260     }
00261     else
00262     {
00263         printf("Error code 0x%02X", result);
00264     }
00265     printf(" detected by ");
00266 
00267     if ((gVmGlobal.errFileId > 0) && (gVmGlobal.errFileId < LEN_FNLOOKUP))
00268     {
00269         printf("%s:", fnlookup[gVmGlobal.errFileId]);
00270     }
00271     else
00272     {
00273         printf("FileId 0x%02X line ", gVmGlobal.errFileId);
00274     }
00275     printf("%d\n", gVmGlobal.errLineNum);
00276 
00277 #else /* HAVE_DEBUG_INFO */
00278 
00279     /* Print error */
00280     printf("Error:     0x%02X\n", result);
00281     printf("  Release: 0x%02X\n", gVmGlobal.errVmRelease);
00282     printf("  FileId:  0x%02X\n", gVmGlobal.errFileId);
00283     printf("  LineNum: %d\n", gVmGlobal.errLineNum);
00284 
00285     /* Print traceback */
00286     {
00287         pPmObj_t pframe;
00288         pPmObj_t pstr;
00289         PmReturn_t retval;
00290 
00291         printf("Traceback (top first):\n");
00292 
00293         /* Get the top frame */
00294         pframe = (pPmObj_t)gVmGlobal.pthread->pframe;
00295 
00296         /* If it's the native frame, print the native function name */
00297         if (pframe == (pPmObj_t)&(gVmGlobal.nativeframe))
00298         {
00299 
00300             /* The last name in the names tuple of the code obj is the name */
00301             retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func->
00302                                    f_co->co_names, -1, &pstr);
00303             if ((retval) != PM_RET_OK)
00304             {
00305                 printf("  Unable to get native func name.\n");
00306                 return;
00307             }
00308             else
00309             {
00310                 printf("  %s() __NATIVE__\n", ((pPmString_t)pstr)->val);
00311             }
00312 
00313             /* Get the frame that called the native frame */
00314             pframe = (pPmObj_t)gVmGlobal.nativeframe.nf_back;
00315         }
00316 
00317         /* Print the remaining frame stack */
00318         for (;
00319              pframe != C_NULL;
00320              pframe = (pPmObj_t)((pPmFrame_t)pframe)->fo_back)
00321         {
00322             /* The last name in the names tuple of the code obj is the name */
00323             retval = tuple_getItem((pPmObj_t)((pPmFrame_t)pframe)->
00324                                    fo_func->f_co->co_names, -1, &pstr);
00325             if ((retval) != PM_RET_OK) break;
00326 
00327             printf("  %s()\n", ((pPmString_t)pstr)->val);
00328         }
00329         printf("  <module>.\n");
00330     }
00331 #endif /* HAVE_DEBUG_INFO */
00332 }