|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- // Simple performance test for Teensy 3.5/3.6 SDHC.
- // Demonstrates yield() efficiency.
-
- // Warning SdFatSdio and SdFatSdioEX normally should
- // not both be used in a program.
- // Each has its own cache and member variables.
-
- #include "SdFat.h"
- #error See Version 2 SDIO example
- // 32 KiB buffer.
- const size_t BUF_DIM = 32768;
-
- // 8 MiB file.
- const uint32_t FILE_SIZE = 256UL*BUF_DIM;
-
- SdFatSdio sd;
-
- SdFatSdioEX sdEx;
-
- File file;
-
- uint8_t buf[BUF_DIM];
-
- // buffer as uint32_t
- uint32_t* buf32 = (uint32_t*)buf;
-
- // Total usec in read/write calls.
- uint32_t totalMicros = 0;
- // Time in yield() function.
- uint32_t yieldMicros = 0;
- // Number of yield calls.
- uint32_t yieldCalls = 0;
- // Max busy time for single yield call.
- uint32_t yieldMaxUsec = 0;
- // Control access to the two versions of SdFat.
- bool useEx = false;
- //-----------------------------------------------------------------------------
- bool sdBusy() {
- return useEx ? sdEx.card()->isBusy() : sd.card()->isBusy();
- }
- //-----------------------------------------------------------------------------
- void errorHalt(const char* msg) {
- if (useEx) {
- sdEx.errorHalt(msg);
- } else {
- sd.errorHalt(msg);
- }
- }
- //------------------------------------------------------------------------------
- uint32_t kHzSdClk() {
- return useEx ? sdEx.card()->kHzSdClk() : sd.card()->kHzSdClk();
- }
- //------------------------------------------------------------------------------
- // Replace "weak" system yield() function.
- void yield() {
- // Only count cardBusy time.
- if (!sdBusy()) {
- return;
- }
- uint32_t m = micros();
- yieldCalls++;
- while (sdBusy()) {
- // Do something here.
- }
- m = micros() - m;
- if (m > yieldMaxUsec) {
- yieldMaxUsec = m;
- }
- yieldMicros += m;
- }
- //-----------------------------------------------------------------------------
- void runTest() {
- // Zero Stats
- totalMicros = 0;
- yieldMicros = 0;
- yieldCalls = 0;
- yieldMaxUsec = 0;
- if (!file.open("TeensyDemo.bin", O_RDWR | O_CREAT)) {
- errorHalt("open failed");
- }
- Serial.println("\nsize,write,read");
- Serial.println("bytes,KB/sec,KB/sec");
- for (size_t nb = 512; nb <= BUF_DIM; nb *= 2) {
- file.truncate(0);
- uint32_t nRdWr = FILE_SIZE/nb;
- Serial.print(nb);
- Serial.print(',');
- uint32_t t = micros();
- for (uint32_t n = 0; n < nRdWr; n++) {
- // Set start and end of buffer.
- buf32[0] = n;
- buf32[nb/4 - 1] = n;
- if (nb != file.write(buf, nb)) {
- errorHalt("write failed");
- }
- }
- t = micros() - t;
- totalMicros += t;
- Serial.print(1000.0*FILE_SIZE/t);
- Serial.print(',');
- file.rewind();
- t = micros();
-
- for (uint32_t n = 0; n < nRdWr; n++) {
- if ((int)nb != file.read(buf, nb)) {
- errorHalt("read failed");
- }
- // crude check of data.
- if (buf32[0] != n || buf32[nb/4 - 1] != n) {
- errorHalt("data check");
- }
- }
- t = micros() - t;
- totalMicros += t;
- Serial.println(1000.0*FILE_SIZE/t);
- }
- file.close();
- Serial.print("\ntotalMicros ");
- Serial.println(totalMicros);
- Serial.print("yieldMicros ");
- Serial.println(yieldMicros);
- Serial.print("yieldCalls ");
- Serial.println(yieldCalls);
- Serial.print("yieldMaxUsec ");
- Serial.println(yieldMaxUsec);
- Serial.print("kHzSdClk ");
- Serial.println(kHzSdClk());
- Serial.println("Done");
- }
- //-----------------------------------------------------------------------------
- void setup() {
- Serial.begin(9600);
- while (!Serial) {
- }
- Serial.println("SdFatSdioEX uses extended multi-block transfers without DMA.");
- Serial.println("SdFatSdio uses a traditional DMA SDIO implementation.");
- Serial.println("Note the difference is speed and busy yield time.\n");
- }
- //-----------------------------------------------------------------------------
- void loop() {
- do {
- delay(10);
- } while (Serial.available() && Serial.read());
-
- Serial.println("Type '1' for SdFatSdioEX or '2' for SdFatSdio");
- while (!Serial.available()) {
- }
- char c = Serial.read();
- if (c != '1' && c != '2') {
- Serial.println("Invalid input");
- return;
- }
- if (c =='1') {
- useEx = true;
- if (!sdEx.begin()) {
- sd.initErrorHalt("SdFatSdioEX begin() failed");
- }
- // make sdEx the current volume.
- sdEx.chvol();
- } else {
- useEx = false;
- if (!sd.begin()) {
- sd.initErrorHalt("SdFatSdio begin() failed");
- }
- // make sd the current volume.
- sd.chvol();
- }
- runTest();
- }
|