Great. Now I have a spinside branch of propside built after following your instructions and a little fight getting ctags built as usual.
No luck with building tiny-js-propeller though.
OK I pull and rebuild propgcc, p2test branch. No go. Compiling tiny-js gets fails with:
propeller-elf-c++ -I . -L . -o xmm-split/TinyJS.elf -Os -mxmm-split -Wall -fno-exceptions -mno-fcache -fno-rtti TinyJS.cpp
TinyJS.cpp: In member function 'void CScriptLex::match(int)':
TinyJS.cpp:331:23: error: aggregate 'std::ostringstream errorString' has incomplete type and cannot be defined
TinyJS.cpp: In static member function 'static std::string CScriptLex::getTokenStr(int)':
TinyJS.cpp:390:19: error: aggregate 'std::ostringstream msg' has incomplete type and cannot be defined
TinyJS.cpp: In member function 'std::string CScriptVar::getParsableString()':
TinyJS.cpp:1212:19: error: aggregate 'std::ostringstream funcStr' has incomplete type and cannot be defined
TinyJS.cpp: In member function 'void CScriptVar::getJSON(std::ostringstream&, std::string)':
TinyJS.cpp:1237:22: error: no match for 'operator<<' in 'destination << "{ \012"'
TinyJS.cpp:1237:22: note: candidate is:
/opt/parallax/lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/include/c++/4.6.1/bits/basic_string.h:2694:59: note: template<class _CharT, class _Traits, class _Alloc> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
TinyJS.cpp:1240:24: error: no match for 'operator<<' in 'destination << indentedLinePrefix'
TinyJS.cpp:1240:24: note: candidate is:
/opt/parallax/lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/include/c++/4.6.1/bits/basic_string.h:2694:59: note: template<class _CharT, class _Traits, class _Alloc> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
T....................
By the way I have to take back what I said about the default branch working on 64 bit wheezy. Today building it still stalls with :
syslex.l:31:21: fatal error: sysinfo.h: No such file or directory
Hmm all my p2test TinyJS build problems went away after Eric pushed that one change this morning.
I was able to build TinyJS on XMMC, but it wouldn't run - probably because of limited HUB RAM.
Runs fine on C3 with XMM-SPLIT though. That was on Debian 32 Squeeze.
I think Daniel Harris has Debian Wheezy. Whether he is watching this is another question entirely ....
I've noticed btw, that if you enter an invalid expression on TinyJS interactive console that the program seems to just exit without any warning. I.E. var a = 5/0.25; will force the program exit in Linux.
If you are building it from the tiny-js-propeller the it has no error reporting anymore. I brutally commented out all the try/throw/catch parts so that we don't need exception support. Figuring that when I have the propeller build working something else could replace that (if only print an error and die)
If you are building it from the tiny-js-propeller the it has no error reporting anymore. I brutally commented out all the try/throw/catch parts so that we don't need exception support. Figuring that when I have the propeller build working something else could replace that (if only print an error and die)
I've built both. There seems to be little difference in program size with/without exceptions.
OK Panic over. In desperation I deleted all my repos and pulled everything afresh. Now I can compile TinyJS with p2test and SimpleIDE spinside works fine:)
Exceptions don't seem to make a huge difference. I get about 680Kbytes without.
Given that we only have a shade less than 3000 lines of code which compiles to about 60KBytes there is a serious amount of bloat being pulled in from C++ standard libs.
I'm sure all the string, stream and vector handling needed by TinyJS can be done in a lot less than 600KBytes. Used to be the entire Linux kernels I built were that size.
Anyone know any techniques for trimming the fat?
Or do we need a smaller stl http://ustl.sourceforge.net/
Or do we need to write our own, tailored fro TinyJS?
No wonder some say don't use C++ on small systems!
Now if only I could find a wall wart for my GadgetGangsta I could see it running...
I'm jealous! You guys are having all the fun. My new job finally "happened" so I'm up to my ears in transition plus I found out the application guru I'll be working with is taking vacation at the end of the month so *somebody* has to be ready to try production support in 2 weeks. I'm having daily brain dumps from the application guru - it's like sparring with Mohamed Alli!
My OLIMEX boards should should today, ready to run the original embedded JS that started all this and my C3 is ready to receive PropJS. I just need to hire an assistant to get it done!!
Anyway, keeps up the great success! I'm living this adventure vicariously for now.
Was able to find my SDRAM board, boot with XMM-SINGLE build, and do some primitive command testing.
Runs much faster than C3, but requires SDcard for un-tethered operation.
Are you having issues in the console with line feeds and such? I had to add multiple "\n"s in my print statements in order to not have them overlap. Also, I get a re-print of half the command that I enter when I press return. Something about that aspect of printing to the console is not quite right...
Are you having issues in the console with line feeds and such? I had to add multiple "\n"s in my print statements in order to not have them overlap. Also, I get a re-print of half the command that I enter when I press return. Something about that aspect of printing to the console is not quite right...
dgately
I noticed if I use non-default options for simpleide in linux, things get a little out of hand. Reset options fixes that. Will have to try on mac/windows too.
Compile/run the program in your mac console and check the behavior there. I found tinyjs does some unexpected things (unexpected to me that is). The print function does not need a \n to make a new-line - it seems like a puts. Moreover, it doesn't like \r at all. The only test in the test suite that prints is the last one and it uses the form var.dump(); so there doesn't appear to have been much print testing. The serial console nature of Script doesn't seem to like multiple line commands for some reason. It's probably best to add the FullDuplexSerial driver for loading long single line programs.
BTW, I did a quick performance comparison, using for(var n = 0; n < 100; n++) { n.dump(); }
On C3 with xmm-split I see a little more than 1 line per second.
On the GG SDRAM with xmm-single I see about 5 lines per second.
I'm the guy who did TinyJS, and I just saw what you're up to here - it's awesome.
I think you've seen Espruino, and one of the reasons you've gone with TinyJS was that it wasn't Open Source. I just wanted to say that we've started a KickStarter with our own board:
And when(if!) it completes successfully, we'll be releasing everything as Open Source. It should be a lot easier to port to the Propeller, and you should be able to use the interactive console and APIs that I have already developed....
I think you have just made my day. I've been teetering on the brink of ordering a board to run "javascript-for-things" for a while now. Instead I'm going to be pledging a hundred quid for your Espruino project.
Of course here we would be very interested in having an open source JS that we can run on the Propeller. So if our pledges make that possible we would be ecstatic.
You have probably noticed that there is a new bigger, faster Propeller chip coming out soon. I don't know if your JS will operate in the 128K of it's internal RAM but it will be supporting the use of 32MB of external SDRAM. I believe the initial dev boards for the Prop II will come with that RAM on
board.
I suspect JS will be quite a lot slower on these devices than on ARM but there are some significant advantages:
1) Whilst one core is executing JS there are 7 other cores for doing any high speed real-time stuff.
2) Video is available for text and graphics.
Seems like an ideal marriage to me. Assuming a neat way can be found to have the JS and those other processes integrate nicely.
Wow, thanks! It's looking like we'll get to our goal!
So the new propeller reads all program code from RAM as well? It might be a bit tight in 128kB - you could just about manage it on an ARM, but I wonder if the code density is as great on the propeller?
I'm sure it'd run great with the external RAM though, and the interpreter should be relatively easy to port.
It should be really exciting - I'm not convinced that you'll be able to run multiple JS threads that easily (because I'm sure someone will ask!) but having video out and some other peripherals could turn it into a fun little general-purpose computer.
I imagine you don't have time to look into the Propeller architecture at this time but I'll attempt a quick summary. It is a bit weird:
1) A core on the Propeller, known as a COG, is a 32 bit processor with 512 32 bit words of what could be seen as "registers" or "memory". This is a stand alone execution unit. It neeeds no other resources to run.
2) I say "registers" or "memory" because a COG executes it's code from that 512 word space and can also use it as variable/register space.
3) A COG has special instructions to access bytes/words/longs from the 32K shared RAM. Known as HUB RAM. A Cog does not naturally execute code from HUB RAM space.
4) There are 8 cores/COGs on a Propeller, all running at 20MIPs. The new Prop II runs at 60MIPs.
5) Access to data in HUB RAM is slower than using the COGs space as the HUB is shared among the COGs in a round robin manner. Hence the name "HUB RAM".
6) Now here is a magic trick: It was discovered you could read instructions from HUB and execute them in COG in a very tight loop and get them dispatched at about one quarter native speed. I think the Prop II can do better. In this way a COG can execute upto 8K of instructions from the HUB RAM. This is known as "Large Memory Model" or LMM. There are C compilers that can generate code to be executed in LMM.
7) The next step is to extend the LMM idea to fetch code from external RAM and use the HUB as a cache from which an LMM like loop can execute them. This is known as "External Memory Model", XMM. That is how I ran TinyJS.
8) LMM is a bit slower of course but: The GCC compiler does do tricks to load tight loops of code directly into COG and run them at full speed.
9) These speed limitation are not so bad as your LMM/XMM code can be run by one COG and any high speed real-time stuff can be written in assebler or C and run in the other 7 COGs.
So how would JS fit here?
I imagine only one COG would run JS.
Other COGs would be running assembler code somehow loaded as binary blobs like some kind of firmware.
How the interpreter and JS code is distributed over HUB RAM and external RAM is not so clear to me. I imagine the interpreter could live in external RAM or FLASH whilst the JS code and data is in HUB RAM. Perhaps vice versa is better if the interpreter fits in 128K bytes. Or of course the interpreter and JS and all data could live in external RAM and the HUB left for other COGs to use.
I'm thinking only of the Prop II. I think the P1 is far too small.
Oh, I forgot to mention there is also a CMM mode where a somewhat compressed form of instructions is fetched from HUB for execution by a kernel in a COG. It reduces code size a lot, like ARM THUMB mode. Execution speed suffers though.
It's an nice idea and i believe the Prop II would run much faster than the STM32 with 72MHz, especially because the propeller doesnt have the following restrictions:
I think Heater is talking about the FPGA emulations of the P2. The actual P2 chips are supposed to run at 160mhz as I recall.
Edit: Oops, sorry! I guess we're talking about two different things. The FPGA runs at 60mhz and the chips, I believe, will run at 160mhz. I didn't notice that Heater mentioned "MIPS" not "Mhz".
Comments
Heater.
I added a top level folder linrelease.sh for linux. Use it instead of release/linux/release.sh.
The current spinside branch is still a "work in progress". Please don't distribute it.
Thanks,
--Steve
Heater, it was meant ironic ;-))
C is my favorit over years.
But compile a vm can be a nice compiler test.
Here a quick test: compile TinyVM (lejos) with gcc:
Cool.
Using -mxmmc should produce smaller code and would run faster (assuming there is enough HUB RAM left for data).
OK, I'll keep a lid on it.
Actually I have to because linrelease.sh fails with:
For the time being ....
This works for 32 bit Debian. You may have to copy the libquazip* to /usr/lib64 ... I'm not sure.
With SIDEPATH=your propside path:
$ cd ${SIDEPATH}/quazip-0.5/quazip
$ qmake -config quazip.pro
$ make clean
$ make
$ sudo cp libquazip* /usr/lib
$ cd ${SIDEPATH}
$ ./linrelease.sh
Great. Now I have a spinside branch of propside built after following your instructions and a little fight getting ctags built as usual.
No luck with building tiny-js-propeller though.
OK I pull and rebuild propgcc, p2test branch. No go. Compiling tiny-js gets fails with:
Yep, same errors. Using the p2test branch.
By the way I have to take back what I said about the default branch working on 64 bit wheezy. Today building it still stalls with :
syslex.l:31:21: fatal error: sysinfo.h: No such file or directory
I was able to build TinyJS on XMMC, but it wouldn't run - probably because of limited HUB RAM.
Runs fine on C3 with XMM-SPLIT though. That was on Debian 32 Squeeze.
I think Daniel Harris has Debian Wheezy. Whether he is watching this is another question entirely ....
I've noticed btw, that if you enter an invalid expression on TinyJS interactive console that the program seems to just exit without any warning. I.E. var a = 5/0.25; will force the program exit in Linux.
I've built both. There seems to be little difference in program size with/without exceptions.
I take that back. Using exceptions adds about 120KB.
Exceptions don't seem to make a huge difference. I get about 680Kbytes without.
Given that we only have a shade less than 3000 lines of code which compiles to about 60KBytes there is a serious amount of bloat being pulled in from C++ standard libs.
I'm sure all the string, stream and vector handling needed by TinyJS can be done in a lot less than 600KBytes. Used to be the entire Linux kernels I built were that size.
Anyone know any techniques for trimming the fat?
Or do we need a smaller stl http://ustl.sourceforge.net/
Or do we need to write our own, tailored fro TinyJS?
No wonder some say don't use C++ on small systems!
Now if only I could find a wall wart for my GadgetGangsta I could see it running...
If you have an error in your JS (or bug in TinyJS) might has well have the REPL issue an error message and bomb out. Run it again from scratch.
My OLIMEX boards should should today, ready to run the original embedded JS that started all this and my C3 is ready to receive PropJS. I just need to hire an assistant to get it done!!
Anyway, keeps up the great success! I'm living this adventure vicariously for now.
Was able to type "print("Hello, World!\n\n");" and got a response from Interactive mode!
This was on my C3 (XMM Split External Flash Code & RAM data)
dgately
Runs much faster than C3, but requires SDcard for un-tethered operation.
Are you having issues in the console with line feeds and such? I had to add multiple "\n"s in my print statements in order to not have them overlap. Also, I get a re-print of half the command that I enter when I press return. Something about that aspect of printing to the console is not quite right...
dgately
I noticed if I use non-default options for simpleide in linux, things get a little out of hand. Reset options fixes that. Will have to try on mac/windows too.
Compile/run the program in your mac console and check the behavior there. I found tinyjs does some unexpected things (unexpected to me that is). The print function does not need a \n to make a new-line - it seems like a puts. Moreover, it doesn't like \r at all. The only test in the test suite that prints is the last one and it uses the form var.dump(); so there doesn't appear to have been much print testing. The serial console nature of Script doesn't seem to like multiple line commands for some reason. It's probably best to add the FullDuplexSerial driver for loading long single line programs.
BTW, I did a quick performance comparison, using for(var n = 0; n < 100; n++) { n.dump(); }
On C3 with xmm-split I see a little more than 1 line per second.
On the GG SDRAM with xmm-single I see about 5 lines per second.
Mileage may vary.
I'm the guy who did TinyJS, and I just saw what you're up to here - it's awesome.
I think you've seen Espruino, and one of the reasons you've gone with TinyJS was that it wasn't Open Source. I just wanted to say that we've started a KickStarter with our own board:
http://www.kickstarter.com/projects/48651611/espruino-javascript-for-things
And when(if!) it completes successfully, we'll be releasing everything as Open Source. It should be a lot easier to port to the Propeller, and you should be able to use the interactive console and APIs that I have already developed....
Wow, hello, welcome to the forum.
I think you have just made my day. I've been teetering on the brink of ordering a board to run "javascript-for-things" for a while now. Instead I'm going to be pledging a hundred quid for your Espruino project.
Of course here we would be very interested in having an open source JS that we can run on the Propeller. So if our pledges make that possible we would be ecstatic.
You have probably noticed that there is a new bigger, faster Propeller chip coming out soon. I don't know if your JS will operate in the 128K of it's internal RAM but it will be supporting the use of 32MB of external SDRAM. I believe the initial dev boards for the Prop II will come with that RAM on
board.
I suspect JS will be quite a lot slower on these devices than on ARM but there are some significant advantages:
1) Whilst one core is executing JS there are 7 other cores for doing any high speed real-time stuff.
2) Video is available for text and graphics.
Seems like an ideal marriage to me. Assuming a neat way can be found to have the JS and those other processes integrate nicely.
So all power to your kickstarter project.
So the new propeller reads all program code from RAM as well? It might be a bit tight in 128kB - you could just about manage it on an ARM, but I wonder if the code density is as great on the propeller?
I'm sure it'd run great with the external RAM though, and the interpreter should be relatively easy to port.
It should be really exciting - I'm not convinced that you'll be able to run multiple JS threads that easily (because I'm sure someone will ask!) but having video out and some other peripherals could turn it into a fun little general-purpose computer.
I imagine you don't have time to look into the Propeller architecture at this time but I'll attempt a quick summary. It is a bit weird:
1) A core on the Propeller, known as a COG, is a 32 bit processor with 512 32 bit words of what could be seen as "registers" or "memory". This is a stand alone execution unit. It neeeds no other resources to run.
2) I say "registers" or "memory" because a COG executes it's code from that 512 word space and can also use it as variable/register space.
3) A COG has special instructions to access bytes/words/longs from the 32K shared RAM. Known as HUB RAM. A Cog does not naturally execute code from HUB RAM space.
4) There are 8 cores/COGs on a Propeller, all running at 20MIPs. The new Prop II runs at 60MIPs.
5) Access to data in HUB RAM is slower than using the COGs space as the HUB is shared among the COGs in a round robin manner. Hence the name "HUB RAM".
6) Now here is a magic trick: It was discovered you could read instructions from HUB and execute them in COG in a very tight loop and get them dispatched at about one quarter native speed. I think the Prop II can do better. In this way a COG can execute upto 8K of instructions from the HUB RAM. This is known as "Large Memory Model" or LMM. There are C compilers that can generate code to be executed in LMM.
7) The next step is to extend the LMM idea to fetch code from external RAM and use the HUB as a cache from which an LMM like loop can execute them. This is known as "External Memory Model", XMM. That is how I ran TinyJS.
8) LMM is a bit slower of course but: The GCC compiler does do tricks to load tight loops of code directly into COG and run them at full speed.
9) These speed limitation are not so bad as your LMM/XMM code can be run by one COG and any high speed real-time stuff can be written in assebler or C and run in the other 7 COGs.
So how would JS fit here?
I imagine only one COG would run JS.
Other COGs would be running assembler code somehow loaded as binary blobs like some kind of firmware.
How the interpreter and JS code is distributed over HUB RAM and external RAM is not so clear to me. I imagine the interpreter could live in external RAM or FLASH whilst the JS code and data is in HUB RAM. Perhaps vice versa is better if the interpreter fits in 128K bytes. Or of course the interpreter and JS and all data could live in external RAM and the HUB left for other COGs to use.
I'm thinking only of the Prop II. I think the P1 is far too small.
Oh, I forgot to mention there is also a CMM mode where a somewhat compressed form of instructions is fetched from HUB for execution by a kernel in a COG. It reduces code size a lot, like ARM THUMB mode. Execution speed suffers though.
I thought the Prop II runs at 200MIPS? (according to http://www.parallaxsemiconductor.com/Products/propeller2specs)
It's an nice idea and i believe the Prop II would run much faster than the STM32 with 72MHz, especially because the propeller doesnt have the following restrictions:
The Prop II could has as many PWM, ADC, UART, SPI, I²C, ... as GPIOs + additional FAT32, Ethernet and video driver.
Edit: Oops, sorry! I guess we're talking about two different things. The FPGA runs at 60mhz and the chips, I believe, will run at 160mhz. I didn't notice that Heater mentioned "MIPS" not "Mhz".
My feeling is that it's enough for some JS fun anyway.