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.

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