<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    Probably worth trying, at least.  That was kind of what I was
    thinking we would do. <br>
    <br>
    I think the only storage I access really frequently is already
    procedure-local, so should be on the stack.  Are there any
    restrictions on doing I/O to/from SPIRAM?  For example, I/O buffers
    aimed at a CAN bus?<br>
    <br>
    For the proverbial back-of-the-envelope purposes, what is the access
    speed for SPIRAM?  Also, what access granularity (i.e. is there a
    fundamental "block" that gets transacted, or is this a sizeof-level
    thing)?<br>
    <br>
    Greg<br>
    <br>
    <br>
    <div class="moz-cite-prefix">Mark Webb-Johnson wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:BFFE55DE-5E2E-450D-A16B-FB2BFCE3579C@webb-johnson.net">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <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 class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">main/ovms.cpp:</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class=""><br class="">
              </span></font></div>
          <div class=""><font class="" face="Andale Mono"><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 class="" face="Andale Mono"><span
                style="font-size: 18px;" class=""><br class="">
              </span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">OVMS > module
                memory</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">Free 8-bit
                197400/282424, 32-bit 424/27596, SPIRAM 4113632/4194252</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">--Task--     Total
                DRAM D/IRAM   IRAM SPIRAM   +/- DRAM D/IRAM   IRAM
                SPIRAM</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">esp_timer        
                17068      0    644  35676     +17068     +0   +644
                +35676</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">main            
                 12452      0      0   5352     +12452     +0     +0
                 +5352</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">Housekeeping    
                 28404      0      0  17292     +28404     +0     +0
                +17292</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">tiT                  
                0      0      0    132         +0     +0     +0   +132</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">AsyncConsole        
                 0      0  26404     20         +0     +0 +26404    +20</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">no task          
                 5348      0      0      0      +5348     +0     +0    
                +0</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">ipc0            
                 10848      0      0      0     +10848     +0     +0    
                +0</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">ipc1                
                12      0      0      0        +12     +0     +0     +0</span></font></div>
          <div class=""><font class="" face="Andale Mono"><span
                style="font-size: 18px;" class="">Tmr Svc          
                 7328      0      0      0      +7328     +0     +0    
                +0</span></font></div>
        </div>
        <div class=""><font class="" face="Andale Mono"><span
              style="font-size: 18px;" class=""><br class="">
            </span></font></div>
        <div class=""><font class="" face="Andale Mono"><span
              style="font-size: 18px;" class="">With WIFI enabled and
              connected to an access point:</span></font></div>
        <div class=""><font class="" face="Andale Mono"><span
              style="font-size: 18px;" class=""><br class="">
            </span></font></div>
        <div class=""><font class="" face="Andale Mono"><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=""
                moz-do-not-send="true">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="" moz-do-not-send="true">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=""
                    moz-do-not-send="true">OvmsDev@lists.teslaclub.hk</a><br
                    class="">
                  <a class="moz-txt-link-freetext" href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a><br
                    class="">
                </blockquote>
                <br class="">
                _______________________________________________<br
                  class="">
                OvmsDev mailing list<br class="">
                <a href="mailto:OvmsDev@lists.teslaclub.hk" class=""
                  moz-do-not-send="true">OvmsDev@lists.teslaclub.hk</a><br
                  class="">
                <a class="moz-txt-link-freetext" href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a><br
                  class="">
              </div>
            </div>
          </blockquote>
        </div>
        <br class="">
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
OvmsDev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:OvmsDev@lists.teslaclub.hk">OvmsDev@lists.teslaclub.hk</a>
<a class="moz-txt-link-freetext" href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>