Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IRAM usage (question) #38

Open
eriksl opened this issue Aug 19, 2018 · 7 comments
Open

IRAM usage (question) #38

eriksl opened this issue Aug 19, 2018 · 7 comments

Comments

@eriksl
Copy link
Contributor

eriksl commented Aug 19, 2018

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
Copy link
Owner

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
Copy link
Contributor Author

eriksl commented Aug 20, 2018

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:

  • rboot compiles stage2a code
  • stage2a is responsible for loading the segments (a.o. iram) of the image
  • esptool converts this into a byte array that is included into rboot.c
  • find_image copies this code to iram, a part of the iram that is normally used for caching flash, not regular iram (just like I suggested, silly me)
  • after find_image finishes, the stage2a code in alternative iram is jumped to
  • somewhere in the sdk init part of the image, the flash cache is activated, after the loading code has run (probably something with "Cache_Read_New()" ;-)

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?:

  • rboot code itself uses no (regular) iram
  • bigflash init uses some iram, but it's taken from the loaded image, so it won't collide.

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
Copy link
Contributor Author

eriksl commented Aug 20, 2018

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
Copy link
Owner

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
Copy link
Contributor Author

eriksl commented Aug 22, 2018

Yes, clear, thanks!

This one a6efefd. 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
Copy link
Contributor Author

eriksl commented Aug 22, 2018

This one:

#ifdef BOOT_RTC_ENABLED
typedef union
{
	rboot_rtc_data	data;
	uint32_t 		overlay[4];
} rboot_rtc_data_overlay_t;
#endif

@eriksl
Copy link
Contributor Author

eriksl commented Aug 26, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants