Explorar el Código

SDCARD_READONLY (#17884)

Leandro A. F. Pereira hace 4 años
padre
commit
801f99edad
No account linked to committer's email address

+ 2
- 0
Marlin/Configuration_adv.h Ver fichero

@@ -1084,6 +1084,8 @@
1084 1084
   // Enable this option and set to HIGH if your SD cards are incorrectly detected.
1085 1085
   //#define SD_DETECT_STATE HIGH
1086 1086
 
1087
+  //#define SDCARD_READONLY                 // Read-only SD card (to save over 2K of flash)
1088
+
1087 1089
   #define SD_PROCEDURE_DEPTH 1              // Increase if you need more nested M32 calls
1088 1090
 
1089 1091
   #define SD_FINISHED_STEPPERRELEASE true   // Disable steppers when SD Print is finished

+ 14
- 0
Marlin/src/inc/SanityCheck.h Ver fichero

@@ -2063,6 +2063,20 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
2063 2063
 #endif
2064 2064
 
2065 2065
 /**
2066
+ * Make sure features that need to write to the SD card are
2067
+ * disabled unless write support is enabled.
2068
+ */
2069
+#if ENABLED(SDCARD_READONLY)
2070
+  #if ENABLED(POWER_LOSS_RECOVERY)
2071
+    #error "POWER_LOSS_RECOVERY is incompatible with SDCARD_READONLY."
2072
+  #elif ENABLED(BINARY_FILE_TRANSFER)
2073
+    #error "BINARY_FILE_TRANSFER is incompatible with SDCARD_READONLY."
2074
+  #elif ENABLED(SDCARD_EEPROM_EMULATION)
2075
+    #error "SDCARD_EEPROM_EMULATION is incompatible with SDCARD_READONLY."
2076
+  #endif
2077
+#endif
2078
+
2079
+/**
2066 2080
  * Make sure only one display is enabled
2067 2081
  */
2068 2082
 #if 1 < 0 \

+ 13
- 8
Marlin/src/sd/Sd2Card.cpp Ver fichero

@@ -179,8 +179,11 @@ void Sd2Card::chipSelect() {
179 179
  * \return true for success, false for failure.
180 180
  */
181 181
 bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
182
+  if (ENABLED(SDCARD_READONLY)) return false;
183
+
182 184
   csd_t csd;
183 185
   if (!readCSD(&csd)) goto FAIL;
186
+
184 187
   // check for single block erase
185 188
   if (!csd.v1.erase_blk_en) {
186 189
     // erase size mask
@@ -535,9 +538,10 @@ bool Sd2Card::waitNotBusy(const millis_t timeout_ms) {
535 538
  * \return true for success, false for failure.
536 539
  */
537 540
 bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
538
-  if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;   // Use address if not SDHC card
541
+  if (ENABLED(SDCARD_READONLY)) return false;
539 542
 
540 543
   bool success = false;
544
+  if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;   // Use address if not SDHC card
541 545
   if (!cardCommand(CMD24, blockNumber)) {
542 546
     if (writeData(DATA_START_BLOCK, src)) {
543 547
       if (waitNotBusy(SD_WRITE_TIMEOUT)) {              // Wait for flashing to complete
@@ -561,6 +565,8 @@ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
561 565
  * \return true for success, false for failure.
562 566
  */
563 567
 bool Sd2Card::writeData(const uint8_t* src) {
568
+  if (ENABLED(SDCARD_READONLY)) return false;
569
+
564 570
   bool success = true;
565 571
   chipSelect();
566 572
   // Wait for previous write to finish
@@ -574,14 +580,9 @@ bool Sd2Card::writeData(const uint8_t* src) {
574 580
 
575 581
 // Send one block of data for write block or write multiple blocks
576 582
 bool Sd2Card::writeData(const uint8_t token, const uint8_t* src) {
583
+  if (ENABLED(SDCARD_READONLY)) return false;
577 584
 
578
-  const uint16_t crc =
579
-    #if ENABLED(SD_CHECK_AND_RETRY)
580
-      CRC_CCITT(src, 512)
581
-    #else
582
-      0xFFFF
583
-    #endif
584
-  ;
585
+  const uint16_t crc = TERN(SD_CHECK_AND_RETRY, CRC_CCITT(src, 512), 0xFFFF);
585 586
   spiSendBlock(token, src);
586 587
   spiSend(crc >> 8);
587 588
   spiSend(crc & 0xFF);
@@ -607,6 +608,8 @@ bool Sd2Card::writeData(const uint8_t token, const uint8_t* src) {
607 608
  * \return true for success, false for failure.
608 609
  */
609 610
 bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) {
611
+  if (ENABLED(SDCARD_READONLY)) return false;
612
+
610 613
   bool success = false;
611 614
   if (!cardAcmd(ACMD23, eraseCount)) {                    // Send pre-erase count
612 615
     if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;   // Use address if not SDHC card
@@ -626,6 +629,8 @@ bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) {
626 629
  * \return true for success, false for failure.
627 630
  */
628 631
 bool Sd2Card::writeStop() {
632
+  if (ENABLED(SDCARD_READONLY)) return false;
633
+
629 634
   bool success = false;
630 635
   chipSelect();
631 636
   if (waitNotBusy(SD_WRITE_TIMEOUT)) {

+ 37
- 3
Marlin/src/sd/SdBaseFile.cpp Ver fichero

@@ -47,6 +47,8 @@ void (*SdBaseFile::dateTime_)(uint16_t* date, uint16_t* time) = 0;
47 47
 
48 48
 // add a cluster to a file
49 49
 bool SdBaseFile::addCluster() {
50
+  if (ENABLED(SDCARD_READONLY)) return false;
51
+
50 52
   if (!vol_->allocContiguous(1, &curCluster_)) return false;
51 53
 
52 54
   // if first cluster of file link to directory entry
@@ -60,6 +62,8 @@ bool SdBaseFile::addCluster() {
60 62
 // Add a cluster to a directory file and zero the cluster.
61 63
 // return with first block of cluster in the cache
62 64
 bool SdBaseFile::addDirCluster() {
65
+  if (ENABLED(SDCARD_READONLY)) return false;
66
+
63 67
   uint32_t block;
64 68
   // max folder size
65 69
   if (fileSize_ / sizeof(dir_t) >= 0xFFFF) return false;
@@ -153,6 +157,8 @@ bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
153 157
  *
154 158
  */
155 159
 bool SdBaseFile::createContiguous(SdBaseFile* dirFile, const char* path, uint32_t size) {
160
+  if (ENABLED(SDCARD_READONLY)) return false;
161
+
156 162
   uint32_t count;
157 163
   // don't allow zero length file
158 164
   if (size == 0) return false;
@@ -419,6 +425,8 @@ bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) {
419 425
  * directory, \a path is invalid or already exists in \a parent.
420 426
  */
421 427
 bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) {
428
+  if (ENABLED(SDCARD_READONLY)) return false;
429
+
422 430
   uint8_t dname[11];
423 431
   SdBaseFile dir1, dir2;
424 432
   SdBaseFile* sub = &dir1;
@@ -449,6 +457,8 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) {
449 457
 }
450 458
 
451 459
 bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
460
+  if (ENABLED(SDCARD_READONLY)) return false;
461
+
452 462
   uint32_t block;
453 463
   dir_t d;
454 464
   dir_t* p;
@@ -632,7 +642,7 @@ bool SdBaseFile::open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t ofla
632 642
   }
633 643
   else {
634 644
     // don't create unless O_CREAT and O_WRITE
635
-    if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) return false;
645
+    if ((oflag & (O_CREAT | O_WRITE)) != (O_CREAT | O_WRITE)) return false;
636 646
     if (emptyFound) {
637 647
       index = dirIndex_;
638 648
       p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
@@ -716,8 +726,14 @@ bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) {
716 726
 
717 727
 // open a cached directory entry. Assumes vol_ is initialized
718 728
 bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
729
+  dir_t* p;
730
+
731
+  #if ENABLED(SDCARD_READONLY)
732
+    if (oflag & (O_WRITE | O_CREAT | O_TRUNC)) goto FAIL;
733
+  #endif
734
+
719 735
   // location of entry in cache
720
-  dir_t* p = &vol_->cache()->dir[dirIndex];
736
+  p = &vol_->cache()->dir[dirIndex];
721 737
 
722 738
   // write or truncate is an error for a directory or read-only file
723 739
   if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) {
@@ -1135,6 +1151,8 @@ dir_t* SdBaseFile::readDirCache() {
1135 1151
  * or an I/O error occurred.
1136 1152
  */
1137 1153
 bool SdBaseFile::remove() {
1154
+  if (ENABLED(SDCARD_READONLY)) return false;
1155
+
1138 1156
   dir_t* d;
1139 1157
   // free any clusters - will fail if read-only or directory
1140 1158
   if (!truncate(0)) return false;
@@ -1172,6 +1190,8 @@ bool SdBaseFile::remove() {
1172 1190
  * or an I/O error occurred.
1173 1191
  */
1174 1192
 bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) {
1193
+  if (ENABLED(SDCARD_READONLY)) return false;
1194
+
1175 1195
   SdBaseFile file;
1176 1196
   return file.open(dirFile, path, O_WRITE) ? file.remove() : false;
1177 1197
 }
@@ -1187,6 +1207,8 @@ bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) {
1187 1207
  * file, newPath is invalid or already exists, or an I/O error occurs.
1188 1208
  */
1189 1209
 bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) {
1210
+  if (ENABLED(SDCARD_READONLY)) return false;
1211
+
1190 1212
   dir_t entry;
1191 1213
   uint32_t dirCluster = 0;
1192 1214
   SdBaseFile file;
@@ -1279,6 +1301,8 @@ restore:
1279 1301
  * directory, is not empty, or an I/O error occurred.
1280 1302
  */
1281 1303
 bool SdBaseFile::rmdir() {
1304
+  if (ENABLED(SDCARD_READONLY)) return false;
1305
+
1282 1306
   // must be open subdirectory
1283 1307
   if (!isSubDir()) return false;
1284 1308
 
@@ -1317,6 +1341,8 @@ bool SdBaseFile::rmdir() {
1317 1341
  * \return true for success, false for failure.
1318 1342
  */
1319 1343
 bool SdBaseFile::rmRfStar() {
1344
+  if (ENABLED(SDCARD_READONLY)) return false;
1345
+
1320 1346
   uint32_t index;
1321 1347
   SdBaseFile f;
1322 1348
   rewind();
@@ -1424,7 +1450,7 @@ void SdBaseFile::setpos(filepos_t* pos) {
1424 1450
  */
1425 1451
 bool SdBaseFile::sync() {
1426 1452
   // only allow open files and directories
1427
-  if (!isOpen()) goto FAIL;
1453
+  if (ENABLED(SDCARD_READONLY) || !isOpen()) goto FAIL;
1428 1454
 
1429 1455
   if (flags_ & F_FILE_DIR_DIRTY) {
1430 1456
     dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
@@ -1524,6 +1550,8 @@ bool SdBaseFile::timestamp(SdBaseFile* file) {
1524 1550
  */
1525 1551
 bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
1526 1552
                            uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
1553
+  if (ENABLED(SDCARD_READONLY)) return false;
1554
+
1527 1555
   uint16_t dirDate, dirTime;
1528 1556
   dir_t* d;
1529 1557
 
@@ -1575,6 +1603,8 @@ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
1575 1603
  * \a length is greater than the current file size or an I/O error occurs.
1576 1604
  */
1577 1605
 bool SdBaseFile::truncate(uint32_t length) {
1606
+  if (ENABLED(SDCARD_READONLY)) return false;
1607
+
1578 1608
   uint32_t newPos;
1579 1609
   // error if not a normal file or read-only
1580 1610
   if (!isFile() || !(flags_ & O_WRITE)) return false;
@@ -1636,6 +1666,10 @@ bool SdBaseFile::truncate(uint32_t length) {
1636 1666
  *
1637 1667
  */
1638 1668
 int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
1669
+  #if ENABLED(SDCARD_READONLY)
1670
+    writeError = true; return -1;
1671
+  #endif
1672
+
1639 1673
   // convert void* to uint8_t*  -  must be before goto statements
1640 1674
   const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
1641 1675
 

+ 16
- 10
Marlin/src/sd/SdVolume.cpp Ver fichero

@@ -46,6 +46,8 @@
46 46
 
47 47
 // find a contiguous group of clusters
48 48
 bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
49
+  if (ENABLED(SDCARD_READONLY)) return false;
50
+
49 51
   // start of group
50 52
   uint32_t bgnCluster;
51 53
   // end of group
@@ -117,18 +119,20 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
117 119
 }
118 120
 
119 121
 bool SdVolume::cacheFlush() {
120
-  if (cacheDirty_) {
121
-    if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data))
122
-      return false;
123
-
124
-    // mirror FAT tables
125
-    if (cacheMirrorBlock_) {
126
-      if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data))
122
+  #if DISABLED(SDCARD_READONLY)
123
+    if (cacheDirty_) {
124
+      if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data))
127 125
         return false;
128
-      cacheMirrorBlock_ = 0;
126
+
127
+      // mirror FAT tables
128
+      if (cacheMirrorBlock_) {
129
+        if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data))
130
+          return false;
131
+        cacheMirrorBlock_ = 0;
132
+      }
133
+      cacheDirty_ = 0;
129 134
     }
130
-    cacheDirty_ = 0;
131
-  }
135
+  #endif
132 136
   return true;
133 137
 }
134 138
 
@@ -190,6 +194,8 @@ bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) {
190 194
 
191 195
 // Store a FAT entry
192 196
 bool SdVolume::fatPut(uint32_t cluster, uint32_t value) {
197
+  if (ENABLED(SDCARD_READONLY)) return false;
198
+
193 199
   uint32_t lba;
194 200
   // error if reserved cluster
195 201
   if (cluster < 2) return false;

+ 25
- 17
Marlin/src/sd/cardreader.cpp Ver fichero

@@ -446,8 +446,8 @@ void CardReader::endFilePrint(TERN_(SD_RESORT, const bool re_sort/*=false*/)) {
446 446
 }
447 447
 
448 448
 void CardReader::openLogFile(char * const path) {
449
-  flag.logging = true;
450
-  openFileWrite(path);
449
+  flag.logging = DISABLED(SDCARD_READONLY);
450
+  TERN(SDCARD_READONLY,,openFileWrite(path));
451 451
 }
452 452
 
453 453
 //
@@ -573,15 +573,19 @@ void CardReader::openFileWrite(char * const path) {
573 573
   const char * const fname = diveToFile(false, curDir, path);
574 574
   if (!fname) return;
575 575
 
576
-  if (file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
577
-    flag.saving = true;
578
-    selectFileByName(fname);
579
-    TERN_(EMERGENCY_PARSER, emergency_parser.disable());
580
-    echo_write_to_file(fname);
581
-    ui.set_status(fname);
582
-  }
583
-  else
576
+  #if ENABLED(SDCARD_READONLY)
584 577
     openFailed(fname);
578
+  #else
579
+    if (file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
580
+      flag.saving = true;
581
+      selectFileByName(fname);
582
+      TERN_(EMERGENCY_PARSER, emergency_parser.disable());
583
+      echo_write_to_file(fname);
584
+      ui.set_status(fname);
585
+    }
586
+    else
587
+      openFailed(fname);
588
+  #endif
585 589
 }
586 590
 
587 591
 //
@@ -596,13 +600,17 @@ void CardReader::removeFile(const char * const name) {
596 600
   const char * const fname = diveToFile(false, curDir, name);
597 601
   if (!fname) return;
598 602
 
599
-  if (file.remove(curDir, fname)) {
600
-    SERIAL_ECHOLNPAIR("File deleted:", fname);
601
-    sdpos = 0;
602
-    TERN_(SDCARD_SORT_ALPHA, presort());
603
-  }
604
-  else
605
-    SERIAL_ECHOLNPAIR("Deletion failed, File: ", fname, ".");
603
+  #if ENABLED(SDCARD_READONLY)
604
+    SERIAL_ECHOLNPAIR("Deletion failed (read-only), File: ", fname, ".");
605
+  #else
606
+    if (file.remove(curDir, fname)) {
607
+      SERIAL_ECHOLNPAIR("File deleted:", fname);
608
+      sdpos = 0;
609
+      TERN_(SDCARD_SORT_ALPHA, presort());
610
+    }
611
+    else
612
+      SERIAL_ECHOLNPAIR("Deletion failed, File: ", fname, ".");
613
+  #endif
606 614
 }
607 615
 
608 616
 void CardReader::report_status() {

+ 1
- 2
buildroot/share/tests/LPC1768-tests Ver fichero

@@ -15,8 +15,7 @@ set -e
15 15
 
16 16
 restore_configs
17 17
 opt_set MOTHERBOARD BOARD_RAMPS_14_RE_ARM_EFB
18
-opt_enable VIKI2 SDSUPPORT SERIAL_PORT_2 NEOPIXEL_LED
19
-
18
+opt_enable VIKI2 SDSUPPORT SDCARD_READONLY SERIAL_PORT_2 NEOPIXEL_LED
20 19
 opt_set NEOPIXEL_PIN P1_16
21 20
 exec_test $1 $2 "ReARM EFB VIKI2, SDSUPPORT, 2 Serial ports (USB CDC + UART0), NeoPixel"
22 21
 

Loading…
Cancelar
Guardar