概述
该流程对于功能单一或者功能变更极少的场景是比较友好的,但是对于设备应用层变更比较多或者公板方案开发应用的场景,上述场景显的有些累赘。那么有什么方式可以解决呢??
对于设备应用层变更比较多或者公板方案开发应用的场景,可能因为应用层稍微修改一下就要出固件版本验证,这对于版本管理,时间周期,固件质量都是比较不友好的。那么我们如何避免这些问题??
那么有什么方式呢??答案是有的,如:使用动态模块或者胶水语言(JerryScript,PikaScript)
动态模块:它更多的是一个 ELF 格式加载器,把单独编译的一个 elf 文件的代码段,数据段加载到内存中,并对其中的符号进行解析,绑定到导出的 API 地址上。因为也独立于固件编译,支持动态加载。不过需要编译一份支持动态模块执行的固件。
胶水语言(JerryScript,PikaScript):其实就是脚本语言,应用将以脚本语言的形式存在,通过动态加载脚本语言执行。不过固件需要对应胶水语言的执行引擎。
上述两种方式都是可以使固件跟应用分离,是的应用的变更不会引起固件的变更,这对于固件的稳定性来说更加有保障。只需要测试单独的应用程序。
动态模块相对于胶水语言来说,明显优势不高,对比:
动态模块 | 胶水语言 | |
---|---|---|
API问题 | 运行固件需要特殊处理,需要将API导出 | 通过对应的引擎编写API导出模块 |
应用形式 | 应用程序需要通过固件编译出对应的ELF文件 | 胶水语言无需编译,直接可通过对应引擎加载运行 |
很明显,作者倾向于胶水来改变开发模式,那么使用哪种胶水语言呢??目前轻量级的胶水语言,有JerryScript,PikaScript。我们该如何选择??
JerryScript | PikaScript | |
---|---|---|
资源占用 | RAM <= 64KB, Flash <= 200KB | RAM <= 4KB, Flash <= 32KB |
语言 | JavaScript | Python |
地域 | 海外 | 中国 |
维护情况 | 停止维护 | 持续维护 |
开发对象 | 懂得前端的人员也可以接手嵌入式应用开发 | 需要熟悉python语言 |
开发难度 | 一般 | 一般 |
使用情况 | UI厂商都是用,柿饼,ACE | 相对较少 |
两种胶水语言各有各的优势,我的选择是根据使用场景,开发人员的角度,所以选择JerryScript来解决我开发的困扰及问题。
JerryScript
物联网设备在CPU性能和内存空间方面皆存在严格受限,在使用V8引擎这类大型引擎时难免存在诸多不便。在此背景下,JerryScript引擎诞生了。JerryScript是由三星开发的一款炙手可热的轻量级引擎,其目的是让JavaScript开发者能够更好地构建物联网应用,JerryScript是一个轻量级的JavaScript引擎,用于资源受限的设备,如微控制器。它可以在RAM小于64KB、闪存小于200KB的设备上运行。
JerryScript的主要特征有:
完全符合ECMAScript 5.1标准;
为ARM Thumb-2编译时,二进制大小为160K;
针对低内存消耗进行了高度优化;
以C99编写,以实现最大的便携性;
快照支持将JavaScript源代码预编译为字节代码;
成熟的C API,易于嵌入应用程序。
JerryScript文档说明:
英文 | 中文 | 链接 |
---|---|---|
Getting Started | 入门 | https://github.com/jerryscript-project/jerryscript/blob/master/docs/00.GETTING-STARTED.md |
Configuration | 配置 | https://github.com/jerryscript-project/jerryscript/blob/master/docs/01.CONFIGURATION.md |
API Reference | API参考 | https://github.com/jerryscript-project/jerryscript/blob/master/docs/02.API-REFERENCE.md |
API Example | API示例 | https://github.com/jerryscript-project/jerryscript/blob/master/docs/03.API-EXAMPLE.md |
Internals | 内部构件 | https://github.com/jerryscript-project/jerryscript/blob/master/docs/04.INTERNALS.md |
Migration Guide | 迁移指南 | https://github.com/jerryscript-project/jerryscript/blob/master/docs/16.MIGRATION-GUIDE.md |
JerryScript使用
目前很多UI厂商都在基于JerryScript作为引擎搭建UI框架,比如像RT-THREAD,OpenHarmony等厂商。而且JerryScript被默认作为第三方组件的形式存在。所以我将以RT-THREAD作为我的开发环境描述JavaScript如何在单片机中运行。
以字符串形式加载JS语法
RT-THREAD中已经拥有JerryScript软件包,所以我们需要下载对应软件包即可:
RT-THREAAD的JerryScript已经适配好了,如console打印等,所以我们也不用关心,直接使用。需要包含两个头文件:#include 和#include
JerryScript引擎启动流程(初始化):
intmain(void) { /*JERRY_ENABLE_EXTERNAL_CONTEXT*/ jerry_port_set_default_context(jerry_create_context(PKG_JMEM_HEAP_SIZE*1024,context_alloc,NULL)); /*Initializeengine*/ jerry_init(JERRY_INIT_EMPTY); js_util_init(); returnRT_EOK; }
因为我们还没搭建文件系统所以不能存放XXX.js文件,我们先通过字符串的形式模拟文件内容。
char*script_test= "varrice="RiceJerryScript"rn" "console.log("hello!!",rice);rn" "console.log("helloJerryScriptrunok!!");rn"; voidjs_parse_test(void) { jerry_value_tparsed_code=jerry_parse(NULL,0,(jerry_char_t*)script_test, rt_strlen(script_test),JERRY_PARSE_NO_OPTS); if(jerry_value_is_error(parsed_code)) { rt_kprintf("jerryparsefailed!n"); } else { jerry_value_tret2=jerry_run(parsed_code); rt_kprintf("%s:jerry_runret=%dn",__func__,ret2); } } MSH_CMD_EXPORT(js_parse_test,js_parse_test);
编译运行结果:
以文件的形式加载JS语法
需要增加文件系统及Ymodem,其中文件系统用来存放js文件,Ymodem用于把文件传输。
增加文件系统组件:
增加Ymodem组件:
文件系统挂载,我使用的板子有spi flash,所以文件系统直接挂载到此flash中:
intmnt_init(void) { if(dfs_mount("W25Q256","/","elm",0,0)==0) { LOG_I("W25Q256mountsuccessful!"); } else { LOG_E("W25Q256mountfailed!"); dfs_mkfs("elm","W25Q256"); if(dfs_mount("W25Q256","/","elm",0,0)==0) { LOG_I("W25Q256mountsuccessful!"); } } return0; } INIT_ENV_EXPORT(mnt_init);
编写JS应用文件--rice.js
rice.js文件内容:
varrice="RiceJerryScript"; console.log("hello!!",rice); console.log("helloJerryScriptrunok!!");
通过Ymodem传输到板子中,我使用的串口工具--XShell,它自带Ymodem组件,所以可以直接传输,流程:
在串口中断输入ry,使单片机进入Ymodem接收模式:
然后选择Ymodem发送文件:
编写使用文件运行JS应用的代码:
voidjs_parse_test(void) { intfd=-1,fileSize=0; char*fileContent=NULL; fd=open("/rice.js",O_RDONLY,0777); if(fd< 0) { rt_kprintf("Open %s failed", "/rice.js"); return; } else { fileSize = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); fileContent = (char *)rt_malloc(fileSize); read(fd, fileContent, fileSize); close(fd); fd = -1; } jerry_value_t parsed_code = jerry_parse((const jerry_char_t *)"/rice.js", (size_t)strlen("/rice.js"), (const jerry_char_t *)fileContent, (size_t)fileSize, JERRY_PARSE_STRICT_MODE); if (jerry_value_is_error(parsed_code)) { rt_kprintf("jerry parse failed!n"); } else { jerry_value_t ret = jerry_run(parsed_code); rt_kprintf("%s : jerry_run ret=%dn", __func__, ret); } } MSH_CMD_EXPORT(js_parse_test, js_parse_test);
编译运行结果:
总结
采用胶水语言,可以减少对固件的修改,应用的变更不会导致固件的变更,而且修改方便快捷。
通过JavaScript,嵌入式研发人员,也慢慢变成类前后端开发模式,这样职责更加清晰。
JavaScript的运行如上,下一篇将讲解C接口方法如何提供给JavaScript应用使用。
-
单片机
+关注
关注
6035文章
44554浏览量
634590 -
API
+关注
关注
2文章
1499浏览量
61957 -
嵌入式开发
+关注
关注
18文章
1028浏览量
47563 -
javascript
+关注
关注
0文章
516浏览量
53850 -
RICE
+关注
关注
0文章
2浏览量
1764
发布评论请先 登录
相关推荐
评论