raburton / rboot

An open source bootloader for the ESP8266
https://richard.burtons.org/tag/rboot/?order=ASC
MIT License
300 stars 72 forks source link

IRAM usage (question) #38

Open eriksl opened 6 years ago

eriksl commented 6 years ago

This is more like a question. I've been using rboot for over two years now, and works like a charm. But there is one thing I can't get my head around. My images are quite tight on IRAM usage (and yes, believe me, I do already use all kinds of tricks to free up the max of it, some code, e.g. timing dependend code, just need IRAM).

I now have between 1400 and sometimes 200 bytes IRAM free (but if it becomes this low, I always immediately free up some).

My question is, how much of the IRAM is used by rboot. I've tried various methods to find out, all with different results, so not very reliable I guess. Or better: how many bytes of the IRAM are required to remain free for rboot to run in? Can you maybe add a function to report this value to the image/user? Or if it could be calculated (start address + length), I could create a dummy entry in the loader script, or make the iram region smaller accordingly, then the loader would already notice any overrun (and report).

Having said this, maybe it's possible to load the code into the SPI caching area, which, AFAIK is not used/mapped at this stage, which means 32 kbytes free to use :-)

Thanks!

raburton commented 6 years ago

I'm not quite sure what're asking because rBoot itself has no impact on your iram segment or the free ram available to your application. If you're referring to ota code that you include in your application, then that should add very little to the iram segment, almost everything in my ota sample is marked as being able to go in the irom section, so there probably only be a few bytes added. At runtime little ram will be used by the ota code itself, as it works with the data buffers passed to it and doesn't need to allocate much itself, but the http code used in the underlying sdk libraries will need more - can't tell you how much though.

eriksl commented 6 years ago

Thanks very much, that was quick too!

In the meantime I've been trying to understand a little bit more of the code, so I could hopefully answer some of the questions myself.

As far as I understand it now:

So I see now that indeed no regular iram is used. If it's correct what I wrote of course.

There are still a lot of things I don't understand yet, especially in combination with bigflash. In that case I guess the rom boot loader calls rboot (in flash, where then slot 0 is mapped?), then the normal boot process takes place and after that, in my own image, the bigflash code, which then runs in iram, unmaps flash en maps the selected flash slot, is that correct? I'm just wondering, Isn't there a way the rboot code can do that before the image is loaded?

My idea of this corresponds with what you wrote?:

The confusion arised from the mentioning of running the segment loader from the top of iram. I always understood that was regular iram, not the alternative iram for flash cache. Which would mean that if I would fill iram to the top, it would collide with the loader code. But it doesn't.

I am happy :-) It means I can use quite a lot more of IRAM.

PS. one of the latest commits introduced a reimplementation of the RTC_RAM code in bigflash for minimal iram usage (no checksum verification). The author made a mistake there, assuming the RTC_RAM would always be valid at that point, it also didn't check for the magic number. In my case RTC RAM wasn't valid (initial boot from power-on) and it kept resetting endlessly. I have a fix for that, also tidied up that code "a bit". Interested?

eriksl commented 6 years ago

BTW I am not using the app code other than the bigflash extension. I have my own flash uploader/downloader/etc code. That's not the rocket science part....

It's this project, if you might wonder: https://github.com/eriksl/esp8266-universal-io-bridge, it does all of the home automation here and needs 16 mbit flash chips because of bigflash.

raburton commented 6 years ago

Your understanding of the process looks about right. The reason rBoot can't set up the flash mapping is two fold. First off if rBoot enabled it then it would not be able to use that upper bit of ram in the cache area. The second is that the mapping is not just done once on boot, it is mapped and unmapped repeatedly by the sdk around certain flash operations. I'm not sure which commit you're referring to where you mention a problem with RTC_RAM code.

eriksl commented 6 years ago

Yes, clear, thanks!

This one a6efefdaf3d79e62a548047677cbb8787762592a. Besides that the commit comment is at least misleading, it doesn't check the magic number.

I think this code is neater (most of the patch, a few extra lines are required on top of the file):

#ifdef BOOT_RTC_ENABLED
        {
            const rboot_rtc_data_overlay_t *rtc_in_iospace;
            rboot_rtc_data_overlay_t rtc_in_dram;
            unsigned int ix;

            rtc_in_iospace = (const rboot_rtc_data_overlay_t *)(0x60001100 + (RBOOT_RTC_ADDR * 4));

            for(ix = 0; ix < sizeof(rtc_in_dram.overlay) / sizeof(rtc_in_dram.overlay[0]); ix++)
                rtc_in_dram.overlay[ix] = rtc_in_iospace->overlay[ix];

            if((rtc_in_dram.data.magic == RBOOT_RTC_MAGIC) && (rtc_in_dram.data.next_mode == MODE_TEMP_ROM))
                val = conf.roms[rtc_in_dram.data.temp_rom];
            else
                val = conf.roms[conf.current_rom];
        }
#else
        val = conf.roms[conf.current_rom];
#endif
eriksl commented 6 years ago

This one:

#ifdef BOOT_RTC_ENABLED
typedef union
{
    rboot_rtc_data  data;
    uint32_t        overlay[4];
} rboot_rtc_data_overlay_t;
#endif
eriksl commented 6 years ago

Actually this (my) code appears to be wrong and not working. The principle is a bit neater (with the union) but the rest is wrong. At this point rboot has already cleared the next/temp boot fields.