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

Thread: Teensy 4.1: SdFat Beta only option?

  1. #1
    Senior Member
    Join Date
    Oct 2015
    Location
    Roma (IT, EU)
    Posts
    312

    Teensy 4.1: SdFat Beta only option?

    Hi,

    so I have this shiny new 4.1 and want to play with the onboard SD.

    Installed the latest TeensyDuino 1.52b6 on Arduino IDE 1.8.12.

    I tried to rebuild an old test of mine, for T3.6, which was based upon Bill's SdFat; but the "regular" SdFat (latest from GitHub) is not happy about "SdFatSdioEx" type when selecting T4.1 (builds OK for T3.6).

    I suppose Bill did not add T4.1 to the regular SdFat yet?

    Is my only option to install the new "SdFat Beta"? Pity since it's not compatible with my existing codebase.

    Just for completeness, this is my source code:

    Code:
    // SdFatSdioEx simple write latency test for Teensy 3.5/3.6 onboard uSD
    // Last Modified FC aka xfer 20181115
    // IMPORTANT NOTE: DO NOT use "LTO" as build option, or it will not run!
    
    #include <SdFat.h>
    
    #define MIN(a,b) ((a<b)?a:b)
    
    #define SERIAL_SPEED 115200
    #define BLOCK_DIM 512
    // Check SD free space!
    #define PREALLOCATED_BLOCKS 512000UL	// 256 MB; compromise between meaningful statistics and total benchmark time
    #define BUF_DIM (256 * BLOCK_DIM)		// 128 KiB: will comfortably fit T3.5/3.6
    #define FILE_SIZE (PREALLOCATED_BLOCKS * BLOCK_DIM)
    
    SdFatSdioEX sdEx;
    
    File file;
    
    uint8_t buf[BUF_DIM];
    
    //-----------------------------------------------------------------------------
    bool sdBusy() {
      return sdEx.card()->isBusy();
    }
    //-----------------------------------------------------------------------------
    void errorHalt(const char* msg) 
    {
    	sdEx.errorHalt(msg);
    }
    //------------------------------------------------------------------------------
    uint32_t kHzSdClk() {
      return sdEx.card()->kHzSdClk(); 
    }  
    
    // Replace "weak" system yield() function
    // Usually it checks for serial data etc.; we don't need it
    void yield() 
    {
    }
    
    ////////////
    // RUNTEST
    ////////////
    
    void runTest(const bool contiguousFile = true, const bool preEraseFile = true) 
    {    
      const char filename[] = "T3sdioex.bin";
      uint32_t first_sector, last_sector;	// 1 sector = 512 bytes
      uint32_t first_erase_sector;
      const size_t erase_count = 2048; // number of sectors to erase at once. 2048*512 = 1 MiB
      const float fMiBs = PREALLOCATED_BLOCKS / 2000.0f;
       
      // Fill buffer with dummy data
      memset(buf, 128, BUF_DIM);
      
      // Zero Stats
      uint32_t singleWriteMicros = 0;
      uint32_t maxSingleWriteMicros = 0;
      
      sdEx.remove(filename);
      Serial.print("Preallocating "); Serial.print(fMiBs, 1); Serial.println(" MiB file");
      if (!file.createContiguous(sdEx.vwd(), filename, FILE_SIZE))
      {
    	  Serial.println("Error from file.createContiguous");
    	  exit(1);
      }
    
      if (!file.contiguousRange(&first_sector, &last_sector))
      {
    	  Serial.println("Error from contiguousRange. Exiting...");
    	  exit(1);
      }
      first_erase_sector = first_sector;
      Serial.println("Pre-erasing file: please wait...");
      while (first_erase_sector <= last_sector)
      {
    	  if (!sdEx.card()->erase(first_erase_sector, MIN(first_erase_sector + erase_count, last_sector)))
    	  {
    		  Serial.print("Error from erase; start sector = "); Serial.println(first_erase_sector);
    		  file.close();
    		  exit(1);
    	  }
    	  first_erase_sector += erase_count;
      }
      file.flush();
      file.rewind();
      Serial.println("\nStarting write benchmark. First writes are quite slow: please be patient");
      delay(200);
      
      Serial.println("\nTransfer size\tWrite speed\tAvg write time\tMax write time");
      Serial.println("bytes\t\tKB/s\t\tus\t\tus\n");
      for (size_t nb = BLOCK_DIM; nb <= BUF_DIM; nb *= 2) // Loop for growing write sizes (nb)
      {
        maxSingleWriteMicros = 0;
        uint32_t nRdWr = FILE_SIZE/nb;
        Serial.print(nb);
        Serial.print("\t\t");
        uint32_t t = micros();
        for (uint32_t n = 0; n < nRdWr; n++) // Number of writes to fill the file, with current write size
        {
          singleWriteMicros = micros();
          if (nb != file.write(buf, nb)) 
          {
            errorHalt("write failed");
          }
          singleWriteMicros = micros() - singleWriteMicros;
          if (singleWriteMicros > maxSingleWriteMicros)
            maxSingleWriteMicros = singleWriteMicros;
        }
        t = micros() - t;
        // Write speed
        Serial.print(1000.0f*FILE_SIZE/t, 1);
        Serial.print("\t\t");
        // Avg write time (us)
        Serial.print(t / nRdWr);
        Serial.print("\t\t");
        // Max write time (us)
        Serial.println(maxSingleWriteMicros);
        
        file.rewind();  // Ready for next write size
        t = micros();
      }
      file.close();
      Serial.print("\n SD clock speed (kHzSdClk): ");
      Serial.print(kHzSdClk());
      Serial.println(" KHz");
    }
    //-----------------------------------------------------------------------------
    
    //////////
    //
    // SETUP
    //
    //////////
    
    void setup() 
    {
      Serial.begin(SERIAL_SPEED);
      while (!Serial);
      Serial.println("Teensy 3.5/3.6 SdFatSdioEx write latency benchmark\n");
    
      if (!sdEx.begin()) 
      {
          sdEx.initErrorHalt("SdFatSdioEX begin() failed");
      }
        // make sdEx the current volume.
      sdEx.chvol();
      
      runTest();
      
      Serial.println("\n*** End of test ***");
    }
    //-----------------------------------------------------------------------------
    
    
    /////////
    //
    // LOOP
    //
    /////////
    
    void loop() 
    {
    }
    Error:

    Code:
    TeensySdioLatencyBench_fc:16: error: 'SdFatSdioEX' does not name a type
    SdFatSdioEX sdEx;

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,490
    Have used the latest SDFat Beta with exFat on T_4.1 and 4.0 with no trouble.

    One included example worked fine and the new LOGGER thread by @MBorgerson :: pjrc.com/threads/60809-Generic-data-logger-object

  3. #3
    Senior Member
    Join Date
    Oct 2015
    Location
    Roma (IT, EU)
    Posts
    312
    Yes, well, the problem is that SdFat Beta does not have SdFatSdioEx at all, not even for T3.6, so it breaks a lot of my code.

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,490
    Bummer. Was just noting that T_4.1 and similar 4.0 do have support in SDFat Beta.

  5. #5
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,637
    Quote Originally Posted by XFer View Post
    Yes, well, the problem is that SdFat Beta does not have SdFatSdioEx at all, not even for T3.6, so it breaks a lot of my code.
    If you wanted to use always the latest HW, you should go with SdFat-beta where Bill is testing out new things.

  6. #6
    Senior Member
    Join Date
    Oct 2015
    Location
    Roma (IT, EU)
    Posts
    312
    Actually I just wanted to test T4.1 vs T3.6; let's wait and see if Bill is going to backport T4.1 support in SdFat v1.
    I'm not in the mood to rewrite so much code at the moment.

  7. #7
    Member JaredReabow's Avatar
    Join Date
    May 2020
    Location
    oxford , UK
    Posts
    56
    I am having this exact problem too, all my existing codebase breaks when moving to beta for t4.1

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,812
    I'm trying to understand the problem. It is anything specific to Teensy 4.1? Or is the main issue Bill changed SdFat's API without compatibility for programs written using the older API? Or some combination?

  9. #9
    Member JaredReabow's Avatar
    Join Date
    May 2020
    Location
    oxford , UK
    Posts
    56
    not sure, the teensySDIOdemo does not work from sdfat beta and all my previous works which use SdFatSdioEx no longer work.
    the SDIO demo says "SdSpiConfig" was not declared.

  10. #10
    Member
    Join Date
    Oct 2019
    Location
    Calgary
    Posts
    41
    Quote Originally Posted by PaulStoffregen View Post
    ...Or is the main issue Bill changed SdFat's API without compatibility for programs written using the older API?...
    In my experience at least, it was that. On the Teensy 4.x, when I moved the changes in my fork of SdFat over to SdFat-beta I probably had about an hour's tinkering to get it back up and running. Most of that was due to constants and structure fields in SdFat-beta having their names changed. And most of what I had to change was in my additions; the #defines for some of the attribute bits had changed. But as there are existing methods to read the values of the attributes, you usually wouldn't notice the change. But since I had added methods to set those bits, I did.

    There were some similar changes to the file timestamp field names as well. Those would probably be noticeable to more people.

    And there was one method in FatVolume (vwd()) that went from being public to private. But in my case it wasn't a major issue. The one place in the code I was using called it could be easily replaced (f.rename(SD.vwd(), newname) became f.rename(newname), which in SdFat-beta amounted to exactly the same thing).

    So while I did have a bit of work to make the migration (and a good half of what I had to change was in my internal additions to SdFat-beta), I don't think any of it was due to the Teensy 4.x.

  11. #11
    Senior Member
    Join Date
    Oct 2015
    Location
    Roma (IT, EU)
    Posts
    312
    Quote Originally Posted by PaulStoffregen View Post
    I'm trying to understand the problem. It is anything specific to Teensy 4.1? Or is the main issue Bill changed SdFat's API without compatibility for programs written using the older API? Or some combination?
    It's a mix.

    1) SdFat v1 does not support Teensy 4.1, so if you try buliding for it, a lot of types are not defined and the build fails.

    2) SdFat Beta supports Teensy 4.1, but is not backward-compatible with v1, so old code would not build (for example: no "SdFatSdioEX").

    So it's a bit of "Catch 22".

Posting Permissions

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