Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 17 of 17

Thread: Bug: EXTMEM "works" without PSRAM

  1. #1
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054

    Bug: EXTMEM "works" without PSRAM

    Code:
    EXTMEM int a;
     
    void setup() {
     a = 123;
     Serial.print(a);
    }
    
    void loop() {}
    Works, even without PSRAM.
    But only as long the dcache wants that it works...

  2. #2
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,590
    Yes, and people are stumbling over it: https://arduino.stackexchange.com/qu...ks/81271#81271

    He tested this in a loop on a board with a badly soldered chip, got the correct values back and concluded that the memtest program didn't work correctly :-/

  3. #3
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    Easy fix: Disable that in the MPU if PSRAM is not detected. Startup.c.
    The code should take care of the PSRAm Size, too. Otherwise you have the same effect with 8MB PSRAM, but you try to use more..

  4. #4
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    Did not test explicitly this issue, but I think there is a good chance that my old unmerged PR re: MPU fixes that already.
    That time I was not aware of this issue.

  5. #5
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    With just removing the MPU setting, it just crashes. This is correct.
    The text however could be better:
    Code:
    CrashReport:
      A problem occurred at (system time) 10:3:59
      Code was executing from address 0x66
      CFSR: 82
        (DACCVIOL) Data Access Violation
        (MMARVALID) Accessed Address: 0x70000000
      Temperature inside the chip was 38.17 C
      Startup CPU clock speed is 600MHz
    Would be nice when it would print "Access to PSRAM, but PSRAM not available" or something like this.

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,854
    Yes, the cache can be misleading. It caused FALSE suggestions that QSPI FLASH was working IIRC.

    Proper usage is only known at runtime:
    Code:
    extern uint8_t external_psram_size;
    EXTMEM int a;
    
    void setup() {
      Serial.begin(1492);
      if ( external_psram_size > 0 ) {
        a = 123;
        Serial.print(a);
      }
      else
        Serial.print("No PSRAM Detected on this board!");
    }
    
    void loop() {}
    On the T_4.0 it builds and returns:
    Code:
    No PSRAM Detected on this board!

  7. #7
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    "Just a crash" works even without that test. It's so easy to just fix the MPU programming...

  8. #8
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,854
    Yes, but that wouldn't help debug a system where a PSRAM was soldered on and not functioning?

    That 'extern' is not referenced on pages below - (it might be nice to not have to know to search "startup.c"):
    pjrc.com/store/teensy41.html :: Could explain the expected runtime values of : extern uint8_t external_psram_size; // will have value of 0, 8, or 16 when detected
    or
    pjrc.com/store/psram.html :: IDE code screen shot

  9. #9
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    Why wouldn't a crash message ""Access to PSRAM, but PSRAM not available" help?
    Even the existing unmodified CrashReport gives a clear indication.

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,854
    Would have to have code to check for any address or above in PSRAM ranges?

    And only helps when user knows : if ( CrashReport) Serial.print( CrashReport);

    That's Paul's decision - but with "C" you can break lots of stuff doing the wrong thing ... especially not having useful documentation.

  11. #11
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    Good news: There is nothing against doing both

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,854
    Quote Originally Posted by Frank B View Post
    Good news: There is nothing against doing both
    That may be true, but it seems a lot like WORK

    Other note would be - EXTMEM is provided to compile on T_4.0?
    > Not sure if that is on purpose?

    LittleFS has this code when asking for RAM drive:
    Code:
      285  #if defined(__IMXRT1062__)
      286: 		return begin(extmem_malloc(size), size);
      287  #else
      288  		return begin(malloc(size), size);
    And this HAS_EXTRAM is handy - lots of room for future growth - at compile time:
    Code:
    #if defined(ARDUINO_TEENSY41)
    // Teensy 4.1 external RAM address range is 0x70000000 to 0x7FFFFFFF
    #define HAS_EXTRAM
    #define IS_EXTMEM(addr) (((uint32_t)ptr >> 28) == 7)
    #endif

  13. #13
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    What work? it's an "if" in startup.c a - one or two liner. More good news, I did that already in a PR. Its also possible, to copy these lines only from there, if the rest is not desired.
    And, that works on a T4, too.
    Edit: Note, that the MPU confit for EXTMEM has to happen *after* the chips are detected. So, just move the corresponding line in startup.c

    To consider connected flash memory (does it actually work with EXTMEM?? Never tried that) you can also simply declare the memory area as readonly.
    EXTMEM can be used anyway only meaningfully if something is written in at some point in the beginning. So readonly is also ok.
    Last edited by Frank B; 09-01-2021 at 11:18 AM.

  14. #14
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    Does flash work with EXTMEM?

  15. #15
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,769
    Quote Originally Posted by Frank B View Post
    Why wouldn't a crash message ""Access to PSRAM, but PSRAM not available" help?
    To properly add this to CrashReport, wouldn't we need to configure the MPU to disallow access to the FlexSPI2 memory range?

    While possible, one complication is we turn on the MPU pretty early in the startup process, so we can start enjoying the cache speedup. External RAM is detected much later. Code would be needed in the configure_external_ram() function do the FlexSPI2 MPU config.

    If this were done somehow, then yes, it would be quite worthwhile to add more text to the CrashReport class to advise that an access violation in that range is regarding non-functional PSRAM.


    Quote Originally Posted by defragster View Post
    And only helps when user knows : if ( CrashReport) Serial.print( CrashReport);

    ... especially not having useful documentation.
    Yes, today few people know of CrashReport and it is (so far) only documented on a blog post and some forum conversations.


    Quote Originally Posted by Frank B View Post
    To consider connected flash memory (does it actually work with EXTMEM?? Never tried that) you can also simply declare the memory area as readonly.
    EXTMEM can be used anyway only meaningfully if something is written in at some point in the beginning. So readonly is also ok.
    Currently we are using EXTMEM only for RAM, and only for the 16MB range 7000,0000 to 70FF,FFFF.

    Except for some very early beta test code, we're not accessing flash on FlexSPI2 as memory mapped. Flash access is always done using the FlexSPI2 "IPS Bus" path.

    Click image for larger version. 

