jshardware.c flash functions for nRF51 & nRF52

Posted on
  • I am trying to implement some functions in jshardware.c

    I want the save() functionality so I can save functions and variables and keep them when the device turns on. and then can use the onInit() functionality as well.

    so I'm assuming to get this working I just need to implement the Flash functions in jshardware.c?

    what exactly is jshSaveToFlash and jshLoadFromFlash supposed to do? I'm not really sure where or what the contents of JsVars is.

    also how would you reccomend implementing jshFlashContainsCode()?

    -Thanks
    Mike

  • jshSaveToFlash takes what's in RAM, compresses it, and writes it into flash memory (which pages are used depend on the board). jshLoadFromFlash just does the opposite.

    jshFlashContainsCode actually just checks for a 'magic word' in memory that shows that the flash has been written.

    However you're best off implementing at a lower level and then flash memory access is available via the Flash module if required - see the STM32 implementation. I think the NRF chips have fixed page sizes? If so you're probably looking in the STM32F1 section of the ifdef, it should be pretty similar.

    Info about what the functions should do is here - let me know if you're not sure though.

    Finally, Espruino needs to know where the free pages are. It's just an entry in BOARD.py here that tells it.

    flash_available is for the firmware size test that runs after compilation. If the pages used are right at the end of flash (they probably should be on the NRFs?) then that size is just the amount of flash minus the space used for storing code, like this

  • @mjdietz
    Many thanks for this post. I need this knowledge for the ESP8266 port but hadn't got there yet. Awesome. Feel free to contact me directly anytime if you want to shoot the breeze on Espruino porting ... maybe we can help each other above and beyond Gordon's awesome support.

    @Gordon
    Nice post and detailed response ... yet MORE stuff for me to study :-)

  • I've studied and plan to study more ... but if anyone can help me out by explaining some architecture it would be appreciated. I am at the point where in the ESP8266 support I can load JavaScript into the ESP8266 for execution ... but now am puzzled on what techniques should come into play should I want to "harden" or "save" the application such that when the ESP8266 boots and loads Espruino ... my app will start and come to life without me having to load it again through UART.

    Neil

  • When saving, Espruino takes what's in RAM, compresses it, and writes it into flash memory somewhere. Loading is the opposite (and Espruino checks to see if it has code just by checking for a magic byte at the end of that memory area).

    First, you need to find some free pages somewhere on the EP8266's flash memory. I don't know enough about it to help there - is there actually some kind of filesystem?

    But as above, once you know that you stick the address and size of memory you can allow into the .py file, then you need to implement:

    • jshFlashGetPage
    • jshFlashErasePage
    • jshFlashRead
    • jshFlashWrite

    Docs in jshardware.h - the design is such that it should work with must types of flash memory. The bonus there is it allows other Espruino code to access flash memory too - for instance for fake eeproms.

    And that's it - everything else should be handled.

    Wasn't this something @aplikatika had done previously? I think his github page mentioned something.

    The saving code did change - because I wanted to make it easier to port to new platforms - but you should be able to crib the relevant bits of his work quite easily.

  • OK so I'm thinking i change my linker file so that the last couple of pages in flash are reserved for saving. So right now in my linker my flash has an ORIGIN address that is incremented so it is just after the softdevice and it has a length that then goes to the end off flash to be used by my application.

    How many pages (each page is 4096 bytes) should I reserve for Espruino at the end so I get full functionality?

    Also in BOARDS.py would address by the address of the first page to be used to save? then flash_availialbe would be the total bytes of these save pages? also what is place_text_section?

    so then jshflashcontainscode() would just check the first address of this flash to see that it has been written? any specific value or just check that it is not completly ereased?

    and are you saying I dont actually have to implemtn jshSaveToFlash and load? I'm not sure how to compress ram etc..

    thanks!
    -Mike

  • I'm thinking i change my linker file so that the last couple of pages in flash are reserved for saving

    In the STM32F1 builds I put the saved code at the end of flash like you're doing, but I keep the linker as-is. I just have the check_flash (iirc?) script that does a sanity check of the binary's size afterwards (based on board.py) to make sure the image isn't so big that it overlaps the end of flash memory.

    The bonus here is that if the binary is too big then you're told - but it still links, so you can look at the symbols in the binary and see what's taking up too much space.

    In the interest of keeping things simple (with those changes for LINKER_x in build_platform_config, I think we could keep the Nordic linker files?) I'd think about doing that.

    How many pages (each page is 4096 bytes) should I reserve for Espruino at the end so I get full functionality?

    It depends on the amount of RAM dedicated to variables... As the RAM is compressed (ish) before writing I'd say you need about half the amount of RAM. So if you had 4000 variables that's 4000 * 16 = 64000 bytes, so I'd save about 32000 bytes?

    Also in BOARDS.py would address by the address of the first page to be used to save? then flash_availialbe would be the total bytes of these save pages? also what is place_text_section?

    I actually wrote these up last week! :) https://github.com/espruino/Espruino/blob/master/README_BuildProcess.md#chip

    But yeah, address would be end_of_flash - size_of_saved_code_area. you can ignore place_text_section as you're using your own linker file.

    Best to look at [the olimexino board file])(https://github.com/espruino/Espruino/blob/master/boards/OLIMEXINO_STM32.py) as that does basically what you want.

    so then jshflashcontainscode() would just check the first address of this flash to see that it has been written?

    Actually the last 4 bytes IIRC - but you shouldn't need to implement that. All you need are these guys and the rest is done for you.

    and are you saying I dont actually have to implemtn jshSaveToFlash and load?

    Yep - literally just these 4 functions and you're sorted

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

jshardware.c flash functions for nRF51 & nRF52

Posted by Avatar for mjdietz @mjdietz

Actions