Proposed, and implemented, some enhancements (1Mb + 1Mb firmware, resizable jsvars size, ...) #5650
Replies: 1 comment
-
Posted at 2017-02-25 by @MaBecker Hi @pedro, looks promising ! Building firmware for ESPs has a lot of compatible setting to make sure it runs for all models. There was a switch to a single board build So why not switch to a two board build: 512K and 4MB Would like to jump in for testing, please share. Posted at 2017-02-26 by Wilberforce Hi @pedro Then when you are ready, you do a pull request to the /espruino/Espruino master. I think you might need to reserve some heap space for the wifi, as it looks like you don't have much heap space left after the vars increase. The buffer for IP are made dynamically and a free heap of 3344 might not be enough. Posted at 2017-02-26 by Pedro Thanks @MaBecker, I am following @wilberforce instructions on to create a branch so that the code cen be checked, and once I get feedback and more testing I will do a pullt request. Need to investigate how to do it : not a git master :) even if I remember doing something similar to patch Linux kernel in the past. Posted at 2017-02-26 by @MaBecker After reading through the source code, I think there is no need to have a new board for ESP, because with make option FLASH_4MB=1
not sure about RESIZABLE_JSVARS Posted at 2017-02-26 by Pedro Thanks @wilberforce, will try to branch the code so that it can be reviewed. Posted at 2017-02-26 by Wilberforce Ok, sounds good. 32k heap sounds like a bit more than usual - was that related to your changes? Posted at 2017-02-26 by @MaBecker @wilberforce normal is 8k heap and 1700 vars Posted at 2017-02-26 by Pedro You are right. For the 4MB map we do not need a new board. For RESIZABLE_JSVARS, as it is behaving differenty as the standard ESP8266 current version, I wanted to make sure not to mess with it and create a new board. To avoid "forking" then new board just includes the standard ESP8266_BOARD.py and changes a few parameters. If there is a cleaner way, will be happy to do it. Posted at 2017-02-26 by Wilberforce Ahh - I see why now - 128 vars at startup, that's why so much heap is available. Posted at 2017-02-26 by Pedro Yes it is. Initially only 128 jsvars are allocated, and it grows as needed. Posted at 2017-02-26 by @MaBecker @pedro can you please briefly explain how to switch to "flashMap": "4MB:1024/1024" Posted at 2017-02-26 by @MaBecker found a lot of information on this espressif page in chapter 4 and 5 Posted at 2017-02-26 by Pedro In the Makefile: ESP_FLASH_SIZE ?= 6 And in user_main.c, change (to avoid a warning):
to
As soon as I have created the branch I will submit the changes for review (including this in the makefile with the proper conditionals) In this mode, user1 and user2 bin files are identical (no different ld files) and the bootloader maps the first or second MB of flash to 0x40200000. As commented before, I need to check in the existing code that there is nothing hardcoded in current espruino build for ESP8266 when referencing flash from the first or second image Posted at 2017-02-26 by Pedro @MaBecker, @wilberforce, how do I create a new branch ? (or do I just fork into my repository). As commented, not a expert github user (mostly a newby here) Posted at 2017-02-26 by @MaBecker These are the hard coded sections I know so far: https://github.com/espruino/Espruino/blob/master/boards/ESP8266_BOARD.py#L46 https://github.com/espruino/Espruino/blob/master/libs/network/esp8266/jswrap_esp8266_network.c#L1185 not sure about https://github.com/espruino/Espruino/blob/master/libs/network/esp8266/ota.c Posted at 2017-02-26 by @MaBecker
That's it :) Attachments: Posted at 2017-02-26 by @MaBecker Next
Attachments: Posted at 2017-02-26 by Pedro Hi @MaBecker, If I did not get anything wrong :) here's the branch : https://github.com/pedro-es/Espruino/tree/esp8266-enhancements I only did one commit for all the files, as they are interrelated. The comments for the commit covers all. Posted at 2017-02-26 by @MaBecker Hi @pedro, looks great, thanks for sharing. Will start to implement this into my branch and run some test. Posted at 2017-02-26 by @MaBecker Your stuff is a great enhancement for ESP8266 with 4MB!
next is the "scripts/build_platform_config.py" stuff Posted at 2017-02-26 by @MaBecker My implementation of FLASH_4MB_C1: Posted at 2017-02-26 by Pedro Happy it is being useful :) Just a couple of remarks:
Posted at 2017-02-26 by @MaBecker Thanks EDIT:
good point, as it is just a linker script keep both :-) Shrink firmware size by six pages and always use first 1MB area, five pages to save code and one page for wifi. What do you think ? Posted at 2017-02-26 by @MaBecker tested wiflash with "4MB:1024/1024" - works - Thanks @tve Posted at 2017-02-27 by Wilberforce @mabe > tested wiflash with "4MB:1024/1024" - works - Thanks Please post your complete wiflash line... Posted at 2017-02-27 by @MaBecker sure
Posted at 2017-02-27 by @MaBecker Five pages for code save and one page for wifi save - and still using one board file :) Posted at 2017-02-27 by Wilberforce Looking good. I think the change of saved code would need to be documented well. I'm wondering if there is a better area for the saved code rather than the end of the application user Space? Posted at 2017-02-27 by @gfwilliams I'd be a bit iffy about the RESIZABLE_JSVARS - it does make things slower, and may possibly also break flat strings/arraybuffers/etc - not to mention make the whole thing just crash with a stack overflow if you run out of memory. I'm not entirely sure what you gain over just having set up a sensible number of JsVars beforehand. The whole unaligned access catcher would be great though - while Espruino tries quite hard not to do unaligned accesses, having something to handle the one or two cases where it does would be really handy. Also, with the flash map - I don't know if all 1MB is really needed at the moment? What would be great is automatically saving code to the extra areas of flash if they were detected - then finally you wouldn't get the 'out of memory' errors when saving Posted at 2017-02-27 by @MaBecker
Is it possible to calculate how many space is needed by save() in worst case? Posted at 2017-02-27 by @gfwilliams
True, and you could probably add a few extra bits and bobs (encryption, etc). With the byte read hack you could simply force all read-only arrays into flash, freeing a lot of RAM. I guess a 4MB build would probably be a good plan then.
You could argue it's JsVars * 16 bytes. But with Posted at 2017-02-27 by @MaBecker Great! So 1MB for save code and 1MB for additional flash space, that's what I am going to configure. Posted at 2017-02-27 by @MaBecker Got all puzzle pieces together.
Posted at 2017-02-28 by Pedro Hi @MaBecker, 1MB for save code won't work, as far as I have seen in the code. The main reason is that saved code must be first allocated somewhere in RAM, and we do not have so much RAM :) Posted at 2017-02-28 by Pedro Hi @gfwilliams, my comments on RESIZABLE_JSVARS above, in my answer to @MaBecker. Regarding the unaligned access code, here it is. I can't remember where I found it first on the internet, so I cannot credit the original idea author (even if current code does not seem too much to the original one...). By the way, it may need some adjustements to compile (this is just copied from another project of mine, and I have only done minor changes for it to compile in Espruino, but not really checked). Important: change everywhere ## by the a single "## hash" caracter (unless somebedy explains me how to write a single "## hash" without it being interpreted by the forum as some special character...) To activate the code, you need to call virtual_unaligned_memory_access() early in user_init()
Posted at 2017-02-28 by @MaBecker Hi @pedro,
I fully agree, it's a waste of space.
At the end it will be a solution that calculates JsVars * 16 byte and add the rest as FlashArea.
I definitely will try it, because this is too temptingly :) Posted at 2017-02-28 by @gfwilliams It'd be worth checking that the firmware update over WiFi can still function in the 1MB/1MB config
However as I said above, you can potentially execute JS directly from flash, so if there were a way to write larger JS (eg in chunks, or with the bootloader) then it could be an option. Wrt RESIZABLE_JSVARS - it's fun to play with, but I think it'd be a huge mistake to make the default builds use it. As I said above, the problems with flat string support could really trip people up - not to mention issues with garbage collection (I'm not sure when that happens currently). There is a branch for 'variable cache' which IMO would be the most exciting if it had a little work done on it. It would use the RAM only for most-used variables, and would journal the rest in flash - giving you potentially 65000 variables. Posted at 2017-02-28 by Wilberforce
Here is the code for the over the air updates... there is a flash map address look up: Posted at 2017-03-02 by user74245 This all sounds interesting, I have some questions: Where are wifi settings stored? Are they now stored twice and thus have to be reset after upgrading? What about saving javascript code to flash, is that now lost when upgrading? And "EEPROM" settings? Posted at 2017-03-02 by @MaBecker Hi @user74245,
Posted at 2017-03-05 by Pedro Hi @gfwilliams, I agree that if RESIZABLE_JSVARS is not stable, and until it is, the default builds should not use it, but I would definetively suggest to leave it there so that it can be compiled directly as an option from the main branch. Otherwise keeping it up to date and bring it up to stable would be a nightmare. At least a couple of my code changes are bug fixes for the existing LINUX RESIZABLE_JSVARS part and should anyway be applied. What is the best way to get this done? Regarding the "variable cache" branch, it is a different topic as I understand it in your comment : RESIZABLE_JSVARS leaves as much heap as possible free when not used for JSVars, and "variable cache" would allow (as you speak of flash cache) to have more JSvars than would fit on RAM. They are two related things, but different in approach and implementation (and complementary to each other in some way). Posted at 2017-03-06 by @gfwilliams
It's not going anywhere. Perhaps the
No, it does work. However Linux can afford to have quite a big chunk size which means that flat strings can usually be allocated.
Usually they are, but if a big area of memory is needed then sometimes it'll be allocated out of a stretch of JsVars. If the block size for resizable jsvars is too small then that may not happen. At least on Linux for things like TLS/HTTPS it won't crash, but the command will fail if a flat string can't be allocated. Also flat strings are usually allocated for types arrays to speed up accesses - if they can't be allocated then the access speed for arrays will drop right down.
That's great - if you could create a branch on your GitHub for those fixes and could issue a Pull Request for them that'd be great. But it helps a great deal to submit changes in several small groups. If something gets broken it's easy enough to look back and see exactly why things were changed then - if it's part of a massive commit you have no idea what changes go with what improvement.
I'm not sure if it's done yet or not, but the idea was that the variable_cache branch would use journalling when writing to flash. The sale way the FlashEEPROM module works at the moment - it's actually pretty kind on flash memory. Also in my tests I found that the majority of code didn't cause writebacks - most often you're just loading code in to execute, and aren't changing anything so have no need to write to flash. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Posted at 2017-02-25 by Pedro
Hi all,
This looks like a great piece of work, and I am migrating some personal project to Espruino with my ESP cards.
For everything to work fine, I needed some enhancements, so I have done them (on v91), and I think it woud be worth sharing so that these can be merged into the public version:
Resizable vars : the code is there, for the Linux version. Just patched a bit to enable it in ESP (should also work for other cards now) and fixed also some minor bugs on the save to / load from flash code (as it was, I think it would also fail on Linux, as with RESIZABLE_JSVARS the vars are stored in blocks, while the compress functions, as they were, read and wrote a full contiguous block of memory)
1024Kb + 1024Kb memory map : Added few lines to the Makefile to create a new target for the ESP 4Mbyte cards. With this layout, now we have 1024KB for firmware and stored vars and functions. Still neeeded to check where to fix some address mapping for the second image, as in this mode the bootloader maps 0x4020000 to either the first or second Mb of flash, and the image itself is exactly identical for user1 and user2. Just need to check in existing code if there is something harcoded around flash address and fix it.
So now, I get:
TO DO:
For the second part, what I use is as small piece of code based on something I found a couple of years ago in Internet and which I enhanced bit, so that ESP can access directly the flash mapped memory independently of alignment, or size (1, 2, 4 bytes) with no further modification to the user code. This is possible because ESP8266 is a bit of a monster, and allows virtualizing memory access through HW catchable exceptions for this kind of memory access errors, so a trap function can directly see the failing opcode and target address, access flash with the right alignment, simulate the opcode and put the result on the right register, and return control to the program (at assembler opcode level) after the offending opcode address.
This is seamless to your code, that can now access memory mapped flash as if it was in the rodata area. Of course, there is an impact in speed, which I have not benchmarked, but not noticed either, as we are not using our ESP8266s to do math intensive calculations (are we?)
Will work on other improvements.
So, if there is interest on it, I have a bunch of ".patch" files I will be happy to submit, or share, or whatever is the best way to get these into the main build.
Beta Was this translation helpful? Give feedback.
All reactions