Graphics on BangleJS2 #6601
Replies: 2 comments
-
Posted at 2024-01-15 by FManga To better demonstrate what I wanted this for (from the PR linked above): Attachments: Posted at 2024-01-15 by @gfwilliams Hi - the issue is that the framebuffer isn't entirely linear (and arraybuffer assumes it is) - because it's sent direct to the LCD via DMA it contains a few command bytes at the beginning of each line. Plus I guess as you found out, having 3 bit color isn't desperately easy to work with. The code in that app is very impressive, but I feel like trying to access the framebuffer directly is going to be a complete nightmare... Apart from the way it moves around every release, Bangle.js does background DMA after you flip - so you may well end up altering the buffer contents while it's being send to the LCD which will cause tearing. We could add a function to get the address of the buffer I guess that could wait for DMA to finish, but it's still a bit iffy - if you accidentally overwrite those command bytes the screen will no longer update correctly. Have you checked the speed difference from just having a pre-allocated ArrayBuffer Graphics object that you write to (in maybe a more sensible bit depth) and blitting that to the screen? I'd have thought that might be reasonably quick. Or even I wonder if your triangle draw implementation is actually that much faster than Bangle's own one, since it seems they do work in a pretty similar way... I guess it's just actually being able to call Bangle.js's one fast enough! Posted at 2024-01-15 by FManga Indeed, working with that framebuffer isn't very easy, but that's part of the point for me. Having to deal with these weird details is fun. My first attempt at this did involve an ArrayBuffer Graphics object. I still don't have a proper grasp of the Bangle.js code, but I was under the impression that it doesn't do a quick blit from that to the framebuffer. There's also the RAM cost. Writing the code that finds the buffer in RAM was fun too, but of course it would be better to have a safe API that takes DMA into account. That said, I don't notice any tearing. Before writing to the framebuffer I call 'g.drawRect(-1, -1, 0, 177)' so that all of the rows get marked as dirty. I imagine this blocks until DMA is done? I haven't checked the speed yet, nor am I sure of the best way to do so. What is the highest resolution timer I can use? Posted at 2024-01-15 by @gfwilliams
can't argue with that! :)
In the case where it's a normal Graphics instance and it's not clipped/scaled/rotated there is a reasonably fast path for rendering - it's not quite as fast as it could be, but it's not too bad.
Ok, great! Yes, that would ensure it's waited. And yes, getTime/Date.now use the same underlying timer - they're only accurate to 1/32768 sec on the Bangle, but I imagine that's still enough for benchmarking frame draw times! And I can imagine about the C/JS difference - the JS interpreter is going to be at least 100x slower than C I imagine Posted at 2024-01-17 by FManga I still haven't gotten around to benchmarking the drawing routines, but I've been experimenting and made a second watch face (also in the PR above). With JS being the bottleneck, benchmarking the triangle function wouldn't help. And maybe I'm going to need texture mapping for the next watchface. :) I haven't tried the ArrayBuffer Graphics yet. In part because of the RAM it'd take up, and even if it's fast enough, it's better to access the buffer directly and let the CPU sleep a bit more, right? Is adding a function to get the buffer an option? I'd sure prefer that instead of probing for it with peek8! :P Posted at 2024-01-17 by @gfwilliams
Yes, I think that'd be fine. Just added - you can get it with Posted at 2024-01-17 by FManga Awesome! Thanks! Posted at 2024-01-18 by Hank Trying not to nag, but a question that I got in mind since you started this thread: Why is it a clock? Posted at 2024-01-18 by FManga It's a clock because that's simpler to start off with, and I wanted to make something animated to entertain my kids. They're two year olds, so they can't actually play games, but they do have fun watching and poking at the screen. I do plan on making games out of this, though. I already have a ship being controlled by the gyro, but I'm not sure if I'm going to turn that into a full game or just a slightly interactive clock. Posted at 2024-01-19 by FManga Just in case anyone finds this interesting or would like to make suggestions: Before trying to implement texture mapping, I decided to try lighting support. Of course, we can't use math.h in compiledC code, so this is where the fun begins:
(quotes and newlines omitted for clarity. It would've been nice if we could use raw string literals for inline assembly) Unfortunately that doesn't work either because gcc really doesn't want to work with floats. To get around that, I assembled that function locally and replaced each instruction with the result as data:
The result of this abomination is attached below. Attachments: Posted at 2024-01-19 by @gfwilliams nice! I should add that the compiler itself is at https://github.com/gfwilliams/EspruinoCompiler if you decide you want to try fiddling around with that. If you were able to change the build such that math.h functions were pulled in as required I bet it'd make a lot of people very happy! Also you might be able to change the compiler flags to let it take raw string literals? Worth adding that right now we have to tell GCC to use softfp so that the argument passing of floats works when calling back to the Espruino interpreter. But you might be able to get it to use softfp for arg passing while still using hardfp instructions - I'm not sure! Posted at 2024-01-19 by FManga I sent you the PR that allows specifically Edit: It'd probably be good to have some other headers in there, such as cstdint.
Looks like changing from soft to softfp is exactly what we want. Edit2: I tested softfp and the compiler does output floating-point instructions. I have no code to test if the float argument passing works as intended, though. Posted at 2024-01-19 by user113695 This is all very exciting. Years ago (for the Bangle 1) I wrote an STL viewer that does some of the heavy lifting in C (viewstl in the app store). Back then I did all the math library function (mostly trig functions) in JS and passed the results into C (simple arithmetic fp ops worked fine, albeit not using the fpu). Posted at 2024-01-19 by FManga It's good to know I'm not the only one trying to do 3D on a Bangle. :P Posted at 2024-01-19 by @gfwilliams I've just updated with the changes (and softfp) and it would appear to be working ok. Now we have some hardware FP support, I wonder if it might be worth implementing at least I can see the Raspberry Pi Pico seems to have optimised implementations? Posted at 2024-01-19 by @gfwilliams I was hoping I could add the following to E.compiledC, but even after accounting for the double-escaping, I'm not having success :
If you have any luck, please let me know! Posted at 2024-01-19 by d3nd3-o0 Some flags @fanoush used in another post : Posted at 2024-01-19 by @fanoush Currently you can pass single precision floats (and converted doubles) into inline C code and back via Float32Array or with shared buffer with Int32Array for conversions of single values when passing parameters (more info https://gist.github.com/fanoush/9227640a869d78d69a799276dff0fb71#file-espruino-fpu-softfp-inlinec-js-L24), maybe it would be nice to support float type directly when passing parameters to native code (with automatic conversion to/from javascript double)? then d2f and f2d would not be needed? Posted at 2024-01-19 by FManga The Pico code is for a Cortex M0+ and what you have in your snippet is incomplete.
Note that you have to call the function explicitly, I couldn't use a float cast and get it to link as __aeabi_d2f. It might work if we compile the assembly into a library and then link to that. If one were to go that far, might as well link to libgcc and let the linker throw away all the stuff that isn't used. Posted at 2024-01-19 by @fanoush
It already works like that, no changes in EspruinoCompiler needed (unless it broke recently) Also using floating point instructions work inside inline C, see my tests linked in previous post. Include files and macros are intentionally blocked https://github.com/gfwilliams/EspruinoCompiler/blob/master/src/compile.js#L466 so you can't include math.h Posted at 2024-01-19 by @fanoush
why do you think so? and btw it is possible to set calling convention per method via attributes and when calling one from another it works https://gist.github.com/fanoush/85ebe50c5c4a54ca15bf2867e27f7cd3 (EDIT: or for cortex m4 here https://gist.github.com/fanoush/0da3e47aee9e20fb11b010cc3aa4e16e ) But anyway, why to use doubles? Cortex M4F can do only floats in hardware, isn't this enough for most stuff discussed here? Posted at 2024-01-19 by FManga
It was set to soft, not softfp. This was changed to softfp today.
This is true...
... but this also changed today. Posted at 2024-01-19 by FManga
The top part of the diff is calling the function I pasted earlier (d2f), in the same compilation unit. The bottom part is calling libgcc's __aeabi_d2f, in a library. The difference is the Both used the exact same compilation flags.
Because JavaScript uses doubles you need to be able to convert to float and back.
Interesting, I didn't know about those. That's probably what's going on in the diff above. I'll do some more testing. Posted at 2024-01-19 by @fanoush
Oh interesting, I was thinking it already changed to softfp when we discussed it long time ago here gfwilliams/EspruinoCompiler#10 so I was using it with my local changes all the time (as I use many boards that are not in the whitelist) EDIT: softfp was already used for quite some time in main firmware https://github.com/espruino/Espruino/blob/255dbb036942c59c2e937d3c80c206d88586be79/ChangeLog#L282 then it briefly changed but was reverted espruino/Espruino@42e336f I was somehow thinking the inline C compiler already moved to softfp too, well, it is great it was finally done now :-) Posted at 2024-01-19 by @fanoush
This could be done before entering your inlineC code if float type was supported directly. And there is the Float32Array - this is part of javascript standard so javascript can already convert it for you to float type. Posted at 2024-01-19 by FManga I don't know what the implication is to support float directly, but it does sound like a good alternative to doing the conversion in C. The conversion needs to happen somewhere. Is it better to have it in Espruino, where it will take up space even if you don't use compiledC, or is it better to have in each compiledC block that uses doubles? Personally, I don't really need to pass floats/doubles to/from C. Just being able to work with floats is enough for me. I merely replied with a working version of the code that was asked for. Posted at 2024-01-20 by FManga For some reason the following compiles fine on my local EspruinoCompiler, but fails on the online one:
Maybe it's a different GCC version? I think fixing it on the online one is just a matter of adding Posted at 2024-01-20 by @fanoush
Well, the conversion code already takes that space in Espruino due to Float32Array. I just tried to implement float type support for native calls in espruino and with this small patch (also attached) it works
Tested with
and I get
EDIT: after comparing output of Attachments: Posted at 2024-01-22 by @gfwilliams @fanoush that's neat! I think I'd been put off doing it because I was concerned there were only 3 bits for the argument type, and we already had 7 arg types - but we do have one free so we might as well use it :) I've just merged that in...
Which bit? @fmanga thanks for the d2f implementation - it's a bit odd it's not getting picked up by the linker automatically if it's in the file though. There's something odd going on there as for Espruino it appears to work fine for us: https://github.com/espruino/Espruino/blob/master/src/jswrap_math.c#L33 Posted at 2024-01-22 by @fanoush
well the code with union of int32 and float will work only on arm with soft or softfp convention so I am not sure what to do when building for other platforms (like linux or esp32) so for those I was thinking about keeping just the enum but ifdef everything out including the nativeCallGetCType "float" line. Or keep it in nativeCallGetCType but fail at runtime when someone calls E.nativeCall on such platforms with float argument in signature - then the ifdef can be only for the 'case JSWAT_FLOAT32:' bits. however for RELEASE=1 it will fail silently. I am not actually sure for which platforms the Inline C and/or E.nativeCall is implemented. So maybe it is Ok to keep it as is. I don't know :-)
can be C vs C++ name mangling, Inline C is actually compiled as C++ source (unlike espruino jswrap_math.c) so something like wrapping it into Posted at 2024-01-22 by @gfwilliams Ahh, ok - Well, while nativeCall is there on most platforms, I think it's only really used on ARM - so I wouldn't worry too much. I guess if people start to use it for built-in functions it could become a problem though... Posted at 2024-01-22 by @fanoush It is the Posted at 2024-01-22 by @gfwilliams Thanks for checking - that's really strange... All of Espruino is compiled with flto and it seems to work in that case... I wonder what's different! Posted at 2024-01-22 by @fanoush it needs
Posted at 2024-01-22 by FManga Wouldn't that also force it into the resulting binary even if it's not used? Posted at 2024-01-22 by @fanoush Unfortunately yes, I just tried and for otherwise unused function it makes it bigger with this. But without this it probably gets optimized out because it is not directly called so LTO removes it(?). Or it is built in a way that linker does not expect later when searching for it - LTO may add some additional flags or mangling(?) that this method in standard library is not expected to have. EDIT: some info is in https://gcc.gnu.org/wiki/LinkTimeOptimizationFAQ that's where I got the Posted at 2024-01-22 by @fanoush
without
However with
Posted at 2024-01-22 by FManga Is there any reason why we don't simply use Posted at 2024-01-22 by @fanoush
https://github.com/gfwilliams/EspruinoCompiler/blob/master/inc/linker.ld#L39 Posted at 2024-01-22 by FManga The linker will still discard anything that isn't actually used so it shouldn't introduce any bloat. Posted at 2024-01-22 by @fanoush Indeed, just tested, and the DISCARD linker script does not work for this as it gets added anyway when I add "-lgcc". I see some suspicious extra .debug_frame section listed by objdump when -lgcc is there but this does not get into the binary as adding it into DISCARD works and the btoa string is still the same even when not seeing it in the output. Not sure if everything from libgcc.a is harmless like this but looks like for this case it works fine indeed. Posted at 2024-01-22 by FManga
I hoped all the compiled code wasn't in RAM. Is this because it's in a string or does the chip not support XiP to run directly from flash? Posted at 2024-01-23 by @fanoush
It is meant for small time critical things, otherwise you are supposed to code mainly in JavaScript :-) EDIT: you can try require("Flash").getFree() if it gives you something sensible on Bangle2, then you could write the code to free area of internal flash directly to test how/if it works EDIT2: 250KB is quite a lot, with some JS code that would manage loading code into that, it could be usable. Posted at 2024-01-23 by @fanoush BTW as the floating point hardware can do only basic operations like +-*/ I tried to add Posted at 2024-01-23 by FManga Ah, with data and code being together it makes sense. Posted at 2024-01-23 by @fanoush By using Flash module it is doable. If you would allocate writable data separately in JS and pass it as pointers to code stored to flash it needs no changes. some js code to manage free internal flash blocks so you would know where the code is loaded shouldn't be hard. the code is position independent. Also you can use your local EspruinoCompiler and distribute just the compiled output as part of your app (with sources somewhere and guide how to recompile it). Posted at 2024-01-23 by FManga For some reason I don't need to add Posted at 2024-01-23 by FManga
Something like this?
Can that be called from C? Also, does the GC know when it is safe to free the Uint8Array?
Edit: To call that from C it seems what I need is Edit2: It might make sense to have a libespruino that implements malloc/free/sin/cos/sinf/cosf/etc by calling the JS implementations. Posted at 2024-01-23 by @gfwilliams So we're saying that just adding
I have tried enabling XIP, but there are some big issues with it - for instance the flash has to be put to sleep when sleeping but then when Bangle.js wakes up, it jumps straight into an IRQ which might try and access an XIP memory address while flash is asleep. It's a nightmare - what you can do is enable a second flash filesystem in internal flash that by default JS files go in - I was going to start producing a second build for it as it's a lot faster, but even that seems to have some problems at the moment (I'm not 100% sure why).
Yes, exactly - definitely don't do
Yes - although I can't say enough how bad an idea I think trying to dynamically allocate data from C is. Can you not just statically allocate everything you need? In which case it's all handled for you by
I just feel like you're trying to do something that this isn't designed for at all. As @fanoush says it was really only designed for the odd function, and even if you did get your project working and release it, my poor server's going to suffer if loads of people start downloading and forcing it to compile the same big project all the time. I wonder whether really what you need is almost a separate project with a Makefile so you can make it locally, and then when it's done just upload the base64 of the compiled code into the app and link to your repo? There are definitely things you can do, for instance when starting up you could call Posted at 2024-01-23 by @fanoush
Maybe, but the storage is not the bottleneck, I tried it with code that was about 600 bytes and it was not worth it but maybe it would make some sense with larger code. However Heatshrink may not be good for binary code As for the malloc code I think it would be more reliable to allocate one big array, send pointer to it once and do the malloc/free inside C on top of that.
Yes, keeping reference is enough but it is also about defragmentation and stuff moving, I think flat arrays are not moved(?) when E.defrag() is triggered, smaller stuff is moved.
When you start using stuff in https://github.com/gfwilliams/EspruinoCompiler/blob/master/src/utils.js#L73 the output of inline compiler is fixed for specific device and FW version so cannot be distributed in binary form (it builds the code with hardcoded value from Posted at 2024-01-23 by FManga I'm actually not trying to do anything specific at the moment, I'm just poking to see what works/doesn't and what's a good idea or not. From there I'll see what I do about this engine I've been making. I like being able to share any resulting games or watchfaces I make on the repo in a way that people don't have to compile things on their own to see it. I didn't know that having inlinedC would result in extra load to the compiler server, I just assumed there was a cache somewhere since there wouldn't be much point in compiling the same code again and again. I had also assumed Posted at 2024-01-23 by @fanoush
It could be used only for storage so it works basically as Storage module on top of internal flash. that would give you direct pointers to data and even code. However it may be tricky to implement writing to such storage when XIP is turned on.
This could be part of minification so people uploading app to watch get js code with already compiled binary. Or in this case it could be part of non minified app (like this)
Yes, same for Posted at 2024-01-23 by @fanoush
atob() is function call, makes new buffer in RAM when called, yes external flash is slower, every byte from SPI flash is read by toggling GPIOs in software, it is fast but much slower than internal RAM/Flash Posted at 2024-01-23 by FManga
Yes, but so is
It's bit bangging SPI? o_O Posted at 2024-01-23 by @fanoush
It is not tokenized but with direct string constants it could be, good idea.
https://github.com/espruino/Espruino/blob/master/targets/nrf5x/jshardware.c#L2496 Posted at 2024-01-23 by @gfwilliams
Yes - it sounds nuts but I have tested both hardware SPI and memory mapped QSPI. At least for the read patterns we do, it's still fastest to bit-bang using 2 bits for data, so that's what we do. Pretokenising complete strings is an interesting idea, and could help in a lot of areas. Right now all we do is turn tokens into single bytes. I guess we could store strings like: Posted at 2024-01-23 by FManga Interesting! This sounds like something fun to play with. Do I need a devkit to mess with this code or can I do it safely over bluetooth without bricking my Banglejs2? Posted at 2024-01-23 by @fanoush
Bluetooth is slow so updating firmware over it gets old pretty quickly but yes it should be mostly safe, there is a watchdog and bootloader so it is not that easy to brick it but it can be done. Better is to use some SWD debug dongle with the charging cable and usb female cable adapter (just cut some old cable with usb female on it). These things are < US$2 on aliexpress (search for daplink) or you can make almost anything into such dongle (like raspberry pico, blue pill board). Also STLINK V2 clones (like this one https://aliexpress.com/item/1005001621626894.html - $1.60 including shipping for me) work - either as is or reflashed with daplink firmware. I have tons of them so when I need it I often take another one instead of disconnecting it from something :-) Posted at 2024-01-23 by FManga I happen to have one of those STLINK V2 clones, so all I need is the usb female cable adapter. Posted at 2024-01-23 by @fanoush
https://www.espruino.com/Bangle.js2+Technical#swd With ST firmware it should work in openocd like this Posted at 2024-01-23 by @gfwilliams I should add that you can usually compile Espruino for Linux (or Windows WSL) by just cloning the repo and typing While you can't test the C compilation there, things like pretokenisation can be tested fine - so it's a much faster, less painful way of developing Posted at 2024-01-23 by FManga My first try at getting this compiling didn't go so well... on a Mac. I'll try again on Arch Linux. Posted at 2024-01-23 by @fanoush May not help much in your case but this works in fresh ubuntu 22.04 in WSL or booted from live CD/USB
I use the final build as a simple non scientific CPU benchmark for random devices :-) Quite long part is last linking phase which is single threaded with gcc 8 so this tries the turbo frequency too. Posted at 2024-01-26 by @gfwilliams Just to add that I'm looking into the raw strings code at the moment - I already have a proof of concept and it looks pretty easy - under 50 lines of changes. I may have to do something a bit more complicated to get the pretokeniser to detect Posted at 2024-01-26 by @gfwilliams Just committed so it'll be in cutting edge builds. Handles normal strings and The real improvement will be if the pretokeniser in the Web IDE / App Loader will do it automatically (when it knows the Bangle firmware supports it!), which I'll try next week. It should be a massive boost for clock faces that load their own fonts/images Posted at 2024-01-26 by @gfwilliams One thought about this - currently we store the raw string as But for a bunch of strings they are less than 255 chars so only need one byte of length. Maybe we should consider doing a bit like MQTT does with variable message length, which IIRC is:
Posted at 2024-01-26 by FManga This sounds a bit like UTF8. Would there happen to be code in the firmware for encoding/decoding that already? Posted at 2024-01-29 by @gfwilliams
There is, but UTF8 encodes the value in the bottom 5/6 bits of the char code (I can't remember exactly) - it's slight overkill I think. But I had an idea over the weekend - I'll just have two raw string types - 0xD1 for 16 bit and 0xD2 for 8 bit length Posted at 2024-01-29 by @fanoush I wonder how it will work when you convert it back to readable data, like using Posted at 2024-01-29 by @gfwilliams Just committed... Posted at 2024-01-29 by @gfwilliams
It's smart enough to know:
It's not perfect, but then if you've enabled pretokenisation you have to expect it won't be able to put everything back exactly as it was Posted at 2024-01-29 by @fanoush There is one more thing about strings I did not know.
via
that the function body is still native string and points to flash however the I was expecting that like If such optimization was there I was wondering what could happen with such strings when parsing or execution of code with these new features just added here but as it is not there there is no issue :-) I guess this optimization I thought was already there could be added too? At least when the string is there full in verbatim and does not contain escape characters e.g. Then in future case of WebIDE replacing I tested this in device with no SPI flash so Storage is native nrf52 flash so maybe for BANGLE2 it may be different? EDIT: I retested with Bangle 2 and the only difference is that function body is "FlashString" not "NativeString" but s2,s3 are in RAM too. But anyway with pretokenized strings this feature may be easier to implement and when done by IDE also the tokenized "aaa"aaa" would be simple string that could be Flash/NativeString (when parsed from code that is also such string = storage file). Posted at 2024-01-29 by @gfwilliams
Correct - it can't easily because as you noted the string might be escaped (although I guess we could have checked for that when parsing). Either way we'd have to parse over it at load time, and then again when we wanted to use it - so while it saves RAM it might not be a clear win for performance.
Correct, yes - and that is now the case if you turn on pretokenisation in the IDE. I'm going to have to update the advice in https://www.espruino.com/Code+Style#other-suggestions ! UpdateI've just pushed an updated Web IDE, BangleApps (in the dev app loader) and a new firmware (the raw strings exposed an interpreter issue that's been around for a while) and the results are really good. Ensure pretokenisation is turned on in the dev app loader, that you have the latest firmware, and click Quick example with the Anton clock: On the same build, I do
Bear in mind that's the whole clock, so it's a big improvement. And it pretty much all comes from loading the font at the start (even though Anton is relatively modest font-wise - other clocks will see bigger benefits). I did a quick benchmark of just how long it takes to load the font, with a test file in Storage:
So it's around 40x faster! Font rendering will be a little slower, but it's not going to be huge compared to that boost. The only downside at the moment is that Espruino will now make all strings in pretokenised code native strings, and I feel like we should probably change it so that if a string is pretokenised but it would fit inside one JsVar (eg it's not going to use any more RAM than the pointer to the string in flash) we should keep it in RAM. Posted at 2024-01-29 by @thyttan I think I notice the improved speed - 40x is impressive!
I did this. Then I compacted the storage via the settings app and the on screen message is incomplete (see attached image). I reinstalled the settings app without pretokenization and tried compacting again, this time the whole message was displayed. I am not sure that it has to do with the new changes, I have not tried with older firmwares and pretokenization. But I thought I'd mention it here anyway. Attachments: Posted at 2024-01-30 by @gfwilliams Interesting, thanks! I can confirm it happens here too, I'll look into it. Please let me know if you notice anything else... Posted at 2024-01-30 by @gfwilliams Ok, it turns out there's something strange with edit: It's
The actual pretokenising works fine by the look of it Posted at 2024-01-30 by @gfwilliams It's now fixed on cutting edge builds! Posted at 2024-01-30 by FManga While it sure isn't as trivial an optimization as it seemed to me at first, the speedup (and space savings?) from your benchmarks sound great! I've updated to the latest firmware. When I try to reinstall all the apps I get the errors in the attachment. The first time I tried, it got stuck updating the Scheduler app. I manually uninstalled/installed it, then tried again. Now it doesn't get stuck but it outputs those errors. In the WebIDE, if I enable pretokenization on Synthwave and try to upload to RAM I get the following error: If I don't enable pretokenization, Synthwave uploads to RAM successfully, but the C++ code no longer works, I haven't looked into what broke yet. If I enable pretokenization but upload to storage instead of RAM, it crashes. It only works if I disable pretokenization and upload to storage. Enabling Esprima minification results in "Error: Unreachable point. logically broken.", but the code uploads anyway. Edit: let c = E.compiledC(`
// int boop(int)
int boop(int d) {
return d * 42;
}
`);
print('boop:', c.boop(3)); Attachments: Posted at 2024-01-30 by @gfwilliams Those errors are expected - the 404s are fine (it tries different URLs to find the files, sometimes they're not at the first URL). They would have happened before too. I've seen There's no Posted at 2024-01-30 by FManga
The PullRequest for it (together with Warpdrive) is still open (espruino/BangleApps#3156). My fork of BangleApps is only missing the last 3 commits, which don't seem to be related. Besides, I was testing on https://www.espruino.com/ide, not my own fork of the IDE. Posted at 2024-01-30 by @fanoush
Oh, I would expect the opposite! With current tokenization the inline C as part of storage file could now have atob array automatically expanded and tokenized so the binary string with executable code may point to the flash memory instead of RAM. could be fixed by inline compiler by generating something like Posted at 2024-01-30 by FManga
That snippet doesn't have static/global variables, so it should be fine anywhere. The crash is probably due to the IDE replacing unknown characters with
This would be best, the others would avoid the atob optimization. Posted at 2024-01-30 by @thyttan The whole message shows for me as well now. Thanks! |
Beta Was this translation helpful? Give feedback.
-
Posted at 2024-01-30 by @thyttan New ram leakI get a new ram leak I didn't have before. It only shows when on cutting edge firmware (2v20.69) and pretokenization is used on upload. So far I noticed it when fastloading from I have not looked closer on Since fastloading from Memory usage increasing when switching between
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2024-01-13 by FManga
Since the BangleJS has a framebuffer, I expected its Graphics Object to extend the arraybuffer one, but that is apparently not the case as
g.buffer
is undefined andg.asImage("object")
returns a copy.Is there any way to access the framebuffer directly?
Edit: Couldn't find a good way to do it, did it anyway.
Also, I think 'LCD' was meant to be 'g' in https://www.espruino.com/Graphics (or does that not apply to the BangleJS2?):
Beta Was this translation helpful? Give feedback.
All reactions