adding the embedded Python init/terminate code

This commit is contained in:
Amy G. Bowersox 2019-12-07 19:43:45 -07:00
parent aad0c5ed98
commit 79bb9552da
9 changed files with 186 additions and 7 deletions

View File

@ -1,17 +1,21 @@
OBJS=main.o sysinput.o fbinit.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o splash.o
LIBS=-lbcm2835 -lpthread
CFLAGS=-g -O -DDEBUG_ASSERT
OBJS=main.o sysinput.o ep_init.o ep_util.o fbinit.o fbprimitive.o log.o gpio.o msg_queue.o \
time_func.o config.o splash.o
LIBS=-lpython3.7m -lcrypt -lbcm2835 -lpthread -ldl -lutil -lm
CFLAGS=-I/usr/include/python3.7m -Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT
LDFLAGS=-L/usr/lib/python3.7/config-3.7m-arm-linux-gnueabihf -Xlinker -export-dynamic -Wl,-O1 \
-Wl,-Bsymbolic-functions
all: upiwin
upiwin: $(OBJS)
gcc -o upiwin $(OBJS) $(LIBS)
gcc -o upiwin $(LDFLAGS) $(OBJS) $(LIBS)
.c.o:
gcc -c $(CFLAGS) $<
splash.o: splash.bin
objcopy -I binary -O elf32-littlearm -B arm --rename-section .data=.rodata,alloc,load,readonly,data,contents splash.bin splash.o
objcopy -I binary -O elf32-littlearm -B arm --rename-section \
.data=.rodata,alloc,load,readonly,data,contents splash.bin splash.o
splash.bin: splash.png ../buildutils/mksplash
../buildutils/mksplash splash.png splash.bin

View File

@ -66,6 +66,7 @@ static void init_defaults(void)
memset(&Gconfig, 0, sizeof(GLOBAL_CONFIG));
Gconfig.framebuffer_device = "/dev/fb1";
Gconfig.touchscreen_device = "/dev/input/touchscreen";
Gconfig.python_loc = "/usr/bin/python3";
Gconfig.button_debounce = 100;
Gconfig.sys_mq_length = 64;
}

View File

@ -9,6 +9,7 @@ typedef void (*PEXITFUNC)(void);
typedef struct tagGLOBAL_CONFIG {
PCSTR framebuffer_device; /* name of frame buffer device */
PCSTR touchscreen_device; /* name of touchscreen device */
PCSTR python_loc; /* location of the Python3 executable */
UINT32 button_debounce; /* minimum time between button up and next button down (ms) */
UINT32 sys_mq_length; /* length of system message queue */
} GLOBAL_CONFIG;

104
src/ep_init.c Normal file
View File

@ -0,0 +1,104 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "scode.h"
#include "config.h"
#include "log.h"
#include "ep_init.h"
#include "ep_util.h"
PCSTR Mod_UPIWIN = "upiwin"; /* name of the primary UPIWIN module */
PCSTR Mod_UPIWIN_tmp = "upiwin_tmp"; /* name of the temporary UPIWIN module */
static wchar_t *python_name = NULL; /* location of the Python executable */
static PyObject *upiwin_module = NULL;
static PyObject *upiwin_tmp_module = NULL;
static PyObject *init_upiwin_module(void)
{
}
static PyObject *init_upiwin_tmp_module(void)
{
}
/* used to link the two modules into Python's init table */
static struct _inittab upiwin_inittab[] = {
{ Mod_UPIWIN, init_upiwin_module },
{ Mod_UPIWIN_tmp, init_upiwin_tmp_module },
{ NULL, NULL }
};
static void epython_cleanup(void)
{
Py_DECREF(upiwin_tmp_module);
upiwin_tmp_module = NULL;
Py_DECREF(upiwin_module);
upiwin_module = NULL;
if (!Py_FinalizeEx())
Log(LWARN, "errors encountered when Python uninitialized itself");
PyMem_RawFree(python_name);
python_name = NULL;
}
HRESULT Epython_setup(void)
{
HRESULT hr;
size_t size;
python_name = Py_DecodeLocale(Gconfig.python_loc, &size);
if (!python_name)
{
if (size==(size_t)(-1))
{
Log(LFATAL, "error allocating Python program location");
return E_OUTOFMEMORY;
}
else
{
Log(LFATAL, "internal error in Py_DecodeLocale");
return E_UNEXPECTED;
}
}
Py_SetProgramName(python_name);
if (PyImport_ExtendInittab(upiwin_inittab))
{
Log(LFATAL, "error allocating extended init table");
hr = E_OUTOFMEMORY;
goto error_0;
}
Py_Initialize();
/* Import the modules */
upiwin_module = PyImport_ImportModule(Mod_UPIWIN);
if (!upiwin_module)
{
Log(LFATAL, "error importing the upiwin module");
hr = Epython_trace_exception();
goto error_1;
}
upiwin_tmp_module = PyImport_ImportModule(Mod_UPIWIN_tmp);
if (!upiwin_tmp_module)
{
Log(LFATAL, "error importing the upiwin_tmp module");
hr = Epython_trace_exception();
goto error_2;
}
hr = Config_exitfunc(epython_cleanup);
if (FAILED(hr))
epython_cleanup();
return hr;
error_2:
Py_DECREF(upiwin_module);
upiwin_module = NULL;
error_1:
Py_FinalizeEx();
error_0:
PyMem_RawFree(python_name);
python_name = NULL;
return hr;
}

