Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

218 lines
5.8KB

  1. /*
  2. * This program is a simple binary write/read benchmark.
  3. */
  4. #include <SPI.h>
  5. #include "SdFat.h"
  6. #include "FreeStack.h"
  7. // Set USE_SDIO to zero for SPI card access.
  8. #define USE_SDIO 0
  9. // SD chip select pin
  10. const uint8_t chipSelect = SS;
  11. // Size of read/write.
  12. const size_t BUF_SIZE = 512;
  13. // File size in MB where MB = 1,000,000 bytes.
  14. const uint32_t FILE_SIZE_MB = 5;
  15. // Write pass count.
  16. const uint8_t WRITE_COUNT = 2;
  17. // Read pass count.
  18. const uint8_t READ_COUNT = 2;
  19. //==============================================================================
  20. // End of configuration constants.
  21. //------------------------------------------------------------------------------
  22. // File size in bytes.
  23. const uint32_t FILE_SIZE = 1000000UL*FILE_SIZE_MB;
  24. uint8_t buf[BUF_SIZE];
  25. // file system
  26. #if USE_SDIO
  27. SdFatSdio sd;
  28. #else // USE_SDIO
  29. SdFat sd;
  30. #endif // USE_SDIO
  31. // Set ENABLE_EXTENDED_TRANSFER_CLASS to use extended SD I/O.
  32. // Requires dedicated use of the SPI bus.
  33. // SdFatEX sd;
  34. // Set ENABLE_SOFTWARE_SPI_CLASS to use software SPI.
  35. // Args are misoPin, mosiPin, sckPin.
  36. // SdFatSoftSpi<6, 7, 5> sd;
  37. // test file
  38. SdFile file;
  39. // Serial output stream
  40. ArduinoOutStream cout(Serial);
  41. //------------------------------------------------------------------------------
  42. // Store error strings in flash to save RAM.
  43. #define error(s) sd.errorHalt(F(s))
  44. //------------------------------------------------------------------------------
  45. void cidDmp() {
  46. cid_t cid;
  47. if (!sd.card()->readCID(&cid)) {
  48. error("readCID failed");
  49. }
  50. cout << F("\nManufacturer ID: ");
  51. cout << hex << int(cid.mid) << dec << endl;
  52. cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl;
  53. cout << F("Product: ");
  54. for (uint8_t i = 0; i < 5; i++) {
  55. cout << cid.pnm[i];
  56. }
  57. cout << F("\nVersion: ");
  58. cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl;
  59. cout << F("Serial number: ") << hex << cid.psn << dec << endl;
  60. cout << F("Manufacturing date: ");
  61. cout << int(cid.mdt_month) << '/';
  62. cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl;
  63. cout << endl;
  64. }
  65. //------------------------------------------------------------------------------
  66. void setup() {
  67. Serial.begin(9600);
  68. // Wait for USB Serial
  69. while (!Serial) {
  70. SysCall::yield();
  71. }
  72. delay(1000);
  73. cout << F("\nUse a freshly formatted SD for best performance.\n");
  74. // use uppercase in hex and use 0X base prefix
  75. cout << uppercase << showbase << endl;
  76. }
  77. //------------------------------------------------------------------------------
  78. void loop() {
  79. float s;
  80. uint32_t t;
  81. uint32_t maxLatency;
  82. uint32_t minLatency;
  83. uint32_t totalLatency;
  84. // Discard any input.
  85. do {
  86. delay(10);
  87. } while (Serial.available() && Serial.read() >= 0);
  88. // F( stores strings in flash to save RAM
  89. cout << F("Type any character to start\n");
  90. while (!Serial.available()) {
  91. SysCall::yield();
  92. }
  93. cout << F("FreeStack: ") << FreeStack() << endl;
  94. #if USE_SDIO
  95. if (!sd.begin()) {
  96. sd.initErrorHalt();
  97. }
  98. #else // USE_SDIO
  99. // Initialize at the highest speed supported by the board that is
  100. // not over 50 MHz. Try a lower speed if SPI errors occur.
  101. if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
  102. sd.initErrorHalt();
  103. }
  104. #endif // USE_SDIO
  105. cout << F("Type is FAT") << int(sd.vol()->fatType()) << endl;
  106. cout << F("Card size: ") << sd.card()->cardSize()*512E-9;
  107. cout << F(" GB (GB = 1E9 bytes)") << endl;
  108. cidDmp();
  109. // open or create file - truncate existing file.
  110. if (!file.open("bench.dat", O_CREAT | O_TRUNC | O_RDWR)) {
  111. error("open failed");
  112. }
  113. // fill buf with known data
  114. for (uint16_t i = 0; i < (BUF_SIZE-2); i++) {
  115. buf[i] = 'A' + (i % 26);
  116. }
  117. buf[BUF_SIZE-2] = '\r';
  118. buf[BUF_SIZE-1] = '\n';
  119. cout << F("File size ") << FILE_SIZE_MB << F(" MB\n");
  120. cout << F("Buffer size ") << BUF_SIZE << F(" bytes\n");
  121. cout << F("Starting write test, please wait.") << endl << endl;
  122. // do write test
  123. uint32_t n = FILE_SIZE/sizeof(buf);
  124. cout <<F("write speed and latency") << endl;
  125. cout << F("speed,max,min,avg") << endl;
  126. cout << F("KB/Sec,usec,usec,usec") << endl;
  127. for (uint8_t nTest = 0; nTest < WRITE_COUNT; nTest++) {
  128. file.truncate(0);
  129. maxLatency = 0;
  130. minLatency = 9999999;
  131. totalLatency = 0;
  132. t = millis();
  133. for (uint32_t i = 0; i < n; i++) {
  134. uint32_t m = micros();
  135. if (file.write(buf, sizeof(buf)) != sizeof(buf)) {
  136. sd.errorPrint("write failed");
  137. file.close();
  138. return;
  139. }
  140. m = micros() - m;
  141. if (maxLatency < m) {
  142. maxLatency = m;
  143. }
  144. if (minLatency > m) {
  145. minLatency = m;
  146. }
  147. totalLatency += m;
  148. }
  149. file.sync();
  150. t = millis() - t;
  151. s = file.fileSize();
  152. cout << s/t <<',' << maxLatency << ',' << minLatency;
  153. cout << ',' << totalLatency/n << endl;
  154. }
  155. cout << endl << F("Starting read test, please wait.") << endl;
  156. cout << endl <<F("read speed and latency") << endl;
  157. cout << F("speed,max,min,avg") << endl;
  158. cout << F("KB/Sec,usec,usec,usec") << endl;
  159. // do read test
  160. for (uint8_t nTest = 0; nTest < READ_COUNT; nTest++) {
  161. file.rewind();
  162. maxLatency = 0;
  163. minLatency = 9999999;
  164. totalLatency = 0;
  165. t = millis();
  166. for (uint32_t i = 0; i < n; i++) {
  167. buf[BUF_SIZE-1] = 0;
  168. uint32_t m = micros();
  169. int32_t nr = file.read(buf, sizeof(buf));
  170. if (nr != sizeof(buf)) {
  171. sd.errorPrint("read failed");
  172. file.close();
  173. return;
  174. }
  175. m = micros() - m;
  176. if (maxLatency < m) {
  177. maxLatency = m;
  178. }
  179. if (minLatency > m) {
  180. minLatency = m;
  181. }
  182. totalLatency += m;
  183. if (buf[BUF_SIZE-1] != '\n') {
  184. error("data check");
  185. }
  186. }
  187. s = file.fileSize();
  188. t = millis() - t;
  189. cout << s/t <<',' << maxLatency << ',' << minLatency;
  190. cout << ',' << totalLatency/n << endl;
  191. }
  192. cout << endl << F("Done") << endl;
  193. file.close();
  194. }