1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-30 08:24:11 +01:00
LibrePilot/flight/libraries/PyMite/platform/desktop/plat.c
2013-04-25 13:13:36 +03:00

353 lines
8.4 KiB
C

/*
# This file is Copyright 2006, 2007, 2009 Dean Hall.
#
# This file is part of the Python-on-a-Chip program.
# Python-on-a-Chip is free software: you can redistribute it and/or modify
# it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1.
#
# Python-on-a-Chip is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# A copy of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
# is seen in the file COPYING up one directory from this.
*/
#undef __FILE_ID__
#define __FILE_ID__ 0x70
/** PyMite platform-specific routines for Desktop target */
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include "pm.h"
void plat_sigalrm_handler(int signal);
/* Desktop target shall use stdio for I/O routines. */
PmReturn_t
plat_init(void)
{
/* Let POSIX' SIGALRM fire every full millisecond. */
/*
* #67 Using sigaction complicates the use of getchar (below),
* so signal() is used instead.
*/
signal(SIGALRM, plat_sigalrm_handler);
ualarm(1000, 1000);
return PM_RET_OK;
}
/* Disables the peripherals and interrupts */
PmReturn_t
plat_deinit(void)
{
/* Cancel alarm and set the alarm handler to the default */
ualarm(0, 0);
signal(SIGALRM, SIG_DFL);
return PM_RET_OK;
}
void
plat_sigalrm_handler(int signal)
{
PmReturn_t retval;
retval = pm_vmPeriodic(1000);
PM_REPORT_IF_ERROR(retval);
}
/*
* Gets a byte from the address in the designated memory space
* Post-increments *paddr.
*/
uint8_t
plat_memGetByte(PmMemSpace_t memspace, uint8_t const **paddr)
{
uint8_t b = 0;
switch (memspace)
{
case MEMSPACE_RAM:
case MEMSPACE_PROG:
b = **paddr;
*paddr += 1;
return b;
case MEMSPACE_EEPROM:
case MEMSPACE_SEEPROM:
case MEMSPACE_OTHER0:
case MEMSPACE_OTHER1:
case MEMSPACE_OTHER2:
case MEMSPACE_OTHER3:
default:
return 0;
}
}
/* Desktop target shall use stdio for I/O routines */
PmReturn_t
plat_getByte(uint8_t *b)
{
int c;
PmReturn_t retval = PM_RET_OK;
c = getchar();
*b = c & 0xFF;
if (c == EOF)
{
PM_RAISE(retval, PM_RET_EX_IO);
}
return retval;
}
/* Desktop target shall use stdio for I/O routines */
PmReturn_t
plat_putByte(uint8_t b)
{
int i;
PmReturn_t retval = PM_RET_OK;
i = putchar(b);
fflush(stdout);
if ((i != b) || (i == EOF))
{
PM_RAISE(retval, PM_RET_EX_IO);
}
return retval;
}
PmReturn_t
plat_getMsTicks(uint32_t *r_ticks)
{
*r_ticks = pm_timerMsTicks;
return PM_RET_OK;
}
void
plat_reportError(PmReturn_t result)
{
#ifdef HAVE_DEBUG_INFO
#define LEN_FNLOOKUP 26
#define LEN_EXNLOOKUP 17
uint8_t res;
pPmFrame_t pframe;
pPmObj_t pstr;
PmReturn_t retval;
uint8_t bcindex;
uint16_t bcsum;
uint16_t linesum;
uint16_t len_lnotab;
uint8_t const *plnotab;
uint16_t i;
/* This table should match src/vm/fileid.txt */
char const * const fnlookup[LEN_FNLOOKUP] = {
"<no file>",
"codeobj.c",
"dict.c",
"frame.c",
"func.c",
"global.c",
"heap.c",
"img.c",
"int.c",
"interp.c",
"pmstdlib_nat.c",
"list.c",
"main.c",
"mem.c",
"module.c",
"obj.c",
"seglist.c",
"sli.c",
"strobj.c",
"tuple.c",
"seq.c",
"pm.c",
"thread.c",
"float.c",
"class.c",
"bytearray.c",
};
/* This table should match src/vm/pm.h PmReturn_t */
char const * const exnlookup[LEN_EXNLOOKUP] = {
"Exception",
"SystemExit",
"IoError",
"ZeroDivisionError",
"AssertionError",
"AttributeError",
"ImportError",
"IndexError",
"KeyError",
"MemoryError",
"NameError",
"SyntaxError",
"SystemError",
"TypeError",
"ValueError",
"StopIteration",
"Warning",
};
/* Print traceback */
printf("Traceback (most recent call first):\n");
/* Get the top frame */
pframe = gVmGlobal.pthread->pframe;
/* If it's the native frame, print the native function name */
if (pframe == (pPmFrame_t)&(gVmGlobal.nativeframe))
{
/* The last name in the names tuple of the code obj is the name */
retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func->
f_co->co_names, -1, &pstr);
if ((retval) != PM_RET_OK)
{
printf(" Unable to get native func name.\n");
return;
}
else
{
printf(" %s() __NATIVE__\n", ((pPmString_t)pstr)->val);
}
/* Get the frame that called the native frame */
pframe = (pPmFrame_t)gVmGlobal.nativeframe.nf_back;
}
/* Print the remaining frame stack */
for (; pframe != C_NULL; pframe = pframe->fo_back)
{
/* The last name in the names tuple of the code obj is the name */
retval = tuple_getItem((pPmObj_t)pframe->fo_func->f_co->co_names,
-1,
&pstr);
if ((retval) != PM_RET_OK) break;
/*
* Get the line number of the current bytecode. Algorithm comes from:
* http://svn.python.org/view/python/trunk/Objects/lnotab_notes.txt?view=markup
*/
bcindex = pframe->fo_ip - pframe->fo_func->f_co->co_codeaddr;
plnotab = pframe->fo_func->f_co->co_lnotab;
len_lnotab = mem_getWord(MEMSPACE_PROG, &plnotab);
bcsum = 0;
linesum = pframe->fo_func->f_co->co_firstlineno;
for (i = 0; i < len_lnotab; i += 2)
{
bcsum += mem_getByte(MEMSPACE_PROG, &plnotab);
if (bcsum > bcindex) break;
linesum += mem_getByte(MEMSPACE_PROG, &plnotab);
}
printf(" File \"%s\", line %d, in %s\n",
((pPmFrame_t)pframe)->fo_func->f_co->co_filename,
linesum,
((pPmString_t)pstr)->val);
}
/* Print error */
res = (uint8_t)result;
if ((res > 0) && ((res - PM_RET_EX) < LEN_EXNLOOKUP))
{
printf("%s", exnlookup[res - PM_RET_EX]);
}
else
{
printf("Error code 0x%02X", result);
}
printf(" detected by ");
if ((gVmGlobal.errFileId > 0) && (gVmGlobal.errFileId < LEN_FNLOOKUP))
{
printf("%s:", fnlookup[gVmGlobal.errFileId]);
}
else
{
printf("FileId 0x%02X line ", gVmGlobal.errFileId);
}
printf("%d\n", gVmGlobal.errLineNum);
#else /* HAVE_DEBUG_INFO */
/* Print error */
printf("Error: 0x%02X\n", result);
printf(" Release: 0x%02X\n", gVmGlobal.errVmRelease);
printf(" FileId: 0x%02X\n", gVmGlobal.errFileId);
printf(" LineNum: %d\n", gVmGlobal.errLineNum);
/* Print traceback */
{
pPmObj_t pframe;
pPmObj_t pstr;
PmReturn_t retval;
printf("Traceback (top first):\n");
/* Get the top frame */
pframe = (pPmObj_t)gVmGlobal.pthread->pframe;
/* If it's the native frame, print the native function name */
if (pframe == (pPmObj_t)&(gVmGlobal.nativeframe))
{
/* The last name in the names tuple of the code obj is the name */
retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func->
f_co->co_names, -1, &pstr);
if ((retval) != PM_RET_OK)
{
printf(" Unable to get native func name.\n");
return;
}
else
{
printf(" %s() __NATIVE__\n", ((pPmString_t)pstr)->val);
}
/* Get the frame that called the native frame */
pframe = (pPmObj_t)gVmGlobal.nativeframe.nf_back;
}
/* Print the remaining frame stack */
for (;
pframe != C_NULL;
pframe = (pPmObj_t)((pPmFrame_t)pframe)->fo_back)
{
/* The last name in the names tuple of the code obj is the name */
retval = tuple_getItem((pPmObj_t)((pPmFrame_t)pframe)->
fo_func->f_co->co_names, -1, &pstr);
if ((retval) != PM_RET_OK) break;
printf(" %s()\n", ((pPmString_t)pstr)->val);
}
printf(" <module>.\n");
}
#endif /* HAVE_DEBUG_INFO */
}