<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><br class=""></div>Another interesting approach:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">main/ovms.cpp:</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class=""><div class="">void* operator new(std::size_t sz)</div><div class=""> {</div><div class=""> return ExternalRamMalloc(sz);</div><div class=""> }</div></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">OVMS > module memory</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">Free 8-bit 197400/282424, 32-bit 424/27596, SPIRAM 4113632/4194252</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">--Task-- Total DRAM D/IRAM IRAM SPIRAM +/- DRAM D/IRAM IRAM SPIRAM</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">esp_timer 17068 0 644 35676 +17068 +0 +644 +35676</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">main 12452 0 0 5352 +12452 +0 +0 +5352</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">Housekeeping 28404 0 0 17292 +28404 +0 +0 +17292</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">tiT 0 0 0 132 +0 +0 +0 +132</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">AsyncConsole 0 0 26404 20 +0 +0 +26404 +20</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">no task 5348 0 0 0 +5348 +0 +0 +0</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">ipc0 10848 0 0 0 +10848 +0 +0 +0</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">ipc1 12 0 0 0 +12 +0 +0 +0</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">Tmr Svc 7328 0 0 0 +7328 +0 +0 +0</span></font></div></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class="">With WIFI enabled and connected to an access point:</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 18px;" class=""><div class="">OVMS > module memory</div><div class="">Free 8-bit 163600/282424, 32-bit 424/27596, SPIRAM 4110952/4194252</div></span></font></div></blockquote><div class=""><div><br class=""></div><div>That is a global override for all C++ objects to be allocated from SPIRAM. I bet you haven’t seen so much free internal RAM on an ESP32 before...</div><div><br class=""></div><div>There are also some C code malloc’s that we could move over as well (the most obvious being javascript duktape, of course, but also mongoose).</div><div><br class=""></div><div>I’m wondering if there is any reason not to simply do this global override for C++ code? Any stuff that won’t work in SPIRAM could explicitly malloc what it needs.</div><div><br class=""></div><div>Regards, Mark.</div><div><br class=""><blockquote type="cite" class=""><div class="">On 17 Feb 2018, at 9:41 PM, Mark Webb-Johnson <<a href="mailto:mark@webb-johnson.net" class="">mark@webb-johnson.net</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">There is a significant performance hit using SPI vs internal ram. There are also restrictions (such as no stacks, no dma targets, ISRs, etc). I’ve tried just changing Malloc to use SPI ram but the Espressif idf libraries don’t work. Maybe in 3-6 months, but not today.<br class=""><br class="">I still have to solve the problem of std:: objects (strings, etc). I think a new c++ memory allocator should work.<br class=""><br class="">Regards, Mark<br class=""><br class=""><blockquote type="cite" class="">On 17 Feb 2018, at 9:33 AM, Stephen Casner <<a href="mailto:casner@acm.org" class="">casner@acm.org</a>> wrote:<br class=""><br class="">Mark,<br class=""><br class="">This looks good to me (LGTM), but there might be cases where we need<br class="">to avoid adding the new ExternalRamAllocated class as a base for a<br class="">building-block class and instead add it as a base of a subset of the<br class="">classes that derive from the building-block class.<br class=""><br class="">If there isn't any significant performance hit going to SPIRAM, then I<br class="">expect most allocations other than stacks and DMA buffers can go<br class="">there.<br class=""><br class=""> -- Steve<br class=""><br class=""><blockquote type="cite" class="">On Fri, 16 Feb 2018, Mark Webb-Johnson wrote:<br class=""><br class=""><br class="">I’ve committed (and pushed) an experimental extension to allow C++ objects to be optionally moved to SPI RAM.<br class=""><br class="">The code is in ovms.h, so should be easily accessible to everything. It is pretty simple:<br class=""><br class="">We have a new class ‘ExternalRamAllocated’. That does nothing except override the new and new[] operators.<br class=""><br class="">Those operators try to malloc from SPI RAM first. If that doesn’t succeed then they fall back to standard internal RAM.<br class=""><br class="">The definition of a C++ class can then be changed to make it “: public ExternalRamAllocated”. Once that is done, any objects of that class allocated will try to be placed in external (SPI) RAM.<br class=""><br class="">For other malloc uses, a general purpose 'void* ExternalRamMalloc(std::size_t sz)’ function is also provided.<br class=""><br class="">To test this, I’ve made a one line change to the OvmsCommand class:<br class=""><br class="">-class OvmsCommand<br class="">+class OvmsCommand : public ExternalRamAllocated<br class=""><br class="">Here is what the memory usage looks like:<br class=""><br class="">With SPI RAM disabled (in menuconfig):<br class=""><br class="">Free 8-bit 120844/284304, 32-bit 30508/57680, SPIRAM 0/0<br class="">--Task-- Total DRAM D/IRAM IRAM SPIRAM +/- DRAM D/IRAM IRAM SPIRAM<br class="">no task 5312 0 0 0 +5312 +0 +0 +0<br class="">esp_timer 52328 0 644 0 +52328 +0 +644 +0<br class="">main 16448 0 0 0 +16448 +0 +0 +0<br class="">ipc0 11096 0 0 0 +11096 +0 +0 +0<br class="">Housekeeping 40576 5120 0 0 +40576 +5120 +0 +0<br class="">tiT 128 0 0 0 +128 +0 +0 +0<br class="">Tmr Svc 884 6444 0 0 +884 +6444 +0 +0<br class="">ipc1 12 0 0 0 +12 +0 +0 +0<br class="">AsyncConsole 20 0 26404 0 +20 +0 +26404 +0<br class=""><br class="">Without deriving OvmsCommand from ExternalRamAllocated:<br class=""><br class="">Free 8-bit 119240/282436, 32-bit 424/27596, SPIRAM 4193924/4194252<br class="">--Task-- Total DRAM D/IRAM IRAM SPIRAM +/- DRAM D/IRAM IRAM SPIRAM<br class="">tiT 0 0 0 128 +0 +0 +0 +128<br class="">Housekeeping 40564 5120 0 12 +40564 +5120 +0 +12<br class="">no task 5348 0 0 0 +5348 +0 +0 +0<br class="">esp_timer 52328 0 644 0 +52328 +0 +644 +0<br class="">main 16448 0 0 0 +16448 +0 +0 +0<br class="">ipc0 11096 0 0 0 +11096 +0 +0 +0<br class="">ipc1 12 0 0 0 +12 +0 +0 +0<br class="">Tmr Svc 884 6444 0 0 +884 +6444 +0 +0<br class="">AsyncConsole 20 0 26404 0 +20 +0 +26404 +0<br class=""><br class="">After deriving OvmsCommand from ExternalRamAllocated:<br class=""><br class="">OVMS > module memory<br class="">Free 8-bit 152308/282432, 32-bit 424/27596, SPIRAM 4160852/4194252<br class="">--Task-- Total DRAM D/IRAM IRAM SPIRAM +/- DRAM D/IRAM IRAM SPIRAM<br class="">esp_timer 31664 0 644 20664 +31664 +0 +644 +20664<br class="">tiT 0 0 0 128 +0 +0 +0 +128<br class="">Housekeeping 39636 0 0 6060 +39636 +0 +0 +6060<br class="">no task 5348 0 0 0 +5348 +0 +0 +0<br class="">main 16448 0 0 0 +16448 +0 +0 +0<br class="">ipc0 11096 0 0 0 +11096 +0 +0 +0<br class="">ipc1 12 0 0 0 +12 +0 +0 +0<br class="">Tmr Svc 7328 0 0 0 +7328 +0 +0 +0<br class="">AsyncConsole 20 0 26404 0 +20 +0 +26404 +0<br class=""><br class="">The advantage of SPI RAM is obvious. 30KB of internal RAM saved with just one line changed in a header file. Most of our other objects like that (metrics, configs, etc) could be equally easily moved to SPI RAM. We can make the decision on a class-by-class basis.<br class=""><br class="">I think this is a pretty good solution. It puts the onus of the decision of whether to put into SPI RAM into the object itself (as presumably the object knows best whether it can actually be put in SPI RAM). It is also extremely simple to define that.<br class=""><br class="">But, it is an experiment. Please let me know what you think.<br class=""><br class="">Regards, Mark.<br class=""><br class=""></blockquote>_______________________________________________<br class="">OvmsDev mailing list<br class=""><a href="mailto:OvmsDev@lists.teslaclub.hk" class="">OvmsDev@lists.teslaclub.hk</a><br class="">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev<br class=""></blockquote><br class="">_______________________________________________<br class="">OvmsDev mailing list<br class=""><a href="mailto:OvmsDev@lists.teslaclub.hk" class="">OvmsDev@lists.teslaclub.hk</a><br class="">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev<br class=""></div></div></blockquote></div><br class=""></div></body></html>