Name:	screenshot.png 
Views:	6 
Size:	72.1 KB 
ID:	25744

    The 3 reasons for this design are:

    1: IPS Bus allows access to 512MB, compared to only 224MB as memory mapped.
    2: Memory mapped access drains away cache from actual variables
    3: Writing can't be done by memory mapped access, only by IPS Bus

  16. #16
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    To properly add this to CrashReport, wouldn't we need to configure the MPU to disallow access to the FlexSPI2 memory range?
    Yes, this is, what this thread is about. Post #3. MPU config.
    Ok, so we don't need to take care about flash.

    Just use this:
    Code:
        // FlexSPI2 PSRAM
        if (external_psram_size == 16) {
            SCB_MPU_RBAR = 0x70000000 | REGION(i++);
            SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_16M;
        } else if (external_psram_size == 8) {
            SCB_MPU_RBAR = 0x70000000 | REGION(i++);
            SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_8M;
        }
    inside configure_cache().
    Right, of course it does need to know the size. This can be done by moving configure_cache a few lines later, or do the PSRAM Config a few lines earlier.

    If you want to harden that even more, consider a last "else" that explicitly disables this area: DEV_NOCACHE | NOACCESS


    Code:
    #ifdef ARDUINO_TEENSY41
        configure_external_ram();
    #endif
        configure_cache();
        startup_early_hook();
        while (millis() < 20) ; // wait at least 20ms before starting USB
    Or whatever.. there will be a way

    At least 20ms is no problem. Neither 300ms.
    Last edited by Frank B; 09-01-2021 at 01:01 PM.

  17. #17
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    ...and magically this crashed now - as the fix is correct.
    Code:
    EXTMEM int a;
     
    void setup() {
      Serial.println(CrashReport);
      a = 123;
      Serial.print(a);
    }
    
    void loop() {}
    Edit:Without this patch TD simply lies, and claims the value would be stored somewhere.
    Code:
    CrashReport:
      A problem occurred at (system time) 0:0:0
      Code was executing from address 0xB4
      CFSR: 82
        (DACCVIOL) Data Access Violation
        (MMARVALID) Accessed Address: 0x70000000
      Temperature inside the chip was 29.85 C
      Startup CPU clock speed is 600MHz
      Reboot was caused by auto reboot after fault or bad interrupt detected
    Even without CrashReport it is useful - as the Teensy restarts and does not do magic things that will go wrong much later, sometime when the cache gets invalidated. Edit: Which can be hard to debug.
    Last edited by Frank B; 09-01-2021 at 12:52 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •