JavaScript on ESP32 - Duktape

User avatar
kolban
Posts: 510
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: JavaScript on ESP32 - Duktape

Postby kolban » Mon Dec 26, 2016 5:31 pm

Howdy,
Sorry for the problem. Latest and greatest now synched.

Up till now I hadn't assumed that anyone was doing anything useful with the Github source and I was merely checking it in when I was about to make some tricky changes. As such there were no branches nor issues nor comments ... my thoughts had been that because this project is still so new, I'd be providing binary drops as needed/requested. However, if you or ANYONE tells me that you'd rather build and work from the source then I'll slow down and start creating tracking issues and working those as a "proper" Github project. However, please don't ask for this yet unless you are considering making some changes yourself. If I know there will be collaborators, I'll bend over backwards to keep things clean and polished and consistent so we all have Github hygiene. However that comes at a cost (for me) in that it will slow down progress as I have to be careful not to touch anything that isn't tracked nor break anything in source. But, again ... if you or anyone has an interest in joining the party ... we'll make it happen ASAP.

As of now, there is a clean source push in Github. I'll plan on releasing refreshed binaries each weekend for those who want to stay current on latest functions and are happy to get flashable images. If anyone reports a bug and it can be fixed quickly, that will result in me uploading a new set of binaries immediately.

My current focus areas are:

1) Improve module loading to reduce RAM and improve design.
2) Work with the Duktape project owner to find ways to improve RAM usage.
3) Add a "Serial" module so that we can read from the serial port from JavaScript which will allow us to run without network.

And as always, if you need immediate feedback, try find me on ESP32 channel on IRC ... userid "kolban".
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

User avatar
Frida854
Posts: 14
Joined: Sat Dec 24, 2016 11:51 am
Location: Middelfart, Denmark

Re: JavaScript on ESP32 - Duktape

Postby Frida854 » Mon Dec 26, 2016 6:23 pm

Don't be I am only a tester. Now it works again.

I like to use 'git pull', to see if all works, and maybe chance a little.
So for me, just take your time I can wait. I'm reading a lot, but understand so little.

I want to ask: when I start, and let it be for a while, it times out and I lose the connection to the webide. Is the only way to get webide to connect again, to reset the 'wipy2.0' (esp32)?
ps: I found out I could start a ping from the console, to keep it alive.

And now a tough one, I would like to have a javascrip I can start before the network starts, because I have a switch on the 'wipy2.0' to switch from extern antenne to intern antenne.
So where can I place this javascript, so that starts before the net.
Yes Frida is my watchdog!

User avatar
kolban
Posts: 510
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: JavaScript on ESP32 - Duktape

Postby kolban » Tue Dec 27, 2016 4:50 pm

When I get good questions like this, I try and write some of it up as docs for the project so we have a record rather than a forum stream ... here is the high level design of the project:

https://github.com/nkolban/duktape-esp3 ... 0design.md

At present, the very first thing that the ESP32 does upon boot is join the local access point network. As such, JS is not running at that point. The reason for this is that as the project slowly cooked, I want to develop using networking access and the project "bootstrapped" itself using networking. Now that we have a JS runtime that is become more and more stable, the actual need to always have a network connection is no longer present. Yesterday we added "Serial" class support. This means that we now have access to all three UARTs from JS. With this in place, we now have the parts to start writing the logic to allow ESP32 Duktape to boot without networking switched on and use UART to communicate. I'm still considering how we might want this to behave and all discussions are welcome.

Since we already have the WiFi class in JS ... for your immediate puzzle ... a workaround for just now would be to write your JavaScript such that it switches off being a station and then,in YOUR code, switches it back on again with the parameters you want. If there are parameters you need that aren't exposed, yell out and we'll add them.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

User avatar
Frida854
Posts: 14
Joined: Sat Dec 24, 2016 11:51 am
Location: Middelfart, Denmark

Re: JavaScript on ESP32 - Duktape

Postby Frida854 » Tue Dec 27, 2016 6:45 pm

It was much easier, I put this code in 'bootwifi.js'

Code: Select all

function bootwifi(bootedCallback) {
   var GPIO = require("gpio.js");
   var pin16 = new GPIO(16); // antenne switch
   var level = false; // true=extern, false=intern
   pin16.setDirection(GPIO.OUTPUT);
   pin16.setLevel(level);

   var bootWiFi_ns = NVS.open("bootwifi", "readwrite");

thank you for your hint.

By the way when i run the blinky script

Code: Select all

var GPIO = require("gpio.js");
var pin25 = new GPIO(25);
var level = true;
pin25.setDirection(GPIO.OUTPUT);
var id = setInterval(function() {
   pin25.setLevel(level);
   level = !level;
}, 1000);

and I then try to use load, I get this often, so I have to reset again.
Yes I know it is under construction. Just to let you know.

Code: Select all

D (25483) log: Processing timer fired for id: 1
D (26489) log: Processing timer fired for id: 1
D (27492) log: Processing timer fired for id: 1
D (28494) log: Processing timer fired for id: 1
D (29497) log: Processing timer fired for id: 1
D (30503) log: Processing timer fired for id: 1
D (31509) log: Processing timer fired for id: 1
D (32515) log: Processing timer fired for id: 1
D (33523) log: Processing timer fired for id: 1
D (34529) log: Processing timer fired for id: 1
D (35533) log: Processing timer fired for id: 1
D (35987) log: selectResult: {"readfds":[0],"writefds":[],"exceptfds":[]}
D (35988) log: loop: working on read of fd=0
D (35989) module_os: >> js_os_accept
D (35990) module_os:  About to call accept on 0
D (35995) module_os: << js_os_accept: new socketfd=3
D (36001) log: We accepted a new client connection: {"sockfd":3}
D (36021) log: IDE_WebServer: We have received a new HTTP client request!
D (36022) dukf_utils: requestHandler: heapSize=24600
D (36054) log: selectResult: {"readfds":[3],"writefds":[],"exceptfds":[]}
D (36055) log: loop: working on read of fd=3
D (36057) module_os: >> js_os_recv
D (36058) module_os: -- js_os_recv: About to receive on fd=3 for a buffer of size 512
D (36065) module_os: << js_os_recv: length=430
D (36070) log: Length of data from recv: 430
D (36077) log: http parsing: GET /files HTTP/1.1
D (36080) log: http Method: GET, path: /files
D (36083) log: http parsing: Host: 192.168.20.41:8000
D (36089) log: http parsing: Connection: keep-alive
D (36093) log: http parsing: Accept: application/json, text/javascript, */*; q=0.01
D (36101) log: http parsing: X-Requested-With: XMLHttpRequest
D (36107) log: http parsing: User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36
D (36121) log: http parsing: Referer: http://192.168.20.41:8000/web/ide.html
D (36128) log: http parsing: Accept-Encoding: gzip, deflate, sdch
D (36134) log: http parsing: Accept-Language: en-US,en;q=0.8
D (36139) log: http parsing:
D (36144) log: End of headers
{"Host":"192.168.20.41:8000","Connection":"keep-alive","Accept":"application/json, text/javascript, */*; q=0.01","X-Requested-With":"XMLHttpRequest","User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36","Referer":"http://192.168.20.41:8000/web/ide.html","Accept-Encoding":"gzip, deflate, sdch","Accept-Language":"en-US,en;q=0.8"}
D (36181) log: HTTP Request on(end):
D (36183) log:  - method: GET
D (36185) log:  - path: /files
D (36193) log:  - headers: {"Host":"192.168.20.41:8000","Connection":"keep-alive","Accept":"application/json, text/javascript, */*; q=0.01","X-Requested-With":"XMLHttpRequest","User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36","Referer":"http://192.168.20.41:8000/web/ide.html","Accept-Encoding":"gzip, deflate, sdch","Accept-Language":"en-US,en;q=0.8"}
D (36227) dukf_utils: ide_webserver: request.on(end): heapSize=16716
D (36237) module_os: >> js_os_send
D (36238) module_os: About to send 17 bytes of data to sockfd=3
D (36242) module_os: - data: "HTTP/1.1 200 OK

"
D (36248) module_os: << js_os_send
D (36252) module_os: >> js_os_send
D (36253) module_os: About to send 2 bytes of data to sockfd=3
D (36258) module_os: - data: "

"
D (36263) module_os: << js_os_send
D (36265) duktape_spiffs: >> esp32_duktape_dump_spiffs_array: rootPath="/"
D (36307) duktape_spiffs: << esp32_duktape_dump_spiffs_array
D (36362) module_os: >> js_os_send
D (36363) module_os: About to send 1911 bytes of data to sockfd=3
D (36363) module_os: - data: "[{"name":"/web/ide.html","size":6018},{"name":"/web/selectAP.html","size":1063},{"name":"/web/ide.js","size":9354},{"name":"/ws.js","size":10418},{"name":"/x.js","size":5483},{"name":"/gpio.js","size":1143},{"name":"/dummy.js","size":4121},{"name":"/neopixels.js","size":1498},{"name":"/http.js","size":8372},{"name":"/status.js","size":592},{"name":"/ide_webserver.js","size":5483},{"name":"/nvs.js","size":1053},{"name":"/RTOS.js","size":242},{"name":"/net.js","size":4142},{"name":"/bootwifi.js","size":5742},{"name":"/url.js","size":2430},{"name":"/httpparser.js","size":9805},{"name":"/init.js","size":2666},{"name":"/dummy3.js","size":4725},{"name":"/ide_webserver.min.js","size":2584},{"name":"/loop.js","size":4810},{"name":"/stream.js","size":5174},{"name":"/tests/test_bootwifi_data.js","size":1087},{"name":"/tests/test_streams.js","size":1524},{"name":"/tests/test_url.js","size":87},{"name":"/tests/test_simpleConsole.js","size":49},{"name":"/tests/test_ws.js","size":482},{"name":"/tests/service_providers/test_http_mashape1.js","size":793},{"name":"/tests/service_providers/test_http_request.js","size":774},{"name":"/tests/test_nvs.js","size":289},{"name":"/tests/test_serial_write.js","size":137},{"name":"/tests/testModule.js","size":239},{"name":"/tests/test_nvs_ints.js","size":360},{"name":"/tests/test_ide_ws.js","size":797},{"name":"/tests/test_gpio_blinky.js","size":177},{"name":"/tests/test_gc.js","size":130},{"name":"/tests/test_sha1.js","size":449},{"name":"/tests/test_date.js","size":44},{"name":"/tests/test_net.js","size":413},{"name":"/tests/test_http_request.js","size":790},{"name":"/tests/test_wifiGetState.js","size":143},{"name":"/Partitions.js","size":290},{"name":"/start.js","size":528},{"name":"/duktape/heap_parser.js","size":2052},{"name":"/dummy2.js","size":71},{"name":"/Serial.js","size":254},{"name":"/module.js","size":301},{"name":"/webserver.js","size":4570}]"
D (36530) module_os: << js_os_send
D (36534) module_os: >> js_os_close
D (36536) module_os: About to close fd=3
D (36541) module_os: << js_os_close
D (36558) log: Processing timer fired for id: 1
D (36569) log: selectResult: {"readfds":[0],"writefds":[],"exceptfds":[]}
D (36570) log: loop: working on read of fd=0
D (36571) module_os: >> js_os_accept
D (36572) module_os:  About to call accept on 0
D (36577) module_os: << js_os_accept: new socketfd=4
D (36583) log: We accepted a new client connection: {"sockfd":4}
D (36604) log: IDE_WebServer: We have received a new HTTP client request!
D (36605) dukf_utils: requestHandler: heapSize=13060
D (36642) log: selectResult: {"readfds":[4],"writefds":[],"exceptfds":[]}
D (36643) log: loop: working on read of fd=4
D (36645) module_os: >> js_os_recv
D (36645) module_os: -- js_os_recv: About to receive on fd=4 for a buffer of size 512
D (36653) module_os: << js_os_recv: length=430
D (36657) log: Length of data from recv: 430
D (36664) log: http parsing: GET /files HTTP/1.1
D (36668) log: http Method: GET, path: /files
D (36671) log: http parsing: Host: 192.168.20.41:8000
D (36676) log: http parsing: Connection: keep-alive
D (36681) log: http parsing: Accept: application/json, text/javascript, */*; q=0.01
D (36688) log: http parsing: X-Requested-With: XMLHttpRequest
D (36694) log: http parsing: User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36
D (36709) log: http parsing: Referer: http://192.168.20.41:8000/web/ide.html
D (36716) log: http parsing: Accept-Encoding: gzip, deflate, sdch
D (36722) log: http parsing: Accept-Language: en-US,en;q=0.8
D (36726) log: http parsing:
D (36731) log: End of headers
{"Host":"192.168.20.41:8000","Connection":"keep-alive","Accept":"application/json, text/javascript, */*; q=0.01","X-Requested-With":"XMLHttpRequest","User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36","Referer":"http://192.168.20.41:8000/web/ide.html","Accept-Encoding":"gzip, deflate, sdch","Accept-Language":"en-US,en;q=0.8"}
D (36769) log: HTTP Request on(end):
D (36770) log:  - method: GET
D (36773) log:  - path: /files
D (36779) log:  - headers: {"Host":"192.168.20.41:8000","Connection":"keep-alive","Accept":"application/json, text/javascript, */*; q=0.01","X-Requested-With":"XMLHttpRequest","User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36","Referer":"http://192.168.20.41:8000/web/ide.html","Accept-Encoding":"gzip, deflate, sdch","Accept-Language":"en-US,en;q=0.8"}
D (36815) dukf_utils: ide_webserver: request.on(end): heapSize=16032
D (36825) module_os: >> js_os_send
D (36825) module_os: About to send 17 bytes of data to sockfd=4
D (36830) module_os: - data: "HTTP/1.1 200 OK

"
D (36836) module_os: << js_os_send
D (36840) module_os: >> js_os_send
D (36840) module_os: About to send 2 bytes of data to sockfd=4
D (36846) module_os: - data: "

"
D (36850) module_os: << js_os_send
D (36854) duktape_spiffs: >> esp32_duktape_dump_spiffs_array: rootPath="/"
D (36889) duktape_spiffs: << esp32_duktape_dump_spiffs_array
Guru Meditation Error: Core  0 panic'ed (Unhandled debug exception)
Register dump:
PC      : 0x401164fc  PS      : 0x00060036  A0      : 0x800e3f3d  A1      : 0x3ffce9a0 
A2      : 0x3ffd1418  A3      : 0x3ffe9cb4  A4      : 0x00000000  A5      : 0x3ffcefe4 
A6      : 0x3fff042c  A7      : 0x00000005  A8      : 0x00000000  A9      : 0x3ffce970 
A10     : 0x00012ff7  A11     : 0x00000004  A12     : 0x3ffcefe4  A13     : 0x00000000 
A14     : 0x00012ff6  A15     : 0xffffffdf  SAR     : 0x00000001  EXCCAUSE: 0x00000001 
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000 

Backtrace: 0x401164fc:0x3ffce9a0 0x400e3f3d:0x3ffce9c0 0x4013936c:0x3ffce9e0 0x40111d8b:0x3ffcea00 0x401163f2:0x3ffcea20 0x40116bac:0x3ffcea40 0x40116bb6:0x3ffcea60 0x40116bc2:0x3ffcea80 0x401180c2:0x3ffceaa0 0x40119adc:0x3ffceac0 0x40116554:0x3ffceaf0 0x401168d2:0x3ffceb50 0x401168e8:0x3ffceb70 0x40116a3f:0x3ffceb90 0x4011e03b:0x3ffcebd0 0x40115291:0x3ffcebf0 0x40115304:0x3ffcec20 0x4011fde3:0x3ffcec40 0x40122919:0x3ffcec70 0x4012294e:0x3ffced40 0x40105e9d:0x3ffced60

Entering gdb stub now.
$T1f#eb
Yes Frida is my watchdog!

User avatar
kolban
Posts: 510
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: JavaScript on ESP32 - Duktape

Postby kolban » Tue Dec 27, 2016 7:38 pm

Wow ... you are GOOD!! ... your ability to modify the base code is excellent. As you delved into "bootwifi.js" you are now starting to see that ESP32-Duktape is itself mostly written in JS. The whole "booting" of the WiFi is itself JS environment. Remember to take copies of changes you make as git pulls or new flashes might replace any changes you made that weren't backed up.

At present, I am assuming that 99.9% of good folks are using the pre-built binaries supplied so far. My plan is to refresh those once a week so as not to inundate folks with too many redundant choices and minimize the breakages. There is "more" to building ESP32-Duktape than just pulling an recompiling. ESP32-Duktape leverages heavily the excellent work by the Duktape team to provide the JavaScript runtime environment which is the heart of ESP32-Duktape. Although easy to consume, Duktape has a wealth of build-time options to optimize and tweak for the deployment environment (in our case ESP32). We are nowhere near close to having an optimal set of settings for our purposes ... however we keep making improvements.

When you download the source, you get a copy of Duktape as part of the story. However, from a virgin environment, we need to run "make duktape_configure" in the home directory of ESP32-Duktape.

This takes the Duktape profile known as "low_memory" plus some ESP32-Duktape specific options and builds the source of a configured Duktape engine for our purposes. My current goals are to reduce RAM utilization. Without the WebIDE we seem to have about 70K available. With the WebIDE it can drop to between 30K-50K. The error in your last post is running out of RAM ... and THAT is my biggest challenge at the moment. However, the future looks rosy. If we combine some hope that ESP-IDF will free up some more (at a virgin boot, ALL ESP-IDF apps only see about 230K out of a much bigger possible) and work being done by the Duktape team that will result in byte code for compile applications ending up in flash as opposed to RAM ... then we can sensibly expect much more.

Keep us posted on the frequency of RAM shortage problems ... on a case by case basis, we can look for ways to improve what we have. Worst case, we can drop down to external compilation (i.e. we compile the JavaScript on a PC) and push it through the serial port (i.e. no WebIDE) and we should have maximal RAM available to us having potentially sacrificed some bells and whistles ... however the story would still be no worse than C compilation/flashing today in terms on workflow.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

User avatar
Frida854
Posts: 14
Joined: Sat Dec 24, 2016 11:51 am
Location: Middelfart, Denmark

Re: JavaScript on ESP32 - Duktape

Postby Frida854 » Fri Dec 30, 2016 6:28 pm

After a fresh download of:

Code: Select all

duktape-esp32
esp-idf
template
xtensa-esp32-elf

I got these errors:

Code: Select all

/home/poul/Programmer/Duktape32/duktape-esp32/main/./module_wifi.c: In function 'js_wifi_connect':
/home/poul/Programmer/Duktape32/duktape-esp32/main/./module_wifi.c:581:3: error: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Werror=pointer-sign]
   strcpy(sta_config.sta.ssid, ssid);
   ^
In file included from /home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/time.h:10:0,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/components/duktape/src/duk_config.h:672,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/components/duktape/src/duktape.h:142,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/main/./module_wifi.c:14:
/home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/string.h:30:15: note: expected 'char * restrict' but argument is of type 'uint8_t *'
 char  *_EXFUN(strcpy,(char *__restrict, const char *__restrict));
               ^
/home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/_ansi.h:65:30: note: in definition of macro '_EXFUN'
 #define _EXFUN(name, proto)  name proto
                              ^
/home/poul/Programmer/Duktape32/duktape-esp32/main/./module_wifi.c:582:3: error: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Werror=pointer-sign]
   strcpy(sta_config.sta.password, password);
   ^
In file included from /home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/time.h:10:0,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/components/duktape/src/duk_config.h:672,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/components/duktape/src/duktape.h:142,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/main/./module_wifi.c:14:
/home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/string.h:30:15: note: expected 'char * restrict' but argument is of type 'uint8_t *'
 char  *_EXFUN(strcpy,(char *__restrict, const char *__restrict));
               ^
/home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/_ansi.h:65:30: note: in definition of macro '_EXFUN'
 #define _EXFUN(name, proto)  name proto
                              ^
/home/poul/Programmer/Duktape32/duktape-esp32/main/./module_wifi.c: In function 'js_wifi_listen':
/home/poul/Programmer/Duktape32/duktape-esp32/main/./module_wifi.c:692:2: error: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Werror=pointer-sign]
  strcpy(ap_config.ap.ssid, ssid);
  ^
