選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

200 行
5.1KB

  1. // Simple performance test for Teensy 3.5/3.6 SDHC.
  2. // Demonstrates yield() efficiency for SDIO modes.
  3. // Uses built-in SD for SPI modes.
  4. #include "SdFat.h"
  5. // SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
  6. // 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
  7. #define SD_FAT_TYPE 3
  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. #if SD_FAT_TYPE == 0
  13. SdFat sd;
  14. File file;
  15. #elif SD_FAT_TYPE == 1
  16. SdFat32 sd;
  17. File32 file;
  18. #elif SD_FAT_TYPE == 2
  19. SdExFat sd;
  20. ExFile file;
  21. #elif SD_FAT_TYPE == 3
  22. SdFs sd;
  23. FsFile file;
  24. #else // SD_FAT_TYPE
  25. #error Invalid SD_FAT_TYPE
  26. #endif // SD_FAT_TYPE
  27. uint8_t buf[BUF_DIM];
  28. // buffer as uint32_t
  29. uint32_t* buf32 = (uint32_t*)buf;
  30. // Total usec in read/write calls.
  31. uint32_t totalMicros = 0;
  32. // Time in yield() function.
  33. uint32_t yieldMicros = 0;
  34. // Number of yield calls.
  35. uint32_t yieldCalls = 0;
  36. // Max busy time for single yield call.
  37. uint32_t yieldMaxUsec = 0;
  38. //-----------------------------------------------------------------------------
  39. void errorHalt(const char* msg) {
  40. Serial.print("Error: ");
  41. Serial.println(msg);
  42. if (sd.sdErrorCode()) {
  43. if (sd.sdErrorCode() == SD_CARD_ERROR_ACMD41) {
  44. Serial.println("Try power cycling the SD card.");
  45. }
  46. printSdErrorSymbol(&Serial, sd.sdErrorCode());
  47. Serial.print(", ErrorData: 0X");
  48. Serial.println(sd.sdErrorData(), HEX);
  49. }
  50. while (true) {}
  51. }
  52. bool ready = false;
  53. //-----------------------------------------------------------------------------
  54. bool sdBusy() {
  55. return ready ? sd.card()->isBusy() : false;
  56. }
  57. //------------------------------------------------------------------------------
  58. // Replace "weak" system yield() function.
  59. void yield() {
  60. // Only count cardBusy time.
  61. if (!sdBusy()) {
  62. return;
  63. }
  64. uint32_t m = micros();
  65. yieldCalls++;
  66. while (sdBusy()) {
  67. // Do something here.
  68. }
  69. m = micros() - m;
  70. if (m > yieldMaxUsec) {
  71. yieldMaxUsec = m;
  72. }
  73. yieldMicros += m;
  74. }
  75. //-----------------------------------------------------------------------------
  76. void runTest() {
  77. // Zero Stats
  78. totalMicros = 0;
  79. yieldMicros = 0;
  80. yieldCalls = 0;
  81. yieldMaxUsec = 0;
  82. if (!file.open("TeensyDemo.bin", O_RDWR | O_CREAT)) {
  83. errorHalt("open failed");
  84. }
  85. Serial.println("\nsize,write,read");
  86. Serial.println("bytes,KB/sec,KB/sec");
  87. for (size_t nb = 512; nb <= BUF_DIM; nb *= 2) {
  88. uint32_t nRdWr = FILE_SIZE/nb;
  89. if (!file.truncate(0)) {
  90. errorHalt("truncate failed");
  91. }
  92. Serial.print(nb);
  93. Serial.print(',');
  94. uint32_t t = micros();
  95. for (uint32_t n = 0; n < nRdWr; n++) {
  96. // Set start and end of buffer.
  97. buf32[0] = n;
  98. buf32[nb/4 - 1] = n;
  99. if (nb != file.write(buf, nb)) {
  100. errorHalt("write failed");
  101. }
  102. }
  103. t = micros() - t;
  104. totalMicros += t;
  105. Serial.print(1000.0*FILE_SIZE/t);
  106. Serial.print(',');
  107. file.rewind();
  108. t = micros();
  109. for (uint32_t n = 0; n < nRdWr; n++) {
  110. if ((int)nb != file.read(buf, nb)) {
  111. errorHalt("read failed");
  112. }
  113. // crude check of data.
  114. if (buf32[0] != n || buf32[nb/4 - 1] != n) {
  115. errorHalt("data check");
  116. }
  117. }
  118. t = micros() - t;
  119. totalMicros += t;
  120. Serial.println(1000.0*FILE_SIZE/t);
  121. }
  122. file.close();
  123. Serial.print("\ntotalMicros ");
  124. Serial.println(totalMicros);
  125. Serial.print("yieldMicros ");
  126. Serial.println(yieldMicros);
  127. Serial.print("yieldCalls ");
  128. Serial.println(yieldCalls);
  129. Serial.print("yieldMaxUsec ");
  130. Serial.println(yieldMaxUsec);
  131. // Serial.print("kHzSdClk ");
  132. // Serial.println(kHzSdClk());
  133. Serial.println("Done");
  134. }
  135. //-----------------------------------------------------------------------------
  136. void setup() {
  137. Serial.begin(9600);
  138. while (!Serial) {
  139. }
  140. }
  141. //-----------------------------------------------------------------------------
  142. void loop() {
  143. static bool warn = true;
  144. if (warn) {
  145. warn = false;
  146. Serial.println(
  147. "SD cards must be power cycled to leave\n"
  148. "SPI mode so do SDIO tests first.\n"
  149. "\nCycle power on the card if an error occurs.");
  150. }
  151. do {
  152. delay(10);
  153. } while (Serial.available() && Serial.read());
  154. Serial.println(
  155. "\nType '1' for FIFO SDIO"
  156. "\n '2' for DMA SDIO"
  157. "\n '3' for Dedicated SPI"
  158. "\n '4' for Shared SPI");
  159. while (!Serial.available()) {
  160. }
  161. char c = Serial.read();
  162. if (c =='1') {
  163. if (!sd.begin(SdioConfig(FIFO_SDIO))) {
  164. errorHalt("begin failed");
  165. }
  166. Serial.println("\nFIFO SDIO mode.");
  167. } else if (c == '2') {
  168. if (!sd.begin(SdioConfig(DMA_SDIO))) {
  169. errorHalt("begin failed");
  170. }
  171. Serial.println("\nDMA SDIO mode - slow for small transfers.");
  172. } else if (c == '3') {
  173. if (!sd.begin(SdSpiConfig(SDCARD_SS_PIN, DEDICATED_SPI, SD_SCK_MHZ(50)))) {
  174. errorHalt("begin failed");
  175. }
  176. Serial.println("\nDedicated SPI mode.");
  177. } else if (c == '4') {
  178. if (!sd.begin(SdSpiConfig(SDCARD_SS_PIN, SHARED_SPI, SD_SCK_MHZ(50)))) {
  179. errorHalt("begin failed");
  180. }
  181. Serial.println("\nShared SPI mode - slow for small transfers.");
  182. } else {
  183. Serial.println("Invalid input");
  184. return;
  185. }
  186. ready = true;
  187. runTest();
  188. ready = false;
  189. }