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.

RawWrite.ino 5.0KB

10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * This program illustrates raw write functions in SdFat that
  3. * can be used for high speed data logging.
  4. *
  5. * This program simulates logging from a source that produces
  6. * data at a constant rate of one block every MICROS_PER_BLOCK.
  7. *
  8. * If a high quality SanDisk card is used with this program
  9. * no overruns occur and the maximum block write time is
  10. * under 2000 micros.
  11. *
  12. * Note: Apps should create a very large file then truncates it
  13. * to the length that is used for a logging. It only takes
  14. * a few seconds to erase a 500 MB file since the card only
  15. * marks the blocks as erased; no data transfer is required.
  16. */
  17. #include <SPI.h>
  18. #include <SdFat.h>
  19. #include <SdFatUtil.h>
  20. // SD chip select pin
  21. const uint8_t chipSelect = SS;
  22. // number of blocks in the contiguous file
  23. const uint32_t BLOCK_COUNT = 10000UL;
  24. // time to produce a block of data
  25. const uint32_t MICROS_PER_BLOCK = 10000;
  26. // file system
  27. SdFat sd;
  28. // test file
  29. SdFile file;
  30. // file extent
  31. uint32_t bgnBlock, endBlock;
  32. // Serial output stream
  33. ArduinoOutStream cout(Serial);
  34. //------------------------------------------------------------------------------
  35. // store error strings in flash to save RAM
  36. #define error(s) sd.errorHalt(F(s))
  37. //------------------------------------------------------------------------------
  38. // log of first overruns
  39. #define OVER_DIM 20
  40. struct {
  41. uint32_t block;
  42. uint32_t micros;
  43. } over[OVER_DIM];
  44. //------------------------------------------------------------------------------
  45. void setup(void) {
  46. Serial.begin(9600);
  47. while (!Serial) {} // wait for Leonardo
  48. }
  49. //------------------------------------------------------------------------------
  50. void loop(void) {
  51. while (Serial.read() >= 0) {}
  52. // pstr stores strings in flash to save RAM
  53. cout << F("Type any character to start\n");
  54. while (Serial.read() <= 0) {}
  55. delay(400); // catch Due reset problem
  56. cout << F("Free RAM: ") << FreeRam() << endl;
  57. // initialize the SD card at SPI_FULL_SPEED for best performance.
  58. // try SPI_HALF_SPEED if bus errors occur.
  59. if (!sd.begin(chipSelect, SPI_FULL_SPEED)) {
  60. sd.initErrorHalt();
  61. }
  62. // delete possible existing file
  63. sd.remove("RawWrite.txt");
  64. // create a contiguous file
  65. if (!file.createContiguous(sd.vwd(), "RawWrite.txt", 512UL*BLOCK_COUNT)) {
  66. error("createContiguous failed");
  67. }
  68. // get the location of the file's blocks
  69. if (!file.contiguousRange(&bgnBlock, &endBlock)) {
  70. error("contiguousRange failed");
  71. }
  72. //*********************NOTE**************************************
  73. // NO SdFile calls are allowed while cache is used for raw writes
  74. //***************************************************************
  75. // clear the cache and use it as a 512 byte buffer
  76. uint8_t* pCache = (uint8_t*)sd.vol()->cacheClear();
  77. // fill cache with eight lines of 64 bytes each
  78. memset(pCache, ' ', 512);
  79. for (uint16_t i = 0; i < 512; i += 64) {
  80. // put line number at end of line then CR/LF
  81. pCache[i + 61] = '0' + (i/64);
  82. pCache[i + 62] = '\r';
  83. pCache[i + 63] = '\n';
  84. }
  85. cout << F("Start raw write of ") << file.fileSize() << F(" bytes at\n");
  86. cout << 512000000UL/MICROS_PER_BLOCK << F(" bytes per second\n");
  87. cout << F("Please wait ") << (BLOCK_COUNT*MICROS_PER_BLOCK)/1000000UL;
  88. cout << F(" seconds\n");
  89. // tell card to setup for multiple block write with pre-erase
  90. if (!sd.card()->writeStart(bgnBlock, BLOCK_COUNT)) {
  91. error("writeStart failed");
  92. }
  93. // init stats
  94. uint16_t overruns = 0;
  95. uint32_t maxWriteTime = 0;
  96. uint32_t t = micros();
  97. uint32_t tNext = t;
  98. // write data
  99. for (uint32_t b = 0; b < BLOCK_COUNT; b++) {
  100. // write must be done by this time
  101. tNext += MICROS_PER_BLOCK;
  102. // put block number at start of first line in block
  103. uint32_t n = b;
  104. for (int8_t d = 5; d >= 0; d--) {
  105. pCache[d] = n || d == 5 ? n % 10 + '0' : ' ';
  106. n /= 10;
  107. }
  108. // write a 512 byte block
  109. uint32_t tw = micros();
  110. if (!sd.card()->writeData(pCache)) {
  111. error("writeData failed");
  112. }
  113. tw = micros() - tw;
  114. // check for max write time
  115. if (tw > maxWriteTime) {
  116. maxWriteTime = tw;
  117. }
  118. // check for overrun
  119. if (micros() > tNext) {
  120. if (overruns < OVER_DIM) {
  121. over[overruns].block = b;
  122. over[overruns].micros = tw;
  123. }
  124. overruns++;
  125. // advance time to reflect overrun
  126. tNext = micros();
  127. } else {
  128. // wait for time to write next block
  129. while(micros() < tNext);
  130. }
  131. }
  132. // total write time
  133. t = micros() - t;
  134. // end multiple block write mode
  135. if (!sd.card()->writeStop()) {
  136. error("writeStop failed");
  137. }
  138. cout << F("Done\n");
  139. cout << F("Elapsed time: ") << setprecision(3)<< 1.e-6*t;
  140. cout << F(" seconds\n");
  141. cout << F("Max write time: ") << maxWriteTime << F(" micros\n");
  142. cout << F("Overruns: ") << overruns << endl;
  143. if (overruns) {
  144. uint8_t n = overruns > OVER_DIM ? OVER_DIM : overruns;
  145. cout << F("fileBlock,micros") << endl;
  146. for (uint8_t i = 0; i < n; i++) {
  147. cout << over[i].block << ',' << over[i].micros << endl;
  148. }
  149. }
  150. // close file for next pass of loop
  151. file.close();
  152. Serial.println();
  153. }