In file included from /home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/time.h:10:0,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/components/duktape/src/duk_config.h:672,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/components/duktape/src/duktape.h:142,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/main/./module_wifi.c:14:
/home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/string.h:30:15: note: expected 'char * restrict' but argument is of type 'uint8_t *'
 char  *_EXFUN(strcpy,(char *__restrict, const char *__restrict));
               ^
/home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/_ansi.h:65:30: note: in definition of macro '_EXFUN'
 #define _EXFUN(name, proto)  name proto
                              ^
/home/poul/Programmer/Duktape32/duktape-esp32/main/./module_wifi.c:694:2: error: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Werror=pointer-sign]
  strcpy(ap_config.ap.password, password);
  ^
In file included from /home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/time.h:10:0,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/components/duktape/src/duk_config.h:672,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/components/duktape/src/duktape.h:142,
                 from /home/poul/Programmer/Duktape32/duktape-esp32/main/./module_wifi.c:14:
/home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/string.h:30:15: note: expected 'char * restrict' but argument is of type 'uint8_t *'
 char  *_EXFUN(strcpy,(char *__restrict, const char *__restrict));
               ^
/home/poul/Programmer/Duktape32/esp-idf/components/newlib/include/_ansi.h:65:30: note: in definition of macro '_EXFUN'
 #define _EXFUN(name, proto)  name proto
                              ^
