interpreters/python: add wrapper to initialize Python

This wrapper application checks if the Python's modules are already
mounted (and mounts them, if not), sets the necessary environment
variables and, then, runs the Python interpreter.
This commit is contained in:
Tiago Medicci
2025-01-29 17:10:49 -03:00
committed by CeDeROM
parent 4c6a6c7b16
commit 87f4eb8021
4 changed files with 116 additions and 38 deletions

View File

@@ -27,7 +27,7 @@ config INTERPRETER_CPYTHON_STACKSIZE
config INTERPRETER_CPYTHON_PRIORITY
int "CPython task priority"
default 150
default 100
---help---
This is the priority of the CPython task.
@@ -37,22 +37,4 @@ config INTERPRETER_CPYTHON_PROGNAME
---help---
This is the name of the program that will be used from the nsh.
config INTERPRETER_CPYTHON_MOUNT_MODULES_STACKSIZE
int "CPython's Modules Mount stack size"
default 4096
---help---
This is the stack size allocated when the CPython's Modules Mount task runs.
config INTERPRETER_CPYTHON_MOUNT_MODULES_PRIORITY
int "CPython's Modules Mount task priority"
default 150
---help---
This is the priority of the CPython's Modules Mount task.
config INTERPRETER_CPYTHON_MOUNT_MODULES_PROGNAME
string "CPython's Modules Mount app name"
default "python_mount_modules"
---help---
This is the name of the program that will be used from the nsh.
endif

View File

@@ -82,6 +82,7 @@ $(CPYTHON_UNPACKNAME): $(CPYTHON_ZIP)
$(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0010-check-for-the-d_ino-member-of-the-structure-dirent.patch
$(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0011-avoid-redefinition-warning-if-UNUSED-is-already-defi.patch
$(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0012-hack-place-_PyRuntime-structure-into-PSRAM-bss-regio.patch
$(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0013-transform-functions-used-by-NuttX-to-lowercase.patch
$(HOSTPYTHON):
mkdir -p $(HOSTBUILD)
@@ -175,13 +176,7 @@ PROGNAME += $(CONFIG_INTERPRETER_CPYTHON_PROGNAME)
PRIORITY += $(CONFIG_INTERPRETER_CPYTHON_PRIORITY)
STACKSIZE += $(CONFIG_INTERPRETER_CPYTHON_STACKSIZE)
MAINSRC += python.c
PROGNAME += $(CONFIG_INTERPRETER_CPYTHON_MOUNT_MODULES_PROGNAME)
PRIORITY += $(CONFIG_INTERPRETER_CPYTHON_MOUNT_MODULES_PRIORITY)
STACKSIZE += $(CONFIG_INTERPRETER_CPYTHON_MOUNT_MODULES_STACKSIZE)
MAINSRC += mount_modules.c
MAINSRC += python_wrapper.c
checkgenromfs:
@genromfs -h 1>/dev/null 2>&1 || { \

View File

@@ -0,0 +1,33 @@
From 914c80b7969d73840bc1b573b478d9148999b7d0 Mon Sep 17 00:00:00 2001
From: Tiago Medicci <tiago.medicci@espressif.com>
Date: Fri, 31 Jan 2025 14:06:21 -0300
Subject: [PATCH 13/13] transform functions used by NuttX to lowercase
---
Include/pylifecycle.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h
index de1bcb1d2cb..044780ee188 100644
--- a/Include/pylifecycle.h
+++ b/Include/pylifecycle.h
@@ -33,6 +33,16 @@ PyAPI_FUNC(void) _Py_NO_RETURN Py_Exit(int);
PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv);
+#if defined(__NuttX__)
+#define py_bytesmain Py_BytesMain
+#endif
+
+void _PyRuntime_Early_Init(void);
+
+#if defined(__NuttX__)
+#define _pyruntime_early_init _PyRuntime_Early_Init
+#endif
+
/* In pathconfig.c */
Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *);
Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetProgramName(void);
--
2.47.1

View File

@@ -1,5 +1,5 @@
/****************************************************************************
* apps/interpreters/python/mount_modules.c
* apps/interpreters/python/python_wrapper.c
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -41,11 +41,14 @@
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/drivers/ramdisk.h>
#include "romfs_cpython_modules.h"
#include "Python.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -61,7 +64,7 @@
#endif
#ifndef CONFIG_CPYTHON_ROMFS_MOUNTPOINT
# define CONFIG_CPYTHON_ROMFS_MOUNTPOINT "/usr/local/lib/"
# define CONFIG_CPYTHON_ROMFS_MOUNTPOINT "/usr/local/lib"
#endif
#ifdef CONFIG_DISABLE_MOUNTPOINT
@@ -90,19 +93,57 @@
****************************************************************************/
/****************************************************************************
* Public Functions
* Name: check_and_mount_romfs
*
* Description:
* Check if the ROMFS is already mounted, and if not, mount it.
*
* Input Parameters:
* None
*
* Returned Value:
* 0 on success, 1 on failure
*
****************************************************************************/
/****************************************************************************
* Name: mount_modules
****************************************************************************/
int main(int argc, FAR char *argv[])
static int check_and_mount_romfs(void)
{
int ret;
int ret = OK;
struct boardioc_romdisk_s desc;
FILE *fp;
char line[256];
int is_mounted = 0;
/* Create a RAM disk for the test */
/* Check if the device is already mounted */
fp = fopen("/proc/fs/mount", "r");
if (fp == NULL)
{
printf("ERROR: Failed to open /proc/fs/mount\n");
UNUSED(desc);
return ret = ERROR;
}
while (fgets(line, sizeof(line), fp))
{
if (strstr(line, CONFIG_CPYTHON_ROMFS_MOUNTPOINT) != NULL)
{
is_mounted = 1;
break;
}
}
fclose(fp);
if (is_mounted)
{
_info("Device is already mounted at %s\n",
CONFIG_CPYTHON_ROMFS_MOUNTPOINT);
UNUSED(desc);
return ret;
}
/* Create a RAM disk */
desc.minor = CONFIG_CPYTHON_ROMFS_RAMDEVNO; /* Minor device number of the ROM disk. */
desc.nsectors = NSECTORS(romfs_cpython_modules_img_len); /* The number of sectors in the ROM disk */
@@ -119,7 +160,7 @@ int main(int argc, FAR char *argv[])
/* Mount the test file system */
printf("Mounting ROMFS filesystem at target=%s with source=%s\n",
_info("Mounting ROMFS filesystem at target=%s with source=%s\n",
CONFIG_CPYTHON_ROMFS_MOUNTPOINT, MOUNT_DEVNAME);
ret = mount(MOUNT_DEVNAME, CONFIG_CPYTHON_ROMFS_MOUNTPOINT, "romfs",
@@ -132,3 +173,30 @@ int main(int argc, FAR char *argv[])
return 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: python_wrapper_main
****************************************************************************/
int main(int argc, FAR char *argv[])
{
int ret;
ret = check_and_mount_romfs();
if (ret != 0)
{
return ret;
}
_pyruntime_early_init();
setenv("PYTHONHOME", "/usr/local", 1);
setenv("PYTHON_BASIC_REPL", "1", 1);
return py_bytesmain(argc, argv);
}