You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
4.3KB

  1. // Simple performance test for Teensy 3.5/3.6 SDHC.
  2. // Demonstrates yield() efficiency.
  3. // Warning SdFatSdio and SdFatSdioEX normally should
  4. // not both be used in a program.
  5. // Each has its own cache and member variables.
  6. #include "SdFat.h"
  7. // 32 KiB buffer.
  8. const size_t BUF_DIM = 32768;
  9. // 8 MiB file.
  10. const uint32_t FILE_SIZE = 256UL*BUF_DIM;
  11. SdFatSdio sd;
  12. SdFatSdioEX sdEx;
  13. File file;
  14. uint8_t buf[BUF_DIM];
  15. // buffer as uint32_t
  16. uint32_t* buf32 = (uint32_t*)buf;
  17. // Total usec in read/write calls.
  18. uint32_t totalMicros = 0;
  19. // Time in yield() function.
  20. uint32_t yieldMicros = 0;
  21. // Number of yield calls.
  22. uint32_t yieldCalls = 0;
  23. // Max busy time for single yield call.
  24. uint32_t yieldMaxUsec = 0;
  25. // Control access to the two versions of SdFat.
  26. bool useEx = false;
  27. //-----------------------------------------------------------------------------
  28. bool sdBusy() {
  29. return useEx ? sdEx.card()->isBusy() : sd.card()->isBusy();
  30. }
  31. //-----------------------------------------------------------------------------
  32. void errorHalt(const char* msg) {
  33. if (useEx) {
  34. sdEx.errorHalt(msg);
  35. } else {
  36. sd.errorHalt(msg);
  37. }
  38. }
  39. //------------------------------------------------------------------------------
  40. uint32_t kHzSdClk() {
  41. return useEx ? sdEx.card()->kHzSdClk() : sd.card()->kHzSdClk();
  42. }
  43. //------------------------------------------------------------------------------
  44. // Replace "weak" system yield() function.
  45. void yield() {
  46. // Only count cardBusy time.
  47. if (!sdBusy()) {
  48. return;
  49. }
  50. uint32_t m = micros();
  51. yieldCalls++;
  52. while (sdBusy()) {
  53. // Do something here.
  54. }
  55. m = micros() - m;
  56. if (m > yieldMaxUsec) {
  57. yieldMaxUsec = m;
  58. }
  59. yieldMicros += m;
  60. }
  61. //-----------------------------------------------------------------------------
  62. void runTest() {
  63. // Zero Stats
  64. totalMicros = 0;
  65. yieldMicros = 0;
  66. yieldCalls = 0;
  67. yieldMaxUsec = 0;
  68. if (!file.open("TeensyDemo.bin", O_RDWR | O_CREAT)) {
  69. errorHalt("open failed");
  70. }
  71. Serial.println("\nsize,write,read");
  72. Serial.println("bytes,KB/sec,KB/sec");
  73. for (size_t nb = 512; nb <= BUF_DIM; nb *= 2) {
  74. file.truncate(0);
  75. uint32_t nRdWr = FILE_SIZE/nb;
  76. Serial.print(nb);
  77. Serial.print(',');
  78. uint32_t t = micros();
  79. for (uint32_t n = 0; n < nRdWr; n++) {
  80. // Set start and end of buffer.
  81. buf32[0] = n;
  82. buf32[nb/4 - 1] = n;
  83. if (nb != file.write(buf, nb)) {
  84. errorHalt("write failed");
  85. }
  86. }
  87. t = micros() - t;
  88. totalMicros += t;
  89. Serial.print(1000.0*FILE_SIZE/t);
  90. Serial.print(',');
  91. file.rewind();
  92. t = micros();
  93. for (uint32_t n = 0; n < nRdWr; n++) {
  94. if ((int)nb != file.read(buf, nb)) {
  95. errorHalt("read failed");
  96. }
  97. // crude check of data.
  98. if (buf32[0] != n || buf32[nb/4 - 1] != n) {
  99. errorHalt("data check");
  100. }
  101. }
  102. t = micros() - t;
  103. totalMicros += t;
  104. Serial.println(1000.0*FILE_SIZE/t);
  105. }
  106. file.close();
  107. Serial.print("\ntotalMicros ");
  108. Serial.println(totalMicros);
  109. Serial.print("yieldMicros ");
  110. Serial.println(yieldMicros);
  111. Serial.print("yieldCalls ");
  112. Serial.println(yieldCalls);
  113. Serial.print("yieldMaxUsec ");
  114. Serial.println(yieldMaxUsec);
  115. Serial.print("kHzSdClk ");
  116. Serial.println(kHzSdClk());
  117. Serial.println("Done");
  118. }
  119. //-----------------------------------------------------------------------------
  120. void setup() {
  121. Serial.begin(9600);
  122. while (!Serial) {
  123. }
  124. Serial.println("SdFatSdioEX uses extended multi-block transfers without DMA.");
  125. Serial.println("SdFatSdio uses a traditional DMA SDIO implementation.");
  126. Serial.println("Note the difference is speed and busy yield time.\n");
  127. }
  128. //-----------------------------------------------------------------------------
  129. void loop() {
  130. do {
  131. delay(10);
  132. } while (Serial.available() && Serial.read());
  133. Serial.println("Type '1' for SdFatSdioEX or '2' for SdFatSdio");
  134. while (!Serial.available()) {
  135. }
  136. char c = Serial.read();
  137. if (c != '1' && c != '2') {
  138. Serial.println("Invalid input");
  139. return;
  140. }
  141. if (c =='1') {
  142. useEx = true;
  143. if (!sdEx.begin()) {
  144. sd.initErrorHalt("SdFatSdioEX begin() failed");
  145. }
  146. // make sdEx the current volume.
  147. sdEx.chvol();
  148. } else {
  149. useEx = false;
  150. if (!sd.begin()) {
  151. sd.initErrorHalt("SdFatSdio begin() failed");
  152. }
  153. // make sd the current volume.
  154. sd.chvol();
  155. }
  156. runTest();
  157. }