@@ -42,6 +42,7 @@ uint8_t SdFile::addCluster() {
4242 firstCluster_ = curCluster_;
4343 flags_ |= F_FILE_DIR_DIRTY;
4444 }
45+ flags_ |= F_FILE_CLUSTER_ADDED;
4546 return true ;
4647}
4748// ------------------------------------------------------------------------------
@@ -1121,12 +1122,14 @@ uint8_t SdFile::seekSet(uint32_t pos) {
11211122 The sync() call causes all modified data and directory fields
11221123 to be written to the storage device.
11231124
1125+ \param[in] blocking If the sync should block until fully complete.
1126+
11241127 \return The value one, true, is returned for success and
11251128 the value zero, false, is returned for failure.
11261129 Reasons for failure include a call to sync() before a file has been
11271130 opened or an I/O error.
11281131*/
1129- uint8_t SdFile::sync (void ) {
1132+ uint8_t SdFile::sync (uint8_t blocking ) {
11301133 // only allow open files and directories
11311134 if (!isOpen ()) {
11321135 return false ;
@@ -1155,7 +1158,12 @@ uint8_t SdFile::sync(void) {
11551158 // clear directory dirty
11561159 flags_ &= ~F_FILE_DIR_DIRTY;
11571160 }
1158- return SdVolume::cacheFlush ();
1161+
1162+ if (!blocking) {
1163+ flags_ &= ~F_FILE_NON_BLOCKING_WRITE;
1164+ }
1165+
1166+ return SdVolume::cacheFlush (blocking);
11591167}
11601168// ------------------------------------------------------------------------------
11611169/* *
@@ -1325,6 +1333,8 @@ size_t SdFile::write(const void* buf, uint16_t nbyte) {
13251333
13261334 // number of bytes left to write - must be before goto statements
13271335 uint16_t nToWrite = nbyte;
1336+ // if blocking writes should be used
1337+ uint8_t blocking = (flags_ & F_FILE_NON_BLOCKING_WRITE) == 0x00 ;
13281338
13291339 // error if not a normal file or is read-only
13301340 if (!isFile () || !(flags_ & O_WRITE)) {
@@ -1383,7 +1393,7 @@ size_t SdFile::write(const void* buf, uint16_t nbyte) {
13831393 if (SdVolume::cacheBlockNumber_ == block) {
13841394 SdVolume::cacheBlockNumber_ = 0XFFFFFFFF ;
13851395 }
1386- if (!vol_->writeBlock (block, src)) {
1396+ if (!vol_->writeBlock (block, src, blocking )) {
13871397 goto writeErrorReturn;
13881398 }
13891399 src += 512 ;
@@ -1473,3 +1483,45 @@ void SdFile::writeln_P(PGM_P str) {
14731483 println ();
14741484}
14751485#endif
1486+ // ------------------------------------------------------------------------------
1487+ /* *
1488+ Check how many bytes can be written without blocking.
1489+
1490+ \return The number of bytes that can be written without blocking.
1491+ */
1492+ int SdFile::availableForWrite () {
1493+ if (!isFile () || !(flags_ & O_WRITE)) {
1494+ return 0 ;
1495+ }
1496+
1497+ // seek to end of file if append flag
1498+ if ((flags_ & O_APPEND) && curPosition_ != fileSize_) {
1499+ if (!seekEnd ()) {
1500+ return 0 ;
1501+ }
1502+ }
1503+
1504+ if (vol_->isBusy ()) {
1505+ return 0 ;
1506+ }
1507+
1508+ if (flags_ & F_FILE_CLUSTER_ADDED) {
1509+ // new cluster added, trigger a non-blocking sync
1510+ sync (0 );
1511+ flags_ &= ~F_FILE_CLUSTER_ADDED;
1512+ return 0 ;
1513+ }
1514+
1515+ if (vol_->isCacheMirrorBlockDirty ()) {
1516+ // cache mirror block is dirty, trigger a non-blocking sync
1517+ vol_->cacheMirrorBlockFlush (0 );
1518+ return 0 ;
1519+ }
1520+
1521+ flags_ |= F_FILE_NON_BLOCKING_WRITE;
1522+
1523+ uint16_t blockOffset = curPosition_ & 0X1FF ;
1524+ uint16_t n = 512 - blockOffset;
1525+
1526+ return n;
1527+ }
0 commit comments