国外seo做的好的网站,网站如何进行网络推广,wordpress阿里云rds,3000元网站建设三年MicroQuickJS 在 APM32F427 的移植示例这几天#xff0c;国内开源新闻都在报道一个新的开源项目#xff1a;MicroQuickJS。该项目是传奇人物 Fabrice Bellard 的开源新作品#xff0c;是一款专为嵌入式系统设计的高效 JavaScript 引擎。详见 mquickjs 仓库 → https://githu…MicroQuickJS 在 APM32F427 的移植示例这几天国内开源新闻都在报道一个新的开源项目MicroQuickJS。该项目是传奇人物 Fabrice Bellard 的开源新作品是一款专为嵌入式系统设计的高效 JavaScript 引擎。详见 mquickjs 仓库 → https://github.com/bellard/mquickjs这名工程师的传奇经历大家自行搜搜膜拜。今天带来的小作文是把这个引擎移植到 APM32F427 并跑一个简单的 Demo话不多说这就开始。移植目标先定个小目标——点灯复制varnumber12;varkey2_pinname PD9;// 基本数学运算number8;console.log(The answer is number);console.log(Sin(PI/4) Math.sin(Math.PI /4));// 板载 GPIO 示例varled2 newAPM32F4xx_Pin(PF0);varled3 newAPM32F4xx_Pin(PF1);varkey2 newAPM32F4xx_Pin(key2_pinname);varts Date.now();varled3_level 0;led2.mode OUTled3.mode OUTkey2.mode INled3.level led3_level;console.log(LED2 mode: led2.mode);console.log(LED3 mode: led3.mode);console.log(KEY2 mode: key2.mode);// 按键回调函数varcb function(pin, level) {console.log(Interrupt! PIN: pin , LEVEL: level);if(led3_level 0) {led3_level 1;}else{led3_level 0;}console.log(LED3: led3_level);led3.level led3_level;}// 注册按键回调APM32F4xx_Pin.int_register(key2_pinname, cb);// 闪灯number5;while(number0) {ts Date.now();led2.level 1;while(Date.now() - ts 500);ts Date.now();led2.level 0;while(Date.now() - ts 500);number-1;console.log(:: number, key2.level);}console.log(Blinked!)功能就看上面 js 文件的注释不再赘述。移植要点先创建一个 APM32F427 的基础工程实现串口对接 printf。GPIO实现 LED 控制及按键中断参考移植的代码仓库 board\board_apm32f427z_tiny.c 文件。第二步是 mquickjs 的移植。从 mquickjs 代码仓库克隆代码放在工程 mquickjs 文件夹按以下说明修改。mquickjs 仓库所需修改文件example.cexample_stdlib.c 和 mqjs_stdlib.cmquickjs.h使用 mquickjs 源码自带的工具生成mquickjs_atom.hexample_stdlib.hexample.c这个文件实现了板级驱动与 js 引擎的对接。例如创建 led 的类 APM32F4xx_Pin 的构造函数 js_apm32f4_gpio_constructor复制staticJSValuejs_apm32f4_gpio_constructor(JSContext *ctx, JSValue *this_val,intargc,JSValue *argv){uint32_tpin;APM32F4_GPIO_Data *d;JSValue obj;if(!(argc FRAME_CF_CTOR))returnJS_ThrowTypeError(ctx,must be called with new);argc ~FRAME_CF_CTOR;if(argc 1){returnJS_ThrowTypeError(ctx,Pin-name must be not empty);}JSCStringBuf buf;constchar*str;size_tlen;str JS_ToCStringLen(ctx, len, argv[0], buf);pin board_pin_from_name(str);if(pin INVALID_PIN_NUMBER){returnJS_ThrowTypeError(ctx,Invalid Pin-name);}obj JS_NewObjectClassUser(ctx, JS_CLASS_APM32F4_GPIO);d malloc(sizeof(*d));d-pin_number pin;JS_SetOpaque(ctx, obj, d);returnobj;}对应的 js 代码复制varled2 newAPM32F4xx_Pin(PF0);example.c 还包含了 example_stdlib.h 这个文件但是这个文件不是手写的也不能随意复制而只能使用 mquickjs 自带的工具自动生成。还有 mquickjs_atom.h 也是类似的方式生成。两个头文件对应两个可执行程序都是需要在主机电脑上编译执行可以参考 mquickjs\Makefile 文件内容。编译这两个工具需要 make.exe 和 gcc.exe请自行搜索安装。我的移植仓库中提供了一个 build_stdlib.bat 批处理文件可以生成工具并生成这两个头文件。example_stdlib.c 和 mqjs_stdlib.cexample_stdlib.c 这个文件末尾会包含 mqjs_stdlib.c用于生成上述工具使用不需要编译到单片机程序里。这两个文件主要是定义 JS 环境下的类主要内容是复制staticconstJSPropDef js_apm32f4_gpio_proto[] {JS_CGETSET_DEF(level, js_apm32f4_pin_level_get, js_apm32f4_pin_level_set ),JS_CGETSET_DEF(mode, js_apm32f4_pin_mode_get, js_apm32f4_pin_mode_set ),JS_PROP_END,};staticconstJSPropDef js_apm32f4_gpio[] {JS_CFUNC_DEF(int_register,2, js_apm32f4_gpio_int_register ),JS_PROP_END,};staticconstJSClassDef js_apm32f4_gpio_class JS_CLASS_DEF(APM32F4_Pin,1, js_apm32f4_gpio_constructor, JS_CLASS_APM32F4_GPIO, js_apm32f4_gpio, js_apm32f4_gpio_proto,NULL, js_apm32f4_gpio_finalizer);js_apm32f4_gpio_class 定义了一个名为 APM32F4_Pin 的 JS 类具备level和mode两个属性并且两个属性均可以 set/get一个用于注册中断的函数int_register在 js 里可以这样使用复制led2.mode OUT;led3.level 1;led3.level 0;console.log(LED2 Mode: led2.mode );mquickjs.h这个文件需要注释这一部分复制//#if INTPTR_MAX INT64_MAX//#define JS_PTR64 /* pointers are 64 bit wide instead of 32 bit wide *///#endif注释掉的原因是强制使用 32-bit 平台而不是自动判断。自动判断会出问题是因为自动生成 example_stdlib.h 和 mquickjs_atom.h 的工具是在 PC 上编译和运行采用自动判断的结果是 64-bit生成的头文件也是使用于 64-bit 与 MCU 的运行环境不同。为了兼顾 MCU 所以只能强制在 PC 上也是 32-bit。js 文件的存储当前的 MCU 没有移植文件系统为了也能相对灵活的运行 js 脚本在 Flash 里划出了最高 16KiB 空间把 js 文件直接存在这个空间中。如果需要更换 js 脚本可以使用 jFlash 把 js 脚本写入这个空间。在工程里可以通过分散加载文件实现空间划分可以通过 .incbin 汇编伪指令把文件直接打包到固件中以便提供“内置”的 js 文件。分散加载文件示例。把文件放在 0x08000000 ~ 0x080FBFFF 存放固件0x080FC000 以上存 js 文件LR_IROM1 0x08000000 0x080FC000 { ; load region size_regionER_IROM1 0x08000000 0x000FC000 { ; load address execution address*.o (RESET, First)*(InRoot$$Sections).ANY (RO).ANY (XO)}RW_IRAM1 0x20000000 0x00060000 { ; RW data.ANY (RW ZI)}}LR_IROM2 0x080FC000 0x4000 {JS_IMAGE 0x080FC000 0x4000 {*(.js_image)}}C 文件中使用 .incbin 汇编伪指令把文件直接打包到固件中复制__attribute__((__used__, section(.js_image)))voidram_iamge(void){__asm(.incbin t.js);__asm(.incbin zero.bin);}程序中直接使用如下的指令获取文件内容复制constchar * js_txt (constchar *)Image$$JS_IMAGE$$Base;其中t.js 是合法的 js 文件zero.bin 是4个字节的“零”文件是为了保证读取 0x080FC000 开始的字符串的\0 结尾。编译运行keil 工程中所需的 C 文件有除了 example.c 与 mquickjs 相关的有4个cutils.c, dtoa.c, libm.c, mquickjs.c。js 运行时会实例化类所以依赖动态内存管理所以也需要一定 heap 空间同时栈空间也不能太小。我的设置是编译下载观察走起~预期现象是复位后 LED2 闪烁 5 次后熄灭按 KEY2 会切换 LED3串口助手截图红色箭头是 bsp 部分的输出内容律师框的部分是 js 脚本的输出。视频为证最后虽然本文介绍的是一个简单的示例但是也证明 js 环境确实运行起来了。还针对 APM32F427 的 GPIO 设计了一个简单的类可供实例化并运行起来麻雀虽小五脏俱全。MicroQuickJS 还有更多值得深挖的点大家都用起来呀~能用js写的最终都会用js写移植的 demo 放在代码仓库 → https://gitee.com/quincyzh/mquickjs_apm32f427欢迎点评~。---------------------作者wangqy_ic链接https://bbs.21ic.com/icview-3501521-1-1.html来源21ic.com此文章已获得原创/原创奖标签著作权归21ic所有任何人未经允许禁止转载。