cc1: some warnings being treated as errors
/home/poul/Programmer/Duktape32/esp-idf/make/component_wrapper.mk:176: recipe for target 'module_wifi.o' failed
make[1]: *** [module_wifi.o] Error 1
/home/poul/Programmer/Duktape32/esp-idf/make/project.mk:376: recipe for target 'main-build' failed
make: *** [main-build] Error 2
Færdig
poul@poul-S400CA ~/Programmer/Duktape32 $

which I don't understand the meaning of. So I will have to wait to you good folks find it out.
Yes Frida is my watchdog!

User avatar
kolban
Posts: 510
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: JavaScript on ESP32 - Duktape

Postby kolban » Sat Dec 31, 2016 2:28 am

It'll be a couple of days before I can update the source, but I think what we are seeing is that the statements of the form:

strcpy(target, source)

are failing to compile. Why this is just showing up now is more the mystery than why at all.

the fix should be to change:

strcpy(target, source)

to

strcpy((char *)target, source)

technically, the compiler is correct ... it looks like the data type of "target" is "uint8_t *" which means a pointer to unsigned 8 bit unsigned integer (bytes_, while strcpy expects the same parameter to be "char *" which means a pointer to signed characters (which in our world almost always maps to bytes). So what we do is explicitly tell the compiler through a "cast" ... hey ... I know what I'm doing, you think this pointer of "uint8_t *" points to an 8 bit unsigned integer as opposed a pointer to a signed character ... but we are all good.

I'll add the proper fix to the Github source in a few days. In the meantime, this might be enough to get you on track again. I've paused JS work to focus on BLE (Bluetooth) and once done, if memory permits, will expose BLE through JS.

... a few days later ...

Aha ... it seems that there was a fix to a bug in the ESP-IDF that coincides with our puzzle ... see:

https://github.com/espressif/esp-idf/issues/40

The ESP-IDF changed the data types for a couple of fields resulting in our breakage. The ESP32-Duktape github code is now consistent with the ESP-IDF as of this date and now compiles cleanly.
Last edited by kolban on Sat Dec 31, 2016 8:54 pm, edited 1 time in total.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

User avatar
Frida854
Posts: 14
Joined: Sat Dec 24, 2016 11:51 am
Location: Middelfart, Denmark

Re: JavaScript on ESP32 - Duktape

Postby Frida854 » Sat Dec 31, 2016 1:52 pm

I'm a happy driver again, it was those 4 lines that had to be changed, in:
duktape-esp32/main/module_wifi.c

Code: Select all

line 581  strcpy((char *)sta_config.sta.ssid, ssid);
line 582  strcpy((char *)sta_config.sta.password, password);

line 692   strcpy((char *)ap_config.ap.ssid, ssid);
line 694   strcpy((char *)ap_config.ap.password, password);
Yes Frida is my watchdog!

cmason
Posts: 9
Joined: Thu Dec 29, 2016 6:39 pm

Re: JavaScript on ESP32 - Duktape

Postby cmason » Sat Dec 31, 2016 6:47 pm

Hi Kolban,

I've been following this with much interest. Thanks for the recent docs, that's helped understanding a lot.

A couple questions:

What's your thinking about public entry points/use cases? It seems like you're mostly interested in delivering a complete "environment" that allows programming directly on the device. This makes total sense and is a worthy goal. However I can think of a couple of other potential goals, subject to your interest:

* An embeddable JS interpreter: obviously duktape is embeddedable, but there are a number of things you've added here such as support for the ESP32 hardware and carefully chosen configuration for memory usage. It might be nice to have a high-level API in C for enabling various parts of the port. For instance: bind a JS REPL to uart0 and then accept telnet on port 1234. Or: here's a JS string, execute it in a RTOS task.

* An embedded web development environment: I'm working on a multichannel WiFi light dimmer as a side project. I'd love to be able to implement only the lowest-level bits of this in C. It would be excellent to have an API that would configure wifi (using your mechanism for configuration-via-access-point), and then launch a web server (in js, ie express) given a virtual file system in flash (that I would build in my project using your fs tools). I see hints of this in the source, but not sure how far along it is. During development, this could make use of the IDE but then the web content could be flashed deployed with out it.

Implied in each of these is the ability to turn on and off certain features/hardware access as appropriate for a project.

What is the best way to embed your esp32-duktape port itself in another project? I understand again the utility of providing pre-compiled binaries for users that primarily want to code directly on the device. For me personally, because some of what I want to do requires C-level code, delivering a stable binary is much less interesting *to me* than delivering a code library I can reuse. I'm assuming that I can do something like a git submodule and then add appropriate bits in my makefile, but it would be great to understand your thinking here.

Understanding that this is probably a side project for you, I'm happy to help with any of the above, if it lines up with your thinking?


Thanks so much,

-c

User avatar
kolban
Posts: 510
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: JavaScript on ESP32 - Duktape

Postby kolban » Sat Dec 31, 2016 7:11 pm

Howdy @cmason,
The core of the work done so far is the Duktape project ... see (http://duktape.org/). This provided an embeddable JavaScript compiler, debugger and runtime written in C. For me, this compiled and ran first time on the ESP32 with no modifications required. So getting JS running on ESP32 is really pretty much a "no-brainer". I have chosen Duktape as my current focus but their are alternative embeddable runtimes including JerryScript.

The ESP32-Duktape project is an attempt to provide the "eco-system" above JavaScript as the language itself. Contrast this with C (a language) and the POSIX libraries (the environment and Java (the language) and the java.* packages (the environment). With JavaScript, there are some defacto standards such as the great work done by the Node.js folks to provide a JS callable environment.

In an ideal world, there would be no need for ESP32-Duktape, instead all effort would be spent in porting Node.js to ESP32 ... however that is unlikely to happen soon ... simply because the ESP32 doesn't have "enough" resources to support a Node.js like environment. If one wants embedded and Node.js, one might consider Raspberry PI Zero, CHIP or Onion Omega.

Given that Duktape runs just fine on the ESP32, I asked myself "what's missing?" ... and the quick answer was networking. This led me to start using 3rd party libraries such as Mongoose to be called from JS. It was here that I started tripping over my own feet ... the models of C libraries and the models of JS don't meet very well (opinion) and as I saw that I needed other layers, the requirements on more and more 3rd party C libraries continued to grow ... I asked myself "What if the eco-system were itself written in JS?". The thinking here is that might by JS runtime agnostic, be a first class JS integration and potentially be portable across platforms ... and ... for me ... an excuse to study new skills for a reason.

So ... how does this all relate to your post? Firstly, if all you need is JS and calling C from JS or calling JS from C ... you won't need ESP32-Duktape ... just go grab Duktape with its excellent docs ... and you are off and running.

If you find that you need higher level "stories" then maybe ESP32-Duktape is something to base your projects upon. It is believed that the end goal will be the ability to take a JS program, load it on top of ESP32-Duktape and ... and off we go ... no C programming required for wifi, networking, HTTP, file systems, GPIO, I2C, SPI etc etc.

For notions such as creating mixed C/JS apps, maybe we can break that down into a work item that might be labeled "How can I supply a user-supplied compiled C module and call it from JS?" ... think for example something a "DLL" on windows or a shared library in Linux.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

Who is online

Users browsing this forum: No registered users and 1 guest