├── .gitignore ├── .gitmodules ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── components └── list │ ├── .gitignore │ ├── .travis.yml │ ├── CMakeLists.txt │ ├── History.md │ ├── Readme.md │ ├── benchmark.c │ ├── component.mk │ ├── package.json │ ├── src │ ├── clist.c │ ├── clist.h │ ├── list_iterator.c │ └── list_node.c │ └── test.c ├── examples ├── http │ └── http_stream.js ├── remote_control │ └── ws2812b.js ├── sigmadelta │ └── led.js ├── spi │ ├── st7735-spi.js │ └── st7789-spi.js └── wifi │ ├── connect_to_ap.js │ └── scan_ap.js ├── main ├── CMakeLists.txt ├── component.mk ├── include │ ├── nodemcujs.h │ └── nodemcujs_config.h ├── nodemcujs_main.c ├── src │ ├── js │ │ ├── console.js │ │ ├── events.js │ │ ├── module.js │ │ ├── nodemcujs.js │ │ ├── path.js │ │ ├── spi.js │ │ ├── util.js │ │ └── wifi.js │ ├── modules │ │ ├── nodemcujs_module_console.c │ │ ├── nodemcujs_module_esp_error.c │ │ ├── nodemcujs_module_gpio.c │ │ ├── nodemcujs_module_http_client.c │ │ ├── nodemcujs_module_nvs_flash.c │ │ ├── nodemcujs_module_process.c │ │ ├── nodemcujs_module_rmt.c │ │ ├── nodemcujs_module_sigmadelta.c │ │ ├── nodemcujs_module_spi_master.c │ │ ├── nodemcujs_module_timers.c │ │ └── nodemcujs_module_wifi.c │ ├── nodemcujs.c │ ├── nodemcujs_binding.c │ ├── nodemcujs_binding.h │ ├── nodemcujs_def.h │ ├── nodemcujs_js.c │ ├── nodemcujs_js.h │ ├── nodemcujs_magic_strings.h │ ├── nodemcujs_module.c │ ├── nodemcujs_module.h │ ├── nodemcujs_module_inl.h │ ├── nodemcujs_string.c │ ├── nodemcujs_string.h │ ├── nodemcujs_string_ext.inl.h │ ├── nodemcujs_utils.c │ └── nodemcujs_utils.h └── tools │ ├── common_py │ ├── __init__.py │ ├── __init__.pyc │ ├── path.py │ ├── path.pyc │ └── system │ │ ├── __init__.py │ │ ├── __init__.pyc │ │ ├── executor.py │ │ ├── filesystem.py │ │ ├── filesystem.pyc │ │ └── platform.py │ └── js2c.py ├── partitions.csv ├── scripts ├── build-firmware.sh ├── install-idf-v3.2.sh └── install-xtensa.sh ├── sdkconfig ├── sdkconfig.old └── spiffs └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | build 3 | .DS_Store -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/jerryscript"] 2 | path = deps/jerryscript 3 | url = https://github.com/jerryscript-project/jerryscript.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | os: linux 3 | dist: bionic 4 | 5 | before_install: 6 | - sudo apt-get install -y git wget libncurses-dev flex bison gperf python python-click python-pip python-setuptools python-serial python-cryptography python-future python-pyparsing python-pyelftools cmake ninja-build ccache 7 | - export IDF_PATH="$HOME/esp-idf-v3.2" 8 | - export XTENSA="$HOME/xtensa-esp32-elf" 9 | - export PATH="$XTENSA/bin:$IDF_PATH/tools:$PATH" 10 | 11 | install: 12 | - scripts/install-xtensa.sh 13 | - scripts/install-idf-v3.2.sh 14 | 15 | script: 16 | - scripts/build-firmware.sh 17 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | set(JERRYSCRIPT_ROOT "${CMAKE_SOURCE_DIR}/deps/jerryscript") 6 | 7 | # Jerryscript setting here 8 | set(JERRY_GLOBAL_HEAP_SIZE "(128)") 9 | set(JERRY_ERROR_MESSAGES ON) 10 | 11 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 12 | project(nodemcujs) 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2022 nodemcujs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nodemcujs [![Build Status](https://travis-ci.com/nodemcujs/nodemcujs-firmware.svg?branch=master)](https://travis-ci.com/nodemcujs/nodemcujs-firmware) 2 | 3 | ### A real JavaScript based interactive firmware for ESP32. 4 | 5 | nodemcujs 是一个在 ESP32 芯片上的 JavaScript 运行时。不同于 NodeMcu,这是在 ESP32 芯片上运行了一个真正的 JavaScript 虚拟机。在 ESP32 上编写 JavaScript 就和编写 NodeJS 程序一样。并且提供了一个 32MBit 的片上虚拟文件系统,你可以编写模块化的应用,然后使用 require() 导入模块。甚至直接将你的兼容 NodeJS 模块运行在 ESP32 上,而无需做任何改动。 6 | 7 | # 文档 | Documentation 8 | 9 | website: https://timor.tech 正在编写文档,under the development 10 | 11 | github: https://github.com/nodemcujs/nodemcujs-doc 12 | 13 | 这是 nodemcujs 的网站,所有文档和最新信息将会发布在这里。也可以通过 fork 项目贡献文章。文档还在不断完善中。 14 | 15 | # 示例 | Examples 16 | 17 | **HTTP Client** 18 | 19 | - [HTTP 流式传输: examples/http/http_stream.js](examples/http/http_stream.js) 20 | 21 | **WIFI** 22 | 23 | - [连接 WIFI: examples/wifi/connect_to_ap.js](examples/wifi/connect_to_ap.js) 24 | - [扫描 WIFI 热点: examples/wifi/scan_ap.js](examples/wifi/scan_ap.js) 25 | 26 | **SPI** 27 | 28 | - [st7735 1.44寸TFT屏幕: examples/spi/st7735-spi.js](examples/spi/st7735-spi.js) 29 | - [st7789 1.3寸IPS屏幕: examples/spi/st7789-spi.js](examples/spi/st7789-spi.js) 30 | 31 | **Sigmadelta Modulation** 32 | 33 | - [led呼吸灯: examples/sigmadelta/led.js](examples/sigmadelta/led.js) 34 | 35 | **Remote Control** 36 | 37 | - [WS2812B 全彩LED: examples/remote_control/ws2812b.js](examples/remote_control/ws2812b.js) 38 | 39 | # 已经支持的功能/模块 | Supported 40 | 41 | **驱动** 42 | 43 | - [x] WIFI: 目前支持 STA 模式,支持 WIFI 事件,扫描热点。AP 模式的 API 正在开发中 44 | - [x] GPIO: 目前支持基本的 mode、write、read 45 | - [x] SPI Master mode: 目前仅支持 HSPI 46 | - [x] Sigmadelta second-order Modulation 47 | - [x] Remote Contrl: 目前仅支持发送数据,可用于红外、WS2812 48 | - [x] NVS FLASH: 用于保存系统信息,比如WIFI设置 49 | - [x] ESP ERROR: 用于查找系统层统一的报错信息,格式化成可阅读的字符串 50 | 51 | **Node** 52 | 53 | - [x] HTTP Client 支持 stream 流式传输,支持基本的 GET/POST/PUT/DELETE etc... 等请求 54 | - [x] 定时器,目前支持 setTimeout、setInterval、delay(同步非阻塞延时) 55 | - [x] CMD模块系统,支持文件系统模块、内置模块、native模块 56 | - [x] native Addons(需源码编译到固件,未来我们会支持 静态库) 57 | - [x] 串口错误日志输出 (方便调试代码报错) 58 | 59 | # 特性 | Feature 60 | 61 | - 纯 C 开发,代码结构遵循 NodeJS,上手简单 62 | - 支持 同步并且非阻塞 编程,能编写准实时、硬件驱动等高实时应用程序。 63 | - 遵循 CMD 模块规范 64 | - 使用开源 JerryScript,内存开销小,开源社区支持 65 | - 完整 ES5, 部分 ES6 语法支持 66 | - 虚拟文件系统 67 | - 串口 shell 命令行交互,方便调试 68 | - 使用官方 ESP_IDF 工程,集成硬件驱动 69 | - 集成 js 文件分区工具,不需要了解分区表,能一键制作文件镜像、烧写文件镜像到 ESP32 板子上 70 | 71 | # Todo 72 | 73 | - [ ] 事件循环 74 | - [ ] 桥接驱动 IIC SPI 75 | - [ ] tGFX 图形库 76 | - [ ] 文件模块 77 | - [ ] 调试功能 78 | - [ ] 完善文档 79 | - [ ] 更多。。。 80 | 81 | # hello world 82 | 83 | ```js 84 | var foo = require('/foo.js') 85 | 86 | console.log('hello nodemcujs') 87 | 88 | process.delay(1000) // sync and non-block 89 | 90 | setTimeout(function() { 91 | console.log('timeout') 92 | }, 1000) 93 | 94 | console.log('hello world') 95 | ``` 96 | 97 | # WIFI hello world 98 | 99 | ```js 100 | var wifi = require('wifi') 101 | 102 | wifi.init(); 103 | 104 | wifi.setMode(wifi.WIFI_MODE.STA); 105 | 106 | wifi.setConfig(wifi.WIFI_MODE.STA, { 107 | ssid: 'SSID', 108 | password: 'PASS', 109 | auth: wifi.WIFI_AUTH_MODE.WIFI_AUTH_WPA2_PSK 110 | }); 111 | 112 | wifi.start(); 113 | wifi.connect(); // connect to ap 114 | ``` 115 | 116 | # 快速开始 117 | 118 | 快速在本地环境构建出可执行的固件并烧写到 ESP32 芯片上。 119 | 120 | ## 1. 开发环境搭建 121 | 122 | 项目使用 CMake `cmake_minimum_required (VERSION 3.5)` 构建。 123 | 124 | 我在 MacOS 10.13、Ubuntu 18.04.2 LTS、Windows 10 中已验证构建通过,你可以选择适合自己的开发环境。 125 | 126 | 在 Windows 中环境设置比较麻烦,请仔细参照官方文档进行环境安装,我多数在 Ubuntu 下进行开发测试。 127 | 128 | ### 1.1 获取 ESP-IDF (V4.3.1) 129 | 130 | 参照官方文档进行安装。注意本项目使用的是 V4.3.1 版本,理论上 v4 全系版本都支持的。 131 | 132 | ESP-IDF(V4.3.1): https://docs.espressif.com/projects/esp-idf/zh_CN/v4.3.1/esp32/get-started/index.html#esp-idf 133 | 134 | 你也可以在没有安装 git 的环境中下载源码包: https://dl.espressif.com/dl/esp-idf/releases/esp-idf-v4.3.1.zip 135 | 136 | ### 1.2 设置工具链 137 | 138 | 在设置工具链前,请按照对应的系统安装必须的软件包: 139 | 140 | - Windows: https://docs.espressif.com/projects/esp-idf/zh_CN/v3.2-rc/get-started/windows-setup.html 141 | - Linux: https://docs.espressif.com/projects/esp-idf/zh_CN/v3.2-rc/get-started/linux-setup.html 142 | - MaxOS: https://docs.espressif.com/projects/esp-idf/zh_CN/v3.2-rc/get-started/macos-setup.html 143 | 144 | 然后按照官方文档进行编译工具链的安装: 145 | 146 | https://docs.espressif.com/projects/esp-idf/zh_CN/v4.3.1/esp32/get-started/index.html#get-started-set-up-tools。 147 | 148 | ## 2. 获取 nodemcujs 源码 149 | 150 | ```bash 151 | $ git clone --recursive git@github.com:nodemcujs/nodemcujs-firmware.git 152 | ``` 153 | 154 | 项目已经将 JerryScript 作为子模块,存放在 `/deps/jerryscript` 目录下。`clone` 的时候会一并将所有子模块 clone 下来。 155 | 156 | 如果你忘记了在 `clone` 时候加 `--recursive` 选项,那么你可以通过下面的命令单独 clone `子模块`。 157 | 158 | ```bash 159 | $ git submodule update --init 160 | ``` 161 | 162 | ## 3. 一键编译固件 163 | 164 | 先进入项目根目录: 165 | 166 | ```bash 167 | $ cd nodemcujs-firmware 168 | ``` 169 | 170 | 创建 build 文件夹,为了编译后的临时文件不影响源码目录。 171 | 172 | ```bash 173 | $ mkdir build 174 | $ cd build 175 | ``` 176 | 177 | 使用 Cmake 构建 178 | 179 | ```bash 180 | $ cmake ../ 181 | ``` 182 | 183 | 可选步骤。配置构建参数。大多数情况下使用默认参数就可以,这里一般只需要配置好串口和波特率。 184 | 185 | ```bash 186 | $ make menuconfig 187 | ``` 188 | 189 | > 注意: 项目使用了自定义的分区表。详情可以查看分区表文件 [partitions.csv][partitions.csv] 190 | 191 | 最后进行编译固件。 192 | 193 | ```bash 194 | $ make 195 | ``` 196 | 197 | ## 4. 一键烧录固件 198 | 199 | 如果编译成功,会生成 4 个文件: 200 | 201 | 1. nodemcujs.bin (可执行 app) 202 | 2. bootloader/bootloader.bin (引导) 203 | 3. partition_table/partition_table.bin (分区表) 204 | 4. storage.bin (用户文件镜像) 205 | 206 | 使用下面的命令进行固件的烧录。 207 | 208 | ```bash 209 | $ make flash 210 | ``` 211 | 212 | 如果你看到控制台输出如下信息,并一直停留,那么你需要手动让 ESP32 芯片进入下载模式。 213 | 214 | ```bash 215 | esptool.py --chip esp32 -b 460800 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x1000 bootloader/bootloader.bin 0x8000 partition_table/partition-table.bin 0x10000 nodemcujs.bin 216 | esptool.py v2.6 217 | Found 3 serial ports 218 | Serial port /dev/ttyUSB0 219 | Connecting........___........___ 220 | ``` 221 | 222 | 等待烧录完成,重启 ESP32 就可以了。 223 | 224 | > 注意:make flash 会自动烧录文件镜像,此文件镜像就是 spiffs 目录下的文件。 225 | 226 | 系统上电会默认启动用户文件系统中的 /index.js,所以你的应用入口可以写在这里。 227 | 228 | 此外你还可以使用 ESPlorer 连接上 ESP32,输入 JavaScript 和它进行交互了。 229 | 230 | ## 5. 手动烧录固件 231 | 232 | 对于没有或者不方便安装 ESP-IDF 工程的用户,可以使用烧录工具进行烧录已经构建好的固件。 233 | 234 | 我们推荐使用 [esptool.py][esptool] 工具进行烧录。可以从 [release][release-github] 页面下载已经构建好的固件。 235 | 236 | Tips: ESP-IDF 内置了 `esptool.py` 工具,可以直接使用。路径在 `$IDF_PATH/components/esptool_py/esptool/esptool.py` 237 | 238 | ```bash 239 | $ python esptool.py --chip esp32 -p /dev/ttyUSB0 -b 460800 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x1000 bootloader.bin 0x8000 partition-table.bin 0x10000 nodemcujs.bin 0x00110000 storage.bin 240 | ``` 241 | 242 | 这里有几点需要说明: 243 | 244 | > -b 参数表示下载固件时使用的波特率,如果出现烧录失败等问题,请尝试降低波特率为 115200 或者 9600。这可能是劣质的串口芯片造成的。 245 | > 246 | > -p 参数表示 ESP32 芯片在你电脑上的串口设备,请替换为实际的值或者端口号。在 Windows 上的可能值为 COM3。 247 | > 248 | > 0x1000 和 0x8000,以及 0x10000 使用的是默认值。 249 | > 250 | > 第一次烧录需要这 3 个文件,以后烧录只需要一个 nodemcujs.bin 文件就行了。 251 | > 252 | > storage.bin 是可选的,系统启动只需要前面三个固件即可。 253 | 254 | ## 6. 制作文件镜像 255 | 256 | nodemcujs 使用 [spiffs][spiffs] 作为默认文件系统,容量大约为 `2.7MB`,所以文件的总大小不能超出此范围。关于为什么容量只有 2.7MB,请参考 [partitions.csv][partitions.csv]。 257 | 258 | 我们建议将要烧录到 flash 存储的文件放到 `spiffs` 文件夹内,在我们的构建系统中,我们将会自动构建 flash 镜像并随固件一起烧录。文件系统是默认以 `/` 为根目录的。 259 | 260 | 制作文件镜像有多种方式,我们推荐使用 nodemcujs 里面集成的方式: 261 | 262 | - 将你的 .js 文件或者其它文件放到项目根目录下的 `spiffs` 文件夹内。 263 | - 然后执行 `make spiffs_storage_bin` 命令即可一键制作文件镜像。 264 | - nodemcujs 会将 `spiffs` 文件夹下面的所有文件打包成一个 `storage.bin` 镜像。 265 | 266 | **手动制作文件镜像** 267 | 268 | 我们使用 [mkspiffs][mkspiffs] 来制作镜像。这是 C++ 工程,首先你要编译它,得到可执行文件 `mkspiffs`。 269 | 270 | ```bash 271 | $ mkspiffs -c spiffs -b 4096 -p 256 -s 0x2F0000 storage.bin 272 | ``` 273 | 274 | 上面的命令会将 `spiffs` 文件夹内的全部文件打包成镜像,并且在当前目录生成 `storage.bin` 文件。 275 | 276 | 这里有几点需要注意: 277 | 278 | > -s 0x2F0000 是 nodemcujs 所使用的大小,至少在目前你不能大于此值。除非你自己定义分区表。 279 | > 280 | > 编译 mkspiffs 时需要传递参数: `CPPFLAGS="-DSPIFFS_OBJ_META_LEN=4"` 否则会出现 nodemcujs 文件系统无法工作。 281 | 282 | ## 7. 烧录文件到 flash 芯片 283 | 284 | nodemcujs 会在启动时检查分区,如果无法挂载 `storage` 分区,则会`自动格式化 storage` 分区并挂载。 285 | 286 | 你可以将你的 JavaScript 应用或者任何文件烧录到 ESP32 上,nodemcujs 会在启动时自动加载 `/spiffs/index.js` 文件,所以这可能是自动启动应用的一个好主意。 287 | 288 | 烧录文件镜像有多种方式,我们推荐使用 nodemcujs 里面集成的方式: 289 | 290 | - 执行 `make flash-storage` 命令即可一键烧录文件镜像。 291 | 292 | **手动烧录文件镜像** 293 | 294 | ```bash 295 | $ python esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 115200 write_flash -z 0x110000 storage.bin 296 | ``` 297 | 298 | > 手动烧录文件镜像请将 /dev/ttyUSB0 替换为你实际的设备,或者自动选择设备。 299 | 300 | 有几点需要注意: 301 | 302 | > 一旦你烧录文件镜像,则原来的分区会被覆盖掉,请知道你自己在做什么。 303 | > 304 | > -z 0x10000 是目前 nodemcujs 默认分区表参数,至少在目前你不能小于此值,否则 app 程序可能会被覆盖。 305 | 306 | ## 8. 更新 jerryscript 307 | 308 | jerryscript 作为一个子模块放置在 `/deps/jerryscript` 目录下,所以更新 jerryscript 很方便,进入 `/deps/jerryscript` 目录,使用 `git` 拉取最新 `commit` 就行了。 309 | 310 | 或者手动下载最新 jerryscript 文件替换掉。 311 | 312 | ## 9. native 模块 313 | 314 | 硬件驱动部分或者性能要求高的部分,我们必须使用 C\C++ 编写,这个时候就需要用到 `native` 模块了。比如 `GPIO` 模块。 315 | 316 | 在这之前,有几个关于模块的概念必须要搞清楚: 317 | 318 | - 第三方模块:用户编写的,存在于文件系统上的 .js 文件,我们叫第三方模块。 319 | - 内置js模块:编译到 nodemcujs 固件里面的 .js 文件,我们叫内置模块,比如 path 模块。它们存在 /main/src/js/ 文件夹下面。 320 | - native模块:使用 C\C++ 编写的模块,我们叫 native模块。比如 GPIO。 321 | 322 | > 注意:通常内置模块包含一个对应的 native模块,我们把 内置js 和 native模块 统称为 内置模块。比如 console。 323 | > 如果一个内置模块有对应的 native模块,则 nodemcujs 会自动将对应的 native模块 注入到 内置js模块中,通过 native 全局变量引用。 324 | 325 | `native` 模块是由 C\C++ 编写的模块,它和 JS 文件模块的使用方法是一样的。native模块以 `nodemcujs_module_xxx.c` 命名,存放在 `/main/src/modules` 文件夹下,我们规定 `native` 模块都必须有一个 `nodemcujs_module_init_xxx` 方法用于导出,该函数的返回值是 `jerry_value_t` 类型。 326 | 327 | 下面我们以编写 `GPIO` 模块为例。 328 | 329 | 首先我们编写该模块的 init 函数: 330 | 331 | ```c 332 | // main/src/modules/nodemcujs_module_gpio.c 333 | 334 | jerry_value_t nodemcujs_module_init_gpio() 335 | { 336 | jerry_value_t gpio = jerry_create_object(); 337 | // ...... 338 | return gpio; 339 | } 340 | ``` 341 | 342 | 新增native模块后,需要重新执行 `cmake ..` 构建。然后我们就可以通过 `var gpio = require('gpio')` 使用了。 343 | 344 | 此外,我们还可以再编写一个对应的内置js模块,把native模块通过js包装成更友好的API: 345 | 346 | ```js 347 | // main/src/js/gpio.js 348 | 349 | var gpio = native; // 这个全局变量 native 就是 C函数 nodemcujs_module_init_gpio 返回的对象 350 | 351 | function GPIO(pin) { 352 | this.pin = pin; 353 | } 354 | 355 | GPIO.prototype.mode = function(mode) { 356 | gpio.mode(this.pin, mode); 357 | } 358 | 359 | GPIO.prototype.write = function(level) { 360 | gpio.write(this.pin, level); 361 | } 362 | 363 | module.exports = GPIO; 364 | ``` 365 | 366 | 最后在 JS 中使用它: 367 | 368 | ```js 369 | var GPIO = require('gpio') // 此时 gpio 就是 gpio.js 到处的对象了 370 | ``` 371 | 372 | `native` 模块是有 `缓存` 的,init 方法被调用后,会将模块的值缓存起来,以后再次 `require` 将会直接返回缓存的值。 373 | 374 | # FAQ | 常见错误一览 375 | 376 | 请前往官方网站查看。 377 | 378 | # License 379 | 380 | [MIT][MIT] 381 | 382 | 383 | 384 | 385 | [esptool]: https://github.com/espressif/esptool 386 | [release-github]: https://github.com/nodemcujs/nodemcujs-firmware/releases 387 | [partitions.csv]: ./partitions.csv 388 | [mkspiffs]: https://github.com/igrr/mkspiffs 389 | [spiffs]: https://docs.espressif.com/projects/esp-idf/zh_CN/v4.3.1/esp32/api-reference/storage/spiffs.html 390 | [MIT]: [./LICENSE] 391 | -------------------------------------------------------------------------------- /components/list/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | bin 3 | .pomo 4 | *.o 5 | build 6 | deps 7 | -------------------------------------------------------------------------------- /components/list/.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | before_install: 3 | - sudo apt-get update 4 | - sudo apt-get install libcurl4-gnutls-dev valgrind -qq 5 | - git clone https://github.com/clibs/clib.git /tmp/clib 6 | - sudo make -C /tmp/clib install 7 | install: clib install --dev 8 | script: 9 | - make bin/test 10 | - valgrind --leak-check=full --error-exitcode=5 ./bin/test 11 | -------------------------------------------------------------------------------- /components/list/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8.12) 2 | 3 | set(COMPONENT_ADD_INCLUDEDIRS "src") 4 | set(COMPONENT_SRCDIRS "src") 5 | 6 | register_component() 7 | -------------------------------------------------------------------------------- /components/list/History.md: -------------------------------------------------------------------------------- 1 | 2 | 0.0.8 / 2015-01-30 3 | ================== 4 | 5 | * fix `list_at` unsigned compare error (bolasblack, #13) 6 | * travis: Fail the build if any memory is leaked 7 | * travis: Update before installing deps 8 | * test: Fix memory leaks 9 | 10 | 0.0.7 / 2014-06-02 11 | ================== 12 | 13 | * ci: Remove benchmarks 14 | * add travis 15 | * test: Fix 'unused parameter' warning 16 | * readme: Update benchmarks 17 | * benchmark: Fix 'unused parameter' warning 18 | * benchmark: Use clibs/bench for CPU time 19 | * readme: Correct types 20 | * readme: Add syntax highlighting 21 | * iterator: set to `NULL` after freeing 22 | 23 | 0.0.6 / 2014-05-06 24 | ================== 25 | 26 | * list.h: Fix header guards 27 | * Add “list” prefix to sources 28 | 29 | 0.0.5 / 2013-10-20 30 | ================== 31 | 32 | * add package.json 33 | * fix free in link_remove(). Closes #3 34 | 35 | 0.0.4 / 2011-04-15 36 | ================== 37 | 38 | * pop -> rpop 39 | * shift -> lpop 40 | * push -> rpush 41 | * unshift -> lpush 42 | 43 | 0.0.3 / 2010-11-27 44 | ================== 45 | 46 | * Added `make install` 47 | * Added `list_shift()` 48 | * Added `list_pop()` 49 | * Lowercased function names and typedefs 50 | * Wrap with extern "C" when \_\_cplusplus 51 | * Installing `list.h` 52 | 53 | 0.0.2 / 2010-08-21 54 | ================== 55 | 56 | * Added `ListNode *List_at(List *self, int index)` 57 | * Added `void List_remove(List *self, ListNode *node)` 58 | * Added `make liblist.a` 59 | 60 | 0.0.1 / 2010-08-13 61 | ================== 62 | 63 | * Initial release 64 | -------------------------------------------------------------------------------- /components/list/Readme.md: -------------------------------------------------------------------------------- 1 | # origin: https://github.com/clibs/list 2 | # author: clibs 3 | 4 | 5 | # list 6 | 7 | C doubly linked list implementation. 8 | 9 | ## API 10 | 11 | Below is the public api currently provided by "list". 12 | 13 | ## list_t *list_new(); 14 | 15 | Allocate and initialize a `list`. 16 | 17 | list_t *mylist = list_new(); 18 | 19 | ## list_node_t \*list_node_new(void *val) 20 | 21 | Allocate and initialize a `list_node_t` with the given _val_. 22 | 23 | ```c 24 | list_node_t *node = list_node_new("my value"); 25 | node->val; // "my value" 26 | ``` 27 | 28 | ## list_node_t \* list_rpush(list_t \*self, list_node_t *node) 29 | 30 | Append _node_ to _self_, returning _node_. 31 | 32 | ```c 33 | list_rpush(list, list_node_new("value")); 34 | list->tail->val; // "value" 35 | ``` 36 | 37 | ## list_node_t \* list_rpop(list_t \*self) 38 | 39 | Return / detach node from the end of the list, or __NULL__. 40 | 41 | ```c 42 | list_node_t *last = list_rpop(names); 43 | ``` 44 | 45 | ## list_node_t \*list_lpush(list_t \*self, list_node_t *node) 46 | 47 | Prepend _node_ to _self_, returning _node_. 48 | 49 | ```c 50 | list_lpush(list, list_node_new("value")); 51 | list->head->val; // "value" 52 | ``` 53 | 54 | ## list_node_t \*list_find(list_t \*self, void *val) 55 | 56 | Return the `list_node_t` containing _val_ or __NULL__. 57 | 58 | ```c 59 | list_node_t *node = list_find(list, "some value"); 60 | ``` 61 | 62 | ## list_node_t \*list_at(list_t *self, int index) 63 | 64 | Return the `list_node_t` at the given _index_, where _index_ 65 | may also be a negative integer indicating an index from the 66 | list _tail_. 67 | 68 | ```c 69 | list_at(list, 0); // first 70 | list_at(list, 1); // second 71 | list_at(list, -1); // last 72 | list_at(list, -3); // third last 73 | ``` 74 | 75 | ## void list_remove(list_t \*self, list_node_t *node) 76 | 77 | Remove _node_ from the list, freeing it and it's value. 78 | 79 | ```c 80 | list_remove(list, node); 81 | ``` 82 | 83 | ## void list_destroy(list_t *self) 84 | 85 | Free the list and all nodes. 86 | 87 | ```c 88 | list_destroy(list); 89 | ``` 90 | 91 | ## list_iterator_t \*list_iterator_new(list_t *list, list_direction_t direction) 92 | 93 | Allocate and initialize a `list_iterator_t` with the given _direction_, 94 | where _direction_ may be __LIST_HEAD__ or __LIST_TAIL__. 95 | 96 | ```c 97 | list_node_t *node; 98 | list_iterator_t *it = list_iterator_new(list, LIST_HEAD); 99 | while ((node = list_iterator_next(it))) { 100 | puts(node->val); 101 | } 102 | ``` 103 | 104 | ## list_node_t \*list_iterator_next(list_iterator_t *self) 105 | 106 | Return the next `list_node_t` or __NULL__. 107 | 108 | ## void list_iterator_destroy(list_iterator_t *self); 109 | 110 | Free the iterator only. 111 | 112 | ```c 113 | list_iterator_destroy(it); 114 | ``` 115 | 116 | ## Examples 117 | 118 | list iteration: 119 | 120 | ```c 121 | list_t *langs = list_new(); 122 | 123 | list_node_t *c = list_rpush(langs, list_node_new("c")); 124 | list_node_t *js = list_rpush(langs, list_node_new("js")); 125 | list_node_t *ruby = list_rpush(langs, list_node_new("ruby")); 126 | 127 | list_node_t *node; 128 | list_iterator_t *it = list_iterator_new(langs, LIST_HEAD); 129 | while ((node = list_iterator_next(it))) { 130 | puts(node->val); 131 | } 132 | 133 | list_iterator_destroy(it); 134 | list_destroy(langs); 135 | ``` 136 | 137 | stdout: 138 | 139 | c 140 | js 141 | ruby 142 | 143 | ## Benchmarks 144 | 145 | $ make benchmark 146 | 147 | 10,000,000 nodes 148 | 149 | lpush: 0.5000s 150 | rpush: 0.5000s 151 | lpop: 0.0312s 152 | rpop: 0.0312s 153 | find (last node): 0.0312s 154 | iterate: 0.0625s 155 | at(100,000): 0.0000s 156 | at(1,000,000): 0.0000s 157 | at(-100,000): 0.0000s 158 | 159 | 160 | 161 | ## Testing 162 | 163 | $ make test 164 | 165 | ## License 166 | 167 | (The MIT License) 168 | 169 | Copyright (c) 2009-2010 TJ Holowaychuk <tj@vision-media.ca> 170 | 171 | Permission is hereby granted, free of charge, to any person obtaining 172 | a copy of this software and associated documentation files (the 173 | 'Software'), to deal in the Software without restriction, including 174 | without limitation the rights to use, copy, modify, merge, publish, 175 | distribute, sublicense, and/or sell copies of the Software, and to 176 | permit persons to whom the Software is furnished to do so, subject to 177 | the following conditions: 178 | 179 | The above copyright notice and this permission notice shall be 180 | included in all copies or substantial portions of the Software. 181 | 182 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 183 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 184 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 185 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 186 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 187 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 188 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 189 | -------------------------------------------------------------------------------- /components/list/benchmark.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "bench/bench.h" 4 | #include "src/clist.h" 5 | 6 | static void 7 | bm(char *label, void (*fn)()) { 8 | printf(" %18s", label); 9 | fflush(stdout); 10 | fn(); 11 | } 12 | 13 | static int nnodes = 10000000; 14 | static float startTime; 15 | 16 | 17 | static void 18 | start() { 19 | startTime = cpu(); 20 | } 21 | 22 | static void 23 | stop() { 24 | float duration = cpu() - startTime; 25 | printf(": \x1b[32m%.4f\x1b[0ms\n", duration); 26 | } 27 | 28 | static void 29 | bm_rpush() { 30 | start(); 31 | int n = nnodes; 32 | list_t *list = list_new(); 33 | while (n--) { 34 | list_rpush(list, list_node_new("foo")); 35 | } 36 | stop(); 37 | } 38 | 39 | static void 40 | bm_lpush() { 41 | start(); 42 | int n = nnodes; 43 | list_t *list = list_new(); 44 | while (n--) { 45 | list_lpush(list, list_node_new("foo")); 46 | } 47 | stop(); 48 | } 49 | 50 | static void 51 | bm_find() { 52 | int n = nnodes; 53 | list_t *list = list_new(); 54 | while (n--) { 55 | list_lpush(list, list_node_new("foo")); 56 | } 57 | list_rpush(list, list_node_new("bar")); 58 | start(); 59 | list_find(list, "bar"); 60 | stop(); 61 | } 62 | 63 | static void 64 | bm_iterate() { 65 | int n = nnodes; 66 | list_t *list = list_new(); 67 | while (n--) { 68 | list_lpush(list, list_node_new("foo")); 69 | } 70 | list_iterator_t *it = list_iterator_new(list, LIST_HEAD); 71 | list_node_t *node; 72 | start(); 73 | while ((node = list_iterator_next(it))) 74 | ; 75 | stop(); 76 | } 77 | 78 | static void 79 | bm_rpop() { 80 | int n = nnodes; 81 | list_t *list = list_new(); 82 | while (n--) { 83 | list_lpush(list, list_node_new("foo")); 84 | } 85 | list_node_t *node; 86 | start(); 87 | while ((node = list_rpop(list))) 88 | ; 89 | stop(); 90 | } 91 | 92 | static void 93 | bm_lpop() { 94 | int n = nnodes; 95 | list_t *list = list_new(); 96 | while (n--) { 97 | list_lpush(list, list_node_new("foo")); 98 | } 99 | list_node_t *node; 100 | start(); 101 | while ((node = list_lpop(list))) 102 | ; 103 | stop(); 104 | } 105 | 106 | static list_t *list; 107 | 108 | static void 109 | bm_at() { 110 | start(); 111 | list_at(list, 100000); 112 | stop(); 113 | } 114 | 115 | static void 116 | bm_at2() { 117 | start(); 118 | list_at(list, 1000000); 119 | stop(); 120 | } 121 | 122 | static void 123 | bm_at3() { 124 | start(); 125 | list_at(list, -100000); 126 | stop(); 127 | } 128 | 129 | int 130 | main(void){ 131 | int n = nnodes; 132 | list = list_new(); 133 | while (n--) list_lpush(list, list_node_new("foo")); 134 | puts("\n 10,000,000 nodes\n"); 135 | bm("lpush", bm_lpush); 136 | bm("rpush", bm_rpush); 137 | bm("lpop", bm_lpop); 138 | bm("rpop", bm_rpop); 139 | bm("find (last node)", bm_find); 140 | bm("iterate", bm_iterate); 141 | bm("at(100,000)", bm_at); 142 | bm("at(1,000,000)", bm_at2); 143 | bm("at(-100,000)", bm_at3); 144 | puts(""); 145 | return 0; 146 | } 147 | -------------------------------------------------------------------------------- /components/list/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # "main" pseudo-component makefile. 3 | # 4 | # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) 5 | 6 | COMPONENT_ADD_INCLUDEDIRS := src 7 | COMPONENT_SRCDIRS := src 8 | 9 | register_component() 10 | -------------------------------------------------------------------------------- /components/list/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "list", 3 | "version": "0.0.8", 4 | "repo": "clibs/list", 5 | "description": "Simple linked list", 6 | "keywords": ["list", "structure"], 7 | "license": "MIT", 8 | "src": [ 9 | "src/list_iterator.c", 10 | "src/list.c", 11 | "src/list_node.c", 12 | "src/list.h" 13 | ], 14 | "development": { 15 | "bench": "*" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /components/list/src/clist.c: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // list.c 4 | // 5 | // Copyright (c) 2010 TJ Holowaychuk 6 | // 7 | 8 | #include "clist.h" 9 | 10 | /* 11 | * Allocate a new clist_t. NULL on failure. 12 | */ 13 | 14 | clist_t * 15 | list_new() { 16 | clist_t *self; 17 | if (!(self = LIST_MALLOC(sizeof(clist_t)))) 18 | return NULL; 19 | self->head = NULL; 20 | self->tail = NULL; 21 | self->free = NULL; 22 | self->match = NULL; 23 | self->len = 0; 24 | return self; 25 | } 26 | 27 | /* 28 | * Free the list. 29 | */ 30 | 31 | void 32 | list_destroy(clist_t *self) { 33 | unsigned int len = self->len; 34 | list_node_t *next; 35 | list_node_t *curr = self->head; 36 | 37 | while (len--) { 38 | next = curr->next; 39 | if (self->free) self->free(curr->val); 40 | LIST_FREE(curr); 41 | curr = next; 42 | } 43 | 44 | LIST_FREE(self); 45 | } 46 | 47 | /* 48 | * Append the given node to the list 49 | * and return the node, NULL on failure. 50 | */ 51 | 52 | list_node_t * 53 | list_rpush(clist_t *self, list_node_t *node) { 54 | if (!node) return NULL; 55 | 56 | if (self->len) { 57 | node->prev = self->tail; 58 | node->next = NULL; 59 | self->tail->next = node; 60 | self->tail = node; 61 | } else { 62 | self->head = self->tail = node; 63 | node->prev = node->next = NULL; 64 | } 65 | 66 | ++self->len; 67 | return node; 68 | } 69 | 70 | /* 71 | * Return / detach the last node in the list, or NULL. 72 | */ 73 | 74 | list_node_t * 75 | list_rpop(clist_t *self) { 76 | if (!self->len) return NULL; 77 | 78 | list_node_t *node = self->tail; 79 | 80 | if (--self->len) { 81 | (self->tail = node->prev)->next = NULL; 82 | } else { 83 | self->tail = self->head = NULL; 84 | } 85 | 86 | node->next = node->prev = NULL; 87 | return node; 88 | } 89 | 90 | /* 91 | * Return / detach the first node in the list, or NULL. 92 | */ 93 | 94 | list_node_t * 95 | list_lpop(clist_t *self) { 96 | if (!self->len) return NULL; 97 | 98 | list_node_t *node = self->head; 99 | 100 | if (--self->len) { 101 | (self->head = node->next)->prev = NULL; 102 | } else { 103 | self->head = self->tail = NULL; 104 | } 105 | 106 | node->next = node->prev = NULL; 107 | return node; 108 | } 109 | 110 | /* 111 | * Prepend the given node to the list 112 | * and return the node, NULL on failure. 113 | */ 114 | 115 | list_node_t * 116 | list_lpush(clist_t *self, list_node_t *node) { 117 | if (!node) return NULL; 118 | 119 | if (self->len) { 120 | node->next = self->head; 121 | node->prev = NULL; 122 | self->head->prev = node; 123 | self->head = node; 124 | } else { 125 | self->head = self->tail = node; 126 | node->prev = node->next = NULL; 127 | } 128 | 129 | ++self->len; 130 | return node; 131 | } 132 | 133 | /* 134 | * Return the node associated to val or NULL. 135 | */ 136 | 137 | list_node_t * 138 | list_find(clist_t *self, void *val) { 139 | list_iterator_t *it = list_iterator_new(self, LIST_HEAD); 140 | list_node_t *node; 141 | 142 | while ((node = list_iterator_next(it))) { 143 | if (self->match) { 144 | if (self->match(val, node->val)) { 145 | list_iterator_destroy(it); 146 | return node; 147 | } 148 | } else { 149 | if (val == node->val) { 150 | list_iterator_destroy(it); 151 | return node; 152 | } 153 | } 154 | } 155 | 156 | list_iterator_destroy(it); 157 | return NULL; 158 | } 159 | 160 | /* 161 | * Return the node at the given index or NULL. 162 | */ 163 | 164 | list_node_t * 165 | list_at(clist_t *self, int index) { 166 | list_direction_t direction = LIST_HEAD; 167 | 168 | if (index < 0) { 169 | direction = clist_tAIL; 170 | index = ~index; 171 | } 172 | 173 | if ((unsigned)index < self->len) { 174 | list_iterator_t *it = list_iterator_new(self, direction); 175 | list_node_t *node = list_iterator_next(it); 176 | while (index--) node = list_iterator_next(it); 177 | list_iterator_destroy(it); 178 | return node; 179 | } 180 | 181 | return NULL; 182 | } 183 | 184 | /* 185 | * Remove the given node from the list, freeing it and it's value. 186 | */ 187 | 188 | void 189 | list_remove(clist_t *self, list_node_t *node) { 190 | node->prev 191 | ? (node->prev->next = node->next) 192 | : (self->head = node->next); 193 | 194 | node->next 195 | ? (node->next->prev = node->prev) 196 | : (self->tail = node->prev); 197 | 198 | if (self->free) self->free(node->val); 199 | 200 | LIST_FREE(node); 201 | --self->len; 202 | } 203 | -------------------------------------------------------------------------------- /components/list/src/clist.h: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // list.h 4 | // 5 | // Copyright (c) 2010 TJ Holowaychuk 6 | // 7 | 8 | #ifndef CLIST_H 9 | #define CLIST_H 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #include 16 | 17 | // Library version 18 | 19 | #define LIST_VERSION "0.0.5" 20 | 21 | // Memory management macros 22 | 23 | #ifndef LIST_MALLOC 24 | #define LIST_MALLOC malloc 25 | #endif 26 | 27 | #ifndef LIST_FREE 28 | #define LIST_FREE free 29 | #endif 30 | 31 | /* 32 | * clist_t iterator direction. 33 | */ 34 | 35 | typedef enum { 36 | LIST_HEAD 37 | , clist_tAIL 38 | } list_direction_t; 39 | 40 | /* 41 | * clist_t node struct. 42 | */ 43 | 44 | typedef struct list_node { 45 | struct list_node *prev; 46 | struct list_node *next; 47 | void *val; 48 | } list_node_t; 49 | 50 | /* 51 | * clist_t struct. 52 | */ 53 | 54 | typedef struct { 55 | list_node_t *head; 56 | list_node_t *tail; 57 | unsigned int len; 58 | void (*free)(void *val); 59 | int (*match)(void *a, void *b); 60 | } clist_t; 61 | 62 | /* 63 | * clist_t iterator struct. 64 | */ 65 | 66 | typedef struct { 67 | list_node_t *next; 68 | list_direction_t direction; 69 | } list_iterator_t; 70 | 71 | // Node prototypes. 72 | 73 | list_node_t * 74 | list_node_new(void *val); 75 | 76 | // clist_t prototypes. 77 | 78 | clist_t * 79 | list_new(); 80 | 81 | list_node_t * 82 | list_rpush(clist_t *self, list_node_t *node); 83 | 84 | list_node_t * 85 | list_lpush(clist_t *self, list_node_t *node); 86 | 87 | list_node_t * 88 | list_find(clist_t *self, void *val); 89 | 90 | list_node_t * 91 | list_at(clist_t *self, int index); 92 | 93 | list_node_t * 94 | list_rpop(clist_t *self); 95 | 96 | list_node_t * 97 | list_lpop(clist_t *self); 98 | 99 | void 100 | list_remove(clist_t *self, list_node_t *node); 101 | 102 | void 103 | list_destroy(clist_t *self); 104 | 105 | // clist_t iterator prototypes. 106 | 107 | list_iterator_t * 108 | list_iterator_new(clist_t *list, list_direction_t direction); 109 | 110 | list_iterator_t * 111 | list_iterator_new_from_node(list_node_t *node, list_direction_t direction); 112 | 113 | list_node_t * 114 | list_iterator_next(list_iterator_t *self); 115 | 116 | void 117 | list_iterator_destroy(list_iterator_t *self); 118 | 119 | #ifdef __cplusplus 120 | } 121 | #endif 122 | 123 | #endif /* CLIST_H */ 124 | -------------------------------------------------------------------------------- /components/list/src/list_iterator.c: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // iterator.c 4 | // 5 | // Copyright (c) 2010 TJ Holowaychuk 6 | // 7 | 8 | #include "clist.h" 9 | 10 | /* 11 | * Allocate a new list_iterator_t. NULL on failure. 12 | * Accepts a direction, which may be LIST_HEAD or LIST_TAIL. 13 | */ 14 | 15 | list_iterator_t * 16 | list_iterator_new(clist_t *list, list_direction_t direction) { 17 | list_node_t *node = direction == LIST_HEAD 18 | ? list->head 19 | : list->tail; 20 | return list_iterator_new_from_node(node, direction); 21 | } 22 | 23 | /* 24 | * Allocate a new list_iterator_t with the given start 25 | * node. NULL on failure. 26 | */ 27 | 28 | list_iterator_t * 29 | list_iterator_new_from_node(list_node_t *node, list_direction_t direction) { 30 | list_iterator_t *self; 31 | if (!(self = LIST_MALLOC(sizeof(list_iterator_t)))) 32 | return NULL; 33 | self->next = node; 34 | self->direction = direction; 35 | return self; 36 | } 37 | 38 | /* 39 | * Return the next list_node_t or NULL when no more 40 | * nodes remain in the list. 41 | */ 42 | 43 | list_node_t * 44 | list_iterator_next(list_iterator_t *self) { 45 | list_node_t *curr = self->next; 46 | if (curr) { 47 | self->next = self->direction == LIST_HEAD 48 | ? curr->next 49 | : curr->prev; 50 | } 51 | return curr; 52 | } 53 | 54 | /* 55 | * Free the list iterator. 56 | */ 57 | 58 | void 59 | list_iterator_destroy(list_iterator_t *self) { 60 | LIST_FREE(self); 61 | self = NULL; 62 | } 63 | -------------------------------------------------------------------------------- /components/list/src/list_node.c: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // node.c 4 | // 5 | // Copyright (c) 2010 TJ Holowaychuk 6 | // 7 | 8 | #include "clist.h" 9 | 10 | /* 11 | * Allocates a new list_node_t. NULL on failure. 12 | */ 13 | 14 | list_node_t * 15 | list_node_new(void *val) { 16 | list_node_t *self; 17 | if (!(self = LIST_MALLOC(sizeof(list_node_t)))) 18 | return NULL; 19 | self->prev = NULL; 20 | self->next = NULL; 21 | self->val = val; 22 | return self; 23 | } -------------------------------------------------------------------------------- /components/list/test.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "src/clist.h" 7 | 8 | // Helpers 9 | 10 | #define test(fn) \ 11 | puts("... \x1b[33m" # fn "\x1b[0m"); \ 12 | test_##fn(); 13 | 14 | static int freeProxyCalls = 0; 15 | 16 | void 17 | freeProxy(void *val) { 18 | ++freeProxyCalls; 19 | free(val); 20 | } 21 | 22 | typedef struct { 23 | char *name; 24 | } User; 25 | 26 | static int 27 | User_equal(User *a, User *b) { 28 | return 0 == strcmp(a->name, b->name); 29 | } 30 | 31 | // Tests 32 | 33 | static void 34 | test_list_node_new() { 35 | char *val = "some value"; 36 | list_node_t *node = list_node_new(val); 37 | assert(node->val == val); 38 | free(node); 39 | } 40 | 41 | static void 42 | test_list_rpush() { 43 | // Setup 44 | clist_t *list = list_new(); 45 | list_node_t *a = list_node_new("a"); 46 | list_node_t *b = list_node_new("b"); 47 | list_node_t *c = list_node_new("c"); 48 | 49 | // a b c 50 | list_rpush(list, a); 51 | list_rpush(list, b); 52 | list_rpush(list, c); 53 | 54 | // Assertions 55 | assert(a == list->head); 56 | assert(c == list->tail); 57 | assert(3 == list->len); 58 | assert(b == a->next); 59 | assert(NULL == a->prev); 60 | assert(c == b->next); 61 | assert(a == b->prev); 62 | assert(NULL == c->next); 63 | assert(b == c->prev); 64 | 65 | list_destroy(list); 66 | } 67 | 68 | static void 69 | test_list_lpush() { 70 | // Setup 71 | clist_t *list = list_new(); 72 | list_node_t *a = list_node_new("a"); 73 | list_node_t *b = list_node_new("b"); 74 | list_node_t *c = list_node_new("c"); 75 | 76 | // c b a 77 | list_rpush(list, a); 78 | list_lpush(list, b); 79 | list_lpush(list, c); 80 | 81 | // Assertions 82 | assert(c == list->head); 83 | assert(a == list->tail); 84 | assert(3 == list->len); 85 | assert(NULL == a->next); 86 | assert(b == a->prev); 87 | assert(a == b->next); 88 | assert(c == b->prev); 89 | assert(b == c->next); 90 | assert(NULL == c->prev); 91 | 92 | list_destroy(list); 93 | } 94 | 95 | static void 96 | test_list_at() { 97 | // Setup 98 | clist_t *list = list_new(); 99 | list_node_t *a = list_node_new("a"); 100 | list_node_t *b = list_node_new("b"); 101 | list_node_t *c = list_node_new("c"); 102 | 103 | // a b c 104 | list_rpush(list, a); 105 | list_rpush(list, b); 106 | list_rpush(list, c); 107 | 108 | // Assertions 109 | assert(a == list_at(list, 0)); 110 | assert(b == list_at(list, 1)); 111 | assert(c == list_at(list, 2)); 112 | assert(NULL == list_at(list, 3)); 113 | 114 | assert(c == list_at(list, -1)); 115 | assert(b == list_at(list, -2)); 116 | assert(a == list_at(list, -3)); 117 | assert(NULL == list_at(list, -4)); 118 | 119 | list_destroy(list); 120 | } 121 | 122 | static void 123 | test_list_destroy() { 124 | // Setup 125 | clist_t *a = list_new(); 126 | list_destroy(a); 127 | 128 | // a b c 129 | clist_t *b = list_new(); 130 | list_rpush(b, list_node_new("a")); 131 | list_rpush(b, list_node_new("b")); 132 | list_rpush(b, list_node_new("c")); 133 | list_destroy(b); 134 | 135 | // Assertions 136 | clist_t *c = list_new(); 137 | c->free = freeProxy; 138 | list_rpush(c, list_node_new(list_node_new("a"))); 139 | list_rpush(c, list_node_new(list_node_new("b"))); 140 | list_rpush(c, list_node_new(list_node_new("c"))); 141 | list_destroy(c); 142 | assert(3 == freeProxyCalls); 143 | } 144 | 145 | static void 146 | test_list_find() { 147 | // Setup 148 | clist_t *langs = list_new(); 149 | list_node_t *js = list_rpush(langs, list_node_new("js")); 150 | list_node_t *ruby = list_rpush(langs, list_node_new("ruby")); 151 | 152 | clist_t *users = list_new(); 153 | users->match = User_equal; 154 | User userTJ = { "tj" }; 155 | User userSimon = { "simon" }; 156 | User userTaylor = { "taylor" }; 157 | list_node_t *tj = list_rpush(users, list_node_new(&userTJ)); 158 | list_node_t *simon = list_rpush(users, list_node_new(&userSimon)); 159 | 160 | // Assertions 161 | list_node_t *a = list_find(langs, "js"); 162 | list_node_t *b = list_find(langs, "ruby"); 163 | list_node_t *c = list_find(langs, "foo"); 164 | assert(js == a); 165 | assert(ruby == b); 166 | assert(NULL == c); 167 | 168 | list_destroy(langs); 169 | 170 | a = list_find(users, &userTJ); 171 | b = list_find(users, &userSimon); 172 | c = list_find(users, &userTaylor); 173 | assert(tj == a); 174 | assert(simon == b); 175 | assert(NULL == c); 176 | 177 | list_destroy(users); 178 | } 179 | 180 | static void 181 | test_list_remove() { 182 | // Setup 183 | clist_t *list = list_new(); 184 | list_node_t *a = list_rpush(list, list_node_new("a")); 185 | list_node_t *b = list_rpush(list, list_node_new("b")); 186 | list_node_t *c = list_rpush(list, list_node_new("c")); 187 | 188 | // Assertions 189 | assert(3 == list->len); 190 | 191 | list_remove(list, b); 192 | assert(2 == list->len); 193 | assert(a == list->head); 194 | assert(c == list->tail); 195 | assert(c == a->next); 196 | assert(NULL == a->prev); 197 | assert(NULL == c->next); 198 | assert(a == c->prev); 199 | 200 | list_remove(list, a); 201 | assert(1 == list->len); 202 | assert(c == list->head); 203 | assert(c == list->tail); 204 | assert(NULL == c->next); 205 | assert(NULL == c->prev); 206 | 207 | list_remove(list, c); 208 | assert(0 == list->len); 209 | assert(NULL == list->head); 210 | assert(NULL == list->tail); 211 | 212 | list_destroy(list); 213 | } 214 | 215 | static void 216 | test_list_rpop() { 217 | // Setup 218 | clist_t *list = list_new(); 219 | list_node_t *a = list_rpush(list, list_node_new("a")); 220 | list_node_t *b = list_rpush(list, list_node_new("b")); 221 | list_node_t *c = list_rpush(list, list_node_new("c")); 222 | 223 | // Assertions 224 | assert(3 == list->len); 225 | 226 | assert(c == list_rpop(list)); 227 | assert(2 == list->len); 228 | assert(a == list->head); 229 | assert(b == list->tail); 230 | assert(a == b->prev); 231 | assert(NULL == list->tail->next && "new tail node next is not NULL"); 232 | assert(NULL == c->prev && "detached node prev is not NULL"); 233 | assert(NULL == c->next && "detached node next is not NULL"); 234 | 235 | free(c); 236 | 237 | assert(b == list_rpop(list)); 238 | assert(1 == list->len); 239 | assert(a == list->head); 240 | assert(a == list->tail); 241 | 242 | free(b); 243 | 244 | assert(a == list_rpop(list)); 245 | assert(0 == list->len); 246 | assert(NULL == list->head); 247 | assert(NULL == list->tail); 248 | 249 | free(a); 250 | 251 | assert(NULL == list_rpop(list)); 252 | assert(0 == list->len); 253 | 254 | list_destroy(list); 255 | } 256 | 257 | static void 258 | test_list_lpop() { 259 | // Setup 260 | clist_t *list = list_new(); 261 | list_node_t *a = list_rpush(list, list_node_new("a")); 262 | list_node_t *b = list_rpush(list, list_node_new("b")); 263 | list_node_t *c = list_rpush(list, list_node_new("c")); 264 | 265 | // Assertions 266 | assert(3 == list->len); 267 | 268 | assert(a == list_lpop(list)); 269 | assert(2 == list->len); 270 | assert(b == list->head); 271 | assert(NULL == list->head->prev && "new head node prev is not NULL"); 272 | assert(NULL == a->prev && "detached node prev is not NULL"); 273 | assert(NULL == a->next && "detached node next is not NULL"); 274 | 275 | free(a); 276 | 277 | assert(b == list_lpop(list)); 278 | assert(1 == list->len); 279 | 280 | free(b); 281 | 282 | assert(c == list_lpop(list)); 283 | assert(0 == list->len); 284 | assert(NULL == list->head); 285 | assert(NULL == list->tail); 286 | 287 | free(c); 288 | 289 | assert(NULL == list_lpop(list)); 290 | assert(0 == list->len); 291 | 292 | list_destroy(list); 293 | } 294 | 295 | static void 296 | test_list_iterator_t() { 297 | // Setup 298 | clist_t *list = list_new(); 299 | list_node_t *tj = list_node_new("tj"); 300 | list_node_t *taylor = list_node_new("taylor"); 301 | list_node_t *simon = list_node_new("simon"); 302 | 303 | // tj taylor simon 304 | list_rpush(list, tj); 305 | list_rpush(list, taylor); 306 | list_rpush(list, simon); 307 | 308 | // Assertions 309 | 310 | // From head 311 | list_iterator_t *it = list_iterator_new(list, LIST_HEAD); 312 | list_node_t *a = list_iterator_next(it); 313 | list_node_t *b = list_iterator_next(it); 314 | list_node_t *c = list_iterator_next(it); 315 | list_node_t *d = list_iterator_next(it); 316 | 317 | assert(a == tj); 318 | assert(b == taylor); 319 | assert(c == simon); 320 | assert(NULL == d); 321 | 322 | list_iterator_destroy(it); 323 | 324 | // From tail 325 | it = list_iterator_new(list, clist_tAIL); 326 | list_node_t *a2 = list_iterator_next(it); 327 | list_node_t *b2 = list_iterator_next(it); 328 | list_node_t *c2 = list_iterator_next(it); 329 | list_node_t *d2 = list_iterator_next(it); 330 | 331 | assert(a2 == simon); 332 | assert(b2 == taylor); 333 | assert(c2 == tj); 334 | assert(NULL == d2); 335 | list_iterator_destroy(it); 336 | 337 | list_destroy(list); 338 | } 339 | 340 | int 341 | main(void){ 342 | printf("\nclist_t: %ld\n", sizeof(clist_t)); 343 | printf("list_node_t: %ld\n", sizeof(list_node_t)); 344 | printf("list_iterator_t: %ld\n\n", sizeof(list_iterator_t)); 345 | test(list_node_new); 346 | test(list_rpush); 347 | test(list_lpush); 348 | test(list_find); 349 | test(list_at); 350 | test(list_remove); 351 | test(list_rpop); 352 | test(list_lpop); 353 | test(list_destroy); 354 | test(list_iterator_t); 355 | puts("... \x1b[32m100%\x1b[0m\n"); 356 | return 0; 357 | } 358 | -------------------------------------------------------------------------------- /examples/http/http_stream.js: -------------------------------------------------------------------------------- 1 | var SSID = 'your xxx_2.4G wifi'; 2 | var PASS = 'your password here'; 3 | 4 | var wifi = require('wifi'); 5 | var HttpClient = require('http_client'); 6 | var nvsFlash = require('nvs_flash'); 7 | var espERROR = require('esp_error'); 8 | 9 | console.log('wifi app init'); 10 | 11 | function wifi_event(name, id, data) { 12 | console.log('receive event: %s %d %j', name, id, data); 13 | var ret; 14 | if (name === wifi.EVENT_NAME.WIFI_EVENT) { 15 | if (id === wifi.WIFI_EVENT_CODE.WIFI_EVENT_STA_START) { 16 | ret = wifi.connect(); 17 | console.log('wifi connecting to AP', ret); 18 | } 19 | } 20 | if (name === wifi.EVENT_NAME.IP_EVENT) { 21 | if (id === wifi.IP_EVENT_CODE.IP_EVENT_STA_GOT_IP) { 22 | setTimeout(function () { 23 | request(); 24 | }, 3000); 25 | } 26 | } 27 | } 28 | 29 | ret = nvsFlash.init(); 30 | console.log('nvs flash init', ret, espERROR.esp_err_to_name(ret)); 31 | ret = wifi.init(wifi.WIFI_MODE.STA); 32 | console.log('wifi init', ret, espERROR.esp_err_to_name(ret)); 33 | ret = wifi.setEventListener(wifi_event); 34 | console.log('wifi setEventListener', ret); 35 | ret = wifi.addListenEvent(wifi.EVENT_NAME.WIFI_EVENT); 36 | console.log('wifi addListenEvent WIFI_EVENT', ret); 37 | ret = wifi.addListenEvent(wifi.EVENT_NAME.IP_EVENT); 38 | console.log('wifi addListenEvent IP_EVENT', ret); 39 | ret = wifi.setMode(wifi.WIFI_MODE.STA); 40 | console.log('wifi setMode', ret); 41 | ret = wifi.setConfig(wifi.WIFI_MODE.STA, { 42 | ssid: SSID, 43 | password: PASS, 44 | auth: wifi.WIFI_AUTH_MODE.WIFI_AUTH_WPA2_PSK 45 | }); 46 | console.log('wifi setConfig', ret); 47 | ret = wifi.start(); 48 | console.log('wifi start', ret); 49 | 50 | function request() { 51 | console.log('start request http...'); 52 | var client = new HttpClient.ClientRequest({ 53 | url: 'http://httpbin.org/get', 54 | timeout: 3000, 55 | authType: 0, 56 | method: 0, 57 | transportType: 1 58 | }); 59 | console.log('create httpRequestClient'); 60 | ret = client.open(0); 61 | console.log('httpclient open', ret); 62 | var contentLength = client.fetchHeaders(); 63 | console.log('httpclient fetch headers', contentLength); 64 | var httpStatus = client.getStatusCode(); 65 | console.log('httpclient response http code', httpStatus); 66 | if (httpStatus === 200) { 67 | var response = client.read(contentLength); 68 | if (typeof response === 'number') { 69 | console.log('httpclient read response error', response); 70 | } else { 71 | console.log('httpclient response:', response); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /examples/remote_control/ws2812b.js: -------------------------------------------------------------------------------- 1 | var rmt = require("rmt"); 2 | 3 | rmt.setup(0, 2, { clock_div: 8, idle_output_en: false }); 4 | rmt.setPattern(0, 4, 1, 9, 0); 5 | rmt.setPattern(1, 9, 1, 4, 0); 6 | 7 | var leds = 12; 8 | 9 | var buffer = new Array(3 * leds); 10 | 11 | function drawPixel(index, r, g, b) { 12 | var i = index * 3; 13 | buffer[i] = g; 14 | buffer[i+1] = r; 15 | buffer[i+2] = b; 16 | } 17 | 18 | function clear(r, g, b) { 19 | for (var index = 0; index < leds; index++) { 20 | buffer[index * 3] = g; 21 | buffer[index * 3 + 1] = r; 22 | buffer[index * 3 + 2] = b; 23 | } 24 | } 25 | 26 | while(true) { 27 | for (var index = 0; index < leds; index++) { 28 | drawPixel(index, 0xff, 0, 0); 29 | rmt.sendSync(0, buffer); 30 | process.delay(300); 31 | drawPixel(index, 0, 0xff, 0); 32 | rmt.sendSync(0, buffer); 33 | process.delay(300); 34 | drawPixel(index, 0, 0, 0xff); 35 | rmt.sendSync(0, buffer); 36 | process.delay(300); 37 | } 38 | for (var delay = 0; delay < 300; delay += 20) { 39 | for (var pos = 0; pos < leds; pos++) { 40 | clear(0, 0, 0); 41 | drawPixel(pos, 255, 255, 255); 42 | rmt.sendSync(0, buffer); 43 | process.delay(300 - delay); 44 | } 45 | } 46 | for (var index = 0; index < 255; index++) { 47 | clear(index, 0, 0); 48 | rmt.sendSync(0, buffer); 49 | process.delay(16); 50 | } 51 | for (var index = 254; index >= 0; index--) { 52 | clear(index, 0, 0); 53 | rmt.sendSync(0, buffer); 54 | process.delay(16); 55 | } 56 | for (var index = 0; index < 255; index++) { 57 | clear(0, index, 0); 58 | rmt.sendSync(0, buffer); 59 | process.delay(16); 60 | } 61 | for (var index = 254; index >= 0; index--) { 62 | clear(0, index, 0); 63 | rmt.sendSync(0, buffer); 64 | process.delay(16); 65 | } 66 | for (var index = 0; index < 255; index++) { 67 | clear(0, 0, index); 68 | rmt.sendSync(0, buffer); 69 | process.delay(16); 70 | } 71 | for (var index = 254; index >= 0; index--) { 72 | clear(0, 0, index); 73 | rmt.sendSync(0, buffer); 74 | process.delay(16); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /examples/sigmadelta/led.js: -------------------------------------------------------------------------------- 1 | var sigmadelta = require('sigmadelta'); 2 | 3 | var LED_PIN = 2; 4 | var CHANNEL = 0; 5 | 6 | sigmadelta.setup(CHANNEL, duty, 0, LED_PIN); 7 | 8 | var duty = 0; 9 | var inc = 1; 10 | setInterval(function() { 11 | sigmadelta.setDuty(CHANNEL, duty); 12 | 13 | duty += inc; 14 | if (duty == 127 || duty == -127) { 15 | inc = inc == 1 ? -1 : 1; 16 | } 17 | }, 10); -------------------------------------------------------------------------------- /examples/spi/st7735-spi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright nodemcujs 3 | * 4 | * Licensed under MIT License. 5 | * you may not use this file except in compliance with the License. 6 | */ 7 | 8 | /** 9 | * for st7735 resolution 128*128 by using 565 color format. 10 | * change mode value to numbe 3 if chip is st7735r. 11 | * data will be lost if speed more than 26MHz. 12 | */ 13 | 14 | var LED_PIN = 2; 15 | var CS_PIN = 15; 16 | var MOSI_PIN = 13; 17 | var MISO_PIN = 12; 18 | var CLK_PIN = 14; 19 | var DC_PIN = 4; 20 | var RST_PIN = 2; 21 | var INPUT = 1; 22 | var OUTPUT = 2; 23 | var HIGH = 1; 24 | var LOW = 0; 25 | 26 | var gpio = require('gpio'); 27 | var SPI = require('spi'); 28 | 29 | gpio.mode(RST_PIN, OUTPUT); 30 | 31 | var spi = new SPI.MASTER(2, { 32 | pinMOSI: MOSI_PIN, 33 | pinMISO: MISO_PIN, 34 | pinCLK: CLK_PIN, 35 | pinCS: CS_PIN, 36 | pinDC: DC_PIN, 37 | mode: 2, 38 | activeDC: 1, 39 | clockHz: 20000000, 40 | maxTransferSize: 128 * 2 41 | }); 42 | 43 | var ok = spi.setup(); 44 | console.log('setup spi:', ok); 45 | 46 | function lcd_init() { 47 | gpio.write(RST_PIN, LOW); 48 | process.delay(120); 49 | gpio.write(RST_PIN, HIGH); 50 | // LCD Init For 1.44Inch LCD Panel with ST7735R. 51 | spi.sendCmdSync(0x11) //Sleep exit 52 | 53 | // ST7735R Frame Rate: Frame rate=fosc/((RTNA x 2 + 40) x (LINE + FPA + BPA +2)) fosc=850khz 54 | spi.sendCmdSync(0xB1) 55 | spi.sendDataSync(0x00) // RNTA 56 | spi.sendDataSync(0x00) // FPA 57 | spi.sendDataSync(0x00) // BPA 58 | 59 | // Frame Rate Control (In Idle mode/ 8-colors) 60 | // spi.sendCmdSync(0xB2) 61 | // spi.sendDataSync(0x01) 62 | // spi.sendDataSync(0x2C) 63 | // spi.sendDataSync(0x2D) 64 | 65 | // Frame Rate Control (In Partial mode/ full colors) 66 | // spi.sendCmdSync(0xB3) 67 | // spi.sendDataSync(0x01) 68 | // spi.sendDataSync(0x2C) 69 | // spi.sendDataSync(0x2D) 70 | // spi.sendDataSync(0x01) 71 | // spi.sendDataSync(0x2C) 72 | // spi.sendDataSync(0x2D) 73 | 74 | // Display Inversion Control 75 | spi.sendCmdSync(0xB4) 76 | spi.sendDataSync(0x07) 77 | 78 | // ST7735R Power Control 1 79 | spi.sendCmdSync(0xC0) 80 | spi.sendDataSync(0xA2) 81 | spi.sendDataSync(0x02) 82 | spi.sendDataSync(0x44) 83 | // Power Control 2 84 | spi.sendCmdSync(0xC1) 85 | spi.sendDataSync(0xC5) 86 | 87 | // Power Control 3 (in Normal mode/ Full colors) 88 | spi.sendCmdSync(0xC2) 89 | spi.sendDataSync(0x0A) 90 | spi.sendDataSync(0x00) 91 | // Power Control 4 (in Idle mode/ 8-colors) 92 | spi.sendCmdSync(0xC3) 93 | spi.sendDataSync(0x8A) 94 | spi.sendDataSync(0x2A) 95 | // Power Control 5 (in Partial mode/ full-colors) 96 | spi.sendCmdSync(0xC4) 97 | spi.sendDataSync(0x8A) 98 | spi.sendDataSync(0xEE) 99 | 100 | // VCOM Control 1 101 | spi.sendCmdSync(0xC5) 102 | spi.sendDataSync(0x0E) 103 | 104 | spi.sendCmdSync(0x36) //MX, MY, RGB mode 105 | spi.sendDataSync(0xC8) 106 | 107 | //ST7735R Gamma ('+'polarity) Correction Characteristics Setting 108 | spi.sendCmdSync(0xe0) 109 | spi.sendDataSync(0x0f) 110 | spi.sendDataSync(0x1a) 111 | spi.sendDataSync(0x0f) 112 | spi.sendDataSync(0x18) 113 | spi.sendDataSync(0x2f) 114 | spi.sendDataSync(0x28) 115 | spi.sendDataSync(0x20) 116 | spi.sendDataSync(0x22) 117 | spi.sendDataSync(0x1f) 118 | spi.sendDataSync(0x1b) 119 | spi.sendDataSync(0x23) 120 | spi.sendDataSync(0x37) 121 | spi.sendDataSync(0x00) 122 | spi.sendDataSync(0x07) 123 | spi.sendDataSync(0x02) 124 | spi.sendDataSync(0x10) 125 | // Gamma '-'polarity Correction Characteristics Setting 126 | spi.sendCmdSync(0xe1) 127 | spi.sendDataSync(0x0f) 128 | spi.sendDataSync(0x1b) 129 | spi.sendDataSync(0x0f) 130 | spi.sendDataSync(0x17) 131 | spi.sendDataSync(0x33) 132 | spi.sendDataSync(0x2c) 133 | spi.sendDataSync(0x29) 134 | spi.sendDataSync(0x2e) 135 | spi.sendDataSync(0x30) 136 | spi.sendDataSync(0x30) 137 | spi.sendDataSync(0x39) 138 | spi.sendDataSync(0x3f) 139 | spi.sendDataSync(0x00) 140 | spi.sendDataSync(0x07) 141 | spi.sendDataSync(0x03) 142 | spi.sendDataSync(0x10) 143 | 144 | // Column Address Set 145 | spi.sendCmdSync(0x2a) 146 | spi.sendDataSync(0x00) 147 | spi.sendDataSync(0x00 + 2) 148 | spi.sendDataSync(0x00) 149 | spi.sendDataSync(0x80 + 2) 150 | // Row Address Set 151 | spi.sendCmdSync(0x2b) 152 | spi.sendDataSync(0x00) 153 | spi.sendDataSync(0x00 + 3) 154 | spi.sendDataSync(0x00) 155 | spi.sendDataSync(0x80 + 3) 156 | 157 | spi.sendCmdSync(0xF0) //Enable test command 158 | spi.sendDataSync(0x01) 159 | spi.sendCmdSync(0xF6) //Disable ram power save mode 160 | spi.sendDataSync(0x00) 161 | 162 | spi.sendCmdSync(0x3A) // Data Color Coding 163 | spi.sendDataSync(0x05) // mode map: 0x03: 4k(444), 0x05: 65k(565), 0x06: 262k(666) 164 | 165 | spi.sendCmdSync(0x29) //Display on 166 | } 167 | 168 | function lcd_setRegion(x1, y1, x2, y2) { 169 | spi.sendCmdSync(0x2a) 170 | spi.sendDataSync(0x00) 171 | spi.sendDataSync(x1 + 2) 172 | spi.sendDataSync(0x00) 173 | spi.sendDataSync(x2 + 2) 174 | 175 | spi.sendCmdSync(0x2b) 176 | spi.sendDataSync(0x00) 177 | spi.sendDataSync(y1 + 3) 178 | spi.sendDataSync(0x00) 179 | spi.sendDataSync(y2 + 3) 180 | spi.sendCmdSync(0x2c) 181 | } 182 | 183 | function lcd_fill(color_h, color_l) { 184 | lcd_setRegion(0, 0, 127, 127); 185 | 186 | var buffer = []; 187 | for (var repeat = 0; repeat < 128; repeat++) { 188 | buffer = buffer.concat([color_h, color_l]); 189 | } 190 | for (var row = 0; row < 128; row++) { 191 | spi.sendDataSync(buffer); 192 | } 193 | } 194 | 195 | lcd_init(); 196 | while (true) { 197 | lcd_fill(0x00, 0x10); 198 | process.delay(600); 199 | lcd_fill(0x03, 0x30); 200 | process.delay(600); 201 | lcd_fill(0x03, 0x3f); 202 | process.delay(600); 203 | lcd_fill(0x63, 0x20); 204 | process.delay(600); 205 | lcd_fill(0x64, 0xc0); 206 | process.delay(600); 207 | lcd_fill(0xb8, 0x11); 208 | process.delay(600); 209 | lcd_fill(0xb8, 0x1f); 210 | process.delay(600); 211 | lcd_fill(0xfc, 0x80); 212 | process.delay(600); 213 | lcd_fill(0xfc, 0x9c); 214 | process.delay(600); 215 | lcd_fill(0x00, 0x00); 216 | process.delay(600); 217 | lcd_fill(0xff, 0xff); 218 | process.delay(600); 219 | } 220 | -------------------------------------------------------------------------------- /examples/spi/st7789-spi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright nodemcujs 3 | * 4 | * Licensed under MIT License. 5 | * you may not use this file except in compliance with the License. 6 | */ 7 | 8 | /** 9 | * for st7789 resolution 240*240 by using 565 color format. 10 | * data will be lost if speed more than 40MHz. 11 | */ 12 | 13 | var LED_PIN = 2; 14 | var CS_PIN = 15; 15 | var MOSI_PIN = 13; 16 | var MISO_PIN = 12; 17 | var CLK_PIN = 14; 18 | var DC_PIN = 4; 19 | var RST_PIN = 2; 20 | var INPUT = 1; 21 | var OUTPUT = 2; 22 | var HIGH = 1; 23 | var LOW = 0; 24 | 25 | var gpio = require('gpio'); 26 | var SPI = require('spi'); 27 | 28 | gpio.mode(RST_PIN, OUTPUT); 29 | 30 | var spi = new SPI.MASTER(2, { 31 | pinMOSI: MOSI_PIN, 32 | pinMISO: MISO_PIN, 33 | pinCLK: CLK_PIN, 34 | pinCS: CS_PIN, 35 | pinDC: DC_PIN, 36 | mode: 3, 37 | activeDC: 1, 38 | clockHz: 40000000, 39 | maxTransferSize: 120 * 2 40 | }); 41 | 42 | var ok = spi.setup(); 43 | console.log('setup spi:', ok); 44 | 45 | function lcd_init() { 46 | gpio.write(RST_PIN, LOW); 47 | process.delay(120); 48 | gpio.write(RST_PIN, HIGH); 49 | 50 | spi.sendCmdSync(0x36) 51 | spi.sendDataSync(0x00) 52 | spi.sendCmdSync(0x3A) 53 | spi.sendDataSync(0x05) 54 | spi.sendCmdSync(0xB2) 55 | spi.sendDataSync(0x0C) 56 | spi.sendDataSync(0x0C) 57 | spi.sendDataSync(0x00) 58 | spi.sendDataSync(0x33) 59 | spi.sendDataSync(0x33) 60 | spi.sendCmdSync(0xB7) 61 | spi.sendDataSync(0x35) 62 | spi.sendCmdSync(0xBB) 63 | spi.sendDataSync(0x19) 64 | spi.sendCmdSync(0xC0) 65 | spi.sendDataSync(0x2C) 66 | spi.sendCmdSync(0xC2) 67 | spi.sendDataSync(0x01) 68 | spi.sendCmdSync(0xC3) 69 | spi.sendDataSync(0x12) 70 | spi.sendCmdSync(0xC4) 71 | spi.sendDataSync(0x20) 72 | spi.sendCmdSync(0xC6) // normal mode 73 | spi.sendDataSync(0x0F) 74 | spi.sendCmdSync(0xD0) 75 | spi.sendDataSync(0xA4) 76 | spi.sendDataSync(0xA1) 77 | spi.sendCmdSync(0xE0) 78 | spi.sendDataSync(0xD0) 79 | spi.sendDataSync(0x04) 80 | spi.sendDataSync(0x0D) 81 | spi.sendDataSync(0x11) 82 | spi.sendDataSync(0x13) 83 | spi.sendDataSync(0x2B) 84 | spi.sendDataSync(0x3F) 85 | spi.sendDataSync(0x54) 86 | spi.sendDataSync(0x4C) 87 | spi.sendDataSync(0x18) 88 | spi.sendDataSync(0x0D) 89 | spi.sendDataSync(0x0B) 90 | spi.sendDataSync(0x1F) 91 | spi.sendDataSync(0x23) 92 | spi.sendCmdSync(0xE1) 93 | spi.sendDataSync(0xD0) 94 | spi.sendDataSync(0x04) 95 | spi.sendDataSync(0x0C) 96 | spi.sendDataSync(0x11) 97 | spi.sendDataSync(0x13) 98 | spi.sendDataSync(0x2C) 99 | spi.sendDataSync(0x3F) 100 | spi.sendDataSync(0x44) 101 | spi.sendDataSync(0x51) 102 | spi.sendDataSync(0x2F) 103 | spi.sendDataSync(0x1F) 104 | spi.sendDataSync(0x1F) 105 | spi.sendDataSync(0x20) 106 | spi.sendDataSync(0x23) 107 | spi.sendCmdSync(0x21) // Display Inversion On 108 | spi.sendCmdSync(0x11) // sleep out 109 | spi.sendCmdSync(0x29) // display on 110 | } 111 | 112 | function lcd_setRotate(direction) { 113 | spi.sendCmdSync(0x36); // MX, MY, RGB mode 114 | if (direction === 0) { 115 | spi.sendDataSync(0x00); 116 | } else { 117 | spi.sendDataSync(0x68); 118 | } 119 | } 120 | 121 | function lcd_setRegion(x1, y1, x2, y2) { 122 | spi.sendCmdSync(0x2a); // Column address set 123 | spi.sendDataSync(0x00); 124 | spi.sendDataSync(x1); 125 | spi.sendDataSync(0x00); 126 | spi.sendDataSync(x2); 127 | spi.sendCmdSync(0x2b); // Column address set 128 | spi.sendDataSync(0x00); 129 | spi.sendDataSync(y1); 130 | spi.sendDataSync(0x00); 131 | spi.sendDataSync(y2); 132 | spi.sendCmdSync(0x2c); // Memory write 133 | } 134 | 135 | function lcd_fill(color_h, color_l) { 136 | lcd_setRegion(0, 0, 239, 239); 137 | var buffer = []; 138 | for (var repeat = 0; repeat < 120; repeat++) { 139 | buffer = buffer.concat([color_h, color_l]); 140 | } 141 | for (var row = 0; row < 480; row++) { 142 | spi.sendDataSync(buffer); 143 | } 144 | } 145 | 146 | lcd_init(); 147 | while (true) { 148 | lcd_setRotate(0); 149 | lcd_fill(0x00, 0x10); 150 | lcd_setRotate(1); 151 | // process.delay(600); 152 | lcd_fill(0x03, 0x30); 153 | lcd_setRotate(0); 154 | // process.delay(600); 155 | lcd_fill(0x03, 0x3f); 156 | lcd_setRotate(1); 157 | // process.delay(600); 158 | lcd_fill(0x63, 0x20); 159 | lcd_setRotate(0); 160 | // process.delay(600); 161 | lcd_fill(0x64, 0xc0); 162 | lcd_setRotate(1); 163 | // process.delay(600); 164 | lcd_fill(0xb8, 0x11); 165 | lcd_setRotate(0); 166 | // process.delay(600); 167 | lcd_fill(0xb8, 0x1f); 168 | lcd_setRotate(1); 169 | // process.delay(600); 170 | lcd_fill(0xfc, 0x80); 171 | lcd_setRotate(0); 172 | // process.delay(600); 173 | lcd_fill(0xfc, 0x9c); 174 | lcd_setRotate(1); 175 | // process.delay(600); 176 | lcd_fill(0x00, 0x00); 177 | lcd_setRotate(0); 178 | // process.delay(600); 179 | lcd_fill(0xff, 0xff); 180 | // process.delay(600); 181 | } 182 | -------------------------------------------------------------------------------- /examples/wifi/connect_to_ap.js: -------------------------------------------------------------------------------- 1 | var SSID = 'your xxx_2.4G wifi'; 2 | var PASS = 'your password here'; 3 | 4 | var wifi = require('wifi'); 5 | var nvsFlash = require('nvs_flash'); 6 | var espERROR = require('esp_error'); 7 | 8 | console.log('wifi app init'); 9 | 10 | function wifi_event(name, id, data) { 11 | console.log('receive event: %s %d %j', name, id, data); 12 | var ret; 13 | if (name === wifi.EVENT_NAME.WIFI_EVENT) { 14 | if (id === wifi.WIFI_EVENT_CODE.WIFI_EVENT_STA_START) { 15 | ret = wifi.connect(); 16 | console.log('wifi connecting to AP', ret); 17 | } 18 | } 19 | } 20 | 21 | var ret; 22 | ret = nvsFlash.init(); 23 | console.log('nvs flash init', ret, espERROR.esp_err_to_name(ret)); 24 | ret = wifi.init(wifi.WIFI_MODE.STA); 25 | console.log('wifi init', ret, espERROR.esp_err_to_name(ret)); 26 | ret = wifi.setEventListener(wifi_event); 27 | console.log('wifi setEventListener', ret); 28 | ret = wifi.addListenEvent(wifi.EVENT_NAME.WIFI_EVENT); 29 | console.log('wifi addListenEvent WIFI_EVENT', ret); 30 | ret = wifi.addListenEvent(wifi.EVENT_NAME.IP_EVENT); 31 | console.log('wifi addListenEvent IP_EVENT', ret); 32 | ret = wifi.setMode(wifi.WIFI_MODE.STA); 33 | console.log('wifi setMode', ret); 34 | ret = wifi.setConfig(wifi.WIFI_MODE.STA, { 35 | ssid: SSID, 36 | password: PASS, 37 | auth: wifi.WIFI_AUTH_MODE.WIFI_AUTH_WPA2_PSK 38 | }); 39 | console.log('wifi setConfig', ret); 40 | ret = wifi.start(); 41 | console.log('wifi start', ret); -------------------------------------------------------------------------------- /examples/wifi/scan_ap.js: -------------------------------------------------------------------------------- 1 | var wifi = require('wifi'); 2 | var nvsFlash = require('nvs_flash'); 3 | var espERROR = require('esp_error'); 4 | 5 | console.log('wifi app init'); 6 | 7 | function wifi_event(name, id, data) { 8 | console.log('receive event: %s %d %j', name, id, data); 9 | 10 | if (name === wifi.EVENT_NAME.WIFI_EVENT) { 11 | if (id === wifi.WIFI_EVENT_CODE.WIFI_EVENT_SCAN_DONE) { 12 | console.log('wifi scan done'); 13 | } 14 | } 15 | } 16 | 17 | var ret; 18 | ret = nvsFlash.init(); 19 | console.log('nvs flash init', ret, espERROR.esp_err_to_name(ret)); 20 | ret = wifi.init(wifi.WIFI_MODE.STA); 21 | console.log('wifi init', ret, espERROR.esp_err_to_name(ret)); 22 | ret = wifi.setEventListener(wifi_event); 23 | console.log('wifi setEventListener', ret); 24 | ret = wifi.addListenEvent(wifi.EVENT_NAME.WIFI_EVENT); 25 | console.log('wifi addListenEvent WIFI_EVENT', ret); 26 | ret = wifi.setMode(wifi.WIFI_MODE.STA); 27 | console.log('wifi setMode', ret); 28 | ret = wifi.start(); 29 | console.log('wifi start', ret); 30 | ret = wifi.scanASync({ 31 | channel: 0, 32 | showHidden: false, 33 | scanType: wifi.SCAN_TYPE.ACTIVE 34 | }); 35 | if (typeof ret === 'number') { 36 | console.log('wifi scan error', espERROR.esp_err_to_name(ret)); 37 | } else { 38 | console.log('wifi scan result', ret); 39 | } -------------------------------------------------------------------------------- /main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register( 2 | INCLUDE_DIRS "include" 3 | REQUIRES "xtensa" "spi_flash" "spiffs" 4 | ) 5 | 6 | cmake_minimum_required(VERSION 3.5) 7 | 8 | set(NODEMCUJS_LIB nodemcujs-main) 9 | set(ROOT_DIR ${CMAKE_SOURCE_DIR}/main) 10 | set(NODEMCUJS_SOURCE_DIR ${CMAKE_SOURCE_DIR}/main/src) 11 | 12 | partition_table_get_partition_info(STORAGE_OFFSET "--partition-type data --partition-subtype spiffs" "offset") 13 | idf_build_get_property(PYTHON PYTHON) 14 | idf_build_get_property(IDF_PATH IDF_PATH) 15 | idf_build_get_property(IDF_TARGET IDF_TARGET) 16 | 17 | message("JERRYSCRIPT_ROOT: ${JERRYSCRIPT_ROOT}") 18 | 19 | aux_source_directory(src NODEMCUJS_SRCS) 20 | aux_source_directory(src/modules NODEMCUJS_SRCS_MODULES) 21 | list(APPEND NODEMCUJS_SRCS ${NODEMCUJS_SRCS_MODULES}) 22 | 23 | # generate nodemcujs js module: nodemcujs_js.c nodemcujs_js.h 24 | set(NODEMCUJS_JS_MODULES) 25 | set(NODEMCUJS_JS_MODULES_PARAM) 26 | 27 | file(GLOB NODEMCUJS_JS_FILES ${NODEMCUJS_SOURCE_DIR}/js/*.js) 28 | foreach(FILE_PATH ${NODEMCUJS_JS_FILES}) 29 | STRING(REGEX REPLACE ".+/(.+)\\..*" "\\1" FILE_NAME ${FILE_PATH}) 30 | list(APPEND NODEMCUJS_JS_MODULES ${FILE_NAME}) 31 | endforeach(FILE_PATH) 32 | 33 | message("Configure nodemcujs js module:") 34 | foreach(MODULE ${NODEMCUJS_JS_MODULES}) 35 | message("-- ENABLE_JS_MODULE_${MODULE}= ON") 36 | list(APPEND NODEMCUJS_JS_MODULES_PARAM "${MODULE}=${NODEMCUJS_SOURCE_DIR}/js/${MODULE}.js") 37 | endforeach() 38 | message("Configure nodemcujs js module end\n") 39 | 40 | # Run js2c 41 | set(JS2C_RUN_MODE "release") 42 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 43 | set(JS2C_RUN_MODE "debug") 44 | endif() 45 | 46 | add_custom_command( 47 | OUTPUT ${NODEMCUJS_SOURCE_DIR}/nodemcujs_js.c ${NODEMCUJS_SOURCE_DIR}/nodemcujs_js.h 48 | COMMAND ${PYTHON} ${ROOT_DIR}/tools/js2c.py 49 | ARGS --buildtype=${JS2C_RUN_MODE} 50 | --modules '${NODEMCUJS_JS_MODULES_PARAM}' 51 | ${JS2C_SNAPSHOT_ARG} 52 | DEPENDS ${ROOT_DIR}/tools/js2c.py 53 | ${NODEMCUJS_SOURCE_DIR}/js/*.js 54 | ) 55 | 56 | list(APPEND NODEMCUJS_SRCS ${NODEMCUJS_SOURCE_DIR}/nodemcujs_js.c ${NODEMCUJS_SOURCE_DIR}/nodemcujs_js.h) 57 | 58 | # generate nodemcujs buildin module: nodemcujs_module_inl.h 59 | message("Configure nodemcujs native module:") 60 | set(NODEMCUJS_MODULE_INL_H "/* 61 | * Copyright 2021-present nodemcujs and other contributors 62 | * 63 | * This file is generated by CMakeLists.txt 64 | * Do not modify this. 65 | */ 66 | 67 | #include \"nodemcujs_module.h\" 68 | ") 69 | set(NODEMCUJS_MODULE_ENTRIES) 70 | set(NODEMCUJS_MODULE_INITIALIZERS) 71 | set(NODEMCUJS_MODULE_OBJECTS) 72 | file(GLOB NODEMCUJS_NATIVE_FILES ${NODEMCUJS_SOURCE_DIR}/modules/*.c) 73 | list(LENGTH NODEMCUJS_NATIVE_FILES NODEMCUJS_MODULE_COUNT) 74 | foreach(NATIVE_MODULE ${NODEMCUJS_NATIVE_FILES}) 75 | string(REPLACE "${NODEMCUJS_SOURCE_DIR}/modules/" "" NATIVE_NAME "${NATIVE_MODULE}") 76 | string(REPLACE "nodemcujs_module_" "" NATIVE_NAME "${NATIVE_NAME}") 77 | string(REPLACE ".c" "" NATIVE_NAME "${NATIVE_NAME}") 78 | set(NODEMCUJS_MODULE_INITIALIZERS "${NODEMCUJS_MODULE_INITIALIZERS} 79 | extern jerry_value_t nodemcujs_module_init_${NATIVE_NAME}();") 80 | set(NODEMCUJS_MODULE_ENTRIES "${NODEMCUJS_MODULE_ENTRIES} 81 | { \"${NATIVE_NAME}\", nodemcujs_module_init_${NATIVE_NAME} },") 82 | set(NODEMCUJS_MODULE_OBJECTS "${NODEMCUJS_MODULE_OBJECTS} 83 | { 0 },") 84 | message("-- ENABLE_NATIVE_MODULE_${NATIVE_NAME}= ON") 85 | endforeach(NATIVE_MODULE) 86 | 87 | file(WRITE ${NODEMCUJS_SOURCE_DIR}/nodemcujs_module_inl.h "${NODEMCUJS_MODULE_INL_H} 88 | const unsigned nodemcujs_modules_count = ${NODEMCUJS_MODULE_COUNT}; 89 | ${NODEMCUJS_MODULE_INITIALIZERS} 90 | 91 | const nodemcujs_module_t nodemcujs_modules[] = {${NODEMCUJS_MODULE_ENTRIES} 92 | }; 93 | 94 | nodemcujs_module_objects_t nodemcujs_module_objects[] = {${NODEMCUJS_MODULE_OBJECTS} 95 | }; 96 | ") 97 | message("Configure nodemcujs native module end\n") 98 | message("File Write: ${NODEMCUJS_SOURCE_DIR}/nodemcujs_module_inl.h") 99 | 100 | list(APPEND NODEMCUJS_SRCS ${NODEMCUJS_SOURCE_DIR}/nodemcujs_module_inl.h) 101 | 102 | add_library(${NODEMCUJS_LIB} STATIC ${NODEMCUJS_SRCS} nodemcujs_main.c) 103 | 104 | # build jerryscript project 105 | 106 | # Xtensa processor architecture optimization 107 | set(EXTERNAL_COMPILE_FLAGS -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -Wno-frame-address) 108 | string(REPLACE ";" "|" EXTERNAL_COMPILE_FLAGS_ALT_SEP "${EXTERNAL_COMPILE_FLAGS}") 109 | 110 | externalproject_add(jerryscript_build 111 | PREFIX ${CMAKE_CURRENT_BINARY_DIR} 112 | SOURCE_DIR ${JERRYSCRIPT_ROOT} 113 | BUILD_IN_SOURCE 0 114 | BINARY_DIR jerryscript 115 | INSTALL_COMMAND "" # Do not install to host 116 | LIST_SEPARATOR | # Use the alternate list separator 117 | CMAKE_ARGS 118 | -DJERRY_GLOBAL_HEAP_SIZE=${JERRY_GLOBAL_HEAP_SIZE} 119 | -DJERRY_ERROR_MESSAGES=${JERRY_ERROR_MESSAGES} 120 | -DJERRY_CMDLINE=OFF 121 | -DENABLE_LTO=OFF # FIXME: This option must be turned off or the cross-compiler settings will be overwritten 122 | -DCMAKE_C_COMPILER_WORKS=true # cross-compiler 123 | -DCMAKE_SYSTEM_NAME=esp-idf 124 | -DCMAKE_SYSTEM_PROCESSOR=xtensa 125 | -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} 126 | -DEXTERNAL_COMPILE_FLAGS=${EXTERNAL_COMPILE_FLAGS_ALT_SEP} 127 | -DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS} 128 | -DCMAKE_LINKER=${CMAKE_LINKER} 129 | -DCMAKE_AR=${CMAKE_AR} 130 | -DCMAKE_NM=${CMAKE_NM} 131 | -DCMAKE_RANLIB=${CMAKE_RANLIB} 132 | -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER 133 | ) 134 | 135 | add_dependencies(${COMPONENT_LIB} jerryscript_build) 136 | 137 | set(COMPONENT_BUILD_PATH ${CMAKE_CURRENT_BINARY_DIR}/jerryscript) 138 | message("jerryscript output: ${COMPONENT_BUILD_PATH}") 139 | 140 | add_prebuilt_library(libjerry-core ${COMPONENT_BUILD_PATH}/lib/libjerry-core.a REQUIRES newlib PRIV_REQUIRES ${COMPONENT_NAME}) 141 | add_prebuilt_library(libjerry-ext ${COMPONENT_BUILD_PATH}/lib/libjerry-ext.a PRIV_REQUIRES ${COMPONENT_NAME}) 142 | add_prebuilt_library(libjerry-port-default-minimal ${COMPONENT_BUILD_PATH}/lib/libjerry-port-default-minimal.a PRIV_REQUIRES ${COMPONENT_NAME}) 143 | 144 | target_link_libraries(${NODEMCUJS_LIB} INTERFACE libjerry-core) 145 | target_link_libraries(${NODEMCUJS_LIB} INTERFACE libjerry-ext) 146 | target_link_libraries(${NODEMCUJS_LIB} INTERFACE libjerry-port-default-minimal) 147 | 148 | target_include_directories(${NODEMCUJS_LIB} PUBLIC ${JERRYSCRIPT_ROOT}/jerry-core/include) 149 | target_include_directories(${NODEMCUJS_LIB} PUBLIC ${JERRYSCRIPT_ROOT}/jerry-ext/include) 150 | 151 | target_include_directories(${NODEMCUJS_LIB} PUBLIC include) 152 | target_include_directories(${NODEMCUJS_LIB} PUBLIC src) 153 | 154 | target_link_libraries(${NODEMCUJS_LIB} PRIVATE idf::spi_flash idf::spiffs idf::list idf::nvs_flash idf::esp_http_client) 155 | 156 | target_link_libraries(${COMPONENT_LIB} INTERFACE ${NODEMCUJS_LIB}) 157 | 158 | # build spiffs image 159 | 160 | spiffs_create_partition_image(storage ../spiffs FLASH_IN_PROJECT) 161 | 162 | add_custom_command( 163 | OUTPUT flash_storage_cmd 164 | COMMAND ${PYTHON} ${IDF_PATH}/components/esptool_py/esptool/esptool.py 165 | ARGS --chip ${IDF_TARGET} 166 | write_flash 167 | -z ${STORAGE_OFFSET} 168 | ${CMAKE_BINARY_DIR}/storage.bin 169 | DEPENDS spiffs_storage_bin 170 | ) 171 | add_custom_target(flash-storage DEPENDS flash_storage_cmd) -------------------------------------------------------------------------------- /main/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # "main" pseudo-component makefile. 3 | # 4 | # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) 5 | 6 | -------------------------------------------------------------------------------- /main/include/nodemcujs.h: -------------------------------------------------------------------------------- 1 | #ifndef NODEMCUJS_H 2 | #define NODEMCUJS_H 3 | 4 | #include 5 | 6 | int nodemcujs_entry(); 7 | 8 | extern jerry_value_t nodemcujs_module_get(const char* name); 9 | 10 | #endif -------------------------------------------------------------------------------- /main/include/nodemcujs_config.h: -------------------------------------------------------------------------------- 1 | #ifndef NODEMCUJS_CONFIG_H 2 | #define NODEMCUJS_CONFIG_H 3 | 4 | #include "driver/uart.h" 5 | 6 | #define INTERACTIVE_UART_NUM UART_NUM_0 7 | #define INTERACTIVE_UART_BAUDRATE 115200 8 | #define INTERACTIVE_UART_TASK_STACK_DEPTH (1024 * 2) 9 | #define INTERACTIVE_UART_RX_BUF_SIZE (1024 * 2) 10 | #define INTERACTIVE_UART_TX_BUF_SIZE (1024 * 2) 11 | 12 | #define PRINT_CHIP_INFO 13 | 14 | #endif -------------------------------------------------------------------------------- /main/nodemcujs_main.c: -------------------------------------------------------------------------------- 1 | /* nodemcu.js entry 2 | 3 | This example code is in the Public Domain (or CC0 licensed, at your option.) 4 | 5 | Unless required by applicable law or agreed to in writing, this 6 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 7 | CONDITIONS OF ANY KIND, either express or implied. 8 | */ 9 | 10 | #include "include/nodemcujs_config.h" 11 | #include "nodemcujs.h" 12 | 13 | #include 14 | #include 15 | 16 | #include "freertos/FreeRTOS.h" 17 | #include "freertos/queue.h" 18 | #include "freertos/task.h" 19 | 20 | #include "jerryscript.h" 21 | #include "jerryscript-ext/handler.h" 22 | #include "jerryscript-port.h" 23 | 24 | #include "esp_system.h" 25 | #include "esp_spi_flash.h" 26 | #include "esp_heap_caps.h" 27 | #include "esp_err.h" 28 | 29 | #include "driver/uart.h" 30 | #include "esp_spiffs.h" 31 | 32 | void nodemcujs_init(void); 33 | 34 | static QueueHandle_t uart_queue; 35 | 36 | static void print_chip_info() 37 | { 38 | size_t free_size = heap_caps_get_free_size(MALLOC_CAP_DEFAULT); 39 | printf("heap free: %d\n", free_size); 40 | 41 | /* Print chip information */ 42 | esp_chip_info_t chip_info; 43 | esp_chip_info(&chip_info); 44 | printf("This is ESP32 chip with %d CPU cores, WiFi%s%s, ", 45 | chip_info.cores, 46 | (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", 47 | (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); 48 | 49 | printf("silicon revision %d, ", chip_info.revision); 50 | 51 | printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024), 52 | (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); 53 | 54 | fflush(stdout); 55 | } 56 | 57 | static void uart_event_task(void *pvParameters) 58 | { 59 | uart_event_t event; 60 | uint8_t *dtmp = (uint8_t *)malloc(INTERACTIVE_UART_RX_BUF_SIZE); 61 | for (;;) 62 | { 63 | // Waiting for UART event. 64 | if (xQueueReceive(uart_queue, (void *)&event, (portTickType)portMAX_DELAY)) 65 | { 66 | bzero(dtmp, INTERACTIVE_UART_RX_BUF_SIZE); 67 | switch (event.type) 68 | { 69 | /** 70 | * We'd better handler data event fast, there would be much more data events than 71 | * other types of events. If we take too much time on data event, the queue might 72 | * be full. 73 | */ 74 | case UART_DATA: 75 | uart_read_bytes(INTERACTIVE_UART_NUM, dtmp, event.size, portMAX_DELAY); 76 | /* Setup Global scope code */ 77 | jerry_value_t parsed_code = jerry_parse(NULL, 0, dtmp, event.size, JERRY_PARSE_NO_OPTS); 78 | 79 | if (!jerry_value_is_error(parsed_code)) 80 | { 81 | /* Execute the parsed source code in the Global scope */ 82 | jerry_value_t ret_value = jerry_run(parsed_code); 83 | 84 | /* Returned value must be freed */ 85 | jerry_release_value(ret_value); 86 | } 87 | else 88 | { 89 | const char *ohno = "something was wrong!"; 90 | uart_write_bytes(INTERACTIVE_UART_NUM, ohno, strlen(ohno)); 91 | } 92 | 93 | /* Parsed source code must be freed */ 94 | jerry_release_value(parsed_code); 95 | // free(dtmp); 96 | break; 97 | //Event of UART ring buffer full 98 | case UART_BUFFER_FULL: 99 | // If buffer full happened, you should consider encreasing your buffer size 100 | // As an example, we directly flush the rx buffer here in order to read more data. 101 | uart_flush_input(INTERACTIVE_UART_NUM); 102 | xQueueReset(uart_queue); 103 | break; 104 | //Others 105 | default: 106 | break; 107 | } 108 | } 109 | } 110 | free(dtmp); 111 | dtmp = NULL; 112 | vTaskDelete(NULL); 113 | } 114 | 115 | /** 116 | * Configure parameters of an UART driver, communication pins and install the driver 117 | * 118 | * - Port: UART0 119 | * - Receive (Rx) buffer: on 120 | * - Transmit (Tx) buffer: off 121 | * - Flow control: off 122 | * - Event queue: on 123 | * - Pin assignment: TxD (default), RxD (default) 124 | */ 125 | static void handle_uart_input() 126 | { 127 | uart_config_t uart_config = { 128 | .baud_rate = INTERACTIVE_UART_BAUDRATE, 129 | .data_bits = UART_DATA_8_BITS, 130 | .parity = UART_PARITY_DISABLE, 131 | .stop_bits = UART_STOP_BITS_1, 132 | .flow_ctrl = UART_HW_FLOWCTRL_DISABLE}; 133 | uart_param_config(INTERACTIVE_UART_NUM, &uart_config); 134 | 135 | //Set UART pins (using UART0 default pins ie no changes.) 136 | uart_set_pin(INTERACTIVE_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); 137 | //Install UART driver, and get the queue. 138 | uart_driver_install(INTERACTIVE_UART_NUM, INTERACTIVE_UART_RX_BUF_SIZE, INTERACTIVE_UART_TX_BUF_SIZE, 20, &uart_queue, 0); 139 | 140 | //Create a task to handler UART event from ISR 141 | xTaskCreate(uart_event_task, "uart_event_task", INTERACTIVE_UART_TASK_STACK_DEPTH, NULL, 12, NULL); 142 | } 143 | 144 | static void mount_spiffs() 145 | { 146 | esp_vfs_spiffs_conf_t conf = { 147 | .base_path = "", 148 | .partition_label = NULL, 149 | .max_files = 5, 150 | .format_if_mount_failed = true 151 | }; 152 | 153 | esp_err_t ret = esp_vfs_spiffs_register(&conf); 154 | 155 | if (ret != ESP_OK) 156 | { 157 | if (ret == ESP_FAIL) 158 | { 159 | printf("Failed to mount or format filesystem\n"); 160 | } 161 | else if (ret == ESP_ERR_NOT_FOUND) 162 | { 163 | printf("Failed to find SPIFFS partition\n"); 164 | } 165 | else 166 | { 167 | printf("Failed to initialize SPIFFS (%s)\n", esp_err_to_name(ret)); 168 | } 169 | return; 170 | } 171 | 172 | size_t total = 0, used = 0; 173 | ret = esp_spiffs_info(NULL, &total, &used); 174 | if (ret != ESP_OK) { 175 | printf("Failed to get SPIFFS partition information (%s)\n", esp_err_to_name(ret)); 176 | } else { 177 | printf("Partition size: total: %d, used: %d\n", total, used); 178 | } 179 | 180 | fflush(stdout); 181 | } 182 | 183 | void app_main() 184 | { 185 | fflush(stdout); 186 | // handle uart input 187 | handle_uart_input(); 188 | // mount spiffs 189 | mount_spiffs(); 190 | // user code init 191 | nodemcujs_init(); 192 | // nodemcujs entry 193 | nodemcujs_entry(); 194 | 195 | while (true) 196 | { 197 | // alive check here. but nothing to do now! 198 | vTaskDelay(1000 / portTICK_PERIOD_MS); 199 | } 200 | 201 | /* Cleanup engine */ 202 | jerry_cleanup(); 203 | } 204 | 205 | void nodemcujs_init(void) 206 | { 207 | #ifdef PRINT_CHIP_INFO 208 | print_chip_info(); 209 | #endif 210 | } 211 | -------------------------------------------------------------------------------- /main/src/js/console.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Native = require('native'); 4 | var util = Native.require('util'); 5 | 6 | function Console() { 7 | this.stdout = native.stdout; 8 | this.stderr = native.stderr; 9 | }; 10 | 11 | Console.prototype.log = 12 | Console.prototype.info = 13 | Console.prototype.warn = 14 | Console.prototype.error = 15 | Console.prototype.debug = function() { 16 | if (arguments.length === 1) { 17 | native.stdout(util.formatValue(arguments[0]) + '\n'); 18 | } else { 19 | native.stdout(util.format.apply(this, arguments) + '\n'); 20 | } 21 | }; 22 | 23 | var console = new Console(); 24 | 25 | module.exports = console; -------------------------------------------------------------------------------- /main/src/js/events.js: -------------------------------------------------------------------------------- 1 | /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 'use strict'; 16 | 17 | var Native = require('native'); 18 | var util = Native.require('util'); 19 | 20 | function $getMaxListeners(that) { 21 | if (that._maxListeners === undefined) { 22 | return EventEmitter.defaultMaxListeners; 23 | } 24 | return that._maxListeners; 25 | } 26 | 27 | function EventEmitter() { 28 | EventEmitter.init.call(this); 29 | } 30 | 31 | module.exports = EventEmitter; 32 | module.exports.EventEmitter = EventEmitter; 33 | 34 | EventEmitter.prototype._eventsCount = 0; 35 | EventEmitter.prototype._maxListeners = undefined; 36 | 37 | var defaultMaxListeners = 7; 38 | 39 | Object.defineProperty(EventEmitter, 'defaultMaxListeners', { 40 | enumerable: true, 41 | get: function() { 42 | return defaultMaxListeners; 43 | }, 44 | set: function(arg) { 45 | if (!arg || typeof arg !== 'number' || arg < 0) { 46 | throw new TypeError('defaultMaxListeners must be a non-negative number'); 47 | } 48 | defaultMaxListeners = arg; 49 | } 50 | }); 51 | 52 | EventEmitter.init = function() { 53 | if (this._events === undefined || 54 | this._events === Object.getPrototypeOf(this)._events) { 55 | this._events = Object.create(null); 56 | this._eventsCount = 0; 57 | } 58 | 59 | this._maxListeners = this._maxListeners || undefined; 60 | }; 61 | 62 | 63 | EventEmitter.prototype.emit = function(type) { 64 | if (!this._events) { 65 | this._events = Object.create(null); 66 | } 67 | 68 | // About to emit 'error' event but there are no listeners for it. 69 | if (type === 'error' && !this._events.error) { 70 | var err = arguments[1]; 71 | if (err instanceof Error) { 72 | throw err; 73 | } else { 74 | throw new Error('Uncaught \'error\' event'); 75 | } 76 | } 77 | 78 | var listeners = this._events[type]; 79 | if (util.isArray(listeners)) { 80 | listeners = listeners.slice(); 81 | var args = Array.prototype.slice.call(arguments, 1); 82 | for (var i = 0; i < listeners.length; ++i) { 83 | listeners[i].apply(this, args); 84 | } 85 | return true; 86 | } 87 | 88 | return false; 89 | }; 90 | 91 | 92 | EventEmitter.prototype.addListener = function(type, listener) { 93 | var max, existing; 94 | 95 | if (!util.isFunction(listener)) { 96 | throw new TypeError('listener must be a function'); 97 | } 98 | 99 | if (!this._events) { 100 | this._events = Object.create(null); 101 | } 102 | 103 | if (this._events.newListener !== undefined) { 104 | this.emit('newListener', type, listener); 105 | } 106 | 107 | existing = this._events[type]; 108 | if (!existing) { 109 | existing = this._events[type] = []; 110 | } 111 | 112 | existing.push(listener); 113 | 114 | // check for listener leak 115 | max = $getMaxListeners(this); 116 | if (max > 0 && existing.length > max && !existing.warned) { 117 | existing.warned = true; 118 | var w = new Error('Possible EventEmitter memory leak detected. ' + 119 | existing.length + ' or more \'' + String(type) + '\' listeners ' + 120 | 'added. Use emitter.setMaxListeners() to ' + 121 | 'increase limit'); 122 | w.name = 'MaxListenersExceededWarning'; 123 | w.emitter = this; 124 | w.type = type; 125 | w.count = existing.length; 126 | process.emitWarning(w); 127 | // TODO: print this warn. 128 | } 129 | 130 | return this; 131 | }; 132 | 133 | 134 | EventEmitter.prototype.on = EventEmitter.prototype.addListener; 135 | 136 | 137 | EventEmitter.prototype.once = function(type, listener) { 138 | if (!util.isFunction(listener)) { 139 | throw new TypeError('listener must be a function'); 140 | } 141 | 142 | // eslint-disable-next-line func-style 143 | var f = function() { 144 | // here `this` is this not global, because EventEmitter binds event object 145 | // for this when it calls back the handler. 146 | this.removeListener(f.type, f); 147 | f.listener.apply(this, arguments); 148 | }; 149 | 150 | f.type = type; 151 | f.listener = listener; 152 | 153 | this.on(type, f); 154 | 155 | return this; 156 | }; 157 | 158 | 159 | EventEmitter.prototype.removeListener = function(type, listener) { 160 | if (!util.isFunction(listener)) { 161 | throw new TypeError('listener must be a function'); 162 | } 163 | 164 | var list = this._events[type]; 165 | if (Array.isArray(list)) { 166 | for (var i = list.length - 1; i >= 0; --i) { 167 | if (list[i] === listener || 168 | (list[i].listener && list[i].listener === listener)) { 169 | list.splice(i, 1); 170 | if (!list.length) { 171 | delete this._events[type]; 172 | if (this._events.removeListener !== undefined) { 173 | this.emit('removeListener', type, listener); 174 | } 175 | } 176 | break; 177 | } 178 | } 179 | } 180 | 181 | return this; 182 | }; 183 | 184 | 185 | EventEmitter.prototype.removeAllListeners = function(type) { 186 | if (arguments.length === 0) { 187 | this._events = Object.create(null); 188 | } else { 189 | delete this._events[type]; 190 | } 191 | 192 | return this; 193 | }; 194 | 195 | 196 | EventEmitter.prototype.listeners = function(type) { 197 | var events = this._events; 198 | if (events === undefined) 199 | return []; 200 | 201 | var evlistener = events[type]; 202 | if (evlistener === undefined) 203 | return []; 204 | 205 | if (typeof evlistener === 'function') 206 | return [evlistener.listener || evlistener]; 207 | 208 | return unwrapListeners(evlistener); 209 | }; 210 | 211 | 212 | EventEmitter.prototype.setMaxListeners = function(n) { 213 | if (!n || typeof n !== 'number' || n < 0) { 214 | throw new TypeError('arguments of setMaxListeners must be a ' + 215 | 'non-negative number'); 216 | } 217 | this._maxListeners = n; 218 | return this; 219 | }; 220 | 221 | 222 | EventEmitter.prototype.getMaxListeners = function() { 223 | return $getMaxListeners(this); 224 | }; 225 | 226 | 227 | function unwrapListeners(arr) { 228 | var ret = new Array(arr.length); 229 | for (var i = 0; i < ret.length; ++i) { 230 | ret[i] = arr[i].listener || arr[i]; 231 | } 232 | return ret; 233 | } 234 | -------------------------------------------------------------------------------- /main/src/js/module.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Native = require('native'); 4 | var path = Native.require('path'); 5 | 6 | function nodemcujs_module_t(id, parent) { 7 | this.id = id; 8 | this.exports = {}; 9 | this.filename = null; 10 | this.parent = parent; 11 | } 12 | 13 | nodemcujs_module_t.cache = {}; 14 | 15 | nodemcujs_module_t.resolveModulePath = function(id, parent) { 16 | if (process.builtin_modules[id]) { 17 | return id; 18 | } 19 | 20 | if (parent && id === parent.id) { 21 | return false; 22 | } 23 | 24 | var filepath = false; 25 | if (id[0] === '/') { 26 | filepath = id; 27 | } else if (!parent) { 28 | filepath = path.join(process.cwd(), id); 29 | } else { 30 | var root = path.dirname(parent.filename); 31 | filepath = path.join(root, id); 32 | } 33 | 34 | return filepath; 35 | } 36 | 37 | nodemcujs_module_t.prototype.require = function(id) { 38 | return nodemcujs_module_t.load(id, this); 39 | } 40 | 41 | nodemcujs_module_t.load = function(id, parent) { 42 | var modulePath = nodemcujs_module_t.resolveModulePath(id, parent); 43 | var cachedModule = nodemcujs_module_t.cache[modulePath]; 44 | if (cachedModule) { 45 | return cachedModule.exports; 46 | } 47 | if (process.builtin_modules[id]) { 48 | return Native.require(id) 49 | } 50 | 51 | if (!modulePath) { 52 | throw new Error('Module not found: ' + id) 53 | } 54 | 55 | var module = new nodemcujs_module_t(id, parent); 56 | module.filename = modulePath; 57 | nodemcujs_module_t.cache[modulePath] = module; 58 | 59 | var ext = path.extname(modulePath); 60 | if (ext === '.json') { 61 | var source = process.readSource(modulePath); 62 | module.exports = JSON.parse(source); 63 | } else { 64 | module.compile(); 65 | } 66 | 67 | return module.exports; 68 | } 69 | 70 | nodemcujs_module_t.prototype.compile = function() { 71 | var __filename = this.filename; 72 | var __dirname = path.dirname(__filename); 73 | var fn = process.compile(__filename); 74 | 75 | var _require = this.require.bind(this); 76 | _require.cache = nodemcujs_module_t.cache; 77 | 78 | fn.apply(this.exports, [ 79 | this.exports, // exports 80 | _require, // require 81 | this, // module 82 | undefined, // native 83 | __filename, // __filename 84 | __dirname // __dirname 85 | ]); 86 | } 87 | 88 | nodemcujs_module_t.runMain = function() { 89 | nodemcujs_module_t.load('/index.js', undefined); 90 | } 91 | 92 | module.exports = nodemcujs_module_t; -------------------------------------------------------------------------------- /main/src/js/nodemcujs.js: -------------------------------------------------------------------------------- 1 | (function nodemcujs() { 2 | this.global = this; 3 | 4 | function Module(id) { 5 | this.id = id; 6 | this.exports = {}; 7 | } 8 | Module.cache = {}; 9 | Module.require = function(id) { 10 | if (id === 'native') { 11 | return Module; 12 | } 13 | 14 | if (Module.cache[id]) { 15 | return Module.cache[id].exports; 16 | } 17 | 18 | var module = new Module(id); 19 | 20 | Module.cache[id] = module; 21 | module.compile(); 22 | 23 | return module.exports; 24 | }; 25 | Module.prototype.compile = function() { 26 | process.compileModule(this, Module.require); 27 | }; 28 | 29 | global.console = Module.require('console'); 30 | process.stdout = { 31 | isTTY: false, 32 | write: console.stdout 33 | }; 34 | process.stderr = { 35 | isTTY: false, 36 | write: console.stderr 37 | }; 38 | var timers = Module.require('timers'); 39 | global.setInterval = timers.setInterval; 40 | global.setTimeout = timers.setTimeout; 41 | global.clearInterval = timers.clearInterval; 42 | global.clearTimeout = timers.clearTimeout; 43 | process.delay = timers.delay; 44 | 45 | var EventEmitter = Module.require('events').EventEmitter; 46 | EventEmitter.call(process); 47 | Object.keys(EventEmitter.prototype).forEach(function(key) { 48 | if (!process[key]) { 49 | process[key] = EventEmitter.prototype[key]; 50 | } 51 | }); 52 | process.emitWarning = function(warning, type, code, ctor) { 53 | process.emit('warning', warning, type, code, ctor); 54 | }; 55 | 56 | console.log("nodemcujs version: %s", process.version); 57 | 58 | Module.require('module').runMain(); 59 | 60 | })(); 61 | -------------------------------------------------------------------------------- /main/src/js/spi.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Native = require('native'); 4 | var spi = Native.require('spi_master'); 5 | var util = Native.require('util'); 6 | 7 | function MASTER(id, options) { 8 | this.id = id; 9 | this.options = options; 10 | } 11 | 12 | MASTER.prototype.setup = function() { 13 | return spi.setup(this.id, this.options); 14 | } 15 | 16 | MASTER.prototype.sendDataSync = function(data) { 17 | if (typeof data !== 'number' && !util.isArray(data)) { 18 | throw new TypeError('The parameter data must be a Number or Array'); 19 | } 20 | return spi.sendSync(this.id, 1, typeof data === 'number' ? [data] : data); 21 | } 22 | 23 | MASTER.prototype.sendCmdSync = function(cmd) { 24 | if (typeof cmd !== 'number' && !util.isArray(cmd)) { 25 | throw new TypeError('The parameter cmd must be a Number or Array'); 26 | } 27 | return spi.sendSync(this.id, 0, typeof cmd === 'number' ? [cmd] : cmd); 28 | } 29 | 30 | module.exports = { 31 | MASTER: MASTER 32 | }; -------------------------------------------------------------------------------- /main/src/js/util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function isNull(arg) { 4 | return arg === null; 5 | } 6 | 7 | 8 | function isDate(arg) { 9 | return arg instanceof Date; 10 | } 11 | 12 | 13 | function isError(arg) { 14 | return arg instanceof Error; 15 | } 16 | 17 | 18 | function isUndefined(arg) { 19 | return arg === undefined; 20 | } 21 | 22 | 23 | function isNullOrUndefined(arg) { 24 | return arg === null || arg === undefined; 25 | } 26 | 27 | 28 | function isNumber(arg) { 29 | return typeof arg === 'number'; 30 | } 31 | 32 | function isFinite(arg) { 33 | return (arg === 0) || (arg !== arg / 2); 34 | } 35 | 36 | function isBoolean(arg) { 37 | return typeof arg === 'boolean'; 38 | } 39 | 40 | 41 | function isString(arg) { 42 | return typeof arg === 'string'; 43 | } 44 | 45 | 46 | function isObject(arg) { 47 | return typeof arg === 'object' && arg != null; 48 | } 49 | 50 | 51 | function isFunction(arg) { 52 | return typeof arg === 'function'; 53 | } 54 | 55 | // FIXME: support Buffer 56 | // function isBuffer(arg) { 57 | // return arg instanceof Buffer; 58 | // } 59 | 60 | function isRegExp(arg) { 61 | return arg instanceof RegExp; 62 | } 63 | 64 | 65 | function inherits(ctor, superCtor) { 66 | ctor.prototype = Object.create(superCtor.prototype, { 67 | constructor: { 68 | value: ctor, 69 | enumerable: false, 70 | writable: true, 71 | configurable: true, 72 | }, 73 | }); 74 | } 75 | 76 | 77 | function format(s) { 78 | if (!isString(s)) { 79 | var arrs = []; 80 | for (var i0 = 0; i0 < arguments.length; ++i0) { 81 | arrs.push(formatValue(arguments[i0])); 82 | } 83 | return arrs.join(' '); 84 | } 85 | 86 | var i = 1; 87 | var args = arguments; 88 | var arg_string; 89 | var str = ''; 90 | var start = 0; 91 | var end = 0; 92 | 93 | while (end < s.length) { 94 | if (s.charAt(end) !== '%') { 95 | end++; 96 | continue; 97 | } 98 | 99 | str += s.slice(start, end); 100 | 101 | switch (s.charAt(end + 1)) { 102 | case 's': 103 | arg_string = String(args[i]); 104 | break; 105 | case 'd': 106 | arg_string = Number(args[i]); 107 | break; 108 | case 'j': 109 | try { 110 | arg_string = JSON.stringify(args[i]); 111 | } catch (_) { 112 | arg_string = '[Circular]'; 113 | } 114 | break; 115 | case '%': 116 | str += '%'; 117 | start = end = end + 2; 118 | continue; 119 | default: 120 | str = str + '%' + s.charAt(end + 1); 121 | start = end = end + 2; 122 | continue; 123 | } 124 | 125 | if (i >= args.length) { 126 | str = str + '%' + s.charAt(end + 1); 127 | } else { 128 | i++; 129 | str += arg_string; 130 | } 131 | 132 | start = end = end + 2; 133 | } 134 | 135 | str += s.slice(start, end); 136 | 137 | while (i < args.length) { 138 | str += ' ' + formatValue(args[i++]); 139 | } 140 | 141 | return str; 142 | } 143 | 144 | function formatValue(v) { 145 | if (v === undefined) 146 | return 'undefined'; 147 | if (v === null) 148 | return 'null'; 149 | 150 | if (v instanceof Error) { 151 | return v.name + ': ' + v.message + '\n' + v.stack; 152 | } 153 | 154 | if (v instanceof Date) { 155 | return v.toString(); 156 | } 157 | // FIXME: support Buffer 158 | // if (Buffer.isBuffer(v)) { 159 | // return v.inspect(); 160 | // } 161 | if (Array.isArray(v)) { 162 | return '[ ' + v.map(formatValue).join(', ') + ' ]'; 163 | } 164 | if (typeof v === 'object') { 165 | return JSON.stringify(v, jsonReplacer, 2); 166 | } 167 | return v.toString(); 168 | } 169 | 170 | 171 | function jsonReplacer(key, value) { 172 | // FIXME: support Buffer 173 | return value; 174 | } 175 | 176 | 177 | function stringToNumber(value, default_value) { 178 | var num = Number(value); 179 | return isNaN(num) ? default_value : num; 180 | } 181 | 182 | 183 | function errnoException(err, syscall, original) { 184 | var errname = 'error'; // uv.errname(err); 185 | var message = syscall + ' ' + errname; 186 | 187 | if (original) 188 | message += ' ' + original; 189 | 190 | var e = new Error(message); 191 | e.code = errname; 192 | e.errno = errname; 193 | e.syscall = syscall; 194 | 195 | return e; 196 | } 197 | 198 | 199 | function exceptionWithHostPort(err, syscall, address, port, additional) { 200 | var details; 201 | if (port && port > 0) { 202 | details = address + ':' + port; 203 | } else { 204 | details = address; 205 | } 206 | 207 | if (additional) { 208 | details += ' - Local (' + additional + ')'; 209 | } 210 | 211 | var ex = exports.errnoException(err, syscall, details); 212 | ex.address = address; 213 | if (port) { 214 | ex.port = port; 215 | } 216 | 217 | return ex; 218 | } 219 | 220 | var codesWarned = {}; 221 | 222 | // Mark that a method should not be used. 223 | // Returns a modified function which warns once by default. 224 | // If --no-deprecation is set, then it is a no-op. 225 | function deprecate(fn, msg, code) { 226 | if (process.noDeprecation === true) { 227 | return fn; 228 | } 229 | 230 | if (code !== undefined && typeof code !== 'string') 231 | throw new TypeError('ERR_INVALID_ARG_TYPE'); 232 | 233 | var warned = false; 234 | function deprecated() { 235 | if (!warned) { 236 | warned = true; 237 | if (code !== undefined) { 238 | if (!codesWarned[code]) { 239 | process.emitWarning(msg, 'DeprecationWarning', code, deprecated); 240 | codesWarned[code] = true; 241 | } 242 | } else { 243 | process.emitWarning(msg, 'DeprecationWarning', deprecated); 244 | } 245 | } 246 | return fn.apply(this, arguments); 247 | } 248 | 249 | // The wrapper will keep the same prototype as fn to maintain prototype chain 250 | Object.setPrototypeOf(deprecated, fn); 251 | if (fn.prototype) { 252 | // Setting this (rather than using Object.setPrototype, as above) ensures 253 | // that calling the unwrapped constructor gives an instanceof the wrapped 254 | // constructor. 255 | deprecated.prototype = fn.prototype; 256 | } 257 | 258 | return deprecated; 259 | } 260 | 261 | // FIXME: use Symbol on implementation done 262 | // var customPromisifySymbol = 'util:promisify:custom'; 263 | // promisify.custom = customPromisifySymbol; 264 | // function promisify(original) { 265 | // if (typeof original != 'function') { 266 | // throw new TypeError('expect a function on promisify'); 267 | // } 268 | // if (typeof original[customPromisifySymbol] == 'function') { 269 | // return original[customPromisifySymbol]; 270 | // } 271 | // return function promisified() { 272 | // var args = Array.prototype.slice.call(arguments, 0); 273 | 274 | // return new Promise((resolve, reject) => { 275 | // args.push(callback); 276 | // original.apply(this, args); 277 | 278 | // function callback(err, result) { 279 | // if (err != null) { 280 | // reject(err); 281 | // return; 282 | // } 283 | // resolve(result); 284 | // } 285 | // }); 286 | // }; 287 | // } 288 | 289 | 290 | exports.isNull = isNull; 291 | exports.isUndefined = isUndefined; 292 | exports.isNullOrUndefined = isNullOrUndefined; 293 | exports.isNumber = isNumber; 294 | exports.isBoolean = isBoolean; 295 | exports.isString = isString; 296 | exports.isObject = isObject; 297 | exports.isFinite = isFinite; 298 | exports.isFunction = isFunction; 299 | // FIXME: support Buffer 300 | // exports.isBuffer = isBuffer; 301 | exports.isRegExp = isRegExp; 302 | exports.isArray = Array.isArray; 303 | exports.exceptionWithHostPort = exceptionWithHostPort; 304 | exports.errnoException = errnoException; 305 | exports.stringToNumber = stringToNumber; 306 | exports.inherits = inherits; 307 | exports.format = format; 308 | exports.formatValue = formatValue; 309 | exports.deprecate = deprecate; 310 | // exports.promisify = promisify; 311 | exports.isDate = isDate; 312 | exports.isError = isError; 313 | -------------------------------------------------------------------------------- /main/src/js/wifi.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Native = require('native'); 4 | var util = Native.require('util'); 5 | var wifi = native 6 | 7 | var WIFI_MODE = { 8 | STA: 1, 9 | AP: 2, 10 | APSTA: 3 11 | }; 12 | 13 | var WIFI_AUTH_MODE = { 14 | WIFI_AUTH_OPEN: 0, 15 | WIFI_AUTH_WEP: 2, 16 | WIFI_AUTH_WPA_PSK: 2, 17 | WIFI_AUTH_WPA2_PSK: 3, 18 | WIFI_AUTH_WPA_WPA2_PSK: 4, 19 | WIFI_AUTH_WPA2_ENTERPRISE: 5, 20 | WIFI_AUTH_WPA3_PSK: 6, 21 | WIFI_AUTH_WPA2_WPA3_PSK: 7, 22 | WIFI_AUTH_WAPI_PSK: 8, 23 | WIFI_AUTH_MAX: 9 24 | }; 25 | 26 | var SCAN_TYPE = { 27 | ACTIVE: 0, 28 | PASSIVE: 1 29 | }; 30 | 31 | var EVENT_NAME_MAP = { 32 | WIFI_EVENT: 1, 33 | IP_EVENT: 2 34 | }; 35 | 36 | var EVENT_NAME = Object.keys(EVENT_NAME_MAP).reduce(function(acc, cur) { 37 | acc[cur] = cur; 38 | return acc; 39 | }, {}); 40 | 41 | var WIFI_EVENT_CODE = { 42 | WIFI_EVENT_WIFI_READY: 0, /**< ESP32 WiFi ready */ 43 | WIFI_EVENT_SCAN_DONE: 1, /**< ESP32 finish scanning AP */ 44 | WIFI_EVENT_STA_START: 2, /**< ESP32 station start */ 45 | WIFI_EVENT_STA_STOP: 3, /**< ESP32 station stop */ 46 | WIFI_EVENT_STA_CONNECTED: 4, /**< ESP32 station connected to AP */ 47 | WIFI_EVENT_STA_DISCONNECTED: 5, /**< ESP32 station disconnected from AP */ 48 | WIFI_EVENT_STA_AUTHMODE_CHANGE: 6, /**< the auth mode of AP connected by ESP32 station changed */ 49 | 50 | WIFI_EVENT_STA_WPS_ER_SUCCESS: 7, /**< ESP32 station wps succeeds in enrollee mode */ 51 | WIFI_EVENT_STA_WPS_ER_FAILED: 8, /**< ESP32 station wps fails in enrollee mode */ 52 | WIFI_EVENT_STA_WPS_ER_TIMEOUT: 9, /**< ESP32 station wps timeout in enrollee mode */ 53 | WIFI_EVENT_STA_WPS_ER_PIN: 10, /**< ESP32 station wps pin code in enrollee mode */ 54 | WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP: 11, /**< ESP32 station wps overlap in enrollee mode */ 55 | 56 | WIFI_EVENT_AP_START: 12, /**< ESP32 soft-AP start */ 57 | WIFI_EVENT_AP_STOP: 13, /**< ESP32 soft-AP stop */ 58 | WIFI_EVENT_AP_STACONNECTED: 14, /**< a station connected to ESP32 soft-AP */ 59 | WIFI_EVENT_AP_STADISCONNECTED: 15, /**< a station disconnected from ESP32 soft-AP */ 60 | WIFI_EVENT_AP_PROBEREQRECVED: 16, /**< Receive probe request packet in soft-AP interface */ 61 | 62 | WIFI_EVENT_FTM_REPORT: 17, /**< Receive report of FTM procedure */ 63 | 64 | /* Add next events after this only */ 65 | WIFI_EVENT_STA_BSS_RSSI_LOW: 18, /**< AP's RSSI crossed configured threshold */ 66 | WIFI_EVENT_ACTION_TX_STATUS: 19, /**< Status indication of Action Tx operation */ 67 | WIFI_EVENT_ROC_DONE: 20, /**< Remain-on-Channel operation complete */ 68 | 69 | WIFI_EVENT_STA_BEACON_TIMEOUT: 21, /**< ESP32 station beacon timeout */ 70 | 71 | WIFI_EVENT_MAX: 22 /**< Invalid WiFi event ID */ 72 | }; 73 | 74 | var IP_EVENT_CODE = { 75 | IP_EVENT_STA_GOT_IP: 0, /*!< station got IP from connected AP */ 76 | IP_EVENT_STA_LOST_IP: 1, /*!< station lost IP and the IP is reset to 0 */ 77 | IP_EVENT_AP_STAIPASSIGNED: 2, /*!< soft-AP assign an IP to a connected station */ 78 | IP_EVENT_GOT_IP6: 3, /*!< station or ap or ethernet interface v6IP addr is preferred */ 79 | IP_EVENT_ETH_GOT_IP: 4, /*!< ethernet got IP from connected AP */ 80 | IP_EVENT_PPP_GOT_IP: 5, /*!< PPP interface got IP */ 81 | IP_EVENT_PPP_LOST_IP: 6, /*!< PPP interface lost IP */ 82 | }; 83 | 84 | function addListenEvent(name) { 85 | var code = EVENT_NAME_MAP[name]; 86 | wifi.addListenEvent(code); 87 | } 88 | 89 | module.exports = { 90 | WIFI_MODE: WIFI_MODE, 91 | WIFI_AUTH_MODE: WIFI_AUTH_MODE, 92 | SCAN_TYPE: SCAN_TYPE, 93 | EVENT_NAME: EVENT_NAME, 94 | WIFI_EVENT_CODE: WIFI_EVENT_CODE, 95 | IP_EVENT_CODE: IP_EVENT_CODE, 96 | 97 | init: wifi.init, 98 | setMode: wifi.setMode, 99 | setConfig: wifi.setConfig, 100 | start: wifi.start, 101 | setEventListener: wifi.setEventListener, 102 | addListenEvent: addListenEvent, 103 | connect: wifi.connect, 104 | scanASync: wifi.scanASync 105 | }; 106 | -------------------------------------------------------------------------------- /main/src/modules/nodemcujs_module_console.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs.h" 2 | #include "nodemcujs_binding.h" 3 | #include "nodemcujs_magic_strings.h" 4 | 5 | #include 6 | 7 | // This function should be able to print utf8 encoded string 8 | // as utf8 is internal string representation in Jerryscript 9 | static jerry_value_t Print(const jerry_value_t* jargv, const jerry_length_t jargc) { 10 | jerry_size_t len = jerry_get_string_size(jargv[0]); 11 | jerry_char_t str[len + 1]; 12 | jerry_string_to_char_buffer(jargv[0], str, len); 13 | str[len] = '\0'; 14 | printf("%s", str); 15 | return jerry_create_undefined(); 16 | } 17 | 18 | 19 | JS_FUNCTION(Stdout) { 20 | return Print(jargv, jargc); 21 | } 22 | 23 | 24 | JS_FUNCTION(Stderr) { 25 | return Print(jargv, jargc); 26 | } 27 | 28 | 29 | jerry_value_t nodemcujs_module_init_console() { 30 | jerry_value_t console = jerry_create_object(); 31 | 32 | nodemcujs_jval_set_method(console, NODEMCUJS_MAGIC_STRING_STDOUT, Stdout); 33 | nodemcujs_jval_set_method(console, NODEMCUJS_MAGIC_STRING_STDERR, Stderr); 34 | 35 | return console; 36 | } 37 | -------------------------------------------------------------------------------- /main/src/modules/nodemcujs_module_esp_error.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs.h" 2 | #include "nodemcujs_binding.h" 3 | 4 | #include "esp_err.h" 5 | 6 | JS_FUNCTION(EspErrToName) { 7 | esp_err_t code = JS_GET_ARG(0, number); 8 | char *name = esp_err_to_name(code); 9 | return jerry_create_string((jerry_char_t*)name); 10 | } 11 | 12 | jerry_value_t nodemcujs_module_init_esp_error() { 13 | jerry_value_t esp_err = jerry_create_object(); 14 | nodemcujs_jval_set_method(esp_err, "esp_err_to_name", EspErrToName); 15 | return esp_err; 16 | } 17 | -------------------------------------------------------------------------------- /main/src/modules/nodemcujs_module_gpio.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs.h" 2 | #include "nodemcujs_binding.h" 3 | #include "nodemcujs_magic_strings.h" 4 | 5 | #include "driver/gpio.h" 6 | 7 | #include "esp_err.h" 8 | 9 | JS_FUNCTION(Mode) { 10 | int pin_num = (int)JS_GET_ARG(0, number); 11 | int pin_mode = (int)JS_GET_ARG(1, number); 12 | esp_err_t status = gpio_set_direction(pin_num, pin_mode); 13 | if (status != ESP_OK) 14 | { 15 | return jerry_create_boolean(false); 16 | } 17 | return jerry_create_boolean(true); 18 | } 19 | 20 | JS_FUNCTION(Write) { 21 | int pin_num = (int)JS_GET_ARG(0, number); 22 | uint32_t pin_level = (uint32_t)JS_GET_ARG(1, number); 23 | esp_err_t status = gpio_set_level(pin_num, pin_level); 24 | if (status != ESP_OK) 25 | { 26 | return jerry_create_boolean(false); 27 | } 28 | return jerry_create_boolean(true); 29 | } 30 | 31 | JS_FUNCTION(Read) { 32 | int pin_num = (int)JS_GET_ARG(0, number); 33 | int level = gpio_get_level(pin_num); 34 | return jerry_create_number((double)level); 35 | } 36 | 37 | jerry_value_t nodemcujs_module_init_gpio() 38 | { 39 | jerry_value_t gpio = jerry_create_object(); 40 | 41 | nodemcujs_jval_set_method(gpio, NODEMCUJS_MAGIC_STRING_MODE, Mode); 42 | nodemcujs_jval_set_method(gpio, NODEMCUJS_MAGIC_STRING_WRITE, Write); 43 | nodemcujs_jval_set_method(gpio, NODEMCUJS_MAGIC_STRING_READ, Read); 44 | 45 | return gpio; 46 | } -------------------------------------------------------------------------------- /main/src/modules/nodemcujs_module_http_client.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs.h" 2 | #include "nodemcujs_def.h" 3 | #include "nodemcujs_string.h" 4 | #include "nodemcujs_binding.h" 5 | 6 | #include "esp_err.h" 7 | #include "esp_http_client.h" 8 | 9 | #include 10 | 11 | static const jerry_object_native_info_t NativeInfoHttpClient; 12 | 13 | JS_FUNCTION(ClientRequest) { 14 | jerry_value_t options = JS_GET_ARG(0, object); 15 | 16 | jerry_value_t jurl = nodemcujs_jval_get_property(options, "url"); 17 | nodemcujs_string_t url = nodemcujs_jval_as_string(jurl); 18 | jerry_release_value(jurl); 19 | jerry_value_t jauthType = nodemcujs_jval_get_property(options, "authType"); 20 | uint8_t auth_type = nodemcujs_jval_as_number(jauthType); 21 | jerry_release_value(jauthType); 22 | jerry_value_t jquery = nodemcujs_jval_get_property(options, "query"); 23 | jerry_value_t jmethod = nodemcujs_jval_get_property(options, "method"); 24 | uint8_t method = nodemcujs_jval_as_number(jmethod); 25 | jerry_release_value(jmethod); 26 | jerry_value_t jtransportType = nodemcujs_jval_get_property(options, "transportType"); 27 | uint8_t transport_type = nodemcujs_jval_as_number(jtransportType); 28 | jerry_release_value(jtransportType); 29 | jerry_value_t jtimeout = nodemcujs_jval_get_property(options, "timeout"); 30 | 31 | esp_http_client_config_t cfg = { 32 | .url = nodemcujs_string_data(&url), 33 | .method = method, 34 | .transport_type = transport_type, 35 | .auth_type = auth_type 36 | }; 37 | 38 | nodemcujs_string_t query; 39 | if (jerry_value_is_string(jquery)) { 40 | query = nodemcujs_jval_as_string(jquery); 41 | cfg.query = nodemcujs_string_data(&query); 42 | } 43 | 44 | if (jerry_value_is_number(jtimeout)) { 45 | int timeout = nodemcujs_jval_as_number(jtimeout); 46 | cfg.timeout_ms = timeout; 47 | } 48 | jerry_release_value(jtimeout); 49 | 50 | esp_http_client_handle_t client = esp_http_client_init(&cfg); 51 | 52 | nodemcujs_string_destroy(&url); 53 | if (jerry_value_is_string(jquery)) { 54 | nodemcujs_string_destroy(&query); 55 | } 56 | jerry_release_value(jquery); 57 | 58 | jerry_set_object_native_pointer(jthis, client, &NativeInfoHttpClient); 59 | return jerry_create_undefined(); 60 | } 61 | 62 | JS_FUNCTION(Open) { 63 | esp_http_client_handle_t client; 64 | bool has_p = jerry_get_object_native_pointer(jthis, &client, &NativeInfoHttpClient); 65 | if (!has_p) { 66 | return jerry_create_error(JERRY_ERROR_REFERENCE, (jerry_char_t*)"The native http client is undefiend"); 67 | } 68 | 69 | int length = JS_GET_ARG(0, number); 70 | esp_err_t err = esp_http_client_open(client, length); 71 | return jerry_create_number(err); 72 | } 73 | 74 | JS_FUNCTION(Write) { 75 | esp_http_client_handle_t client; 76 | bool has_p = jerry_get_object_native_pointer(jthis, &client, &NativeInfoHttpClient); 77 | if (!has_p) { 78 | return jerry_create_error(JERRY_ERROR_REFERENCE, (jerry_char_t*)"The native http client is undefiend"); 79 | } 80 | 81 | nodemcujs_string_t data = JS_GET_ARG(0, string); 82 | int wlen = esp_http_client_write(client, nodemcujs_string_data(&data), nodemcujs_string_size(&data)); 83 | nodemcujs_string_destroy(&data); 84 | return jerry_create_number(wlen); 85 | } 86 | 87 | JS_FUNCTION(FetchHeaders) { 88 | esp_http_client_handle_t client; 89 | bool has_p = jerry_get_object_native_pointer(jthis, &client, &NativeInfoHttpClient); 90 | if (!has_p) { 91 | return jerry_create_error(JERRY_ERROR_REFERENCE, (jerry_char_t*)"The native http client is undefiend"); 92 | } 93 | 94 | int content_length = esp_http_client_fetch_headers(client); 95 | return jerry_create_number(content_length); 96 | } 97 | 98 | JS_FUNCTION(GetStatusCode) { 99 | esp_http_client_handle_t client; 100 | bool has_p = jerry_get_object_native_pointer(jthis, &client, &NativeInfoHttpClient); 101 | if (!has_p) { 102 | return jerry_create_error(JERRY_ERROR_REFERENCE, (jerry_char_t*)"The native http client is undefiend"); 103 | } 104 | 105 | int code = esp_http_client_get_status_code(client); 106 | return jerry_create_number(code); 107 | } 108 | 109 | JS_FUNCTION(Read) { 110 | esp_http_client_handle_t client; 111 | bool has_p = jerry_get_object_native_pointer(jthis, &client, &NativeInfoHttpClient); 112 | if (!has_p) { 113 | return jerry_create_error(JERRY_ERROR_REFERENCE, (jerry_char_t*)"The native http client is undefiend"); 114 | } 115 | 116 | uint32_t len = JS_GET_ARG(0, number); 117 | char *buffer = (char*)malloc(len + 1); 118 | if (buffer == NULL) { 119 | return jerry_create_error(JERRY_ERROR_RANGE, (jerry_char_t*)NODE_OUT_OF_MEMORY); 120 | } 121 | int rlen = esp_http_client_read(client, buffer, len); 122 | if (rlen < 0) { 123 | free(buffer); 124 | return jerry_create_number(rlen); 125 | } 126 | if (rlen == 0) { 127 | free(buffer); 128 | return jerry_create_string((jerry_char_t*)""); 129 | } 130 | buffer[rlen] = '\0'; 131 | jerry_value_t jstr = jerry_create_string((jerry_char_t*)buffer); 132 | free(buffer); 133 | return jstr; 134 | } 135 | 136 | JS_FUNCTION(Close) { 137 | esp_http_client_handle_t client; 138 | bool has_p = jerry_get_object_native_pointer(jthis, &client, &NativeInfoHttpClient); 139 | if (!has_p) { 140 | return jerry_create_error(JERRY_ERROR_REFERENCE, (jerry_char_t*)"The native http client is undefiend"); 141 | } 142 | 143 | esp_err_t err = esp_http_client_close(client); 144 | return jerry_create_number(err); 145 | } 146 | 147 | JS_FUNCTION(Cleanup) { 148 | esp_http_client_handle_t client; 149 | bool has_p = jerry_get_object_native_pointer(jthis, &client, &NativeInfoHttpClient); 150 | if (!has_p) { 151 | return jerry_create_error(JERRY_ERROR_REFERENCE, (jerry_char_t*)"The native http client is undefiend"); 152 | } 153 | 154 | esp_err_t err = esp_http_client_cleanup(client); 155 | NESP_CHECK_OK(err); 156 | jerry_set_object_native_pointer(jthis, NULL, &NativeInfoHttpClient); 157 | return jerry_create_number(err); 158 | } 159 | 160 | jerry_value_t nodemcujs_module_init_http_client() { 161 | jerry_value_t httpClient = jerry_create_object(); 162 | jerry_value_t jClientRequest = jerry_create_external_function(ClientRequest); 163 | jerry_value_t prototype = jerry_create_object(); 164 | 165 | nodemcujs_jval_set_method(prototype, "open", Open); 166 | nodemcujs_jval_set_method(prototype, "write", Write); 167 | nodemcujs_jval_set_method(prototype, "read", Read); 168 | nodemcujs_jval_set_method(prototype, "fetchHeaders", FetchHeaders); 169 | nodemcujs_jval_set_method(prototype, "getStatusCode", GetStatusCode); 170 | nodemcujs_jval_set_method(prototype, "close", Close); 171 | nodemcujs_jval_set_method(prototype, "cleanup", Cleanup); 172 | nodemcujs_jval_set_property_jval(jClientRequest, "prototype", prototype); 173 | nodemcujs_jval_set_property_jval(httpClient, "ClientRequest", jClientRequest); 174 | 175 | jerry_release_value(prototype); 176 | jerry_release_value(jClientRequest); 177 | return httpClient; 178 | } 179 | -------------------------------------------------------------------------------- /main/src/modules/nodemcujs_module_nvs_flash.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs.h" 2 | #include "nodemcujs_def.h" 3 | #include "nodemcujs_binding.h" 4 | 5 | #include "nvs_flash.h" 6 | #include "esp_err.h" 7 | 8 | JS_FUNCTION(Init) { 9 | esp_err_t err = nvs_flash_init(); 10 | if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { 11 | err = nvs_flash_erase(); 12 | NESP_CHECK_OK(err); 13 | err = nvs_flash_init(); 14 | NESP_CHECK_OK(err); 15 | } 16 | return jerry_create_number(ESP_OK); 17 | } 18 | 19 | jerry_value_t nodemcujs_module_init_nvs_flash() { 20 | jerry_value_t nvs_flash = jerry_create_object(); 21 | nodemcujs_jval_set_method(nvs_flash, "init", Init); 22 | return nvs_flash; 23 | } -------------------------------------------------------------------------------- /main/src/modules/nodemcujs_module_process.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs.h" 2 | #include "nodemcujs_js.h" 3 | #include "nodemcujs_def.h" 4 | #include "nodemcujs_string.h" 5 | #include "nodemcujs_module.h" 6 | #include "nodemcujs_binding.h" 7 | #include "nodemcujs_magic_strings.h" 8 | 9 | #include 10 | 11 | #include 12 | 13 | static jerry_value_t WrapEval(const char* name, size_t name_len, char* source, 14 | size_t length) { 15 | static const char* args = "exports, require, module, native, __filename, __dirname"; 16 | 17 | jerry_value_t res = 18 | jerry_parse_function((const jerry_char_t*)name, name_len, 19 | (const jerry_char_t*)args, strlen(args), 20 | (const jerry_char_t*)source, length, false); 21 | 22 | return res; 23 | } 24 | 25 | JS_FUNCTION(CompileModule) { 26 | jerry_value_t jmodule = JS_GET_ARG(0, object); 27 | jerry_value_t jrequire = JS_GET_ARG(1, function); 28 | 29 | jerry_value_t jid = nodemcujs_jval_get_property(jmodule, "id"); 30 | nodemcujs_string_t id = nodemcujs_jval_as_string(jid); 31 | jerry_release_value(jid); 32 | const char* name = nodemcujs_string_data(&id); 33 | 34 | int i = 0; 35 | while (js_modules[i].name != NULL) { 36 | if (!strcmp(js_modules[i].name, name)) { 37 | break; 38 | } 39 | 40 | i++; 41 | } 42 | 43 | jerry_value_t native_module_jval = nodemcujs_module_get(name); 44 | if (jerry_value_is_error(native_module_jval)) { 45 | return native_module_jval; 46 | } 47 | 48 | jerry_value_t jexports = nodemcujs_jval_get_property(jmodule, "exports"); 49 | jerry_value_t jres = jerry_create_undefined(); 50 | 51 | if (js_modules[i].name != NULL) { 52 | jres = WrapEval(name, nodemcujs_string_size(&id), (char*)js_modules[i].code, 53 | js_modules[i].length); 54 | if (!jerry_value_is_error(jres)) { 55 | jerry_value_t args[] = { jexports, jrequire, jmodule, 56 | native_module_jval }; 57 | 58 | jerry_value_t jfunc = jres; 59 | jres = jerry_call_function(jfunc, jerry_create_undefined(), args, 60 | sizeof(args) / sizeof(jerry_value_t)); 61 | jerry_release_value(jfunc); 62 | } 63 | } else if (!jerry_value_is_undefined(native_module_jval)) { 64 | nodemcujs_jval_set_property_jval(jmodule, "exports", native_module_jval); 65 | } else { 66 | jres = jerry_create_error(JERRY_ERROR_COMMON, (jerry_char_t*)"native module not found"); 67 | } 68 | 69 | jerry_release_value(jexports); 70 | nodemcujs_string_destroy(&id); 71 | return jres; 72 | } 73 | 74 | JS_FUNCTION(Compile) { 75 | nodemcujs_string_t path = JS_GET_ARG(0, string); 76 | const char* filename = nodemcujs_string_data(&path); 77 | 78 | size_t size = 0; 79 | jerry_char_t* script = jerry_port_read_source(filename, &size); 80 | 81 | if (script == NULL) { 82 | NLOG_ERR("No such file: %s", filename); 83 | return jerry_create_undefined(); 84 | } 85 | if (size == 0) { 86 | NLOG_ERR("Can not read file: %s", filename); 87 | return jerry_create_undefined(); 88 | } 89 | 90 | jerry_value_t jres = WrapEval(filename, strlen(filename), (char*)script, size); 91 | nodemcujs_string_destroy(&path); 92 | jerry_port_release_source(script); 93 | return jres; 94 | } 95 | 96 | JS_FUNCTION(Cwd) { 97 | return jerry_create_string_from_utf8((jerry_char_t*)"/"); 98 | } 99 | 100 | JS_FUNCTION(ReadSource) { 101 | nodemcujs_string_t path = JS_GET_ARG(0, string); 102 | const char* filename = nodemcujs_string_data(&path); 103 | 104 | size_t size = 0; 105 | jerry_char_t* source = jerry_port_read_source(filename, &size); 106 | 107 | if (source == NULL) { 108 | nodemcujs_string_destroy(&path); 109 | return jerry_create_error(JERRY_ERROR_COMMON, (jerry_char_t*)"ReadSource error, not a regular file"); 110 | } 111 | if (size == 0) { 112 | nodemcujs_string_destroy(&path); 113 | return jerry_create_string_from_utf8((jerry_char_t*)""); 114 | } 115 | 116 | jerry_value_t jres = jerry_create_string_from_utf8(source); 117 | nodemcujs_string_destroy(&path); 118 | jerry_port_release_source(source); 119 | 120 | return jres; 121 | } 122 | 123 | static void SetBuiltinModules(jerry_value_t builtin_modules) { 124 | for (unsigned i = 0; js_modules[i].name; i++) { 125 | nodemcujs_jval_set_property_jval(builtin_modules, js_modules[i].name, jerry_create_boolean(true)); 126 | } 127 | for (unsigned i = 0; i < nodemcujs_modules_count; i++) { 128 | nodemcujs_jval_set_property_jval(builtin_modules, nodemcujs_modules[i].name, jerry_create_boolean(true)); 129 | } 130 | } 131 | 132 | jerry_value_t nodemcujs_module_init_process() { 133 | jerry_value_t process = jerry_create_object(); 134 | nodemcujs_jval_set_method(process, NODEMCUJS_MAGIC_STRING_COMPILEMODULE, CompileModule); 135 | nodemcujs_jval_set_method(process, NODEMCUJS_MAGIC_STRING_COMPILE, Compile); 136 | nodemcujs_jval_set_method(process, NODEMCUJS_MAGIC_STRING_CWD, Cwd); 137 | nodemcujs_jval_set_string(process, "version", "v"NODEMCUJS_VERSION); 138 | 139 | jerry_value_t builtin_modules = jerry_create_object(); 140 | SetBuiltinModules(builtin_modules); 141 | nodemcujs_jval_set_property_jval(process, NODEMCUJS_MAGIC_STRING_BUILTIN_MODULES, builtin_modules); 142 | jerry_release_value(builtin_modules); 143 | 144 | nodemcujs_jval_set_method(process, NODEMCUJS_MAGIC_STRING_READSOURCE, ReadSource); 145 | 146 | return process; 147 | } -------------------------------------------------------------------------------- /main/src/modules/nodemcujs_module_rmt.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs.h" 2 | #include "nodemcujs_def.h" 3 | #include "nodemcujs_binding.h" 4 | #include "nodemcujs_magic_strings.h" 5 | 6 | #include "esp_attr.h" 7 | #include "driver/rmt.h" 8 | 9 | #include 10 | 11 | IRAM_ATTR rmt_item32_t PATTERN0 = {{{ 0, 0, 0, 0 }}}; 12 | IRAM_ATTR rmt_item32_t PATTERN1 = {{{ 0, 0, 0, 0 }}}; 13 | 14 | JS_FUNCTION(Setup) { 15 | uint8_t channel = JS_GET_ARG(0, number); 16 | uint8_t pin = JS_GET_ARG(1, number); 17 | jerry_value_t jconfig = JS_GET_ARG(2, object); 18 | jerry_value_t jclkDiv = nodemcujs_jval_get_property(jconfig, "clock_div"); 19 | uint8_t clkDiv = nodemcujs_jval_as_number(jclkDiv); 20 | jerry_release_value(jclkDiv); 21 | jerry_value_t jidleOutputEN = nodemcujs_jval_get_property(jconfig, "idle_output_en"); 22 | bool idleOutputEN = nodemcujs_jval_as_boolean(jidleOutputEN); 23 | jerry_release_value(idleOutputEN); 24 | 25 | rmt_config_t cfg = RMT_DEFAULT_CONFIG_TX(pin, channel); 26 | cfg.clk_div = clkDiv; 27 | cfg.tx_config.idle_output_en = idleOutputEN; 28 | rmt_config(&cfg); 29 | rmt_driver_install(cfg.channel, 0, 0); 30 | 31 | return jerry_create_boolean(true); 32 | } 33 | 34 | JS_FUNCTION(SetPattern) { 35 | uint8_t pattern = JS_GET_ARG(0, number); 36 | uint16_t t0 = JS_GET_ARG(1, number); 37 | uint8_t l0 = JS_GET_ARG(2, number); 38 | uint16_t t1 = JS_GET_ARG(3, number); 39 | uint8_t l1 = JS_GET_ARG(4, number); 40 | 41 | if (pattern == 0) { 42 | PATTERN0 = (rmt_item32_t){{{ t0, l0, t1, l1 }}}; 43 | } else { 44 | PATTERN1 = (rmt_item32_t){{{ t0, l0, t1, l1 }}}; 45 | } 46 | 47 | return jerry_create_boolean(true); 48 | } 49 | 50 | JS_FUNCTION(SendSync) { 51 | uint8_t channel = JS_GET_ARG(0, number); 52 | jerry_value_t data = JS_GET_ARG(1, array); 53 | 54 | jerry_value_t jlength = nodemcujs_jval_get_property(data, NODEMCUJS_MAGIC_STRING_LENGTH); 55 | int length = nodemcujs_jval_as_number(jlength); 56 | 57 | for (int i = 0; i < length; i++) { 58 | jerry_value_t jdata = jerry_get_property_by_index(data, i); 59 | uint8_t value = (uint8_t)nodemcujs_jval_as_number(jdata); 60 | jerry_release_value(jdata); 61 | for (size_t j = 0; j < 8; j++) { 62 | if ((value >> (7 - j)) & 0x01) { 63 | rmt_write_items(channel, &PATTERN1, 1, true); 64 | } else { 65 | rmt_write_items(channel, &PATTERN0, 1, true); 66 | } 67 | } 68 | } 69 | jerry_release_value(jlength); 70 | 71 | return jerry_create_boolean(true); 72 | } 73 | 74 | jerry_value_t nodemcujs_module_init_rmt() { 75 | jerry_value_t rmt = jerry_create_object(); 76 | nodemcujs_jval_set_method(rmt, "setup", Setup); 77 | nodemcujs_jval_set_method(rmt, "setPattern", SetPattern); 78 | nodemcujs_jval_set_method(rmt, "sendSync", SendSync); 79 | return rmt; 80 | } -------------------------------------------------------------------------------- /main/src/modules/nodemcujs_module_sigmadelta.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs.h" 2 | #include "nodemcujs_def.h" 3 | #include "nodemcujs_binding.h" 4 | 5 | #include "esp_system.h" 6 | #include "esp_attr.h" 7 | #include "driver/sigmadelta.h" 8 | 9 | JS_FUNCTION(Setup) { 10 | uint8_t channel = JS_GET_ARG(0, number); 11 | int8_t duty = JS_GET_ARG(1, number); 12 | uint8_t prescale = JS_GET_ARG(2, number); 13 | uint8_t gpio = JS_GET_ARG(3, number); 14 | 15 | sigmadelta_config_t cfg = { 16 | .channel = channel, 17 | .sigmadelta_duty = duty, 18 | .sigmadelta_prescale = prescale, 19 | .sigmadelta_gpio = gpio 20 | }; 21 | esp_err_t ret = sigmadelta_config(&cfg); 22 | if (ret != ESP_OK) { 23 | return jerry_create_boolean(false); 24 | } 25 | return jerry_create_boolean(true); 26 | } 27 | 28 | JS_FUNCTION(SetDuty) { 29 | uint8_t channel = JS_GET_ARG(0, number); 30 | int8_t duty = JS_GET_ARG(1, number); 31 | esp_err_t ret = sigmadelta_set_duty(channel, duty); 32 | if (ret != ESP_OK) { 33 | return jerry_create_boolean(false); 34 | } 35 | return jerry_create_boolean(true); 36 | } 37 | 38 | jerry_value_t nodemcujs_module_init_sigmadelta() { 39 | jerry_value_t sigmadelta = jerry_create_object(); 40 | nodemcujs_jval_set_method(sigmadelta, "setup", Setup); 41 | nodemcujs_jval_set_method(sigmadelta, "setDuty", SetDuty); 42 | return sigmadelta; 43 | } 44 | -------------------------------------------------------------------------------- /main/src/modules/nodemcujs_module_spi_master.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs.h" 2 | #include "nodemcujs_def.h" 3 | #include "nodemcujs_binding.h" 4 | #include "nodemcujs_magic_strings.h" 5 | 6 | #include "esp_system.h" 7 | #include "esp_attr.h" 8 | #include "driver/gpio.h" 9 | #include "driver/spi_master.h" 10 | 11 | #include 12 | 13 | typedef struct nodemcujs_spi_device_handle { 14 | uint8_t pinDC; 15 | uint8_t activeDC; 16 | spi_device_handle_t spi; 17 | } nodemcujs_spi_device_handle_t; 18 | 19 | typedef struct nodemcujs_spi_transaction_context { 20 | uint8_t DC; 21 | uint8_t RW; 22 | nodemcujs_spi_device_handle_t *device; 23 | } nodemcujs_spi_transaction_context_t; 24 | 25 | nodemcujs_spi_device_handle_t spi2 = { -1, 1, NULL}; 26 | 27 | void IRAM_ATTR spiTransferCallbackPRE(spi_transaction_t *t) { 28 | nodemcujs_spi_transaction_context_t *transaction = (nodemcujs_spi_transaction_context_t*)t->user; 29 | gpio_set_level(transaction->device->pinDC, transaction->DC ? transaction->device->activeDC : transaction->device->activeDC ? 0 : 1); 30 | } 31 | 32 | void IRAM_ATTR spiTransferCallbackPOST(spi_transaction_t *t) { 33 | nodemcujs_spi_transaction_context_t *transaction = (nodemcujs_spi_transaction_context_t*)t->user; 34 | if (transaction->RW == 1) { 35 | free((void*)t->tx_buffer); 36 | } 37 | free(transaction); 38 | free(t); 39 | } 40 | 41 | JS_FUNCTION(SendSync) { 42 | int id = JS_GET_ARG(0, number); 43 | int dc = JS_GET_ARG(1, number); 44 | jerry_value_t data = JS_GET_ARG(2, array); 45 | 46 | jerry_value_t jlength = nodemcujs_jval_get_property(data, NODEMCUJS_MAGIC_STRING_LENGTH); 47 | int length = nodemcujs_jval_as_number(jlength); 48 | uint8_t *buffer = (uint8_t*)malloc(length); 49 | NODEMCUJS_ASSERT(buffer != NULL); 50 | 51 | for (int i = 0; i < length; i++) { 52 | jerry_value_t jdata = jerry_get_property_by_index(data, i); 53 | buffer[i] = (uint8_t)nodemcujs_jval_as_number(jdata); 54 | jerry_release_value(jdata); 55 | } 56 | jerry_release_value(jlength); 57 | 58 | spi_transaction_t *t = (spi_transaction_t*)malloc(sizeof(spi_transaction_t)); 59 | NODEMCUJS_ASSERT(t != NULL); 60 | memset(t, 0, sizeof(spi_transaction_t)); 61 | t->length = length * 8; 62 | t->tx_buffer = buffer; 63 | 64 | esp_err_t ret; 65 | if (id == 2) { 66 | nodemcujs_spi_transaction_context_t *transaction = (nodemcujs_spi_transaction_context_t*)malloc(sizeof(nodemcujs_spi_transaction_context_t)); 67 | transaction->DC = dc; 68 | transaction->RW = 1; 69 | transaction->device = &spi2; 70 | t->user = (void*)transaction; 71 | ret = spi_device_polling_transmit(spi2.spi, t); 72 | if (ret != ESP_OK) { 73 | ESP_ERROR_CHECK(ret); 74 | return jerry_create_boolean(false); 75 | } 76 | return jerry_create_boolean(true); 77 | } 78 | return jerry_create_error(JERRY_ERROR_RANGE, (jerry_char_t*)"SPI Host not found"); 79 | } 80 | 81 | JS_FUNCTION(Setup) { 82 | int id = JS_GET_ARG(0, number); 83 | jerry_value_t spiConfig = JS_GET_ARG(1, object); 84 | jerry_value_t jpinMOSI = nodemcujs_jval_get_property(spiConfig, "pinMOSI"); 85 | int pinMOSI = nodemcujs_jval_as_number(jpinMOSI); 86 | jerry_release_value(jpinMOSI); 87 | jerry_value_t jpinMISO = nodemcujs_jval_get_property(spiConfig, "pinMISO"); 88 | int pinMISO = nodemcujs_jval_as_number(jpinMISO); 89 | jerry_release_value(jpinMISO); 90 | jerry_value_t jpinCLK = nodemcujs_jval_get_property(spiConfig, "pinCLK"); 91 | int pinCLK = nodemcujs_jval_as_number(jpinCLK); 92 | jerry_release_value(jpinCLK); 93 | jerry_value_t jmaxTransferSize = nodemcujs_jval_get_property(spiConfig, "maxTransferSize"); 94 | int maxTransferSize = nodemcujs_jval_as_number(jmaxTransferSize); 95 | jerry_release_value(jmaxTransferSize); 96 | 97 | jerry_value_t jclockHz = nodemcujs_jval_get_property(spiConfig, "clockHz"); 98 | int clockHz = nodemcujs_jval_as_number(jclockHz); 99 | jerry_release_value(jclockHz); 100 | jerry_value_t jmode = nodemcujs_jval_get_property(spiConfig, "mode"); 101 | int mode = nodemcujs_jval_as_number(jmode); 102 | jerry_release_value(jmode); 103 | jerry_value_t jpinCS = nodemcujs_jval_get_property(spiConfig, "pinCS"); 104 | int pinCS = nodemcujs_jval_as_number(jpinCS); 105 | jerry_release_value(jpinCS); 106 | jerry_value_t jpinDC = nodemcujs_jval_get_property(spiConfig, "pinDC"); 107 | jerry_value_t jactiveDC = nodemcujs_jval_get_property(spiConfig, "activeDC"); 108 | if (id == 2) { 109 | spi2.pinDC = nodemcujs_jval_as_number(jpinDC); 110 | spi2.activeDC = nodemcujs_jval_as_number(jactiveDC); 111 | gpio_set_direction(spi2.pinDC, GPIO_MODE_OUTPUT); 112 | } 113 | jerry_release_value(jpinDC); 114 | jerry_release_value(jactiveDC); 115 | 116 | spi_bus_config_t buscfg = { 117 | .mosi_io_num = pinMOSI, 118 | .miso_io_num = pinMISO, 119 | .sclk_io_num = pinCLK, 120 | .quadhd_io_num = -1, 121 | .quadwp_io_num = -1, 122 | .max_transfer_sz = maxTransferSize 123 | }; 124 | spi_device_interface_config_t devcfg = { 125 | .clock_speed_hz = clockHz, 126 | .mode = mode, 127 | .spics_io_num = pinCS, 128 | .queue_size = 10, 129 | .pre_cb = spiTransferCallbackPRE, 130 | .post_cb = spiTransferCallbackPOST 131 | }; 132 | 133 | esp_err_t ret; 134 | if (id == 2) { 135 | ret = spi_bus_initialize(HSPI_HOST, &buscfg, SPI_DMA_CH2); 136 | ESP_ERROR_CHECK(ret); 137 | if (ret != ESP_OK) { 138 | return jerry_create_boolean(false); 139 | } 140 | ret = spi_bus_add_device(HSPI_HOST, &devcfg, &spi2.spi); 141 | ESP_ERROR_CHECK(ret); 142 | if (ret != ESP_OK) { 143 | return jerry_create_boolean(false); 144 | } 145 | return jerry_create_boolean(true); 146 | } 147 | return jerry_create_error(JERRY_ERROR_RANGE, (jerry_char_t*)"SPI Host not found"); 148 | } 149 | 150 | jerry_value_t nodemcujs_module_init_spi_master() { 151 | jerry_value_t spi_master = jerry_create_object(); 152 | nodemcujs_jval_set_method(spi_master, "setup", Setup); 153 | nodemcujs_jval_set_method(spi_master, "sendSync", SendSync); 154 | return spi_master; 155 | } -------------------------------------------------------------------------------- /main/src/modules/nodemcujs_module_timers.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs.h" 2 | #include "nodemcujs_binding.h" 3 | #include "nodemcujs_magic_strings.h" 4 | 5 | #include "clist.h" 6 | 7 | #include "freertos/FreeRTOS.h" 8 | #include "freertos/timers.h" 9 | #include "freertos/task.h" 10 | 11 | #include "jerryscript-ext/handler.h" 12 | 13 | clist_t *timerIdList; 14 | uint8_t timerId = 0; 15 | 16 | typedef struct jerry_timer_t 17 | { 18 | jerry_value_t funcObj; 19 | uint8_t timerId; 20 | TimerHandle_t timerHandler; 21 | bool repeat; 22 | } jerry_timer_t; 23 | 24 | static void timeout_callback(TimerHandle_t pxTimer) 25 | { 26 | list_node_t *node; 27 | jerry_timer_t *timer = NULL; 28 | list_iterator_t *it = list_iterator_new(timerIdList, LIST_HEAD); 29 | while ((node = list_iterator_next(it))) 30 | { 31 | timer = (jerry_timer_t *)node->val; 32 | if (timer->timerId == (uint8_t)pvTimerGetTimerID(pxTimer)) 33 | { 34 | jerry_call_function(timer->funcObj, NULL, NULL, 0); 35 | if (!timer->repeat) 36 | { 37 | jerry_release_value(timer->funcObj); 38 | xTimerStop(timer->timerHandler, NULL); 39 | xTimerDelete(timer->timerHandler, NULL); 40 | free(timer); 41 | list_remove(timerIdList, node); 42 | } 43 | break; 44 | } 45 | } 46 | list_iterator_destroy(it); 47 | } 48 | 49 | JS_FUNCTION(SetIntervalHandler) { 50 | jerry_value_t jscallback = JS_GET_ARG(0, function); 51 | TickType_t interval = (TickType_t)JS_GET_ARG(1, number); 52 | 53 | if (timerId == 0) 54 | { 55 | timerId = 1; 56 | } 57 | jerry_timer_t *timer = (jerry_timer_t *)malloc(sizeof(struct jerry_timer_t)); 58 | timer->repeat = true; 59 | // Acquire types with reference counter (increase the references). 60 | timer->funcObj = jerry_acquire_value(jscallback); 61 | timer->timerId = timerId; 62 | 63 | TimerHandle_t timerHandler = xTimerCreate("jtmr", interval / portTICK_PERIOD_MS, pdTRUE, (void *)timer->timerId, timeout_callback); 64 | timer->timerHandler = timerHandler; 65 | 66 | list_node_t *node = list_node_new(timer); 67 | 68 | list_rpush(timerIdList, node); 69 | 70 | xTimerStart(timerHandler, NULL); 71 | 72 | return jerry_create_number(timerId++); 73 | } 74 | 75 | JS_FUNCTION(SetTimeoutHandler) { 76 | jerry_value_t jscallback = JS_GET_ARG(0, function); 77 | TickType_t timeout = (TickType_t)JS_GET_ARG(1, number); 78 | 79 | if (timerId == 0) 80 | { 81 | timerId = 1; 82 | } 83 | jerry_timer_t *timer = (jerry_timer_t *)malloc(sizeof(struct jerry_timer_t)); 84 | timer->repeat = false; 85 | // Acquire types with reference counter (increase the references). 86 | timer->funcObj = jerry_acquire_value(jscallback); 87 | timer->timerId = timerId; 88 | 89 | TimerHandle_t timerHandler = xTimerCreate("jtmr", timeout / portTICK_PERIOD_MS, pdTRUE, (void *)timer->timerId, timeout_callback); 90 | timer->timerHandler = timerHandler; 91 | 92 | list_node_t *node = list_node_new(timer); 93 | 94 | list_rpush(timerIdList, node); 95 | 96 | xTimerStart(timerHandler, NULL); 97 | 98 | return jerry_create_number(timerId++); 99 | } 100 | 101 | JS_FUNCTION(ClearTimerHandler) { 102 | uint8_t id = (uint8_t)JS_GET_ARG(0, number); 103 | 104 | list_node_t *node; 105 | jerry_timer_t *timer; 106 | list_iterator_t *it = list_iterator_new(timerIdList, LIST_HEAD); 107 | while ((node = list_iterator_next(it))) 108 | { 109 | timer = (jerry_timer_t *)node->val; 110 | if (timer->timerId == id) 111 | { 112 | jerry_release_value(timer->funcObj); 113 | xTimerStop(timer->timerHandler, NULL); 114 | xTimerDelete(timer->timerHandler, NULL); 115 | free(timer); 116 | list_remove(timerIdList, node); 117 | break; 118 | } 119 | } 120 | list_iterator_destroy(it); 121 | return jerry_create_undefined(); 122 | } 123 | 124 | JS_FUNCTION(Delay) { 125 | TickType_t delay = JS_GET_ARG(0, number); 126 | vTaskDelay(delay / portTICK_PERIOD_MS); 127 | return jerry_create_boolean(true); 128 | } 129 | 130 | jerry_value_t nodemcujs_module_init_timers() 131 | { 132 | timerIdList = list_new(); 133 | 134 | jerry_value_t timer = jerry_create_object(); 135 | 136 | nodemcujs_jval_set_method(timer, "setInterval", SetIntervalHandler); 137 | nodemcujs_jval_set_method(timer, NODEMCUJS_MAGIC_STRING_SETTIMEOUT, SetTimeoutHandler); 138 | nodemcujs_jval_set_method(timer, "clearInterval", ClearTimerHandler); 139 | nodemcujs_jval_set_method(timer, "clearTimeout", ClearTimerHandler); 140 | nodemcujs_jval_set_method(timer, "delay", Delay); 141 | 142 | return timer; 143 | } -------------------------------------------------------------------------------- /main/src/modules/nodemcujs_module_wifi.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "nodemcujs.h" 4 | #include "nodemcujs_def.h" 5 | #include "nodemcujs_string.h" 6 | #include "nodemcujs_binding.h" 7 | 8 | #include "esp_event.h" 9 | #include "esp_wifi.h" 10 | 11 | #include "freertos/FreeRTOS.h" 12 | #include "freertos/task.h" 13 | 14 | #include "esp_err.h" 15 | 16 | static jerry_value_t JS_EVENT_CB = NULL; 17 | 18 | static void event_handler(void* arg, esp_event_base_t base, int32_t id, void* data) { 19 | if (!JS_EVENT_CB) { 20 | return; 21 | } 22 | 23 | jerry_value_t jdata = jerry_create_object(); 24 | jerry_value_t args[] = { 25 | jerry_create_string((jerry_char_t*)base), 26 | jerry_create_number(id), 27 | jdata 28 | }; 29 | 30 | if (base == IP_EVENT) { 31 | if (id == IP_EVENT_STA_GOT_IP) { 32 | ip_event_got_ip_t* event = (ip_event_got_ip_t*) data; 33 | char ip[16]; 34 | char netmask[16]; 35 | char gw[16]; 36 | uint8_t ip_len = sprintf(ip, IPSTR, IP2STR(&event->ip_info.ip)); 37 | uint8_t netmask_len = sprintf(netmask, IPSTR, IP2STR(&event->ip_info.netmask)); 38 | uint8_t gw_len = sprintf(gw, IPSTR, IP2STR(&event->ip_info.gw)); 39 | ip[ip_len] = '\0'; 40 | netmask[netmask_len] = '\0'; 41 | gw[gw_len] = '\0'; 42 | 43 | nodemcujs_jval_set_property_jval(jdata, "ip_changed", jerry_create_boolean(event->ip_changed)); 44 | nodemcujs_jval_set_property_jval(jdata, "ip", jerry_create_string((jerry_char_t*)ip)); 45 | nodemcujs_jval_set_property_jval(jdata, "netmask", jerry_create_string((jerry_char_t*)netmask)); 46 | nodemcujs_jval_set_property_jval(jdata, "gw", jerry_create_string((jerry_char_t*)gw)); 47 | } 48 | } 49 | 50 | if (base == WIFI_EVENT) { 51 | 52 | } 53 | 54 | jerry_call_function(JS_EVENT_CB, NULL, args, 3); 55 | } 56 | 57 | JS_FUNCTION(Init) { 58 | uint8_t mode = JS_GET_ARG(0, number); 59 | 60 | esp_err_t err = esp_netif_init(); 61 | NESP_CHECK_OK(err); 62 | err = esp_event_loop_create_default(); 63 | NESP_CHECK_OK(err); 64 | 65 | // STA 66 | if (mode == 1) { 67 | esp_netif_create_default_wifi_sta(); 68 | } else if (mode == 2) { 69 | esp_netif_create_default_wifi_ap(); 70 | } else { 71 | return jerry_create_error(JERRY_ERROR_RANGE, (jerry_char_t*)"Unsupported WIFI Mode"); 72 | } 73 | 74 | wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); 75 | err = esp_wifi_init(&cfg); 76 | NESP_CHECK_OK(err); 77 | 78 | return jerry_create_number(ESP_OK); 79 | } 80 | 81 | JS_FUNCTION(SetMode) { 82 | wifi_mode_t mode = JS_GET_ARG(0, number); 83 | esp_err_t err = esp_wifi_set_mode(mode); 84 | 85 | return jerry_create_number(err); 86 | } 87 | 88 | JS_FUNCTION(setConfig) { 89 | uint8_t mode = JS_GET_ARG(0, number); 90 | jerry_value_t config = JS_GET_ARG(1, object); 91 | jerry_value_t jssid = nodemcujs_jval_get_property(config, "ssid"); 92 | nodemcujs_string_t ssid = nodemcujs_jval_as_string(jssid); 93 | jerry_release_value(jssid); 94 | jerry_value_t jpass = nodemcujs_jval_get_property(config, "password"); 95 | nodemcujs_string_t pass = nodemcujs_jval_as_string(jpass); 96 | jerry_release_value(jpass); 97 | jerry_value_t jauth = nodemcujs_jval_get_property(config, "auth"); 98 | uint8_t auth = nodemcujs_jval_as_number(jauth); 99 | jerry_release_value(jauth); 100 | 101 | wifi_interface_t interface = WIFI_IF_STA; 102 | wifi_config_t cfg = {}; 103 | 104 | if (mode == 1) { 105 | wifi_sta_config_t sta = { 106 | .threshold = { 107 | .authmode = auth 108 | }, 109 | .pmf_cfg = { 110 | .capable = true, 111 | .required = false 112 | }, 113 | }; 114 | strcpy((char*)sta.ssid, nodemcujs_string_data(&ssid)); 115 | strcpy((char*)sta.password, nodemcujs_string_data(&pass)); 116 | cfg.sta = sta; 117 | } else if (mode == 2) { 118 | interface = WIFI_IF_AP; 119 | wifi_ap_config_t ap = { 120 | .ssid_len = nodemcujs_string_size(&ssid), 121 | .max_connection = 4, 122 | .authmode = auth 123 | }; 124 | strcpy((char*)ap.ssid, nodemcujs_string_data(&ssid)); 125 | strcpy((char*)ap.password, nodemcujs_string_data(&pass)); 126 | cfg.ap = ap; 127 | } 128 | 129 | nodemcujs_string_destroy(&ssid); 130 | nodemcujs_string_destroy(&pass); 131 | 132 | esp_err_t err = esp_wifi_set_config(interface, &cfg); 133 | 134 | return jerry_create_number(err); 135 | } 136 | 137 | JS_FUNCTION(Start) { 138 | esp_err_t err = esp_wifi_start(); 139 | 140 | return jerry_create_number(err); 141 | } 142 | 143 | JS_FUNCTION(SetEventListener) { 144 | jerry_value_t jsFunc = JS_GET_ARG(0, function); 145 | JS_EVENT_CB = jerry_acquire_value(jsFunc); 146 | 147 | return jerry_create_boolean(true); 148 | } 149 | 150 | JS_FUNCTION(AddListenEvent) { 151 | uint8_t code = JS_GET_ARG(0, number); 152 | esp_event_base_t base; 153 | 154 | switch (code) 155 | { 156 | case 1: 157 | base = WIFI_EVENT; 158 | break; 159 | case 2: 160 | base = IP_EVENT; 161 | break; 162 | default: 163 | return jerry_create_error(JERRY_ERROR_RANGE, (jerry_char_t*)"Unknow event id"); 164 | break; 165 | } 166 | 167 | esp_err_t err = esp_event_handler_instance_register( 168 | base, 169 | ESP_EVENT_ANY_ID, 170 | &event_handler, 171 | NULL, 172 | NULL 173 | ); 174 | 175 | return jerry_create_number(err); 176 | } 177 | 178 | JS_FUNCTION(Connect) { 179 | esp_err_t err = esp_wifi_connect(); 180 | return jerry_create_number(err); 181 | } 182 | 183 | JS_FUNCTION(ScanASync) { 184 | jerry_value_t config = JS_GET_ARG(0, object); 185 | 186 | jerry_value_t jchannel = nodemcujs_jval_get_property(config, "channel"); 187 | uint8_t channel = nodemcujs_jval_as_number(jchannel); 188 | jerry_release_value(jchannel); 189 | 190 | jerry_value_t jshowHidden = nodemcujs_jval_get_property(config, "showHidden"); 191 | bool show_hidden = nodemcujs_jval_as_boolean(jshowHidden); 192 | jerry_release_value(jshowHidden); 193 | 194 | jerry_value_t jscanType = nodemcujs_jval_get_property(config, "scanType"); 195 | uint8_t scan_type = nodemcujs_jval_as_number(jscanType); 196 | jerry_release_value(jscanType); 197 | 198 | wifi_scan_config_t cfg = { 199 | .ssid = NULL, 200 | .bssid = NULL, 201 | .channel = channel, 202 | .show_hidden = show_hidden, 203 | .scan_type = scan_type, 204 | .scan_time = { 205 | .passive = 120, 206 | .active = { 207 | .max = 0, 208 | .min = 0 209 | } 210 | } 211 | }; 212 | esp_err_t err = esp_wifi_scan_start(&cfg, false); 213 | NESP_CHECK_OK(err); 214 | vTaskDelay(13 * 120 / portTICK_PERIOD_MS); 215 | 216 | uint16_t apCount = 0; 217 | err = esp_wifi_scan_get_ap_num(&apCount); 218 | NESP_CHECK_OK(err); 219 | wifi_ap_record_t apInfos[apCount]; 220 | err = esp_wifi_scan_get_ap_records(&apCount, apInfos); 221 | NESP_CHECK_OK(err); 222 | jerry_value_t jarr = jerry_create_array(apCount); 223 | for (uint16_t i = 0; i < apCount; i++) 224 | { 225 | jerry_value_t japInfo = jerry_create_object(); 226 | wifi_ap_record_t apInfo = apInfos[i]; 227 | nodemcujs_jval_set_string(japInfo, "ssid", (char*)apInfo.ssid); 228 | nodemcujs_jval_set_string(japInfo, "bssid", (char*)apInfo.bssid); 229 | nodemcujs_jval_set_property_jval(japInfo, "rssi", jerry_create_number(apInfo.rssi)); 230 | jerry_set_property_by_index(jarr, i, japInfo); 231 | } 232 | 233 | return jarr; 234 | } 235 | 236 | jerry_value_t nodemcujs_module_init_wifi() { 237 | jerry_value_t wifi = jerry_create_object(); 238 | nodemcujs_jval_set_method(wifi, "init", Init); 239 | nodemcujs_jval_set_method(wifi, "setMode", SetMode); 240 | nodemcujs_jval_set_method(wifi, "setConfig", setConfig); 241 | nodemcujs_jval_set_method(wifi, "start", Start); 242 | nodemcujs_jval_set_method(wifi, "setEventListener", SetEventListener); 243 | nodemcujs_jval_set_method(wifi, "addListenEvent", AddListenEvent); 244 | nodemcujs_jval_set_method(wifi, "connect", Connect); 245 | nodemcujs_jval_set_method(wifi, "scanASync", ScanASync); 246 | return wifi; 247 | } 248 | -------------------------------------------------------------------------------- /main/src/nodemcujs.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs_binding.h" 2 | #include "nodemcujs_js.h" 3 | #include "nodemcujs_def.h" 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | static bool nodemcujs_init_jerry() { 11 | jerry_init(JERRY_INIT_EMPTY); 12 | return true; 13 | } 14 | 15 | static bool nodemcujs_run() { 16 | bool throws = false; 17 | jerry_value_t jmain = nodemcujs_jhelper_eval("nodemcujs.js", strlen("nodemcujs.js"), 18 | nodemcujs_s, nodemcujs_l, false, &throws); 19 | 20 | if (throws) { 21 | jerry_value_t error = jerry_get_value_from_error(jmain, false); 22 | jerry_value_t message = jerry_value_to_string (error); 23 | jerry_size_t size = jerry_get_string_size (message); 24 | jerry_char_t buffer[size]; 25 | jerry_string_to_utf8_char_buffer(message, buffer, size); 26 | buffer[size] = '\0'; 27 | NLOG_ERR("Script Error: %s", (char*)buffer); 28 | jerry_release_value(error); 29 | jerry_release_value(message); 30 | } 31 | 32 | jerry_release_value(jmain); 33 | return !throws; 34 | } 35 | 36 | static int nodemcujs_start() { 37 | const jerry_value_t global = jerry_get_global_object(); 38 | const jerry_value_t process = nodemcujs_module_get("process"); 39 | nodemcujs_jval_set_property_jval(global, "process", process); 40 | 41 | jerry_release_value(global); 42 | 43 | nodemcujs_run(); 44 | return 0; 45 | } 46 | 47 | int nodemcujs_entry() { 48 | nodemcujs_init_jerry(); 49 | 50 | int ret_code = nodemcujs_start(); 51 | return ret_code; 52 | } 53 | -------------------------------------------------------------------------------- /main/src/nodemcujs_binding.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs_binding.h" 2 | #include "nodemcujs_def.h" 3 | 4 | #include 5 | 6 | bool nodemcujs_jval_as_boolean(jerry_value_t jval) { 7 | return jerry_get_boolean_value(jval); 8 | } 9 | 10 | double nodemcujs_jval_as_number(jerry_value_t jval) { 11 | return jerry_get_number_value(jval); 12 | } 13 | 14 | jerry_value_t nodemcujs_jval_as_object(jerry_value_t jval) { 15 | return jval; 16 | } 17 | 18 | jerry_value_t nodemcujs_jval_as_array(jerry_value_t jval) { 19 | return jval; 20 | } 21 | 22 | jerry_value_t nodemcujs_jval_as_function(jerry_value_t jval) { 23 | return jval; 24 | } 25 | 26 | nodemcujs_string_t nodemcujs_jval_as_string(jerry_value_t jval) { 27 | NODEMCUJS_ASSERT(jerry_value_is_string(jval)); 28 | jerry_size_t size = jerry_get_utf8_string_size(jval); 29 | if (size == 0) { 30 | return nodemcujs_string_create(); 31 | } 32 | char* buffer = malloc(size + 1); 33 | jerry_char_t* str = (jerry_char_t*)(buffer); 34 | size_t check = jerry_string_to_utf8_char_buffer(jval, str, size); 35 | NODEMCUJS_ASSERT(size == check); 36 | buffer[size] = '\0'; 37 | 38 | nodemcujs_string_t res = nodemcujs_string_create_with_buffer(buffer, size); 39 | return res; 40 | } 41 | 42 | void nodemcujs_jval_set_property_jval(jerry_value_t jobj, const char* name, 43 | jerry_value_t value) { 44 | jerry_value_t prop_name = jerry_create_string((const jerry_char_t*)(name)); 45 | jerry_value_t ret_val = jerry_set_property(jobj, prop_name, value); 46 | jerry_release_value(prop_name); 47 | 48 | jerry_release_value(ret_val); 49 | } 50 | 51 | void nodemcujs_jval_set_method(jerry_value_t jobj, const char* name, 52 | jerry_external_handler_t handler) { 53 | jerry_value_t jfunc = jerry_create_external_function(handler); 54 | nodemcujs_jval_set_property_jval(jobj, name, jfunc); 55 | jerry_release_value(jfunc); 56 | } 57 | 58 | void nodemcujs_jval_set_string(jerry_value_t jobj, const char* name, const char* value) { 59 | jerry_value_t jval = jerry_create_string((jerry_char_t*)value); 60 | nodemcujs_jval_set_property_jval(jobj, name, jval); 61 | jerry_release_value(jval); 62 | } 63 | 64 | jerry_value_t nodemcujs_jhelper_eval(const char* name, size_t name_len, 65 | const uint8_t* data, size_t size, 66 | bool strict_mode, bool* throws) { 67 | jerry_value_t res = 68 | jerry_parse((const jerry_char_t*)name, name_len, 69 | (const jerry_char_t*)data, size, 70 | strict_mode ? JERRY_PARSE_STRICT_MODE : JERRY_PARSE_NO_OPTS); 71 | 72 | *throws = jerry_value_is_error(res); 73 | 74 | if (!*throws) { 75 | jerry_value_t func = res; 76 | res = jerry_run(func); 77 | jerry_release_value(func); 78 | 79 | *throws = jerry_value_is_error(res); 80 | } 81 | 82 | return res; 83 | } 84 | 85 | jerry_value_t nodemcujs_jval_get_property(jerry_value_t jobj, const char* name) { 86 | NODEMCUJS_ASSERT(jerry_value_is_object(jobj)); 87 | 88 | jerry_value_t prop_name = jerry_create_string((const jerry_char_t*)(name)); 89 | jerry_value_t res = jerry_get_property(jobj, prop_name); 90 | jerry_release_value(prop_name); 91 | 92 | if (jerry_value_is_error(res)) { 93 | jerry_release_value(res); 94 | return jerry_acquire_value(jerry_create_undefined()); 95 | } 96 | 97 | return res; 98 | } -------------------------------------------------------------------------------- /main/src/nodemcujs_binding.h: -------------------------------------------------------------------------------- 1 | #ifndef NODEMCUJS_BINDING_H 2 | #define NODEMCUJS_BINDING_H 3 | 4 | #include "nodemcujs_string.h" 5 | 6 | #include 7 | 8 | #include 9 | 10 | 11 | #define JS_FUNCTION(name) \ 12 | static jerry_value_t name(const jerry_value_t jfunc, \ 13 | const jerry_value_t jthis, \ 14 | const jerry_value_t jargv[], \ 15 | const jerry_length_t jargc) 16 | 17 | /* Type Converters */ 18 | bool nodemcujs_jval_as_boolean(jerry_value_t); 19 | double nodemcujs_jval_as_number(jerry_value_t); 20 | jerry_value_t nodemcujs_jval_as_object(jerry_value_t); 21 | jerry_value_t nodemcujs_jval_as_array(jerry_value_t); 22 | jerry_value_t nodemcujs_jval_as_function(jerry_value_t); 23 | nodemcujs_string_t nodemcujs_jval_as_string(jerry_value_t); 24 | 25 | void nodemcujs_jval_set_property_jval(jerry_value_t jobj, const char* name, 26 | jerry_value_t value); 27 | 28 | jerry_value_t nodemcujs_jval_get_property(jerry_value_t jobj, const char* name); 29 | 30 | void nodemcujs_jval_set_method(jerry_value_t jobj, const char* name, 31 | jerry_external_handler_t handler); 32 | 33 | void nodemcujs_jval_set_string(jerry_value_t jobj, const char* name, const char* value); 34 | 35 | // Evaluates javascript source file. 36 | jerry_value_t nodemcujs_jhelper_eval(const char* name, size_t name_len, 37 | const uint8_t* data, size_t size, 38 | bool strict_mode, bool* throws); 39 | 40 | #define JS_GET_ARG(index, type) nodemcujs_jval_as_##type(jargv[index]) 41 | 42 | #endif -------------------------------------------------------------------------------- /main/src/nodemcujs_def.h: -------------------------------------------------------------------------------- 1 | #ifndef NODEMCUJS_DEF_H 2 | #define NODEMCUJS_DEF_H 3 | 4 | #include "nodemcujs_utils.h" 5 | 6 | #include 7 | 8 | #define STRINGIFY(x) #x 9 | 10 | #define TOSTRING(x) STRINGIFY(x) 11 | 12 | // #ifndef NODE_MAJOR_VERSION 13 | #define NODE_MAJOR_VERSION 0 14 | // #endif 15 | // #ifndef NODE_MINOR_VERSION 16 | #define NODE_MINOR_VERSION 0 17 | // #endif 18 | // #ifndef NODE_PATCH_VERSION 19 | #define NODE_PATCH_VERSION 0 20 | // #endif 21 | 22 | #define NODEMCUJS_VERSION \ 23 | TOSTRING(NODE_MAJOR_VERSION)"." \ 24 | TOSTRING(NODE_MINOR_VERSION)"." \ 25 | TOSTRING(NODE_PATCH_VERSION) 26 | 27 | #define NODE_OUT_OF_MEMORY "OOM" 28 | 29 | // works for gcc and IAR's compiler 30 | #define NLOG_ERR(message, ...) \ 31 | printf("%s:%d: "message"\n", __FILE__, __LINE__, ## __VA_ARGS__) 32 | 33 | #define NODEMCUJS_ASSERT(x) \ 34 | do { \ 35 | if (!(x)) { \ 36 | NLOG_ERR("%s:%d: Assertion '%s' failed.\n", __FILE__, __LINE__, \ 37 | #x); \ 38 | force_terminate(); \ 39 | } \ 40 | } while (0) 41 | 42 | #endif 43 | 44 | #define NESP_CHECK_OK(err) \ 45 | do { \ 46 | if (err != ESP_OK) { \ 47 | return jerry_create_number(err); \ 48 | } \ 49 | } while (0) 50 | -------------------------------------------------------------------------------- /main/src/nodemcujs_js.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * This file is generated by tools/js2c.py 17 | * Do not modify this. 18 | */ 19 | #ifndef NODEMCUJS_JS_H 20 | #define NODEMCUJS_JS_H 21 | 22 | extern const char console_n[]; 23 | extern const uint8_t console_s[]; 24 | extern const size_t console_l; 25 | 26 | extern const char events_n[]; 27 | extern const uint8_t events_s[]; 28 | extern const size_t events_l; 29 | 30 | extern const char module_n[]; 31 | extern const uint8_t module_s[]; 32 | extern const size_t module_l; 33 | 34 | extern const char nodemcujs_n[]; 35 | extern const uint8_t nodemcujs_s[]; 36 | extern const size_t nodemcujs_l; 37 | 38 | extern const char path_n[]; 39 | extern const uint8_t path_s[]; 40 | extern const size_t path_l; 41 | 42 | extern const char spi_n[]; 43 | extern const uint8_t spi_s[]; 44 | extern const size_t spi_l; 45 | 46 | extern const char util_n[]; 47 | extern const uint8_t util_s[]; 48 | extern const size_t util_l; 49 | 50 | extern const char wifi_n[]; 51 | extern const uint8_t wifi_s[]; 52 | extern const size_t wifi_l; 53 | 54 | typedef struct { 55 | const char* name; 56 | const void* code; 57 | const size_t length; 58 | } nodemcujs_js_module_t; 59 | 60 | extern const nodemcujs_js_module_t js_modules[]; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /main/src/nodemcujs_magic_strings.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #ifndef NODEMCUJS_STRING_CONSTANTS_H 17 | #define NODEMCUJS_STRING_CONSTANTS_H 18 | 19 | #define NODEMCUJS_MAGIC_STRING_0 "0" 20 | #define NODEMCUJS_MAGIC_STRING_1 "1" 21 | #define NODEMCUJS_MAGIC_STRING_2 "2" 22 | #define NODEMCUJS_MAGIC_STRING_3 "3" 23 | #define NODEMCUJS_MAGIC_STRING_ABORT "abort" 24 | #define NODEMCUJS_MAGIC_STRING_ADC "Adc" 25 | #define NODEMCUJS_MAGIC_STRING_ADDHEADER "addHeader" 26 | #define NODEMCUJS_MAGIC_STRING_ADDMEMBERSHIP "addMembership" 27 | #define NODEMCUJS_MAGIC_STRING_ADDRESS "address" 28 | #define NODEMCUJS_MAGIC_STRING_ARCH "arch" 29 | #define NODEMCUJS_MAGIC_STRING_ARGV "argv" 30 | #define NODEMCUJS_MAGIC_STRING_BASE64WRITE "base64Write" 31 | #define NODEMCUJS_MAGIC_STRING_BAUDRATE "baudRate" 32 | #define NODEMCUJS_MAGIC_STRING_BIND "bind" 33 | #define NODEMCUJS_MAGIC_STRING_BINDCONTROL "bindControl" 34 | #define NODEMCUJS_MAGIC_STRING_BINDING "binding" 35 | #define NODEMCUJS_MAGIC_STRING_BINDRAW "bindRaw" 36 | #define NODEMCUJS_MAGIC_STRING_BINDUSER "bindUser" 37 | #define NODEMCUJS_MAGIC_STRING_BITORDER "bitOrder" 38 | #define NODEMCUJS_MAGIC_STRING_BITORDER_U "BITORDER" 39 | #define NODEMCUJS_MAGIC_STRING_BITSPERWORD "bitsPerWord" 40 | #define NODEMCUJS_MAGIC_STRING_BOARD "board" 41 | #define NODEMCUJS_MAGIC_STRING_BOTH_U "BOTH" 42 | #define NODEMCUJS_MAGIC_STRING_BUFFER "Buffer" 43 | #define NODEMCUJS_MAGIC_STRING_BUILTIN_MODULES "builtin_modules" 44 | #define NODEMCUJS_MAGIC_STRING__BUFFER "_buffer" 45 | #define NODEMCUJS_MAGIC_STRING__BUILTIN "_builtin" 46 | #define NODEMCUJS_MAGIC_STRING_BUS "bus" 47 | #define NODEMCUJS_MAGIC_STRING_BYTELENGTH "byteLength" 48 | #define NODEMCUJS_MAGIC_STRING_REJECTUNAUTHORIZED "rejectUnauthorized" 49 | #define NODEMCUJS_MAGIC_STRING_BYTEPARSED "byteParsed" 50 | #define NODEMCUJS_MAGIC_STRING_CA "ca" 51 | #define NODEMCUJS_MAGIC_STRING_CERT "cert" 52 | #define NODEMCUJS_MAGIC_STRING_CHDIR "chdir" 53 | #define NODEMCUJS_MAGIC_STRING_CHIP "chip" 54 | #define NODEMCUJS_MAGIC_STRING_CHIPSELECT "chipSelect" 55 | #define NODEMCUJS_MAGIC_STRING_CHIPSELECT_U "CHIPSELECT" 56 | #define NODEMCUJS_MAGIC_STRING_CLIENT_ID "clientId" 57 | #define NODEMCUJS_MAGIC_STRING_CLOSE "close" 58 | #define NODEMCUJS_MAGIC_STRING_CLOSESYNC "closeSync" 59 | #define NODEMCUJS_MAGIC_STRING_CODE "code" 60 | #define NODEMCUJS_MAGIC_STRING_COMPARE "compare" 61 | #define NODEMCUJS_MAGIC_STRING_COMPILE "compile" 62 | #define NODEMCUJS_MAGIC_STRING_COMPILEMODULE "compileModule" 63 | #define NODEMCUJS_MAGIC_STRING_COMPILESNAPSHOT "compileSnapshot" 64 | #define NODEMCUJS_MAGIC_STRING_CONNECT "connect" 65 | #define NODEMCUJS_MAGIC_STRING_COPY "copy" 66 | #define NODEMCUJS_MAGIC_STRING_CREATEREQUEST "createRequest" 67 | #define NODEMCUJS_MAGIC_STRING__CREATESTAT "_createStat" 68 | #define NODEMCUJS_MAGIC_STRING_CREATETCP "createTCP" 69 | #define NODEMCUJS_MAGIC_STRING_CWD "cwd" 70 | #define NODEMCUJS_MAGIC_STRING_DATABITS "dataBits" 71 | #define NODEMCUJS_MAGIC_STRING_DEBUGGERSOURCECOMPILE "debuggerSourceCompile" 72 | #define NODEMCUJS_MAGIC_STRING_DEBUGGERWAITSOURCE "debuggerWaitSource" 73 | #define NODEMCUJS_MAGIC_STRING_DEVICE "device" 74 | #define NODEMCUJS_MAGIC_STRING_DIRECTION "direction" 75 | #define NODEMCUJS_MAGIC_STRING_DIRECTION_U "DIRECTION" 76 | #define NODEMCUJS_MAGIC_STRING_DOEXIT "doExit" 77 | #define NODEMCUJS_MAGIC_STRING_DROPMEMBERSHIP "dropMembership" 78 | #define NODEMCUJS_MAGIC_STRING_DUP "dup" 79 | #define NODEMCUJS_MAGIC_STRING_DUTYCYCLE "dutyCycle" 80 | #define NODEMCUJS_MAGIC_STRING_EDGE "edge" 81 | #define NODEMCUJS_MAGIC_STRING_EDGE_U "EDGE" 82 | #define NODEMCUJS_MAGIC_STRING_EMIT "emit" 83 | #define NODEMCUJS_MAGIC_STRING_EMITEXIT "emitExit" 84 | #define NODEMCUJS_MAGIC_STRING_ENV "env" 85 | #define NODEMCUJS_MAGIC_STRING_ERRNAME "errname" 86 | #define NODEMCUJS_MAGIC_STRING_EXECUTE "execute" 87 | #define NODEMCUJS_MAGIC_STRING_EXITCODE "exitCode" 88 | #define NODEMCUJS_MAGIC_STRING_EXPORT "export" 89 | #define NODEMCUJS_MAGIC_STRING_FALLING_U "FALLING" 90 | #define NODEMCUJS_MAGIC_STRING_FAMILY "family" 91 | #define NODEMCUJS_MAGIC_STRING_FINISH "finish" 92 | #define NODEMCUJS_MAGIC_STRING_FINISHREQUEST "finishRequest" 93 | #define NODEMCUJS_MAGIC_STRING_FLOAT_U "FLOAT" 94 | #define NODEMCUJS_MAGIC_STRING_FSTAT "fstat" 95 | #define NODEMCUJS_MAGIC_STRING_GC "gc" 96 | #define NODEMCUJS_MAGIC_STRING_GETADDRINFO "getaddrinfo" 97 | #define NODEMCUJS_MAGIC_STRING_GETFREEMEM "getFreeMem" 98 | #define NODEMCUJS_MAGIC_STRING_GETHOSTNAME "getHostname" 99 | #define NODEMCUJS_MAGIC_STRING_GETIFACEADDR "getInterfaceAddresses" 100 | #define NODEMCUJS_MAGIC_STRING_GETPRIORITY "getPriority" 101 | #define NODEMCUJS_MAGIC_STRING_GETSOCKNAME "getsockname" 102 | #define NODEMCUJS_MAGIC_STRING_GETTOTALMEM "getTotalMem" 103 | #define NODEMCUJS_MAGIC_STRING_GETPEERNAME "getpeername" 104 | #define NODEMCUJS_MAGIC_STRING_GETUPTIME "getUptime" 105 | #define NODEMCUJS_MAGIC_STRING__GETOSRELEASE "_getOSRelease" 106 | #define NODEMCUJS_MAGIC_STRING__GETPROCESSTITLE "_getProcessTitle" 107 | #define NODEMCUJS_MAGIC_STRING_GPIO "Gpio" 108 | #define NODEMCUJS_MAGIC_STRING_HANDLER "handler" 109 | #define NODEMCUJS_MAGIC_STRING_HANDLETIMEOUT "handleTimeout" 110 | #define NODEMCUJS_MAGIC_STRING_HEADER_SIZE "headerSize" 111 | #define NODEMCUJS_MAGIC_STRING_HEADERS "headers" 112 | #define NODEMCUJS_MAGIC_STRING_HEXWRITE "hexWrite" 113 | #define NODEMCUJS_MAGIC_STRING_HIGH_U "HIGH" 114 | #define NODEMCUJS_MAGIC_STRING_HOME_U "HOME" 115 | #define NODEMCUJS_MAGIC_STRING_HOST "host" 116 | #define NODEMCUJS_MAGIC_STRING_HRTIME "hrtime" 117 | #define NODEMCUJS_MAGIC_STRING_HTTPPARSER "HTTPParser" 118 | #define NODEMCUJS_MAGIC_STRING_HTTPPARSER_SNAKECASE "http_parser" 119 | #define NODEMCUJS_MAGIC_STRING_ID "id" 120 | #define NODEMCUJS_MAGIC_STRING_IN "IN" 121 | #define NODEMCUJS_MAGIC_STRING__INCOMING "_incoming" 122 | #define NODEMCUJS_MAGIC_STRING_NODEMCUJS_ENV_U "NODEMCUJS_ENV" 123 | #define NODEMCUJS_MAGIC_STRING_NODEMCUJS_PATH_U "NODEMCUJS_PATH" 124 | #define NODEMCUJS_MAGIC_STRING_NODEMCUJS "nodemcujs" 125 | #define NODEMCUJS_MAGIC_STRING_IPV4 "IPv4" 126 | #define NODEMCUJS_MAGIC_STRING_IPV6 "IPv6" 127 | #define NODEMCUJS_MAGIC_STRING_ISALIVEEXCEPTFOR "isAliveExceptFor" 128 | #define NODEMCUJS_MAGIC_STRING_ISATTY "isatty" 129 | #define NODEMCUJS_MAGIC_STRING_ISDEVUP "isDevUp" 130 | #define NODEMCUJS_MAGIC_STRING_ISDIRECTORY "isDirectory" 131 | #define NODEMCUJS_MAGIC_STRING_ISFILE "isFile" 132 | #define NODEMCUJS_MAGIC_STRING_KEEPALIVE "keepalive" 133 | #define NODEMCUJS_MAGIC_STRING_KEY "key" 134 | #define NODEMCUJS_MAGIC_STRING_KILL "kill" 135 | #define NODEMCUJS_MAGIC_STRING_LENGTH "length" 136 | #define NODEMCUJS_MAGIC_STRING_LISTEN "listen" 137 | #define NODEMCUJS_MAGIC_STRING_LOOPBACK "loopback" 138 | #define NODEMCUJS_MAGIC_STRING_LSTAT "lstat" 139 | #define NODEMCUJS_MAGIC_STRING_LSB "LSB" 140 | #define NODEMCUJS_MAGIC_STRING_MAXSPEED "maxSpeed" 141 | #define NODEMCUJS_MAGIC_STRING_MBEDTLS "mbedtls" 142 | #define NODEMCUJS_MAGIC_STRING_MEMORYUSAGE "memoryUsage" 143 | #define NODEMCUJS_MAGIC_STRING_METHOD "method" 144 | #define NODEMCUJS_MAGIC_STRING_METHODS "methods" 145 | #define NODEMCUJS_MAGIC_STRING_MKDIR "mkdir" 146 | #define NODEMCUJS_MAGIC_STRING_MODE "mode" 147 | #define NODEMCUJS_MAGIC_STRING_MODE_U "MODE" 148 | #define NODEMCUJS_MAGIC_STRING_MSB "MSB" 149 | #define NODEMCUJS_MAGIC_STRING_NODE "node" 150 | #define NODEMCUJS_MAGIC_STRING_NONE_U "NONE" 151 | #define NODEMCUJS_MAGIC_STRING_ONBODY "OnBody" 152 | #define NODEMCUJS_MAGIC_STRING_ONCLOSE "onclose" 153 | #define NODEMCUJS_MAGIC_STRING_ONCLOSED "onClosed" 154 | #define NODEMCUJS_MAGIC_STRING_ONCONNECTION "onconnection" 155 | #define NODEMCUJS_MAGIC_STRING_ONDATA "onData" 156 | #define NODEMCUJS_MAGIC_STRING_ONEND "onEnd" 157 | #define NODEMCUJS_MAGIC_STRING_ONERROR "onError" 158 | #define NODEMCUJS_MAGIC_STRING_ONHEADERSCOMPLETE "OnHeadersComplete" 159 | #define NODEMCUJS_MAGIC_STRING_ONHEADERS "OnHeaders" 160 | #define NODEMCUJS_MAGIC_STRING_ONMESSAGECOMPLETE "OnMessageComplete" 161 | #define NODEMCUJS_MAGIC_STRING_ONMESSAGE "onmessage" 162 | #define NODEMCUJS_MAGIC_STRING__ONNEXTTICK "_onNextTick" 163 | #define NODEMCUJS_MAGIC_STRING_ONREAD "onread" 164 | #define NODEMCUJS_MAGIC_STRING_ONSOCKET "onSocket" 165 | #define NODEMCUJS_MAGIC_STRING_ONTIMEOUT "onTimeout" 166 | #define NODEMCUJS_MAGIC_STRING__ONUNCAUGHTEXCEPTION "_onUncaughtException" 167 | #define NODEMCUJS_MAGIC_STRING__ONUVCHECK "_onUVCheck" 168 | #define NODEMCUJS_MAGIC_STRING_ONWRITABLE "onWritable" 169 | #define NODEMCUJS_MAGIC_STRING_OPENDRAIN_U "OPENDRAIN" 170 | #define NODEMCUJS_MAGIC_STRING_OPEN "open" 171 | #define NODEMCUJS_MAGIC_STRING_OPENNATIVEMODULE "openNativeModule" 172 | #define NODEMCUJS_MAGIC_STRING_OUT_U "OUT" 173 | #define NODEMCUJS_MAGIC_STRING_OWNER "owner" 174 | #define NODEMCUJS_MAGIC_STRING_PASSWORD "password" 175 | #define NODEMCUJS_MAGIC_STRING_PAUSE "pause" 176 | #define NODEMCUJS_MAGIC_STRING_PAYLOAD "payload" 177 | #define NODEMCUJS_MAGIC_STRING_PAYLOAD_MISSING_SIZE "payloadMissingSize" 178 | #define NODEMCUJS_MAGIC_STRING_PAYLOAD_REAL_SIZE "payloadRealSize" 179 | #define NODEMCUJS_MAGIC_STRING_PAYLOAD_SIZE "payloadSize" 180 | #define NODEMCUJS_MAGIC_STRING_PERIOD "period" 181 | #define NODEMCUJS_MAGIC_STRING_PID "pid" 182 | #define NODEMCUJS_MAGIC_STRING_PIN "pin" 183 | #define NODEMCUJS_MAGIC_STRING_PLATFORM "platform" 184 | #define NODEMCUJS_MAGIC_STRING_PORT "port" 185 | #define NODEMCUJS_MAGIC_STRING_PROTOCOL_VERSION "protocolVersion" 186 | #define NODEMCUJS_MAGIC_STRING_PROTOTYPE "prototype" 187 | #define NODEMCUJS_MAGIC_STRING_PULLDOWN_U "PULLDOWN" 188 | #define NODEMCUJS_MAGIC_STRING_PULLUP_U "PULLUP" 189 | #define NODEMCUJS_MAGIC_STRING_PUSHPULL_U "PUSHPULL" 190 | #define NODEMCUJS_MAGIC_STRING_QOS "qos" 191 | #define NODEMCUJS_MAGIC_STRING_READDIR "readdir" 192 | #define NODEMCUJS_MAGIC_STRING_READ "read" 193 | #define NODEMCUJS_MAGIC_STRING_READDOUBLELE "readDoubleLE" 194 | #define NODEMCUJS_MAGIC_STRING_READFLOATLE "readFloatLE" 195 | #define NODEMCUJS_MAGIC_STRING_READSOURCE "readSource" 196 | #define NODEMCUJS_MAGIC_STRING_READSTART "readStart" 197 | #define NODEMCUJS_MAGIC_STRING_READSYNC "readSync" 198 | #define NODEMCUJS_MAGIC_STRING_READUINT8 "readUInt8" 199 | #define NODEMCUJS_MAGIC_STRING_RECVSTART "recvStart" 200 | #define NODEMCUJS_MAGIC_STRING_RECVSTOP "recvStop" 201 | #define NODEMCUJS_MAGIC_STRING_REF "ref" 202 | #define NODEMCUJS_MAGIC_STRING_REINITIALIZE "reinitialize" 203 | #define NODEMCUJS_MAGIC_STRING_RENAME "rename" 204 | #define NODEMCUJS_MAGIC_STRING_REQUEST_U "REQUEST" 205 | #define NODEMCUJS_MAGIC_STRING_RESPONSE_U "RESPONSE" 206 | #define NODEMCUJS_MAGIC_STRING_RESUME "resume" 207 | #define NODEMCUJS_MAGIC_STRING_RETAIN "retain" 208 | #define NODEMCUJS_MAGIC_STRING__REUSEADDR "_reuseAddr" 209 | #define NODEMCUJS_MAGIC_STRING_RISING_U "RISING" 210 | #define NODEMCUJS_MAGIC_STRING_RMDIR "rmdir" 211 | #define NODEMCUJS_MAGIC_STRING_SEND "send" 212 | #define NODEMCUJS_MAGIC_STRING_SENDREQUEST "sendRequest" 213 | #define NODEMCUJS_MAGIC_STRING_SETADDRESS "setAddress" 214 | #define NODEMCUJS_MAGIC_STRING_SETBROADCAST "setBroadcast" 215 | #define NODEMCUJS_MAGIC_STRING_SETDUTYCYCLE "setDutyCycle" 216 | #define NODEMCUJS_MAGIC_STRING_SETENABLE "setEnable" 217 | #define NODEMCUJS_MAGIC_STRING_SETFILTER "setFilter" 218 | #define NODEMCUJS_MAGIC_STRING_SETFREQUENCY "setFrequency" 219 | #define NODEMCUJS_MAGIC_STRING_SETKEEPALIVE "setKeepAlive" 220 | #define NODEMCUJS_MAGIC_STRING_SETMULTICASTLOOPBACK "setMulticastLoopback" 221 | #define NODEMCUJS_MAGIC_STRING_SETMULTICASTTTL "setMulticastTTL" 222 | #define NODEMCUJS_MAGIC_STRING_SETPERIOD "setPeriod" 223 | #define NODEMCUJS_MAGIC_STRING_SETPRIORITY "setPriority" 224 | #define NODEMCUJS_MAGIC_STRING_SETTIMEOUT "setTimeout" 225 | #define NODEMCUJS_MAGIC_STRING_SETTTL "setTTL" 226 | #define NODEMCUJS_MAGIC_STRING__SETPROCESSTITLE "_setProcessTitle" 227 | #define NODEMCUJS_MAGIC_STRING_SHOULDKEEPALIVE "shouldkeepalive" 228 | #define NODEMCUJS_MAGIC_STRING_SHUTDOWN "shutdown" 229 | #define NODEMCUJS_MAGIC_STRING_SLICE "slice" 230 | #define NODEMCUJS_MAGIC_STRING_SPI "Spi" 231 | #define NODEMCUJS_MAGIC_STRING_START "start" 232 | #define NODEMCUJS_MAGIC_STRING_STARTPROFILING "startProfiling" 233 | #define NODEMCUJS_MAGIC_STRING__STARTUVCHECK "_startUVCheck" 234 | #define NODEMCUJS_MAGIC_STRING_STAT "stat" 235 | #define NODEMCUJS_MAGIC_STRING_STATS "stats" 236 | #define NODEMCUJS_MAGIC_STRING_STATUS_MSG "status_msg" 237 | #define NODEMCUJS_MAGIC_STRING_STATUS "status" 238 | #define NODEMCUJS_MAGIC_STRING_STDERR "stderr" 239 | #define NODEMCUJS_MAGIC_STRING_STDOUT "stdout" 240 | #define NODEMCUJS_MAGIC_STRING_STOP "stop" 241 | #define NODEMCUJS_MAGIC_STRING_STOPPROFILING "stopProfiling" 242 | #define NODEMCUJS_MAGIC_STRING__STOPUVCHECK "_stopUVCheck" 243 | #define NODEMCUJS_MAGIC_STRING_TAKESNAPSHOT "takeSnapshot" 244 | #define NODEMCUJS_MAGIC_STRING_TOBASE64 "toBase64" 245 | #define NODEMCUJS_MAGIC_STRING_TOHEXSTRING "toHexString" 246 | #define NODEMCUJS_MAGIC_STRING_TOPIC "topic" 247 | #define NODEMCUJS_MAGIC_STRING_TOSTRING "toString" 248 | #define NODEMCUJS_MAGIC_STRING_TRANSFERARRAY "transferArray" 249 | #define NODEMCUJS_MAGIC_STRING_TRANSFERBUFFER "transferBuffer" 250 | #define NODEMCUJS_MAGIC_STRING_UMASK "umask" 251 | #define NODEMCUJS_MAGIC_STRING_UNEXPORT "unexport" 252 | #define NODEMCUJS_MAGIC_STRING_UNLINK "unlink" 253 | #define NODEMCUJS_MAGIC_STRING_UNREF "unref" 254 | #define NODEMCUJS_MAGIC_STRING_UPGRADE "upgrade" 255 | #define NODEMCUJS_MAGIC_STRING_URL "url" 256 | #define NODEMCUJS_MAGIC_STRING_USERNAME "username" 257 | #define NODEMCUJS_MAGIC_STRING_UV "uv" 258 | #define NODEMCUJS_MAGIC_STRING_VERSION "version" 259 | #define NODEMCUJS_MAGIC_STRING_VERSIONS "versions" 260 | #define NODEMCUJS_MAGIC_STRING_WILL "will" 261 | #define NODEMCUJS_MAGIC_STRING_WRITESYNC "writeSync" 262 | #define NODEMCUJS_MAGIC_STRING_WRITEUINT8 "writeUInt8" 263 | #define NODEMCUJS_MAGIC_STRING_WRITE "write" 264 | #define NODEMCUJS_MAGIC_STRING_WRITEUTF8STRING "writeUtf8String" 265 | #define NODEMCUJS_MAGIC_STRING__WRITE "_write" 266 | 267 | #endif /* NODEMCUJS_STRING_CONSTANTS_H */ 268 | -------------------------------------------------------------------------------- /main/src/nodemcujs_module.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs_module.h" 2 | #include "nodemcujs_module_inl.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | jerry_value_t nodemcujs_module_get(const char* name) { 9 | for (unsigned i = 0; i < nodemcujs_modules_count; i++) { 10 | if (!strcmp(name, nodemcujs_modules[i].name)) { 11 | if (nodemcujs_module_objects[i].jmodule == 0) { 12 | nodemcujs_module_objects[i].jmodule = nodemcujs_modules[i].fn_register(); 13 | } 14 | return nodemcujs_module_objects[i].jmodule; 15 | } 16 | } 17 | return jerry_create_undefined(); 18 | } -------------------------------------------------------------------------------- /main/src/nodemcujs_module.h: -------------------------------------------------------------------------------- 1 | #ifndef NODEMCUJS_MODULE_H 2 | #define NODEMCUJS_MODULE_H 3 | 4 | #include 5 | 6 | typedef jerry_value_t (*register_func)(); 7 | 8 | typedef struct nodemcujs_module 9 | { 10 | const char* name; 11 | register_func fn_register; 12 | } nodemcujs_module_t; 13 | 14 | typedef struct nodemcujs_module_objects 15 | { 16 | jerry_value_t jmodule; 17 | } nodemcujs_module_objects_t; 18 | 19 | extern const unsigned nodemcujs_modules_count; 20 | 21 | extern const nodemcujs_module_t nodemcujs_modules[]; 22 | 23 | extern nodemcujs_module_objects_t nodemcujs_module_objects[]; 24 | 25 | #endif -------------------------------------------------------------------------------- /main/src/nodemcujs_module_inl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021-present nodemcujs and other contributors 3 | * 4 | * This file is generated by CMakeLists.txt 5 | * Do not modify this. 6 | */ 7 | 8 | #include "nodemcujs_module.h" 9 | 10 | const unsigned nodemcujs_modules_count = 11; 11 | 12 | extern jerry_value_t nodemcujs_module_init_console(); 13 | extern jerry_value_t nodemcujs_module_init_esp_error(); 14 | extern jerry_value_t nodemcujs_module_init_gpio(); 15 | extern jerry_value_t nodemcujs_module_init_http_client(); 16 | extern jerry_value_t nodemcujs_module_init_nvs_flash(); 17 | extern jerry_value_t nodemcujs_module_init_process(); 18 | extern jerry_value_t nodemcujs_module_init_rmt(); 19 | extern jerry_value_t nodemcujs_module_init_sigmadelta(); 20 | extern jerry_value_t nodemcujs_module_init_spi_master(); 21 | extern jerry_value_t nodemcujs_module_init_timers(); 22 | extern jerry_value_t nodemcujs_module_init_wifi(); 23 | 24 | const nodemcujs_module_t nodemcujs_modules[] = { 25 | { "console", nodemcujs_module_init_console }, 26 | { "esp_error", nodemcujs_module_init_esp_error }, 27 | { "gpio", nodemcujs_module_init_gpio }, 28 | { "http_client", nodemcujs_module_init_http_client }, 29 | { "nvs_flash", nodemcujs_module_init_nvs_flash }, 30 | { "process", nodemcujs_module_init_process }, 31 | { "rmt", nodemcujs_module_init_rmt }, 32 | { "sigmadelta", nodemcujs_module_init_sigmadelta }, 33 | { "spi_master", nodemcujs_module_init_spi_master }, 34 | { "timers", nodemcujs_module_init_timers }, 35 | { "wifi", nodemcujs_module_init_wifi }, 36 | }; 37 | 38 | nodemcujs_module_objects_t nodemcujs_module_objects[] = { 39 | { 0 }, 40 | { 0 }, 41 | { 0 }, 42 | { 0 }, 43 | { 0 }, 44 | { 0 }, 45 | { 0 }, 46 | { 0 }, 47 | { 0 }, 48 | { 0 }, 49 | { 0 }, 50 | }; 51 | -------------------------------------------------------------------------------- /main/src/nodemcujs_string.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs_string.h" 2 | #include "nodemcujs_def.h" 3 | 4 | #include 5 | #include 6 | 7 | nodemcujs_string_t nodemcujs_string_create() { 8 | nodemcujs_string_t str; 9 | 10 | str.size = 0; 11 | str.data = NULL; 12 | 13 | return str; 14 | } 15 | 16 | nodemcujs_string_t nodemcujs_string_create_with_size(const char* data, size_t size) { 17 | nodemcujs_string_t str; 18 | 19 | str.size = size; 20 | 21 | if (size > 0) { 22 | NODEMCUJS_ASSERT(data != NULL); 23 | str.data = malloc(size); 24 | memcpy(str.data, data, size); 25 | } else { 26 | str.data = NULL; 27 | } 28 | 29 | return str; 30 | } 31 | 32 | nodemcujs_string_t nodemcujs_string_create_with_buffer(char* buffer, size_t size) { 33 | nodemcujs_string_t str; 34 | 35 | str.size = size; 36 | 37 | if (size > 0) { 38 | NODEMCUJS_ASSERT(buffer != NULL); 39 | str.data = buffer; 40 | } else { 41 | str.data = NULL; 42 | } 43 | 44 | return str; 45 | } 46 | 47 | void nodemcujs_string_destroy(nodemcujs_string_t* str) { 48 | if (str->data != NULL) { 49 | free(str->data); 50 | str->size = 0; 51 | } 52 | } 53 | 54 | const char* nodemcujs_string_data(const nodemcujs_string_t* str) { 55 | if (str->data == NULL) { 56 | return ""; 57 | } 58 | return str->data; 59 | } 60 | 61 | size_t nodemcujs_string_size(const nodemcujs_string_t* str) { 62 | return str->size; 63 | } -------------------------------------------------------------------------------- /main/src/nodemcujs_string.h: -------------------------------------------------------------------------------- 1 | #ifndef NODEMCUJS_STRING_H 2 | #define NODEMCUJS_STRING_H 3 | 4 | #include 5 | 6 | typedef struct nodemcujs_string 7 | { 8 | size_t size; 9 | char* data; 10 | } nodemcujs_string_t; 11 | 12 | nodemcujs_string_t nodemcujs_string_create(); 13 | nodemcujs_string_t nodemcujs_string_create_with_size(const char* data, size_t size); 14 | nodemcujs_string_t nodemcujs_string_create_with_buffer(char* buffer, size_t size); 15 | 16 | void nodemcujs_string_destroy(nodemcujs_string_t* str); 17 | 18 | // Returns pointer to the bytes (never returns NULL) 19 | const char* nodemcujs_string_data(const nodemcujs_string_t* str); 20 | 21 | size_t nodemcujs_string_size(const nodemcujs_string_t* str); 22 | 23 | #endif -------------------------------------------------------------------------------- /main/src/nodemcujs_string_ext.inl.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * This file is generated by tools/js2c.py 17 | * Do not modify this. 18 | */ 19 | #define JERRY_MAGIC_STRING_ITEMS \ 20 | MAGICSTR_EX_DEF(MAGIC_STR_0, "0") \ 21 | MAGICSTR_EX_DEF(MAGIC_STR_1, "1") \ 22 | MAGICSTR_EX_DEF(MAGIC_STR_2, "2") \ 23 | MAGICSTR_EX_DEF(MAGIC_STR_3, "3") \ 24 | MAGICSTR_EX_DEF(MAGIC_STR_4, "IN") \ 25 | MAGICSTR_EX_DEF(MAGIC_STR_5, "ca") \ 26 | MAGICSTR_EX_DEF(MAGIC_STR_6, "gc") \ 27 | MAGICSTR_EX_DEF(MAGIC_STR_7, "id") \ 28 | MAGICSTR_EX_DEF(MAGIC_STR_8, "uv") \ 29 | MAGICSTR_EX_DEF(MAGIC_STR_9, "Adc") \ 30 | MAGICSTR_EX_DEF(MAGIC_STR_10, "LSB") \ 31 | MAGICSTR_EX_DEF(MAGIC_STR_11, "MSB") \ 32 | MAGICSTR_EX_DEF(MAGIC_STR_12, "OUT") \ 33 | MAGICSTR_EX_DEF(MAGIC_STR_13, "Spi") \ 34 | MAGICSTR_EX_DEF(MAGIC_STR_14, "bus") \ 35 | MAGICSTR_EX_DEF(MAGIC_STR_15, "cwd") \ 36 | MAGICSTR_EX_DEF(MAGIC_STR_16, "dup") \ 37 | MAGICSTR_EX_DEF(MAGIC_STR_17, "env") \ 38 | MAGICSTR_EX_DEF(MAGIC_STR_18, "key") \ 39 | MAGICSTR_EX_DEF(MAGIC_STR_19, "pid") \ 40 | MAGICSTR_EX_DEF(MAGIC_STR_20, "pin") \ 41 | MAGICSTR_EX_DEF(MAGIC_STR_21, "qos") \ 42 | MAGICSTR_EX_DEF(MAGIC_STR_22, "ref") \ 43 | MAGICSTR_EX_DEF(MAGIC_STR_23, "url") \ 44 | MAGICSTR_EX_DEF(MAGIC_STR_24, "BOTH") \ 45 | MAGICSTR_EX_DEF(MAGIC_STR_25, "EDGE") \ 46 | MAGICSTR_EX_DEF(MAGIC_STR_26, "Gpio") \ 47 | MAGICSTR_EX_DEF(MAGIC_STR_27, "HIGH") \ 48 | MAGICSTR_EX_DEF(MAGIC_STR_28, "HOME") \ 49 | MAGICSTR_EX_DEF(MAGIC_STR_29, "IPv4") \ 50 | MAGICSTR_EX_DEF(MAGIC_STR_30, "IPv6") \ 51 | MAGICSTR_EX_DEF(MAGIC_STR_31, "MODE") \ 52 | MAGICSTR_EX_DEF(MAGIC_STR_32, "NONE") \ 53 | MAGICSTR_EX_DEF(MAGIC_STR_33, "arch") \ 54 | MAGICSTR_EX_DEF(MAGIC_STR_34, "argv") \ 55 | MAGICSTR_EX_DEF(MAGIC_STR_35, "bind") \ 56 | MAGICSTR_EX_DEF(MAGIC_STR_36, "cert") \ 57 | MAGICSTR_EX_DEF(MAGIC_STR_37, "chip") \ 58 | MAGICSTR_EX_DEF(MAGIC_STR_38, "code") \ 59 | MAGICSTR_EX_DEF(MAGIC_STR_39, "copy") \ 60 | MAGICSTR_EX_DEF(MAGIC_STR_40, "edge") \ 61 | MAGICSTR_EX_DEF(MAGIC_STR_41, "emit") \ 62 | MAGICSTR_EX_DEF(MAGIC_STR_42, "host") \ 63 | MAGICSTR_EX_DEF(MAGIC_STR_43, "kill") \ 64 | MAGICSTR_EX_DEF(MAGIC_STR_44, "mode") \ 65 | MAGICSTR_EX_DEF(MAGIC_STR_45, "node") \ 66 | MAGICSTR_EX_DEF(MAGIC_STR_46, "open") \ 67 | MAGICSTR_EX_DEF(MAGIC_STR_47, "port") \ 68 | MAGICSTR_EX_DEF(MAGIC_STR_48, "read") \ 69 | MAGICSTR_EX_DEF(MAGIC_STR_49, "send") \ 70 | MAGICSTR_EX_DEF(MAGIC_STR_50, "stat") \ 71 | MAGICSTR_EX_DEF(MAGIC_STR_51, "stop") \ 72 | MAGICSTR_EX_DEF(MAGIC_STR_52, "will") \ 73 | MAGICSTR_EX_DEF(MAGIC_STR_53, "FLOAT") \ 74 | MAGICSTR_EX_DEF(MAGIC_STR_54, "abort") \ 75 | MAGICSTR_EX_DEF(MAGIC_STR_55, "board") \ 76 | MAGICSTR_EX_DEF(MAGIC_STR_56, "chdir") \ 77 | MAGICSTR_EX_DEF(MAGIC_STR_57, "close") \ 78 | MAGICSTR_EX_DEF(MAGIC_STR_58, "fstat") \ 79 | MAGICSTR_EX_DEF(MAGIC_STR_59, "lstat") \ 80 | MAGICSTR_EX_DEF(MAGIC_STR_60, "mkdir") \ 81 | MAGICSTR_EX_DEF(MAGIC_STR_61, "onEnd") \ 82 | MAGICSTR_EX_DEF(MAGIC_STR_62, "owner") \ 83 | MAGICSTR_EX_DEF(MAGIC_STR_63, "pause") \ 84 | MAGICSTR_EX_DEF(MAGIC_STR_64, "rmdir") \ 85 | MAGICSTR_EX_DEF(MAGIC_STR_65, "slice") \ 86 | MAGICSTR_EX_DEF(MAGIC_STR_66, "start") \ 87 | MAGICSTR_EX_DEF(MAGIC_STR_67, "stats") \ 88 | MAGICSTR_EX_DEF(MAGIC_STR_68, "topic") \ 89 | MAGICSTR_EX_DEF(MAGIC_STR_69, "umask") \ 90 | MAGICSTR_EX_DEF(MAGIC_STR_70, "unref") \ 91 | MAGICSTR_EX_DEF(MAGIC_STR_71, "write") \ 92 | MAGICSTR_EX_DEF(MAGIC_STR_72, "Buffer") \ 93 | MAGICSTR_EX_DEF(MAGIC_STR_73, "OnBody") \ 94 | MAGICSTR_EX_DEF(MAGIC_STR_74, "PULLUP") \ 95 | MAGICSTR_EX_DEF(MAGIC_STR_75, "RISING") \ 96 | MAGICSTR_EX_DEF(MAGIC_STR_76, "_write") \ 97 | MAGICSTR_EX_DEF(MAGIC_STR_77, "device") \ 98 | MAGICSTR_EX_DEF(MAGIC_STR_78, "doExit") \ 99 | MAGICSTR_EX_DEF(MAGIC_STR_79, "export") \ 100 | MAGICSTR_EX_DEF(MAGIC_STR_80, "family") \ 101 | MAGICSTR_EX_DEF(MAGIC_STR_81, "finish") \ 102 | MAGICSTR_EX_DEF(MAGIC_STR_82, "hrtime") \ 103 | MAGICSTR_EX_DEF(MAGIC_STR_83, "isFile") \ 104 | MAGICSTR_EX_DEF(MAGIC_STR_84, "isatty") \ 105 | MAGICSTR_EX_DEF(MAGIC_STR_85, "length") \ 106 | MAGICSTR_EX_DEF(MAGIC_STR_86, "listen") \ 107 | MAGICSTR_EX_DEF(MAGIC_STR_87, "method") \ 108 | MAGICSTR_EX_DEF(MAGIC_STR_88, "onData") \ 109 | MAGICSTR_EX_DEF(MAGIC_STR_89, "onread") \ 110 | MAGICSTR_EX_DEF(MAGIC_STR_90, "period") \ 111 | MAGICSTR_EX_DEF(MAGIC_STR_91, "rename") \ 112 | MAGICSTR_EX_DEF(MAGIC_STR_92, "resume") \ 113 | MAGICSTR_EX_DEF(MAGIC_STR_93, "retain") \ 114 | MAGICSTR_EX_DEF(MAGIC_STR_94, "setTTL") \ 115 | MAGICSTR_EX_DEF(MAGIC_STR_95, "status") \ 116 | MAGICSTR_EX_DEF(MAGIC_STR_96, "stderr") \ 117 | MAGICSTR_EX_DEF(MAGIC_STR_97, "stdout") \ 118 | MAGICSTR_EX_DEF(MAGIC_STR_98, "unlink") \ 119 | MAGICSTR_EX_DEF(MAGIC_STR_99, "FALLING") \ 120 | MAGICSTR_EX_DEF(MAGIC_STR_100, "REQUEST") \ 121 | MAGICSTR_EX_DEF(MAGIC_STR_101, "_buffer") \ 122 | MAGICSTR_EX_DEF(MAGIC_STR_102, "address") \ 123 | MAGICSTR_EX_DEF(MAGIC_STR_103, "bindRaw") \ 124 | MAGICSTR_EX_DEF(MAGIC_STR_104, "binding") \ 125 | MAGICSTR_EX_DEF(MAGIC_STR_105, "compare") \ 126 | MAGICSTR_EX_DEF(MAGIC_STR_106, "compile") \ 127 | MAGICSTR_EX_DEF(MAGIC_STR_107, "connect") \ 128 | MAGICSTR_EX_DEF(MAGIC_STR_108, "errname") \ 129 | MAGICSTR_EX_DEF(MAGIC_STR_109, "execute") \ 130 | MAGICSTR_EX_DEF(MAGIC_STR_110, "handler") \ 131 | MAGICSTR_EX_DEF(MAGIC_STR_111, "headers") \ 132 | MAGICSTR_EX_DEF(MAGIC_STR_112, "isDevUp") \ 133 | MAGICSTR_EX_DEF(MAGIC_STR_113, "mbedtls") \ 134 | MAGICSTR_EX_DEF(MAGIC_STR_114, "methods") \ 135 | MAGICSTR_EX_DEF(MAGIC_STR_115, "onError") \ 136 | MAGICSTR_EX_DEF(MAGIC_STR_116, "onclose") \ 137 | MAGICSTR_EX_DEF(MAGIC_STR_117, "payload") \ 138 | MAGICSTR_EX_DEF(MAGIC_STR_118, "readdir") \ 139 | MAGICSTR_EX_DEF(MAGIC_STR_119, "upgrade") \ 140 | MAGICSTR_EX_DEF(MAGIC_STR_120, "version") \ 141 | MAGICSTR_EX_DEF(MAGIC_STR_121, "BITORDER") \ 142 | MAGICSTR_EX_DEF(MAGIC_STR_122, "PULLDOWN") \ 143 | MAGICSTR_EX_DEF(MAGIC_STR_123, "PUSHPULL") \ 144 | MAGICSTR_EX_DEF(MAGIC_STR_124, "RESPONSE") \ 145 | MAGICSTR_EX_DEF(MAGIC_STR_125, "_builtin") \ 146 | MAGICSTR_EX_DEF(MAGIC_STR_126, "baudRate") \ 147 | MAGICSTR_EX_DEF(MAGIC_STR_127, "bindUser") \ 148 | MAGICSTR_EX_DEF(MAGIC_STR_128, "bitOrder") \ 149 | MAGICSTR_EX_DEF(MAGIC_STR_129, "clientId") \ 150 | MAGICSTR_EX_DEF(MAGIC_STR_130, "dataBits") \ 151 | MAGICSTR_EX_DEF(MAGIC_STR_131, "emitExit") \ 152 | MAGICSTR_EX_DEF(MAGIC_STR_132, "exitCode") \ 153 | MAGICSTR_EX_DEF(MAGIC_STR_133, "hexWrite") \ 154 | MAGICSTR_EX_DEF(MAGIC_STR_134, "loopback") \ 155 | MAGICSTR_EX_DEF(MAGIC_STR_135, "maxSpeed") \ 156 | MAGICSTR_EX_DEF(MAGIC_STR_136, "onClosed") \ 157 | MAGICSTR_EX_DEF(MAGIC_STR_137, "onSocket") \ 158 | MAGICSTR_EX_DEF(MAGIC_STR_138, "password") \ 159 | MAGICSTR_EX_DEF(MAGIC_STR_139, "platform") \ 160 | MAGICSTR_EX_DEF(MAGIC_STR_140, "readSync") \ 161 | MAGICSTR_EX_DEF(MAGIC_STR_141, "recvStop") \ 162 | MAGICSTR_EX_DEF(MAGIC_STR_142, "shutdown") \ 163 | MAGICSTR_EX_DEF(MAGIC_STR_143, "toBase64") \ 164 | MAGICSTR_EX_DEF(MAGIC_STR_144, "toString") \ 165 | MAGICSTR_EX_DEF(MAGIC_STR_145, "unexport") \ 166 | MAGICSTR_EX_DEF(MAGIC_STR_146, "username") \ 167 | MAGICSTR_EX_DEF(MAGIC_STR_147, "versions") \ 168 | MAGICSTR_EX_DEF(MAGIC_STR_148, "DIRECTION") \ 169 | MAGICSTR_EX_DEF(MAGIC_STR_149, "OPENDRAIN") \ 170 | MAGICSTR_EX_DEF(MAGIC_STR_150, "OnHeaders") \ 171 | MAGICSTR_EX_DEF(MAGIC_STR_151, "_incoming") \ 172 | MAGICSTR_EX_DEF(MAGIC_STR_152, "addHeader") \ 173 | MAGICSTR_EX_DEF(MAGIC_STR_153, "closeSync") \ 174 | MAGICSTR_EX_DEF(MAGIC_STR_154, "createTCP") \ 175 | MAGICSTR_EX_DEF(MAGIC_STR_155, "direction") \ 176 | MAGICSTR_EX_DEF(MAGIC_STR_156, "dutyCycle") \ 177 | MAGICSTR_EX_DEF(MAGIC_STR_157, "getUptime") \ 178 | MAGICSTR_EX_DEF(MAGIC_STR_158, "keepalive") \ 179 | MAGICSTR_EX_DEF(MAGIC_STR_159, "nodemcujs") \ 180 | MAGICSTR_EX_DEF(MAGIC_STR_160, "onTimeout") \ 181 | MAGICSTR_EX_DEF(MAGIC_STR_161, "onmessage") \ 182 | MAGICSTR_EX_DEF(MAGIC_STR_162, "prototype") \ 183 | MAGICSTR_EX_DEF(MAGIC_STR_163, "readStart") \ 184 | MAGICSTR_EX_DEF(MAGIC_STR_164, "readUInt8") \ 185 | MAGICSTR_EX_DEF(MAGIC_STR_165, "recvStart") \ 186 | MAGICSTR_EX_DEF(MAGIC_STR_166, "setEnable") \ 187 | MAGICSTR_EX_DEF(MAGIC_STR_167, "setFilter") \ 188 | MAGICSTR_EX_DEF(MAGIC_STR_168, "setPeriod") \ 189 | MAGICSTR_EX_DEF(MAGIC_STR_169, "writeSync") \ 190 | MAGICSTR_EX_DEF(MAGIC_STR_170, "CHIPSELECT") \ 191 | MAGICSTR_EX_DEF(MAGIC_STR_171, "HTTPParser") \ 192 | MAGICSTR_EX_DEF(MAGIC_STR_172, "_onUVCheck") \ 193 | MAGICSTR_EX_DEF(MAGIC_STR_173, "_reuseAddr") \ 194 | MAGICSTR_EX_DEF(MAGIC_STR_174, "byteLength") \ 195 | MAGICSTR_EX_DEF(MAGIC_STR_175, "byteParsed") \ 196 | MAGICSTR_EX_DEF(MAGIC_STR_176, "chipSelect") \ 197 | MAGICSTR_EX_DEF(MAGIC_STR_177, "getFreeMem") \ 198 | MAGICSTR_EX_DEF(MAGIC_STR_178, "headerSize") \ 199 | MAGICSTR_EX_DEF(MAGIC_STR_179, "onWritable") \ 200 | MAGICSTR_EX_DEF(MAGIC_STR_180, "readSource") \ 201 | MAGICSTR_EX_DEF(MAGIC_STR_181, "setAddress") \ 202 | MAGICSTR_EX_DEF(MAGIC_STR_182, "setTimeout") \ 203 | MAGICSTR_EX_DEF(MAGIC_STR_183, "status_msg") \ 204 | MAGICSTR_EX_DEF(MAGIC_STR_184, "writeUInt8") \ 205 | MAGICSTR_EX_DEF(MAGIC_STR_185, "_createStat") \ 206 | MAGICSTR_EX_DEF(MAGIC_STR_186, "_onNextTick") \ 207 | MAGICSTR_EX_DEF(MAGIC_STR_187, "base64Write") \ 208 | MAGICSTR_EX_DEF(MAGIC_STR_188, "bindControl") \ 209 | MAGICSTR_EX_DEF(MAGIC_STR_189, "bitsPerWord") \ 210 | MAGICSTR_EX_DEF(MAGIC_STR_190, "getHostname") \ 211 | MAGICSTR_EX_DEF(MAGIC_STR_191, "getPriority") \ 212 | MAGICSTR_EX_DEF(MAGIC_STR_192, "getTotalMem") \ 213 | MAGICSTR_EX_DEF(MAGIC_STR_193, "getaddrinfo") \ 214 | MAGICSTR_EX_DEF(MAGIC_STR_194, "getpeername") \ 215 | MAGICSTR_EX_DEF(MAGIC_STR_195, "getsockname") \ 216 | MAGICSTR_EX_DEF(MAGIC_STR_196, "http_parser") \ 217 | MAGICSTR_EX_DEF(MAGIC_STR_197, "isDirectory") \ 218 | MAGICSTR_EX_DEF(MAGIC_STR_198, "memoryUsage") \ 219 | MAGICSTR_EX_DEF(MAGIC_STR_199, "payloadSize") \ 220 | MAGICSTR_EX_DEF(MAGIC_STR_200, "readFloatLE") \ 221 | MAGICSTR_EX_DEF(MAGIC_STR_201, "sendRequest") \ 222 | MAGICSTR_EX_DEF(MAGIC_STR_202, "setPriority") \ 223 | MAGICSTR_EX_DEF(MAGIC_STR_203, "toHexString") \ 224 | MAGICSTR_EX_DEF(MAGIC_STR_204, "_stopUVCheck") \ 225 | MAGICSTR_EX_DEF(MAGIC_STR_205, "onconnection") \ 226 | MAGICSTR_EX_DEF(MAGIC_STR_206, "readDoubleLE") \ 227 | MAGICSTR_EX_DEF(MAGIC_STR_207, "reinitialize") \ 228 | MAGICSTR_EX_DEF(MAGIC_STR_208, "setBroadcast") \ 229 | MAGICSTR_EX_DEF(MAGIC_STR_209, "setDutyCycle") \ 230 | MAGICSTR_EX_DEF(MAGIC_STR_210, "setFrequency") \ 231 | MAGICSTR_EX_DEF(MAGIC_STR_211, "setKeepAlive") \ 232 | MAGICSTR_EX_DEF(MAGIC_STR_212, "takeSnapshot") \ 233 | MAGICSTR_EX_DEF(MAGIC_STR_213, "NODEMCUJS_ENV") \ 234 | MAGICSTR_EX_DEF(MAGIC_STR_214, "_getOSRelease") \ 235 | MAGICSTR_EX_DEF(MAGIC_STR_215, "_startUVCheck") \ 236 | MAGICSTR_EX_DEF(MAGIC_STR_216, "addMembership") \ 237 | MAGICSTR_EX_DEF(MAGIC_STR_217, "compileModule") \ 238 | MAGICSTR_EX_DEF(MAGIC_STR_218, "createRequest") \ 239 | MAGICSTR_EX_DEF(MAGIC_STR_219, "finishRequest") \ 240 | MAGICSTR_EX_DEF(MAGIC_STR_220, "handleTimeout") \ 241 | MAGICSTR_EX_DEF(MAGIC_STR_221, "stopProfiling") \ 242 | MAGICSTR_EX_DEF(MAGIC_STR_222, "transferArray") \ 243 | MAGICSTR_EX_DEF(MAGIC_STR_223, "NODEMCUJS_PATH") \ 244 | MAGICSTR_EX_DEF(MAGIC_STR_224, "dropMembership") \ 245 | MAGICSTR_EX_DEF(MAGIC_STR_225, "startProfiling") \ 246 | MAGICSTR_EX_DEF(MAGIC_STR_226, "transferBuffer") \ 247 | MAGICSTR_EX_DEF(MAGIC_STR_227, "builtin_modules") \ 248 | MAGICSTR_EX_DEF(MAGIC_STR_228, "compileSnapshot") \ 249 | MAGICSTR_EX_DEF(MAGIC_STR_229, "payloadRealSize") \ 250 | MAGICSTR_EX_DEF(MAGIC_STR_230, "protocolVersion") \ 251 | MAGICSTR_EX_DEF(MAGIC_STR_231, "setMulticastTTL") \ 252 | MAGICSTR_EX_DEF(MAGIC_STR_232, "shouldkeepalive") \ 253 | MAGICSTR_EX_DEF(MAGIC_STR_233, "writeUtf8String") \ 254 | MAGICSTR_EX_DEF(MAGIC_STR_234, "_getProcessTitle") \ 255 | MAGICSTR_EX_DEF(MAGIC_STR_235, "_setProcessTitle") \ 256 | MAGICSTR_EX_DEF(MAGIC_STR_236, "isAliveExceptFor") \ 257 | MAGICSTR_EX_DEF(MAGIC_STR_237, "openNativeModule") \ 258 | MAGICSTR_EX_DEF(MAGIC_STR_238, "OnHeadersComplete") \ 259 | MAGICSTR_EX_DEF(MAGIC_STR_239, "OnMessageComplete") \ 260 | MAGICSTR_EX_DEF(MAGIC_STR_240, "debuggerWaitSource") \ 261 | MAGICSTR_EX_DEF(MAGIC_STR_241, "payloadMissingSize") \ 262 | MAGICSTR_EX_DEF(MAGIC_STR_242, "rejectUnauthorized") \ 263 | MAGICSTR_EX_DEF(MAGIC_STR_243, "_onUncaughtException") \ 264 | MAGICSTR_EX_DEF(MAGIC_STR_244, "setMulticastLoopback") \ 265 | MAGICSTR_EX_DEF(MAGIC_STR_245, "debuggerSourceCompile") \ 266 | MAGICSTR_EX_DEF(MAGIC_STR_246, "getInterfaceAddresses") \ 267 | 268 | -------------------------------------------------------------------------------- /main/src/nodemcujs_utils.c: -------------------------------------------------------------------------------- 1 | #include "nodemcujs_utils.h" 2 | 3 | #include 4 | 5 | void force_terminate() { 6 | exit(EXIT_FAILURE); 7 | } -------------------------------------------------------------------------------- /main/src/nodemcujs_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef NODEMCUJS_UTILS_H 2 | #define NODEMCUJS_UTILS_H 3 | 4 | void force_terminate(); 5 | 6 | #endif -------------------------------------------------------------------------------- /main/tools/common_py/__init__.py: -------------------------------------------------------------------------------- 1 | # Required for Python to search this directory for module files 2 | -------------------------------------------------------------------------------- /main/tools/common_py/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodemcujs/nodemcujs-firmware/dc778b2825021746c9b180455191c07f276302e2/main/tools/common_py/__init__.pyc -------------------------------------------------------------------------------- /main/tools/common_py/path.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """ common path for scripts """ 16 | 17 | from common_py.system.filesystem import FileSystem as fs 18 | 19 | # Root directory for the project. 20 | PROJECT_ROOT = fs.abspath(fs.join(fs.dirname(__file__), fs.pardir, fs.pardir)) 21 | 22 | # Source code directory. 23 | SRC_ROOT = fs.join(PROJECT_ROOT, 'src') 24 | 25 | # Root Build directory. 26 | BUILD_ROOT = fs.join(PROJECT_ROOT, 'build') 27 | 28 | # Root Build directory. 29 | TOOLS_ROOT = fs.join(PROJECT_ROOT, 'tools') 30 | 31 | # Root directory for dependencies. 32 | DEPS_ROOT = fs.join(PROJECT_ROOT, 'deps') 33 | 34 | # Root directory for test. 35 | TEST_ROOT = fs.join(PROJECT_ROOT, 'test') 36 | 37 | RUN_PASS_DIR = fs.join(TEST_ROOT, 'run_pass') 38 | 39 | RUN_FAIL_DIR = fs.join(TEST_ROOT, 'run_fail') 40 | 41 | RESOURCE_DIR = fs.join(TEST_ROOT, 'resources') 42 | 43 | # Root directory for JerryScript submodule. 44 | JERRY_ROOT = fs.join(DEPS_ROOT, 'jerry') 45 | 46 | # Root directory of JerryScript profiles. 47 | JERRY_PROFILE_ROOT = fs.join(JERRY_ROOT, 'jerry-core', 'profiles') 48 | 49 | # Root directory for libtuv submodule. 50 | TUV_ROOT = fs.join(DEPS_ROOT, 'libtuv') 51 | 52 | # Root directory for http-parser submodule. 53 | HTTPPARSER_ROOT = fs.join(DEPS_ROOT, 'http-parser') 54 | 55 | # Build configuration file path. 56 | BUILD_CONFIG_PATH = fs.join(PROJECT_ROOT, 'build.config') 57 | 58 | # IoT.js build information. 59 | BUILD_INFO_PATH = fs.join(TOOLS_ROOT, 'iotjs_build_info.js') 60 | -------------------------------------------------------------------------------- /main/tools/common_py/path.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodemcujs/nodemcujs-firmware/dc778b2825021746c9b180455191c07f276302e2/main/tools/common_py/path.pyc -------------------------------------------------------------------------------- /main/tools/common_py/system/__init__.py: -------------------------------------------------------------------------------- 1 | # Required for Python to search this directory for module files 2 | -------------------------------------------------------------------------------- /main/tools/common_py/system/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodemcujs/nodemcujs-firmware/dc778b2825021746c9b180455191c07f276302e2/main/tools/common_py/system/__init__.pyc -------------------------------------------------------------------------------- /main/tools/common_py/system/executor.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import print_function 16 | 17 | import subprocess 18 | from os import environ 19 | 20 | 21 | class Executor(object): 22 | _TERM_RED = "\033[1;31m" 23 | _TERM_YELLOW = "\033[1;33m" 24 | _TERM_GREEN = "\033[1;32m" 25 | _TERM_BLUE = "\033[1;34m" 26 | _TERM_EMPTY = "\033[0m" 27 | 28 | @staticmethod 29 | def cmd_line(cmd, args=[]): 30 | return ' '.join([cmd] + args) 31 | 32 | @staticmethod 33 | def print_cmd_line(cmd, args=[]): 34 | print("%s%s%s" % (Executor._TERM_BLUE, Executor.cmd_line(cmd, args), 35 | Executor._TERM_EMPTY)) 36 | print() 37 | 38 | @staticmethod 39 | def fail(msg): 40 | print() 41 | print("%s%s%s" % (Executor._TERM_RED, msg, Executor._TERM_EMPTY)) 42 | print() 43 | exit(1) 44 | 45 | @staticmethod 46 | def run_cmd(cmd, args=[], quiet=False, cwd=None): 47 | if not quiet: 48 | Executor.print_cmd_line(cmd, args) 49 | try: 50 | return subprocess.call([cmd] + args, cwd=cwd, env=environ) 51 | except OSError as e: 52 | Executor.fail("[Failed - %s] %s" % (cmd, e.strerror)) 53 | 54 | @staticmethod 55 | def run_cmd_output(cmd, args=[], quiet=False): 56 | if not quiet: 57 | Executor.print_cmd_line(cmd, args) 58 | try: 59 | return subprocess.check_output([cmd] + args) 60 | except OSError as e: 61 | Executor.fail("[Failed - %s] %s" % (cmd, e.strerror)) 62 | 63 | @staticmethod 64 | def check_run_cmd(cmd, args=[], quiet=False, cwd=None): 65 | retcode = Executor.run_cmd(cmd, args, quiet, cwd) 66 | if retcode != 0: 67 | Executor.fail("[Failed - %d] %s" % (retcode, 68 | Executor.cmd_line(cmd, args))) 69 | -------------------------------------------------------------------------------- /main/tools/common_py/system/filesystem.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Copyright (C) 2010 Google Inc. All rights reserved. 16 | # 17 | # Redistribution and use in source and binary forms, with or without 18 | # modification, are permitted provided that the following conditions are 19 | # met: 20 | # 21 | # * Redistributions of source code must retain the above copyright 22 | # notice, this list of conditions and the following disclaimecd r. 23 | # * Redistributions in binary form must reproduce the above 24 | # copyright notice, this list of conditions and the following disclaimer 25 | # in the documentation and/or other materials provided with the 26 | # distribution. 27 | # * Neither the name of Google Inc. nor the names of its 28 | # contributors may be used to endorse or promote products derived from 29 | # this software without specific prior written permission. 30 | # 31 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 36 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 37 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 38 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 41 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 | 43 | """ Wrapper object for the file system """ 44 | 45 | 46 | import codecs 47 | import errno 48 | import filecmp 49 | import glob 50 | import hashlib 51 | import os 52 | import shutil 53 | import sys 54 | import tempfile 55 | import time 56 | try: 57 | import exceptions 58 | except ImportError: 59 | class exceptions(object): 60 | OSError = OSError 61 | 62 | 63 | class FileSystem(object): 64 | """FileSystem interface for IoT.js. 65 | 66 | Unless otherwise noted, all paths are allowed to be either absolute 67 | or relative.""" 68 | sep = os.sep 69 | pardir = os.pardir 70 | 71 | @staticmethod 72 | def abspath(path): 73 | # FIXME: This gross hack is needed while we transition from Cygwin 74 | # to native Windows, because we have some mixing of file conventions 75 | # from different tools: 76 | if sys.platform == 'cygwin': 77 | path = os.path.normpath(path) 78 | path_components = path.split(os.sep) 79 | if (path_components and len(path_components[0]) == 2 80 | and path_components[0][1] == ':'): 81 | path_components[0] = path_components[0][0] 82 | path = os.path.join('/', 'cygdrive', *path_components) 83 | 84 | return os.path.abspath(path) 85 | 86 | @staticmethod 87 | def realpath(path): 88 | return os.path.realpath(path) 89 | 90 | @staticmethod 91 | def path_to_module(module_name): 92 | """A wrapper for all calls to __file__ to allow easy unit testing.""" 93 | # FIXME: This is the only use of sys in this file. It's possible this 94 | # function should move elsewhere. 95 | # __file__ is always an absolute path. 96 | return sys.modules[module_name].__file__ 97 | 98 | @staticmethod 99 | def expanduser(path): 100 | return os.path.expanduser(path) 101 | 102 | @staticmethod 103 | def basename(path): 104 | return os.path.basename(path) 105 | 106 | @staticmethod 107 | def chdir(path): 108 | return os.chdir(path) 109 | 110 | @staticmethod 111 | def copy(source, destination): 112 | shutil.copy(source, destination) 113 | 114 | @staticmethod 115 | def copyfile(source, destination): 116 | shutil.copyfile(source, destination) 117 | 118 | @staticmethod 119 | def dirname(path): 120 | return os.path.dirname(path) 121 | 122 | @staticmethod 123 | def exists(path): 124 | return os.path.exists(path) 125 | 126 | @staticmethod 127 | def dirs_under(path, dir_filter=None): 128 | """Return the list of all directories under the given path in 129 | topdown order. 130 | 131 | Args: 132 | dir_filter: if not None, the filter will be invoked 133 | with the filesystem object and the path of each dirfound. 134 | The dir is included in the result if the callback returns True. 135 | """ 136 | def filter_all(dirpath): 137 | return True 138 | dir_filter = dir_filter or filter_all 139 | 140 | dirs = [] 141 | for (dirpath, dirnames, filenames) in os.walk(path): 142 | if dir_filter(dirpath): 143 | dirs.append(dirpath) 144 | return dirs 145 | 146 | @staticmethod 147 | def files_under(path, dirs_to_skip=[], file_filter=None): 148 | """Return the list of all files under the given path in topdown order. 149 | 150 | Args: 151 | dirs_to_skip: a list of directories to skip over during the 152 | traversal (e.g., .svn, resources, etc.) 153 | file_filter: if not None, the filter will be invoked 154 | with the filesystem object and the dirname and basename of 155 | each file found. The file is included in the result if the 156 | callback returns True. 157 | """ 158 | def filter_all(dirpath, basename): 159 | return True 160 | 161 | file_filter = file_filter or filter_all 162 | files = [] 163 | if FileSystem.isfile(path): 164 | if file_filter(dirname(path), FileSystem.basename(path)): 165 | files.append(path) 166 | return files 167 | 168 | if FileSystem.basename(path) in dirs_to_skip: 169 | return [] 170 | 171 | for (dirpath, dirnames, filenames) in os.walk(path): 172 | for d in dirs_to_skip: 173 | if d in dirnames: 174 | dirnames.remove(d) 175 | 176 | for filename in filenames: 177 | if file_filter(dirpath, filename): 178 | files.append(FileSystem.join(dirpath, filename)) 179 | return files 180 | 181 | @staticmethod 182 | def getcwd(): 183 | return os.getcwd() 184 | 185 | @staticmethod 186 | def glob(path): 187 | return glob.glob(path) 188 | 189 | @staticmethod 190 | def isabs(path): 191 | return os.path.isabs(path) 192 | 193 | @staticmethod 194 | def isfile(path): 195 | return os.path.isfile(path) 196 | 197 | @staticmethod 198 | def getsize(path): 199 | return os.path.getsize(path) 200 | 201 | @staticmethod 202 | def isdir(path): 203 | return os.path.isdir(path) 204 | 205 | @staticmethod 206 | def join(*comps): 207 | return os.path.join(*comps) 208 | 209 | @staticmethod 210 | def listdir(path): 211 | return os.listdir(path) 212 | 213 | @staticmethod 214 | def mkdtemp(**kwargs): 215 | """Create and return a uniquely named directory. 216 | 217 | This is like tempfile.mkdtemp, but if used in a with statement 218 | the directory will self-delete at the end of the block (if the 219 | directory is empty; non-empty directories raise errors). The 220 | directory can be safely deleted inside the block as well, if so 221 | desired. 222 | 223 | Note that the object returned is not a string and does not support 224 | all of the string methods. If you need a string, coerce the object 225 | to a string and go from there. 226 | """ 227 | class TemporaryDirectory(object): 228 | def __init__(self, **kwargs): 229 | self._kwargs = kwargs 230 | self._directory_path = tempfile.mkdtemp(**self._kwargs) 231 | 232 | def __str__(self): 233 | return self._directory_path 234 | 235 | def __enter__(self): 236 | return self._directory_path 237 | 238 | def __exit__(self, type, value, traceback): 239 | # Only self-delete if necessary. 240 | 241 | # FIXME: Should we delete non-empty directories? 242 | if os.path.exists(self._directory_path): 243 | os.rmdir(self._directory_path) 244 | 245 | return TemporaryDirectory(**kwargs) 246 | 247 | @staticmethod 248 | def maybe_make_directory(*path): 249 | """Create the specified directory if it doesn't already exist.""" 250 | try: 251 | os.makedirs(FileSystem.join(*path)) 252 | except OSError as e: 253 | if e.errno != errno.EEXIST: 254 | raise 255 | 256 | @staticmethod 257 | def move(source, destination): 258 | shutil.move(source, destination) 259 | 260 | @staticmethod 261 | def mtime(path): 262 | return os.stat(path).st_mtime 263 | 264 | @staticmethod 265 | def normpath(path): 266 | return os.path.normpath(path) 267 | 268 | @staticmethod 269 | def open_binary_tempfile(suffix): 270 | """Create, open, and return a binary temp file. Returns a tuple of 271 | the file and the name.""" 272 | temp_fd, temp_name = tempfile.mkstemp(suffix) 273 | f = os.fdopen(temp_fd, 'wb') 274 | return f, temp_name 275 | 276 | @staticmethod 277 | def open_binary_file_for_reading(path): 278 | return codecs.open(path, 'rb') 279 | 280 | @staticmethod 281 | def read_binary_file(path): 282 | """Return the contents of the file at the given path as a 283 | byte string.""" 284 | with file(path, 'rb') as f: 285 | return f.read() 286 | 287 | @staticmethod 288 | def write_binary_file(path, contents): 289 | with file(path, 'wb') as f: 290 | f.write(contents) 291 | 292 | @staticmethod 293 | def open_text_file_for_reading(path, errors='strict'): 294 | # Note: There appears to be an issue with the returned file objects 295 | # not being seekable. See http://stackoverflow.com/questions/1510188/ 296 | # can-seek-and-tell-work-with-utf-8-encoded-documents-in-python . 297 | return codecs.open(path, 'r', 'utf8', errors) 298 | 299 | @staticmethod 300 | def open_text_file_for_writing(path): 301 | return codecs.open(path, 'w', 'utf8') 302 | 303 | @staticmethod 304 | def open_stdin(): 305 | return codecs.StreamReaderWriter(sys.stdin, 306 | codecs.getreader('utf8'), 307 | codecs.getwriter('utf8'), 308 | 'replace') 309 | 310 | @staticmethod 311 | def read_text_file(path): 312 | """Return the contents of the file at the given path as 313 | a Unicode string. 314 | 315 | The file is read assuming it is a UTF-8 encoded file with no BOM.""" 316 | with codecs.open(path, 'r', 'utf8') as f: 317 | return f.read() 318 | 319 | @staticmethod 320 | def write_text_file(path, contents): 321 | """Write the contents to the file at the given location. 322 | 323 | The file is written encoded as UTF-8 with no BOM.""" 324 | with codecs.open(path, 'w', 'utf-8') as f: 325 | f.write(contents.decode('utf-8') if type(contents) == str 326 | else contents) 327 | 328 | @staticmethod 329 | def sha1(path): 330 | contents = FileSystem.read_binary_file(path) 331 | return hashlib.sha1(contents).hexdigest() 332 | 333 | @staticmethod 334 | def relpath(path, start='.'): 335 | return os.path.relpath(path, start) 336 | 337 | class _WindowsError(exceptions.OSError): 338 | """Fake exception for Linux and Mac.""" 339 | pass 340 | 341 | @staticmethod 342 | def remove(path, osremove=os.remove): 343 | """On Windows, if a process was recently killed and it held on to a 344 | file, the OS will hold on to the file for a short while. This makes 345 | attempts to delete the file fail. To work around that, this method 346 | will retry for a few seconds until Windows is done with the file.""" 347 | try: 348 | exceptions.WindowsError 349 | except AttributeError: 350 | exceptions.WindowsError = FileSystem._WindowsError 351 | 352 | retry_timeout_sec = 3.0 353 | sleep_interval = 0.1 354 | while True: 355 | try: 356 | osremove(path) 357 | return True 358 | except exceptions.WindowsError as e: 359 | time.sleep(sleep_interval) 360 | retry_timeout_sec -= sleep_interval 361 | if retry_timeout_sec < 0: 362 | raise e 363 | 364 | @staticmethod 365 | def rmtree(path): 366 | """Delete the directory rooted at path, whether empty or not.""" 367 | shutil.rmtree(path, ignore_errors=True) 368 | 369 | @staticmethod 370 | def copytree(source, destination): 371 | shutil.copytree(source, destination) 372 | 373 | @staticmethod 374 | def split(path): 375 | """Return (dirname, basename + '.' + ext)""" 376 | return os.path.split(path) 377 | 378 | @staticmethod 379 | def splitext(path): 380 | """Return (dirname + os.sep + basename, '.' + ext)""" 381 | return os.path.splitext(path) 382 | 383 | @staticmethod 384 | def compare(path1, path2): 385 | return filecmp.cmp(path1, path2) 386 | -------------------------------------------------------------------------------- /main/tools/common_py/system/filesystem.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodemcujs/nodemcujs-firmware/dc778b2825021746c9b180455191c07f276302e2/main/tools/common_py/system/filesystem.pyc -------------------------------------------------------------------------------- /main/tools/common_py/system/platform.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | 17 | 18 | class Platform(object): 19 | def __init__(self): 20 | _os, _, _, _, _arch = os.uname() 21 | self._os = _os 22 | self._arch = _arch 23 | 24 | def os(self): 25 | """ Retrieve host OS name. """ 26 | return self._os.lower() 27 | 28 | def arch(self): 29 | """ Retrieve host arch name. """ 30 | arch = self._arch.lower() 31 | if arch in ["armv7l"]: 32 | arch = "arm" 33 | return arch 34 | -------------------------------------------------------------------------------- /main/tools/js2c.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # This file converts src/js/*.js to a C-array in src/nodemcujs_js.[h|c] file. 18 | # And this file also generates magic string list in src/nodemcujs_string_ext.inl.h 19 | # file to reduce JerryScript heap usage. 20 | 21 | import os 22 | import re 23 | import subprocess 24 | import struct 25 | import string 26 | 27 | from common_py.system.filesystem import FileSystem as fs 28 | from common_py import path 29 | 30 | def regroup(l, n): 31 | return [l[i:i+n] for i in range(0, len(l), n)] 32 | 33 | 34 | def remove_comments(code): 35 | pattern = r'(\".*?\"|\'.*?\')|(/\*.*?\*/|//[^\r\n]*$)' 36 | regex = re.compile(pattern, re.MULTILINE | re.DOTALL) 37 | 38 | def _replacer(match): 39 | if match.group(2) is not None: 40 | return "" 41 | else: 42 | return match.group(1) 43 | 44 | return regex.sub(_replacer, code) 45 | 46 | 47 | def remove_whitespaces(code): 48 | return re.sub('\n+', '\n', re.sub('\n +', '\n', code)) 49 | 50 | 51 | def force_str(string): 52 | if not isinstance(string, str): 53 | return string.decode('utf-8') 54 | else: 55 | return string 56 | 57 | 58 | def parse_literals(code): 59 | JERRY_SNAPSHOT_VERSION = 51 60 | JERRY_SNAPSHOT_MAGIC = 0x5952524A 61 | 62 | literals = set() 63 | # header format: 64 | # uint32_t magic 65 | # uint32_t version 66 | # uint32_t global opts 67 | # uint32_t literal table offset 68 | header = struct.unpack('I' * 4, code[0:4 * 4]) 69 | if header[0] != JERRY_SNAPSHOT_MAGIC: 70 | print('Incorrect snapshot format! Magic number is incorrect') 71 | exit(1) 72 | print(header) 73 | if header[1] != JERRY_SNAPSHOT_VERSION: 74 | print ('Please check jerry snapshot version (Last confirmed: %d)' 75 | % JERRY_SNAPSHOT_VERSION) 76 | exit(1) 77 | 78 | code_ptr = header[3] + 4 79 | 80 | while code_ptr < len(code): 81 | length = struct.unpack('H', code[code_ptr : code_ptr + 2])[0] 82 | code_ptr = code_ptr + 2 83 | if length == 0: 84 | continue 85 | if length < 32: 86 | item = struct.unpack('%ds' % length, 87 | code[code_ptr : code_ptr + length]) 88 | literals.add(force_str(item[0])) 89 | code_ptr = code_ptr + length + (length % 2) 90 | 91 | return literals 92 | 93 | 94 | LICENSE = ''' 95 | /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors 96 | * 97 | * Licensed under the Apache License, Version 2.0 (the \"License\"); 98 | * you may not use this file except in compliance with the License. 99 | * You may obtain a copy of the License at 100 | * 101 | * http://www.apache.org/licenses/LICENSE-2.0 102 | * 103 | * Unless required by applicable law or agreed to in writing, software 104 | * distributed under the License is distributed on an \"AS IS\" BASIS 105 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 106 | * See the License for the specific language governing permissions and 107 | * limitations under the License. 108 | * 109 | * This file is generated by tools/js2c.py 110 | * Do not modify this. 111 | */ 112 | ''' 113 | 114 | HEADER1 = '''#ifndef NODEMCUJS_JS_H 115 | #define NODEMCUJS_JS_H 116 | ''' 117 | 118 | FOOTER1 = ''' 119 | #endif 120 | ''' 121 | 122 | HEADER2 = '''#include 123 | #include 124 | #include "nodemcujs_js.h" 125 | ''' 126 | 127 | EMPTY_LINE = '\n' 128 | 129 | MAGIC_STRINGS_HEADER = '#define JERRY_MAGIC_STRING_ITEMS \\\n' 130 | 131 | MODULE_SNAPSHOT_VARIABLES_H = ''' 132 | extern const char module_{NAME}[]; 133 | extern const uint32_t module_{NAME}_idx; 134 | ''' 135 | 136 | MODULE_SNAPSHOT_VARIABLES_C = ''' 137 | #define MODULE_{NAME}_IDX ({IDX}) 138 | const char module_{NAME}[] = "{NAME}"; 139 | const uint32_t module_{NAME}_idx = MODULE_{NAME}_IDX; 140 | ''' 141 | 142 | NATIVE_SNAPSHOT_STRUCT_H = ''' 143 | typedef struct { 144 | const char* name; 145 | const uint32_t idx; 146 | } nodemcujs_js_module_t; 147 | 148 | extern const nodemcujs_js_module_t js_modules[]; 149 | ''' 150 | 151 | MODULE_VARIABLES_H = ''' 152 | extern const char {NAME}_n[]; 153 | extern const uint8_t {NAME}_s[]; 154 | extern const size_t {NAME}_l; 155 | ''' 156 | 157 | MODULE_VARIABLES_C = ''' 158 | #define SIZE_{NAME_UPPER} {SIZE} 159 | const size_t {NAME}_l = SIZE_{NAME_UPPER}; 160 | const char {NAME}_n[] = "{NAME}"; 161 | const uint8_t {NAME}_s[] = {{ 162 | {CODE} 163 | }}; 164 | ''' 165 | 166 | NATIVE_STRUCT_H = ''' 167 | typedef struct { 168 | const char* name; 169 | const void* code; 170 | const size_t length; 171 | } nodemcujs_js_module_t; 172 | 173 | extern const nodemcujs_js_module_t js_modules[]; 174 | ''' 175 | 176 | NATIVE_STRUCT_C = ''' 177 | const nodemcujs_js_module_t js_modules[] = {{ 178 | {MODULES} 179 | }}; 180 | ''' 181 | 182 | 183 | def hex_format(ch): 184 | if isinstance(ch, str): 185 | ch = ord(ch) 186 | 187 | return "0x{:02x}".format(ch) 188 | 189 | 190 | def format_code(code, indent): 191 | lines = [] 192 | # convert all characters to hex format 193 | converted_code = map(hex_format, code) 194 | # 10 hex number per line 195 | for line in regroup(", ".join(converted_code), 10 * 6): 196 | lines.append((' ' * indent) + line.strip()) 197 | 198 | return "\n".join(lines) 199 | 200 | 201 | def merge_snapshots(snapshot_infos, snapshot_tool): 202 | output_path = fs.join(path.SRC_ROOT, 'js','merged.modules') 203 | cmd = [snapshot_tool, "merge", "-o", output_path] 204 | cmd.extend([item['path'] for item in snapshot_infos]) 205 | 206 | ret = subprocess.call(cmd) 207 | 208 | if ret != 0: 209 | msg = "Failed to merge %s: - %d" % (snapshot_infos, ret) 210 | print("%s%s%s" % ("\033[1;31m", msg, "\033[0m")) 211 | exit(1) 212 | 213 | for item in snapshot_infos: 214 | fs.remove(item['path']) 215 | 216 | with open(output_path, 'rb') as snapshot: 217 | code = snapshot.read() 218 | 219 | fs.remove(output_path) 220 | return code 221 | 222 | 223 | def get_snapshot_contents(js_path, snapshot_tool): 224 | """ Convert the given module with the snapshot generator 225 | and return the resulting bytes. 226 | """ 227 | wrapped_path = js_path + ".wrapped" 228 | snapshot_path = js_path + ".snapshot" 229 | module_name = os.path.splitext(os.path.basename(js_path))[0] 230 | 231 | with open(wrapped_path, 'w') as fwrapped, open(js_path, "r") as fmodule: 232 | if module_name != "nodemcujs": 233 | fwrapped.write("(function(exports, require, module, native) {\n") 234 | 235 | fwrapped.write(fmodule.read()) 236 | 237 | if module_name != "nodemcujs": 238 | fwrapped.write("});\n") 239 | 240 | ret = subprocess.call([snapshot_tool, 241 | "generate", 242 | "--context", "eval", 243 | "-o", snapshot_path, 244 | wrapped_path]) 245 | 246 | fs.remove(wrapped_path) 247 | if ret != 0: 248 | msg = "Failed to dump %s: - %d" % (js_path, ret) 249 | print("%s%s%s" % ("\033[1;31m", msg, "\033[0m")) 250 | fs.remove(snapshot_path) 251 | exit(1) 252 | 253 | return snapshot_path 254 | 255 | 256 | def get_js_contents(js_path, is_debug_mode=False): 257 | """ Read the contents of the given js module. """ 258 | with open(js_path, "r") as f: 259 | code = f.read() 260 | 261 | # minimize code when in release mode 262 | if not is_debug_mode: 263 | code = remove_comments(code) 264 | code = remove_whitespaces(code) 265 | return code 266 | 267 | 268 | def js2c(buildtype, js_modules, snapshot_tool=None, verbose=False): 269 | is_debug_mode = (buildtype == "debug") 270 | no_snapshot = (snapshot_tool == None) 271 | magic_string_set = set() 272 | 273 | str_const_regex = re.compile('^#define NODEMCUJS_MAGIC_STRING_\w+\s+"(\w+)"$') 274 | with open(fs.join(path.SRC_ROOT, 'nodemcujs_magic_strings.h'), 'r') as fin_h: 275 | for line in fin_h: 276 | result = str_const_regex.search(line) 277 | if result: 278 | magic_string_set.add(result.group(1)) 279 | 280 | # generate the code for the modules 281 | with open(fs.join(path.SRC_ROOT, 'nodemcujs_js.h'), 'w') as fout_h, \ 282 | open(fs.join(path.SRC_ROOT, 'nodemcujs_js.c'), 'w') as fout_c: 283 | 284 | fout_h.write(LICENSE) 285 | fout_h.write(HEADER1) 286 | fout_c.write(LICENSE) 287 | fout_c.write(HEADER2) 288 | 289 | snapshot_infos = [] 290 | js_module_names = [] 291 | for idx, module in enumerate(sorted(js_modules)): 292 | [name, js_path] = module.split('=', 1) 293 | js_module_names.append(name) 294 | if verbose: 295 | print('Processing module: %s' % name) 296 | 297 | if no_snapshot: 298 | code = get_js_contents(js_path, is_debug_mode) 299 | code_string = format_code(code, 1) 300 | 301 | fout_h.write(MODULE_VARIABLES_H.format(NAME=name)) 302 | fout_c.write(MODULE_VARIABLES_C.format(NAME=name, 303 | NAME_UPPER=name.upper(), 304 | SIZE=len(code), 305 | CODE=code_string)) 306 | else: 307 | code_path = get_snapshot_contents(js_path, snapshot_tool) 308 | info = {'name': name, 'path': code_path, 'idx': idx} 309 | snapshot_infos.append(info) 310 | 311 | fout_h.write(MODULE_SNAPSHOT_VARIABLES_H.format(NAME=name)) 312 | fout_c.write(MODULE_SNAPSHOT_VARIABLES_C.format(NAME=name, 313 | IDX=idx)) 314 | 315 | if no_snapshot: 316 | modules_struct = [ 317 | ' {{ {0}_n, {0}_s, SIZE_{1} }},'.format(name, name.upper()) 318 | for name in sorted(js_module_names) 319 | ] 320 | modules_struct.append(' { NULL, NULL, 0 }') 321 | else: 322 | code = merge_snapshots(snapshot_infos, snapshot_tool) 323 | code_string = format_code(code, 1) 324 | magic_string_set |= parse_literals(code) 325 | 326 | name = 'nodemcujs_js_modules' 327 | fout_h.write(MODULE_VARIABLES_H.format(NAME=name)) 328 | fout_c.write(MODULE_VARIABLES_C.format(NAME=name, 329 | NAME_UPPER=name.upper(), 330 | SIZE=len(code), 331 | CODE=code_string)) 332 | modules_struct = [ 333 | ' {{ module_{0}, MODULE_{0}_IDX }},'.format(info['name']) 334 | for info in snapshot_infos 335 | ] 336 | modules_struct.append(' { NULL, 0 }') 337 | 338 | if no_snapshot: 339 | native_struct_h = NATIVE_STRUCT_H 340 | else: 341 | native_struct_h = NATIVE_SNAPSHOT_STRUCT_H 342 | 343 | fout_h.write(native_struct_h) 344 | fout_h.write(FOOTER1) 345 | 346 | fout_c.write(NATIVE_STRUCT_C.format(MODULES="\n".join(modules_struct))) 347 | fout_c.write(EMPTY_LINE) 348 | 349 | # Write out the external magic strings 350 | magic_str_path = fs.join(path.SRC_ROOT, 'nodemcujs_string_ext.inl.h') 351 | with open(magic_str_path, 'w') as fout_magic_str: 352 | fout_magic_str.write(LICENSE) 353 | fout_magic_str.write(MAGIC_STRINGS_HEADER) 354 | 355 | sorted_strings = sorted(magic_string_set, key=lambda x: (len(x), x)) 356 | for idx, magic_string in enumerate(sorted_strings): 357 | magic_text = repr(magic_string)[1:-1] 358 | magic_text = magic_text.replace("\"", "\\\"") 359 | 360 | fout_magic_str.write(' MAGICSTR_EX_DEF(MAGIC_STR_%d, "%s") \\\n' 361 | % (idx, magic_text)) 362 | # an empty line is required to avoid compile warning 363 | fout_magic_str.write(EMPTY_LINE) 364 | 365 | 366 | if __name__ == "__main__": 367 | import argparse 368 | parser = argparse.ArgumentParser() 369 | 370 | parser.add_argument('--buildtype', 371 | choices=['debug', 'release'], default='debug', 372 | help='Specify the build type: %(choices)s (default: %(default)s)') 373 | parser.add_argument('--modules', required=True, 374 | help='List of JS files to process. Format: ' 375 | '=,=,...') 376 | parser.add_argument('--snapshot-tool', default=None, 377 | help='Executable to use for generating snapshots and merging them ' 378 | '(ex.: the JerryScript snapshot tool). ' 379 | 'If not specified the JS files will be directly processed.') 380 | parser.add_argument('-v', '--verbose', default=False, 381 | help='Enable verbose output.') 382 | 383 | options = parser.parse_args() 384 | 385 | if not options.snapshot_tool: 386 | print('Converting JS modules to C arrays (no snapshot)') 387 | else: 388 | print('Using "%s" as snapshot tool' % options.snapshot_tool) 389 | 390 | modules = options.modules.replace(',', ' ').split() 391 | js2c(options.buildtype, modules, options.snapshot_tool, options.verbose) 392 | -------------------------------------------------------------------------------- /partitions.csv: -------------------------------------------------------------------------------- 1 | # Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild 2 | # Name, Type, SubType, Offset, Size, Flags 3 | nvs, data, nvs, 0x9000, 0x6000, 4 | phy_init, data, phy, 0xf000, 0x1000, 5 | factory, app, factory, 0x10000, 1M, 6 | storage, data, spiffs, , 0x2F0000, 7 | -------------------------------------------------------------------------------- /scripts/build-firmware.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir build 4 | cd build 5 | cmake .. 6 | make -------------------------------------------------------------------------------- /scripts/install-idf-v3.2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ~/ 4 | 5 | wget https://github.com/espressif/esp-idf/releases/download/v3.2/esp-idf-v3.2.zip 6 | unzip -q esp-idf-v3.2.zip 7 | python -m pip install --user -r esp-idf-v3.2/requirements.txt -------------------------------------------------------------------------------- /scripts/install-xtensa.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ~/ 4 | 5 | wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz 6 | tar -zxf xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz -------------------------------------------------------------------------------- /spiffs/index.js: -------------------------------------------------------------------------------- 1 | var LED_PIN = 2; 2 | var INPUT = 1; 3 | var OUTPUT = 2; 4 | var HIGH = 1; 5 | var LOW = 0; 6 | 7 | var gpio = require('gpio'); 8 | gpio.mode(LED_PIN, OUTPUT); 9 | 10 | console.log("staring sort test..."); 11 | 12 | function sort(arr) { 13 | var n = arr.length; 14 | var temp = null; 15 | for (var i = 0; i < n - 1; i++) { 16 | for (var j = 0; j < n - 1 - i; j++) { 17 | if (arr[j] > arr[j + 1]) { 18 | temp = arr[j]; 19 | arr[j] = arr[j + 1]; 20 | arr[j + 1] = temp; 21 | } 22 | } 23 | } 24 | return arr; 25 | } 26 | 27 | var testArray = [49, 38, 65, 97, 76, 13, 27, 49, 38, 65, 97, 76, 13, 27]; 28 | var startTime = new Date(); 29 | 30 | var index = 0; 31 | for (index = 0; index <= 99; index++) { 32 | sort(testArray); 33 | } 34 | console.log("sort 100 times: %dms", (new Date() - startTime)); 35 | 36 | var state = HIGH; 37 | 38 | setInterval(function() { 39 | gpio.write(LED_PIN, state); 40 | state = state === HIGH ? LOW : HIGH; 41 | }, 1000); --------------------------------------------------------------------------------