11
src/ep_init.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef __EP_INIT_H_INCLUDED
#define __EP_INIT_H_INCLUDED
#include "wintype.h"
extern PCSTR Mod_UPIWIN;
extern PCSTR Mod_UPIWIN_tmp;
extern HRESULT Epython_setup(void);
#endif /* __EP_INIT_H_INCLUDED */

44
src/ep_util.c Normal file
View File

@ -0,0 +1,44 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "scode.h"
#include "ep_util.h"
#include "log.h"
void Epython_log_object(int level, const char *label, PyObject *object)
{
BOOL traced = FALSE;
PyObject *repr;
PCSTR pstr;
repr = PyObject_Repr(object);
if (repr)
{
ASSERT(PyUnicode_Check(repr));
pstr = PyUnicode_AsUTF8(repr);
Log(level, "object %s: %s", label, pstr);
traced = TRUE;
Py_DECREF(repr);
}
if (!traced)
Log(level, "object %s: could not be logged (memory error)", label);
}
HRESULT Epython_trace_exception(void)
{
HRESULT hr = E_FAIL;
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
if (!type)
return S_OK;
Epython_log_object(LERROR, "exception type", type);
Epython_log_object(LERROR, "exception value", value);
Epython_log_object(LERROR, "exception traceback", value);
Py_DECREF(type);
Py_DECREF(value);
Py_DECREF(traceback);
return hr;
}

11
src/ep_util.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef __EP_UTIL_H_INCLUDED
#define __EP_UTIL_H_INCLUDED
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "wintype.h"
extern void Epython_log_object(int level, const char *label, PyObject *object);
extern HRESULT Epython_trace_exception(void);
#endif /* __EP_UTIL_H_INCLUDED */

View File

@ -8,6 +8,7 @@
#include "fbinit.h"
#include "fbprimitive.h"
#include "time_func.h"
#include "ep_init.h"
#include "sysinput.h"
static void do_draw(void)
@ -46,10 +47,12 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
if (FAILED(Gpio_setup()))
return EXIT_FAILURE;
if (FAILED(Epython_setup()))
return EXIT_FAILURE;
if (FAILED(Sys_enable_input()))
return EXIT_FAILURE;
Log(LINFO, "Pausing at startup.");
sleep(3); /* wait to show off splash screen */
sleep(2); /* wait to show off splash screen */
Fb_clear();
/* temporary drawing here */

View File

@ -64,6 +64,6 @@
#define E_UNEXPECTED SCODE_CAST(0x8000FFFF) /* unexpected error */
/* UPIWIN-specific errorcodes */
#define UPIWIN_E_OUTOFRANGE SCODE_CAST(0x80060000) /* value out of range */
#define UPIWIN_E_INVALIDSTRING SCODE_CAST(0x80060000) /* invalid string (decode error) */
#endif /* __SCODE_H_INCLUDED */