QuickJS
JS
移植于Quickjs
QuickJS是一个小型的嵌入式Javascript引擎。它几乎完整支持ES2020规范,包括Promise,箭头函数,模块、异步生成器、代理和 BigInt。
- 小巧且易于嵌入集成,只需几个 C 文件,无外部依赖
- 启动时间极短的快速解释器
- 几乎完整的ES2020支持,包括模块,异步生成器。是其它嵌入式JS引擎不可比拟的。
QuickJS作者 Fabrice Bellard。
法布里斯·贝拉法国著名的计算机程序员,你可能未听说其名但如下软件你一定很熟悉:
- FFmpeg、
- QEMU
- QuickJS
视频展示
示例 读取ds3231实时时钟,并使用LVGL 显示在屏幕上
js
import * as fs from "fs"
import * as lvgl from "lvgl"
import {GPIO,I2C,SPI} from "rp2040";
console.log("this is JS message\r\n",Object.keys(lvgl));
SetGpioCallBack(isr_callback);
var btnEventTable ={};
function reg_btn_callback(pin,func){
let evList = btnEventTable[pin+''];
if(evList){
let exist = evList.find(it=>it == func);
if(!exist) btnEventTable[pin+''].push(func);
}
else btnEventTable[pin+''] =[func];
}
function isr_callback(pin,mask){
if(btnEventTable[pin+'']){
for(let f of btnEventTable[pin+'']){
if(typeof(f) == 'function'){
f(pin,mask);
}
}
}
btnEventTable[pin+''] = [];
}
function tm_format (tm){
function b2(v){if(v>=10)return v;return "0"+v;}
let year = tm.getFullYear();
let month = tm.getMonth()+1;
let date = tm.getDate();
let hour = tm.getHours();
let minutes = tm.getMinutes();
let seconds = tm.getSeconds();
let mSec = tm.getMilliseconds();
// hour = (hour +8) %24
let date_str = `${year}-${b2(month)}-${b2(date)} ${b2(hour)}:${b2(minutes)}:${b2(seconds)}`;
return date_str;
}
var n_num = 0;
var pin_17 = new GPIO(17);
function wait_one_sec(sec = 1) {
return new Promise((resolve, err) => {
setTimeout(() => {
resolve(sec);
}, sec * 1000);
})
}
function wait_btn_click(key) {
return new Promise((resolve, err) => {
function do_it(k,m){
resolve({key:k,mask:m})
}
reg_btn_callback(key,do_it);
})
}
function ds3231_rtc(i2c,addr){
function bcd2dec(dec){
return parseInt(dec.toString(16),10);
}
i2c.write(addr,[0]);
let bytes = new Uint8Array(i2c.read(addr,7));
let [ss,mm,hh,d,m,y] = [0,1,2,4,5,6].map(i=>bcd2dec(bytes[i]));
let datetime = new Date(y+2000, m, d, hh, mm, ss);
let tm_Str = tm_format(datetime);
console.log(`Read:`,bytes ,"Datetime:",tm_Str);
lvgl.text(tm_Str);
return datetime;
}
async function test_promise() {
wait_one_sec(5).then( async _ => {
console.log("After 5 seconds");
GPIO.Toggle(17);
await wait_btn_click(21).then( obj =>{
let {key,mask} = obj;
console.log(`KEY DOWN: ${key} ${mask}`);
GPIO.Toggle(17)
})
})
try{
let i2c_bus = new I2C(5,4);//clk_pin,sda_pin,clock
let devs = i2c_bus.scan();
console.log(`SCAN devs count ${devs.length} => [${devs.map(d=>d.toString(16)).join(',')}]`)
if(devs.length){
setInterval(_=>{
devs.map(addr=>{
if(addr ==0x68) ds3231_rtc(i2c_bus,addr);
})
},1000)
}
}catch(err){
console.log("ERR",err);
}
}
test_promise();
import * as fs from "fs"
import * as lvgl from "lvgl"
import {GPIO,I2C,SPI} from "rp2040";
console.log("this is JS message\r\n",Object.keys(lvgl));
SetGpioCallBack(isr_callback);
var btnEventTable ={};
function reg_btn_callback(pin,func){
let evList = btnEventTable[pin+''];
if(evList){
let exist = evList.find(it=>it == func);
if(!exist) btnEventTable[pin+''].push(func);
}
else btnEventTable[pin+''] =[func];
}
function isr_callback(pin,mask){
if(btnEventTable[pin+'']){
for(let f of btnEventTable[pin+'']){
if(typeof(f) == 'function'){
f(pin,mask);
}
}
}
btnEventTable[pin+''] = [];
}
function tm_format (tm){
function b2(v){if(v>=10)return v;return "0"+v;}
let year = tm.getFullYear();
let month = tm.getMonth()+1;
let date = tm.getDate();
let hour = tm.getHours();
let minutes = tm.getMinutes();
let seconds = tm.getSeconds();
let mSec = tm.getMilliseconds();
// hour = (hour +8) %24
let date_str = `${year}-${b2(month)}-${b2(date)} ${b2(hour)}:${b2(minutes)}:${b2(seconds)}`;
return date_str;
}
var n_num = 0;
var pin_17 = new GPIO(17);
function wait_one_sec(sec = 1) {
return new Promise((resolve, err) => {
setTimeout(() => {
resolve(sec);
}, sec * 1000);
})
}
function wait_btn_click(key) {
return new Promise((resolve, err) => {
function do_it(k,m){
resolve({key:k,mask:m})
}
reg_btn_callback(key,do_it);
})
}
function ds3231_rtc(i2c,addr){
function bcd2dec(dec){
return parseInt(dec.toString(16),10);
}
i2c.write(addr,[0]);
let bytes = new Uint8Array(i2c.read(addr,7));
let [ss,mm,hh,d,m,y] = [0,1,2,4,5,6].map(i=>bcd2dec(bytes[i]));
let datetime = new Date(y+2000, m, d, hh, mm, ss);
let tm_Str = tm_format(datetime);
console.log(`Read:`,bytes ,"Datetime:",tm_Str);
lvgl.text(tm_Str);
return datetime;
}
async function test_promise() {
wait_one_sec(5).then( async _ => {
console.log("After 5 seconds");
GPIO.Toggle(17);
await wait_btn_click(21).then( obj =>{
let {key,mask} = obj;
console.log(`KEY DOWN: ${key} ${mask}`);
GPIO.Toggle(17)
})
})
try{
let i2c_bus = new I2C(5,4);//clk_pin,sda_pin,clock
let devs = i2c_bus.scan();
console.log(`SCAN devs count ${devs.length} => [${devs.map(d=>d.toString(16)).join(',')}]`)
if(devs.length){
setInterval(_=>{
devs.map(addr=>{
if(addr ==0x68) ds3231_rtc(i2c_bus,addr);
})
},1000)
}
}catch(err){
console.log("ERR",err);
}
}
test_promise();
API for JS
全局obj
- console.log
- sleep
- active_port
- flash_mcu
- setTimeout
- setInterval
- clearTimeout
- parseJSON
- SetGpioCallBack
- loadScript
fs
- mount
- mkfs
- open
- remove
- rename
- stat
- readdir
- rmdir
- loadFile
- loadScript
GPIO
- GPIO.Dir
- GPIO.Pull
- GPIO.Init
- GPIO.Toggle
- GPIO.On
- GPIO.Off
- GPIO.Get
- GPIO.Set
I2C
- reset
- scan
- read
- write
SPI
- init
- read
- write
- WR
- port
- cs
- baudrate
- mode