aboutsummaryrefslogtreecommitdiff
path: root/targets
diff options
context:
space:
mode:
authorPhilippe <65032815+pgu-swir@users.noreply.github.com>2020-10-21 10:56:59 -0700
committerGitHub <noreply@github.com>2020-10-21 19:56:59 +0200
commitf3030175422cd36fc10e5e37bd75a766dd30da04 (patch)
tree98a64b70ddbcdb9160c2bd23f552ec04848612ca /targets
parent8a0a86e3c7346c139b74d18e40faafb5dfcf5e3c (diff)
espressif's ESP-IDF port (#4270)
JerryScript-DCO-1.0-Signed-off-by: Philippe pgu-swir@users.noreply.github.com Co-authored-by: Philippe <pgu-swir@users.noreply.github.com>
Diffstat (limited to 'targets')
-rw-r--r--targets/esp-idf/CMakeLists.txt.example16
-rw-r--r--targets/esp-idf/README.md28
-rw-r--r--targets/esp-idf/date.c67
-rw-r--r--targets/esp-idf/debugger.c28
-rw-r--r--targets/esp-idf/external-context.c43
-rw-r--r--targets/esp-idf/fatal.c34
-rw-r--r--targets/esp-idf/io.c145
-rw-r--r--targets/esp-idf/module.c113
8 files changed, 474 insertions, 0 deletions
diff --git a/targets/esp-idf/CMakeLists.txt.example b/targets/esp-idf/CMakeLists.txt.example
new file mode 100644
index 00000000..84a5fc4a
--- /dev/null
+++ b/targets/esp-idf/CMakeLists.txt.example
@@ -0,0 +1,16 @@
+# assumes there is a component with this the following
+# - set the JERRY_DIR wherever the jerryscript source code (the include files) is
+# - a "lib" directory with the 2 libraries below
+
+set(JERRY_DIR ${PROJECT_DIR}/../../jerryscript/)
+
+idf_component_register(
+ SRC_DIRS ${JERRY_DIR}/targets/esp-idf
+ INCLUDE_DIRS ${JERRY_DIR}/jerry-core/include ${JERRY_DIR}/jerry-ext/include
+)
+
+add_prebuilt_library(libjerry-core lib/libjerry-core.a REQUIRES newlib PRIV_REQUIRES ${COMPONENT_NAME})
+add_prebuilt_library(libjerry-ext lib/libjerry-ext.a PRIV_REQUIRES ${COMPONENT_NAME})
+
+target_link_libraries(${COMPONENT_LIB} INTERFACE libjerry-core)
+target_link_libraries(${COMPONENT_LIB} INTERFACE libjerry-ext)
diff --git a/targets/esp-idf/README.md b/targets/esp-idf/README.md
new file mode 100644
index 00000000..da9fb20b
--- /dev/null
+++ b/targets/esp-idf/README.md
@@ -0,0 +1,28 @@
+This is a port for espressif's esp-idf (esp32). The LIBM, LTO and STRIP options should be disabled, so to build under the IDF toolchain, just run the following command
+
+```
+python tools\build.py --toolchain=cmake/toolchain-esp32.cmake --cmake-param "-GUnix Makefiles" --jerry-cmdline=OFF --jerry-port-default=OFF --jerry-libm=OFF --lto=OFF --strip=OFF
+```
+
+NB: the LIBM, STRIP and LTO might be disabled by platform as well. I strongly suggest limiting heap memorry with '--mem-heap=128' but that really depends on the SRAM avaiulable on your esp32.
+
+Then copy the artefacts 'build/lib/\*.a' in an esp-idf component named 'jerryscript' (eg) and use a 'CMakeLists.txt' like this one
+
+```
+# assumes there is a component with this the following
+# - set the JERRY_DIR wherever the jerryscript source code (the include files) is
+# - a "lib" directory with the 2 libraries below
+
+set(JERRY_DIR ${PROJECT_DIR}/../../jerryscript/)
+
+idf_component_register(
+ SRC_DIRS ${JERRY_DIR}/targets/esp-idf
+ INCLUDE_DIRS ${JERRY_DIR}/jerry-core/include ${JERRY_DIR}/jerry-ext/include
+)
+
+add_prebuilt_library(libjerry-core lib/libjerry-core.a REQUIRES newlib PRIV_REQUIRES ${COMPONENT_NAME})
+add_prebuilt_library(libjerry-ext lib/libjerry-ext.a PRIV_REQUIRES ${COMPONENT_NAME})
+
+target_link_libraries(${COMPONENT_LIB} INTERFACE libjerry-core)
+target_link_libraries(${COMPONENT_LIB} INTERFACE libjerry-ext)
+```
diff --git a/targets/esp-idf/date.c b/targets/esp-idf/date.c
new file mode 100644
index 00000000..e9ebdb3c
--- /dev/null
+++ b/targets/esp-idf/date.c
@@ -0,0 +1,67 @@
+/* Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include "jerryscript-port.h"
+
+/**
+ * Default implementation of jerry_port_get_local_time_zone_adjustment. Uses the 'tm_gmtoff' field
+ * of 'struct tm' (a GNU extension) filled by 'localtime_r' if available on the
+ * system, does nothing otherwise.
+ *
+ * @return offset between UTC and local time at the given unix timestamp, if
+ * available. Otherwise, returns 0, assuming UTC time.
+ */
+double jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */
+ bool is_utc) /**< is the time above in UTC? */
+{
+ struct tm tm;
+ char buf[8];
+ time_t now = (time_t) (unix_ms / 1000);
+
+ localtime_r (&now, &tm);
+
+ if (!is_utc)
+ {
+ strftime(buf, 8, "%z", &tm);
+ now -= -atof(buf) * 3600 * 1000 / 100;
+ localtime_r (&now, &tm);
+ }
+
+ strftime(buf, 8, "%z", &tm);
+
+ return -atof(buf) * 3600 * 1000 / 100;
+} /* jerry_port_get_local_time_zone_adjustment */
+
+/**
+ * Default implementation of jerry_port_get_current_time. Uses 'gettimeofday' if
+ * available on the system, does nothing otherwise.
+ *
+ * @return milliseconds since Unix epoch - if 'gettimeofday' is available and
+ * executed successfully,
+ * 0 - otherwise.
+ */
+double jerry_port_get_current_time (void)
+{
+ struct timeval tv;
+
+ if (gettimeofday (&tv, NULL) == 0)
+ {
+ return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
+ }
+ return 0.0;
+} /* jerry_port_get_current_time */
diff --git a/targets/esp-idf/debugger.c b/targets/esp-idf/debugger.c
new file mode 100644
index 00000000..71324392
--- /dev/null
+++ b/targets/esp-idf/debugger.c
@@ -0,0 +1,28 @@
+/* Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+
+#include "jerryscript-port.h"
+
+/**
+ * Default implementation of jerry_port_sleep. Uses 'nanosleep' or 'usleep' if
+ * available on the system, does nothing otherwise.
+ */
+void jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */
+{
+ vTaskDelay( sleep_time / portTICK_PERIOD_MS);
+} /* jerry_port_sleep */
diff --git a/targets/esp-idf/external-context.c b/targets/esp-idf/external-context.c
new file mode 100644
index 00000000..4863a8a6
--- /dev/null
+++ b/targets/esp-idf/external-context.c
@@ -0,0 +1,43 @@
+/* Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jerryscript-port.h"
+
+/**
+ * Pointer to the current context.
+ * Note that it is a global variable, and is not a thread safe implementation.
+ * But I don't see how jerryscript can make that thread-safe, only the appication can
+ */
+static jerry_context_t *current_context_p = NULL;
+
+/**
+ * Set the current_context_p as the passed pointer.
+ */
+void
+jerry_port_default_set_current_context (jerry_context_t *context_p) /**< points to the created context */
+{
+ current_context_p = context_p;
+} /* jerry_port_default_set_current_context */
+
+/**
+ * Get the current context.
+ *
+ * @return the pointer to the current context
+ */
+jerry_context_t *
+jerry_port_get_current_context (void)
+{
+ return current_context_p;
+} /* jerry_port_get_current_context */
diff --git a/targets/esp-idf/fatal.c b/targets/esp-idf/fatal.c
new file mode 100644
index 00000000..b178ff7d
--- /dev/null
+++ b/targets/esp-idf/fatal.c
@@ -0,0 +1,34 @@
+/* Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "esp_system.h"
+#include "esp_log.h"
+
+#include "jerryscript-port.h"
+
+static const char TAG[] = "JS";
+
+/**
+ * Default implementation of jerry_port_fatal. Calls 'abort' if exit code is
+ * non-zero, 'exit' otherwise.
+ */
+void jerry_port_fatal (jerry_fatal_code_t code) /**< cause of error */
+{
+ ESP_LOGE(TAG, "Fatal error %d", code);
+ vTaskSuspend(NULL);
+ abort();
+} /* jerry_port_fatal */
diff --git a/targets/esp-idf/io.c b/targets/esp-idf/io.c
new file mode 100644
index 00000000..fab28abe
--- /dev/null
+++ b/targets/esp-idf/io.c
@@ -0,0 +1,145 @@
+/* Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include "esp_log.h"
+
+#include "jerryscript-port.h"
+#include "jerryscript-debugger.h"
+
+static const char TAG[] = "JS";
+
+static esp_log_level_t crosslog(jerry_log_level_t level)
+{
+ switch(level)
+ {
+ case JERRY_LOG_LEVEL_ERROR: return ESP_LOG_ERROR;
+ case JERRY_LOG_LEVEL_WARNING: return ESP_LOG_WARN;
+ case JERRY_LOG_LEVEL_DEBUG: return ESP_LOG_DEBUG;
+ case JERRY_LOG_LEVEL_TRACE: return ESP_LOG_VERBOSE;
+ }
+
+ return ESP_LOG_NONE;
+}
+
+#ifndef DISABLE_EXTRA_API
+
+/**
+ * Actual log level
+ */
+static jerry_log_level_t jerry_port_default_log_level = JERRY_LOG_LEVEL_ERROR;
+
+#define JERRY_PORT_DEFAULT_LOG_LEVEL jerry_port_default_log_level
+
+/**
+ * Get the log level
+ *
+ * @return current log level
+ *
+ * Note:
+ * This function is only available if the port implementation library is
+ * compiled without the DISABLE_EXTRA_API macro.
+ */
+jerry_log_level_t
+jerry_port_default_get_log_level (void)
+{
+ return jerry_port_default_log_level;
+} /* jerry_port_default_get_log_level */
+
+/**
+ * Set the log level
+ *
+ * Note:
+ * This function is only available if the port implementation library is
+ * compiled without the DISABLE_EXTRA_API macro.
+ */
+void
+jerry_port_default_set_log_level (jerry_log_level_t level) /**< log level */
+{
+ jerry_port_default_log_level = level;
+} /* jerry_port_default_set_log_level */
+
+#else /* DISABLE_EXTRA_API */
+#define JERRY_PORT_DEFAULT_LOG_LEVEL JERRY_LOG_LEVEL_ERROR
+#endif /* !DISABLE_EXTRA_API */
+
+/**
+ * Default implementation of jerry_port_log. Prints log message to the standard
+ * error with 'vfprintf' if message log level is less than or equal to the
+ * current log level.
+ *
+ * If debugger support is enabled, printing happens first to an in-memory buffer,
+ * which is then sent both to the standard error and to the debugger client.
+ *
+ * Note:
+ * Changing the log level from JERRY_LOG_LEVEL_ERROR is only possible if
+ * the port implementation library is compiled without the
+ * DISABLE_EXTRA_API macro.
+ */
+void
+jerry_port_log (jerry_log_level_t level, /**< message log level */
+ const char *format, /**< format string */
+ ...) /**< parameters */
+{
+ if (level <= JERRY_PORT_DEFAULT_LOG_LEVEL)
+ {
+ va_list args;
+ va_start (args, format);
+#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
+ int length = vsnprintf (NULL, 0, format, args);
+ va_end (args);
+ va_start (args, format);
+
+ JERRY_VLA (char, buffer, length + 1);
+ vsnprintf (buffer, (size_t) length + 1, format, args);
+
+ esp_log_write(crosslog(level), TAG, buffer);
+ jerry_debugger_send_log (level, (jerry_char_t *) buffer, (jerry_size_t) length);
+#else /* If jerry-debugger isn't defined, libc is turned on */
+ esp_log_writev(crosslog(level), TAG, format, args);
+#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
+ va_end (args);
+ }
+} /* jerry_port_log */
+
+#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
+
+#define DEBUG_BUFFER_SIZE (256)
+static char debug_buffer[DEBUG_BUFFER_SIZE];
+static int debug_buffer_index = 0;
+
+#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
+
+/**
+ * Default implementation of jerry_port_print_char. Uses 'putchar' to
+ * print a single character to standard output.
+ */
+void
+jerry_port_print_char (char c) /**< the character to print */
+{
+ putchar(c);
+
+#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
+ debug_buffer[debug_buffer_index++] = c;
+
+ if ((debug_buffer_index == DEBUG_BUFFER_SIZE) || (c == '\n'))
+ {
+ jerry_debugger_send_output ((jerry_char_t *) debug_buffer, (jerry_size_t) debug_buffer_index);
+ debug_buffer_index = 0;
+ }
+#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
+} /* jerry_port_print_char */
diff --git a/targets/esp-idf/module.c b/targets/esp-idf/module.c
new file mode 100644
index 00000000..e3faab23
--- /dev/null
+++ b/targets/esp-idf/module.c
@@ -0,0 +1,113 @@
+/* Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "jerryscript-port.h"
+
+/**
+ * Opens file with the given path and reads its source.
+ * @return the source of the file
+ */
+uint8_t *
+jerry_port_read_source (const char *file_name_p, /**< file name */
+ size_t *out_size_p) /**< [out] read bytes */
+{
+ FILE *file_p = fopen (file_name_p, "rb");
+
+ if (file_p == NULL)
+ {
+ jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to open file: %s\n", file_name_p);
+ return NULL;
+ }
+
+ struct stat info = { };
+ fstat(fileno(file_p), &info);
+ uint8_t *buffer_p = (uint8_t *) malloc (info.st_size);
+
+ if (buffer_p == NULL)
+ {
+ fclose (file_p);
+
+ jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to allocate memory for file: %s\n", file_name_p);
+ return NULL;
+ }
+
+ size_t bytes_read = fread (buffer_p, 1u, info.st_size, file_p);
+ if (bytes_read != info.st_size)
+ {
+ fclose (file_p);
+ free (buffer_p);
+
+ jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to read file: %s\n", file_name_p);
+ return NULL;
+ }
+
+ fclose (file_p);
+ *out_size_p = bytes_read;
+
+ return buffer_p;
+} /* jerry_port_read_source */
+
+/**
+ * Release the previously opened file's content.
+ */
+void
+jerry_port_release_source (uint8_t *buffer_p) /**< buffer to free */
+{
+ free (buffer_p);
+} /* jerry_port_release_source */
+
+/**
+ * Normalize a file path
+ *
+ * @return length of the path written to the output buffer
+ */
+size_t
+jerry_port_normalize_path (const char *in_path_p, /**< input file path */
+ char *out_buf_p, /**< output buffer */
+ size_t out_buf_size, /**< size of output buffer */
+ char *base_file_p) /**< base file path */
+{
+ size_t ret = strlen(base_file_p) + strlen(in_path_p) + 1;
+
+ if (ret < out_buf_size) {
+ strcpy (out_buf_p, base_file_p);
+ strcat (out_buf_p, "/");
+ strcat (out_buf_p, in_path_p);
+ return ret;
+ }
+
+ return 0;
+} /* jerry_port_normalize_path */
+
+/**
+ * Get the module object of a native module.
+ *
+ * @return Undefined, if 'name' is not a native module
+ * jerry_value_t containing the module object, otherwise
+ */
+jerry_value_t
+jerry_port_get_native_module (jerry_value_t name) /**< module specifier */
+{
+ (void) name;
+ return jerry_create_undefined ();
+} /* jerry_port_get_native_module */