ff_fat.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694
  1. /*
  2. * FreeRTOS+FAT V2.3.3
  3. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  6. * this software and associated documentation files (the "Software"), to deal in
  7. * the Software without restriction, including without limitation the rights to
  8. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  9. * the Software, and to permit persons to whom the Software is furnished to do so,
  10. * subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in all
  13. * copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  17. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  18. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  19. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * https://www.FreeRTOS.org
  23. * https://github.com/FreeRTOS
  24. *
  25. */
  26. /**
  27. * @file ff_fat.c
  28. * @ingroup FAT
  29. *
  30. * @defgroup FAT Fat File-System
  31. * @brief Handles FAT access and traversal.
  32. *
  33. * Provides file-system interfaces for the FAT file-system.
  34. **/
  35. #include "ff_headers.h"
  36. #include <string.h>
  37. #if ffconfigFAT_USES_STAT
  38. /* This module make use of a buffer caching called 'FF_FATBuffers_t'.
  39. * The struct below may gather statistics about its usage: hits/misses.
  40. */
  41. struct SFatStat fatStat;
  42. #endif /* ffconfigFAT_USES_STAT */
  43. /* prvGetFromFATBuffers() will see if the FF_Buffer_t pointed to by ppxBuffer contains the
  44. * buffer that is needed, i.e. opened for the same sector and with the correct R/W mode.
  45. * If ppxBuffer is NULL or if it can not be used, a new buffer will be created.
  46. * The buffer pointed to by ppxBuffer will either be released or its pointer will be returned.
  47. */
  48. FF_Buffer_t * prvGetFromFATBuffers( FF_IOManager_t * pxIOManager,
  49. FF_FATBuffers_t * pxFATBuffers,
  50. BaseType_t xBufferIndex,
  51. uint32_t ulFATSector,
  52. FF_Error_t * pxError,
  53. uint8_t ucMode );
  54. #if ( ffconfigFAT12_SUPPORT != 0 )
  55. /* A very special case for FAT12: an entry is stored in two sectors.
  56. * Read the two sectors and merge the two values found.
  57. */
  58. static uint32_t prvGetFAT12Entry( FF_IOManager_t * pxIOManager,
  59. FF_Error_t * pxError,
  60. FF_FATBuffers_t * pxFATBuffers,
  61. uint32_t ulFATSector );
  62. #endif
  63. #if ( ffconfigFAT12_SUPPORT != 0 )
  64. /* Same as above: put a FAT12 entry that is spread-out over two sectors.
  65. * Read the current value first to preserve and merge the earlier 4 bits
  66. * of an adjacent FAT12 entry.
  67. */
  68. static FF_Error_t prvPutFAT12Entry( FF_IOManager_t * pxIOManager,
  69. uint32_t ulCluster,
  70. uint32_t ulValue,
  71. FF_FATBuffers_t * pxFATBuffers,
  72. uint32_t ulFATSector );
  73. #endif
  74. #if ( ffconfigFAT12_SUPPORT != 0 )
  75. /* A generic less-optimised way of finding the first free cluster.
  76. * Used for FAT12 only.
  77. */
  78. static uint32_t prvFindFreeClusterSimple( FF_IOManager_t * pxIOManager,
  79. FF_Error_t * pxError );
  80. #endif /* ffconfigFAT12_SUPPORT */
  81. #if ( ffconfigFAT12_SUPPORT != 0 )
  82. /* A generic less-optimised way of counting free clusters.
  83. * Used for FAT12 only.
  84. */
  85. static uint32_t prvCountFreeClustersSimple( FF_IOManager_t * pxIOManager,
  86. FF_Error_t * pxError );
  87. #endif /* ffconfigFAT12_SUPPORT */
  88. /* Have a cluster number and translate it to an LBA (Logical Block Address).
  89. * 'ulSectorsPerCluster' should be seen as 'blocks per cluster', where the length of one
  90. * block is defined in the PBR (Partition Boot Record) at FF_FAT_BYTES_PER_SECTOR (offset 0x0B).
  91. */
  92. uint32_t FF_Cluster2LBA( FF_IOManager_t * pxIOManager,
  93. uint32_t ulCluster )
  94. {
  95. uint32_t ulLBA = 0;
  96. FF_Partition_t * pxPartition;
  97. if( pxIOManager != NULL )
  98. {
  99. pxPartition = &( pxIOManager->xPartition );
  100. if( ulCluster >= 2 )
  101. {
  102. ulLBA = ( ( ulCluster - 2 ) * pxPartition->ulSectorsPerCluster ) + pxPartition->ulFirstDataSector;
  103. }
  104. else
  105. {
  106. ulLBA = pxPartition->ulClusterBeginLBA;
  107. }
  108. }
  109. return ulLBA;
  110. }
  111. /*-----------------------------------------------------------*/
  112. /*
  113. * Major and Minor sectors/blocks:
  114. *
  115. * A cluster is defined as N "sectors". Those sectors in fact are "major blocks"
  116. * whose size is defined in a field called 'FF_FAT_BYTES_PER_SECTOR' in the PBR.
  117. *
  118. * I/O to the disk takes place in "minor block" of usually 512 byte and the addressing
  119. * is also based on "minor block" sector numbers.
  120. *
  121. * In most cases, Major == Minor == 512 bytes.
  122. *
  123. * Here below some translations are done for 'entries', which can be 1-byte entries
  124. * as well as the 32-byte directory entries.
  125. *
  126. */
  127. /* Translate an 'entry number' (ulEntry) to a relative cluster number,
  128. * where e.g. 'ulEntry' may be a sequence number of a directory entry for
  129. * which ulEntrySize = 32 bytes.
  130. */
  131. uint32_t FF_getClusterChainNumber( FF_IOManager_t * pxIOManager,
  132. uint32_t ulEntry,
  133. uint32_t ulEntrySize )
  134. {
  135. uint32_t ulBytesPerCluster = pxIOManager->xPartition.usBlkSize * pxIOManager->xPartition.ulSectorsPerCluster;
  136. uint32_t ulEntriesPerCluster = ( ulBytesPerCluster / ulEntrySize );
  137. /* E.g. ulBytesPerCluster = 16384, ulEntrySize = 32: 16384 / 32 = 512 entries per cluster. */
  138. return ulEntry / ulEntriesPerCluster;
  139. }
  140. /*-----------------------------------------------------------*/
  141. /* If the above function returns a cluster number, this function
  142. * returns a BYTE position within that cluster. */
  143. uint32_t FF_getClusterPosition( FF_IOManager_t * pxIOManager,
  144. uint32_t ulEntry,
  145. uint32_t ulEntrySize )
  146. {
  147. uint32_t ulBytesPerCluster = pxIOManager->xPartition.usBlkSize * pxIOManager->xPartition.ulSectorsPerCluster;
  148. uint32_t ulEntriesPerCluster = ( ulBytesPerCluster / ulEntrySize );
  149. /* Return the block offset within the current cluster: */
  150. return ( ulEntry % ulEntriesPerCluster ) * ulEntrySize;
  151. }
  152. /*-----------------------------------------------------------*/
  153. /* Return the block offset (= number of major blocks) within the current cluster: */
  154. uint32_t FF_getMajorBlockNumber( FF_IOManager_t * pxIOManager,
  155. uint32_t ulEntry,
  156. uint32_t ulEntrySize )
  157. {
  158. uint32_t ulBytesPerCluster = pxIOManager->xPartition.usBlkSize * pxIOManager->xPartition.ulSectorsPerCluster;
  159. uint32_t ulEntriesPerCluster = ( ulBytesPerCluster / ulEntrySize );
  160. uint32_t ulRelClusterEntry;
  161. /* Calculate the entry number within a cluster: */
  162. ulRelClusterEntry = ulEntry % ulEntriesPerCluster;
  163. /* Return the block offset within the current cluster: */
  164. return ulRelClusterEntry / ( pxIOManager->xPartition.usBlkSize / ulEntrySize );
  165. }
  166. /*-----------------------------------------------------------*/
  167. /* Return the minor block number within the current major block */
  168. uint32_t FF_getMinorBlockNumber( FF_IOManager_t * pxIOManager,
  169. uint32_t ulEntry,
  170. uint32_t ulEntrySize )
  171. {
  172. uint32_t ulBytesPerCluster = pxIOManager->xPartition.usBlkSize * pxIOManager->xPartition.ulSectorsPerCluster;
  173. uint32_t ulEntriesPerCluster = ( ulBytesPerCluster / ulEntrySize );
  174. uint32_t ulRelClusterEntry;
  175. uint32_t ulRelMajorBlockEntry;
  176. /* Calculate the entry number within a cluster: */
  177. ulRelClusterEntry = ulEntry % ulEntriesPerCluster;
  178. ulRelMajorBlockEntry = ulRelClusterEntry % ( pxIOManager->xPartition.usBlkSize / ulEntrySize );
  179. return ulRelMajorBlockEntry / ( pxIOManager->usSectorSize / ulEntrySize );
  180. }
  181. /*-----------------------------------------------------------*/
  182. /* Get the entry number within the minor block */
  183. uint32_t FF_getMinorBlockEntry( FF_IOManager_t * pxIOManager,
  184. uint32_t ulEntry,
  185. uint32_t ulEntrySize )
  186. {
  187. uint32_t ulBytesPerCluster = pxIOManager->xPartition.usBlkSize * pxIOManager->xPartition.ulSectorsPerCluster;
  188. uint32_t ulEntriesPerCluster = ( ulBytesPerCluster / ulEntrySize );
  189. uint32_t ulRelClusterEntry;
  190. uint32_t ulRelMajorBlockEntry;
  191. /* Calculate the entry number within a cluster: */
  192. ulRelClusterEntry = ulEntry % ulEntriesPerCluster;
  193. ulRelMajorBlockEntry = ulRelClusterEntry % ( pxIOManager->xPartition.usBlkSize / ulEntrySize );
  194. return ulRelMajorBlockEntry % ( pxIOManager->usSectorSize / ulEntrySize );
  195. }
  196. /*-----------------------------------------------------------*/
  197. FF_Error_t FF_ReleaseFATBuffers( FF_IOManager_t * pxIOManager,
  198. FF_FATBuffers_t * pxFATBuffers )
  199. {
  200. BaseType_t xIndex;
  201. FF_Error_t xError = FF_ERR_NONE;
  202. FF_Buffer_t * pxBuffer;
  203. #if ffconfigBUF_STORE_COUNT != 2
  204. #warning Only maintaining one FAT table
  205. #endif
  206. /* 'ffconfigBUF_STORE_COUNT' equals to the number of FAT tables. */
  207. for( xIndex = 0; xIndex < ffconfigBUF_STORE_COUNT; xIndex++ )
  208. {
  209. pxBuffer = pxFATBuffers->pxBuffers[ xIndex ];
  210. if( pxBuffer != NULL )
  211. {
  212. FF_Error_t xTempError = FF_ERR_NONE;
  213. pxFATBuffers->pxBuffers[ xIndex ] = NULL;
  214. xTempError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  215. if( FF_isERR( xError ) == pdFALSE )
  216. {
  217. /* as everywhere, this function will return
  218. * the first error that occurred, if any. */
  219. xError = xTempError;
  220. }
  221. }
  222. }
  223. #if ffconfigFAT_USES_STAT
  224. {
  225. fatStat.clearCount++;
  226. }
  227. #endif /* ffconfigFAT_USES_STAT */
  228. return xError;
  229. }
  230. /*-----------------------------------------------------------*/
  231. FF_Buffer_t * prvGetFromFATBuffers( FF_IOManager_t * pxIOManager,
  232. FF_FATBuffers_t * pxFATBuffers,
  233. BaseType_t xBufferIndex,
  234. uint32_t ulFATSector,
  235. FF_Error_t * pxError,
  236. uint8_t ucMode )
  237. {
  238. FF_Error_t xError = FF_ERR_NONE;
  239. FF_Buffer_t * pxBuffer = NULL;
  240. if( pxFATBuffers != NULL )
  241. {
  242. /* See if the same buffer can be reused. */
  243. pxBuffer = pxFATBuffers->pxBuffers[ xBufferIndex ];
  244. if( pxBuffer != NULL )
  245. {
  246. /* Now the buffer is either owned by pxBuffer,
  247. * or it has been released, so put it to NULL. */
  248. pxFATBuffers->pxBuffers[ xBufferIndex ] = NULL;
  249. if(
  250. ( pxBuffer->ulSector == ulFATSector ) &&
  251. ( ( ( ucMode & FF_MODE_WRITE ) == 0 ) ||
  252. ( ( pxBuffer->ucMode & FF_MODE_WRITE ) != 0 ) )
  253. )
  254. {
  255. /* Same sector, AND
  256. * write-permission is not required OR the buffer has write permission:
  257. * it can be reused. */
  258. #if ffconfigFAT_USES_STAT
  259. {
  260. fatStat.reuseCount[ ( ucMode & FF_MODE_WRITE ) ? 1 : 0 ]++;
  261. }
  262. #endif /* ffconfigFAT_USES_STAT */
  263. }
  264. else
  265. {
  266. xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  267. pxBuffer = NULL;
  268. #if ffconfigFAT_USES_STAT
  269. {
  270. fatStat.missCount[ ( ucMode & FF_MODE_WRITE ) ? 1 : 0 ]++;
  271. }
  272. #endif /* ffconfigFAT_USES_STAT */
  273. }
  274. }
  275. else
  276. {
  277. #if ffconfigFAT_USES_STAT
  278. {
  279. fatStat.getCount[ ( ucMode & FF_MODE_WRITE ) ? 1 : 0 ]++;
  280. }
  281. #endif /* ffconfigFAT_USES_STAT */
  282. }
  283. }
  284. if( ( pxBuffer == NULL ) && ( FF_isERR( xError ) == pdFALSE ) )
  285. {
  286. pxBuffer = FF_GetBuffer( pxIOManager, ulFATSector, ucMode );
  287. if( pxBuffer == NULL )
  288. {
  289. /* Setting an error code without the Module/Function,
  290. * will be filled-in by the caller. */
  291. xError = ( FF_Error_t ) ( FF_ERR_DEVICE_DRIVER_FAILED | FF_ERRFLAG );
  292. }
  293. }
  294. *pxError = xError;
  295. return pxBuffer;
  296. }
  297. #if ( ffconfigFAT12_SUPPORT != 0 )
  298. /* A very special case for FAT12: an entry is stored in two sectors.
  299. * Read the two sectors and merge the two values found. */
  300. static uint32_t prvGetFAT12Entry( FF_IOManager_t * pxIOManager,
  301. FF_Error_t * pxError,
  302. FF_FATBuffers_t * pxFATBuffers,
  303. uint32_t ulFATSector )
  304. {
  305. FF_Error_t xError = FF_ERR_NONE;
  306. FF_Buffer_t * pxBuffer = NULL;
  307. /* preferred buffer access mode, user might want to update this entry
  308. * and set it to FF_MODE_WRITE. */
  309. uint8_t ucMode = pxFATBuffers ? pxFATBuffers->ucMode : FF_MODE_READ;
  310. /* Collect the two bytes in an array. */
  311. uint8_t ucBytes[ 2 ];
  312. /* The function return value. */
  313. uint32_t ulFATEntry = 0UL;
  314. pxBuffer = prvGetFromFATBuffers( pxIOManager, pxFATBuffers, 0, ulFATSector, &xError, ucMode );
  315. if( FF_isERR( xError ) )
  316. {
  317. xError = FF_GETERROR( xError ) | FF_GETFATENTRY;
  318. }
  319. else
  320. {
  321. /* Fetch the very last byte of this segment. */
  322. ucBytes[ 0 ] = FF_getChar( pxBuffer->pucBuffer, ( uint16_t ) ( pxIOManager->usSectorSize - 1 ) );
  323. xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  324. /* release the other buffer as well. */
  325. if( ( FF_isERR( xError ) == pdFALSE ) && ( pxFATBuffers != NULL ) )
  326. {
  327. xError = FF_ReleaseFATBuffers( pxIOManager, pxFATBuffers );
  328. }
  329. if( FF_isERR( xError ) == pdFALSE )
  330. {
  331. /* Second Buffer get the first Byte in buffer (second byte of out address)! */
  332. pxBuffer = FF_GetBuffer( pxIOManager, ulFATSector + 1, ucMode );
  333. if( pxBuffer == NULL )
  334. {
  335. xError = ( FF_Error_t ) ( FF_ERR_DEVICE_DRIVER_FAILED | FF_GETFATENTRY );
  336. }
  337. else
  338. {
  339. /* Read the first byte from the subsequent sector. */
  340. ucBytes[ 1 ] = FF_getChar( pxBuffer->pucBuffer, 0 );
  341. /* And release that buffer. */
  342. xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  343. if( FF_isERR( xError ) == pdFALSE )
  344. {
  345. /* Join the two bytes: */
  346. ulFATEntry = ( uint32_t ) FF_getShort( ( uint8_t * ) ucBytes, 0 );
  347. }
  348. }
  349. }
  350. }
  351. *pxError = xError;
  352. return ( int32_t ) ulFATEntry;
  353. }
  354. #endif /* ffconfigFAT12_SUPPORT */
  355. /*-----------------------------------------------------------*/
  356. /* Get a FAT entry, which is nothing more than a number referring to a sector. */
  357. uint32_t FF_getFATEntry( FF_IOManager_t * pxIOManager,
  358. uint32_t ulCluster,
  359. FF_Error_t * pxError,
  360. FF_FATBuffers_t * pxFATBuffers )
  361. {
  362. FF_Buffer_t * pxBuffer = NULL;
  363. uint32_t ulFATOffset;
  364. uint32_t ulFATSector = 0;
  365. uint32_t ulFATSectorEntry;
  366. /* The function result. */
  367. uint32_t ulFATEntry = 0;
  368. uint32_t ulLBAAdjust;
  369. uint32_t ulRelClusterEntry = 0;
  370. FF_Error_t xError = FF_ERR_NONE;
  371. /* preferred mode, user might want to update this entry. */
  372. uint8_t ucMode = pxFATBuffers ? pxFATBuffers->ucMode : FF_MODE_READ;
  373. FF_Assert_Lock( pxIOManager, FF_FAT_LOCK );
  374. if( ulCluster >= pxIOManager->xPartition.ulNumClusters )
  375. {
  376. /* _HT_ find a more specific error code.
  377. * Probably not really important as this is a function internal to the library. */
  378. xError = ( FF_Error_t ) ( FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE | FF_GETFATENTRY );
  379. }
  380. else
  381. {
  382. if( pxIOManager->xPartition.ucType == FF_T_FAT32 )
  383. {
  384. ulFATOffset = ulCluster * 4;
  385. }
  386. else if( pxIOManager->xPartition.ucType == FF_T_FAT16 )
  387. {
  388. ulFATOffset = ulCluster * 2;
  389. }
  390. else /* pxIOManager->xPartition.ucType == FF_T_FAT12 */
  391. {
  392. ulFATOffset = ulCluster + ( ulCluster / 2 );
  393. }
  394. ulFATSector = pxIOManager->xPartition.ulFATBeginLBA + ( ulFATOffset / pxIOManager->xPartition.usBlkSize );
  395. ulFATSectorEntry = ulFATOffset % pxIOManager->xPartition.usBlkSize;
  396. ulLBAAdjust = ulFATSectorEntry / ( ( uint32_t ) pxIOManager->usSectorSize );
  397. ulRelClusterEntry = ulFATSectorEntry % pxIOManager->usSectorSize;
  398. ulFATSector = FF_getRealLBA( pxIOManager, ulFATSector );
  399. ulFATSector += ulLBAAdjust;
  400. }
  401. #if ( ffconfigFAT12_SUPPORT != 0 )
  402. if( ( pxIOManager->xPartition.ucType == FF_T_FAT12 ) &&
  403. ( FF_isERR( xError ) == pdFALSE ) &&
  404. ( ulRelClusterEntry == ( uint32_t ) ( ( pxIOManager->usSectorSize - 1 ) ) ) )
  405. {
  406. /* Fat Entry SPANS a Sector!
  407. * It has 4 bits on one sector and 8 bits on the other sector.
  408. * Handle this in a separate function prvGetFAT12Entry(). */
  409. ulFATEntry = prvGetFAT12Entry( pxIOManager, &xError, pxFATBuffers, ulFATSector );
  410. if( ( ulCluster & 0x0001 ) != 0 )
  411. {
  412. /* For odd clusters, shift the address 4 bits to the right: */
  413. ulFATEntry = ( ulFATEntry & 0xfff0 ) >> 4;
  414. }
  415. else
  416. {
  417. /* For even clusters, take the lower 12 bits: */
  418. ulFATEntry = ( ulFATEntry & 0x0fff );
  419. }
  420. /* Return ulFATEntry, unless xError contains an error. */
  421. }
  422. else
  423. #endif /* ffconfigFAT12_SUPPORT */
  424. if( FF_isERR( xError ) == pdFALSE )
  425. {
  426. /* Handle FAT16, FAT32, and FAT12 (in case the entry lies on a single sector). */
  427. pxBuffer = prvGetFromFATBuffers( pxIOManager, pxFATBuffers, 0, ulFATSector, &xError, ucMode );
  428. if( FF_isERR( xError ) )
  429. {
  430. xError = FF_GETERROR( xError ) | FF_GETFATENTRY;
  431. }
  432. else
  433. {
  434. switch( pxIOManager->xPartition.ucType )
  435. {
  436. case FF_T_FAT32:
  437. ulFATEntry = FF_getLong( pxBuffer->pucBuffer, ulRelClusterEntry );
  438. /* Clear the top 4 bits. */
  439. ulFATEntry &= 0x0fffffff;
  440. break;
  441. case FF_T_FAT16:
  442. ulFATEntry = ( uint32_t ) FF_getShort( pxBuffer->pucBuffer, ulRelClusterEntry );
  443. break;
  444. #if ( ffconfigFAT12_SUPPORT != 0 )
  445. case FF_T_FAT12:
  446. ulFATEntry = ( uint32_t ) FF_getShort( pxBuffer->pucBuffer, ulRelClusterEntry );
  447. /* Entries are either stored as 4 + 8 bits or as 8 + 4 bits,
  448. * depending on the cluster being odd or even. */
  449. if( ( ulCluster & 0x0001 ) != 0 )
  450. {
  451. /* For odd clusters, shift the address 4 bits to the right: */
  452. ulFATEntry = ( ulFATEntry & 0xfff0 ) >> 4;
  453. }
  454. else
  455. {
  456. /* For even clusters, take the lower 12 bits: */
  457. ulFATEntry = ( ulFATEntry & 0x0fff );
  458. }
  459. break;
  460. #endif /* if ( ffconfigFAT12_SUPPORT != 0 ) */
  461. default:
  462. ulFATEntry = 0;
  463. break;
  464. }
  465. if( pxFATBuffers != NULL )
  466. {
  467. /* Store the buffer. */
  468. pxFATBuffers->pxBuffers[ 0 ] = pxBuffer;
  469. }
  470. else
  471. {
  472. /* Or release it. */
  473. xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  474. }
  475. } /* if( FF_isERR( xError ) == pdFALSE ) */
  476. } /* else Handle FAT16, FAT32, and FAT12 (in case the entry lies on a single sector). */
  477. if( FF_isERR( xError ) )
  478. {
  479. /* The sector address 0 is not meaningful and here it is used as the 'error value'. */
  480. ulFATEntry = 0UL;
  481. }
  482. if( pxError != NULL )
  483. {
  484. *pxError = xError;
  485. }
  486. return ( int32_t ) ulFATEntry;
  487. } /* FF_getFATEntry() */
  488. /*-----------------------------------------------------------*/
  489. /* Write all zero's to all sectors of a given cluster. */
  490. FF_Error_t FF_ClearCluster( FF_IOManager_t * pxIOManager,
  491. uint32_t ulCluster )
  492. {
  493. FF_Error_t xError = FF_ERR_NONE;
  494. FF_Buffer_t * pxBuffer = NULL;
  495. BaseType_t xIndex;
  496. uint32_t ulBaseLBA;
  497. /* Calculate from cluster number to a real block address. */
  498. ulBaseLBA = FF_Cluster2LBA( pxIOManager, ulCluster );
  499. ulBaseLBA = FF_getRealLBA( pxIOManager, ulBaseLBA );
  500. for( xIndex = 0; xIndex < ( BaseType_t ) pxIOManager->xPartition.ulSectorsPerCluster; xIndex++ )
  501. {
  502. if( xIndex == 0 )
  503. {
  504. /* When using the FF_MODE_WR_ONLY flag, the data will not be read from disk.
  505. * Only in the first round a buffer will be claimed. */
  506. pxBuffer = FF_GetBuffer( pxIOManager, ulBaseLBA, FF_MODE_WR_ONLY );
  507. if( pxBuffer == NULL )
  508. {
  509. xError = ( FF_Error_t ) ( FF_ERR_DEVICE_DRIVER_FAILED | FF_CLEARCLUSTER );
  510. break;
  511. }
  512. memset( pxBuffer->pucBuffer, 0x00, pxIOManager->usSectorSize );
  513. }
  514. xError = FF_BlockWrite( pxIOManager, ulBaseLBA + xIndex, 1, pxBuffer->pucBuffer, pdFALSE );
  515. if( FF_isERR( xError ) )
  516. {
  517. break;
  518. }
  519. }
  520. if( pxBuffer != NULL )
  521. {
  522. FF_Error_t xTempError;
  523. /* The contents of the buffer (all zero's) has been written explicitly to disk
  524. * by calling FF_BlockWrite(). Therefore, the bModified should be cleared. */
  525. pxBuffer->bModified = pdFALSE;
  526. /* Releasing the handle will not write anything */
  527. xTempError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  528. if( FF_isERR( xError ) == pdFALSE )
  529. {
  530. xError = xTempError;
  531. }
  532. }
  533. return xError;
  534. }
  535. /*-----------------------------------------------------------*/
  536. /**
  537. * @private
  538. * @brief Returns the Cluster address of the Cluster number from the beginning of a chain.
  539. *
  540. * @param pxIOManager FF_IOManager_t Object
  541. * @param ulStart Cluster address of the first cluster in the chain.
  542. * @param ulCount Number of Cluster in the chain,
  543. *
  544. *
  545. *
  546. **/
  547. uint32_t FF_TraverseFAT( FF_IOManager_t * pxIOManager,
  548. uint32_t ulStart,
  549. uint32_t ulCount,
  550. FF_Error_t * pxError )
  551. {
  552. FF_Error_t xError = FF_ERR_NONE;
  553. uint32_t ulIndex;
  554. uint32_t ulFatEntry = ulStart;
  555. uint32_t ulCurrentCluster = ulStart;
  556. FF_FATBuffers_t xFATBuffers;
  557. BaseType_t xTakeLock = FF_Has_Lock( pxIOManager, FF_FAT_LOCK ) == pdFALSE;
  558. /* xFATBuffers is nothing more than an array of FF_Buffer_t's.
  559. * One buffer for each FAT copy on disk. */
  560. FF_InitFATBuffers( &xFATBuffers, FF_MODE_READ );
  561. if( xTakeLock )
  562. {
  563. FF_LockFAT( pxIOManager );
  564. }
  565. for( ulIndex = 0; ulIndex < ulCount; ulIndex++ )
  566. {
  567. ulFatEntry = FF_getFATEntry( pxIOManager, ulCurrentCluster, &xError, &xFATBuffers );
  568. if( FF_isERR( xError ) )
  569. {
  570. ulFatEntry = 0;
  571. break;
  572. }
  573. if( FF_isEndOfChain( pxIOManager, ulFatEntry ) )
  574. {
  575. ulFatEntry = ulCurrentCluster;
  576. break;
  577. }
  578. ulCurrentCluster = ulFatEntry;
  579. }
  580. if( xTakeLock )
  581. {
  582. FF_UnlockFAT( pxIOManager );
  583. }
  584. {
  585. FF_Error_t xTempError;
  586. xTempError = FF_ReleaseFATBuffers( pxIOManager, &xFATBuffers );
  587. if( FF_isERR( xError ) == pdFALSE )
  588. {
  589. xError = xTempError;
  590. }
  591. }
  592. *pxError = xError;
  593. return ulFatEntry;
  594. }
  595. /*-----------------------------------------------------------*/
  596. uint32_t FF_FindEndOfChain( FF_IOManager_t * pxIOManager,
  597. uint32_t ulStart,
  598. FF_Error_t * pxError )
  599. {
  600. uint32_t ulFatEntry = ulStart;
  601. FF_Error_t xError;
  602. if( FF_isEndOfChain( pxIOManager, ulStart ) == pdFALSE )
  603. {
  604. /* Traverse FAT for (2^32-1) items/clusters,
  605. * or until end-of-chain is encountered. */
  606. ulFatEntry = FF_TraverseFAT( pxIOManager, ulStart, ~0UL, &xError );
  607. }
  608. else
  609. {
  610. xError = FF_ERR_NONE;
  611. }
  612. *pxError = xError;
  613. return ulFatEntry;
  614. }
  615. /*-----------------------------------------------------------*/
  616. /**
  617. * @private
  618. * @brief Tests if the ulFATEntry is an End of Chain Marker.
  619. *
  620. * @param pxIOManager FF_IOManager_t Object
  621. * @param ulFATEntry The fat entry from the FAT table to be checked.
  622. *
  623. * @return pdTRUE if it is an end of chain, otherwise pdFALSE.
  624. *
  625. **/
  626. BaseType_t FF_isEndOfChain( FF_IOManager_t * pxIOManager,
  627. uint32_t ulFATEntry )
  628. {
  629. BaseType_t xResult = pdFALSE;
  630. if( pxIOManager->xPartition.ucType == FF_T_FAT32 )
  631. {
  632. if( ( ulFATEntry & 0x0fffffff ) >= 0x0ffffff8 )
  633. {
  634. xResult = pdTRUE;
  635. }
  636. }
  637. else if( pxIOManager->xPartition.ucType == FF_T_FAT16 )
  638. {
  639. if( ulFATEntry >= 0x0000fff8 )
  640. {
  641. xResult = pdTRUE;
  642. }
  643. }
  644. else
  645. {
  646. if( ulFATEntry >= 0x00000ff8 )
  647. {
  648. xResult = pdTRUE;
  649. }
  650. }
  651. if( ulFATEntry == 0x00000000 )
  652. {
  653. xResult = pdTRUE; /* Perhaps trying to read a deleted file! */
  654. }
  655. return xResult;
  656. }
  657. /*-----------------------------------------------------------*/
  658. #if ( ffconfigFAT12_SUPPORT != 0 )
  659. static FF_Error_t prvPutFAT12Entry( FF_IOManager_t * pxIOManager,
  660. uint32_t ulCluster,
  661. uint32_t ulValue,
  662. FF_FATBuffers_t * pxFATBuffers,
  663. uint32_t ulFATSector )
  664. {
  665. FF_Buffer_t * pxBuffer = NULL;
  666. /* For FAT12 FAT Table Across sector boundary traversal. */
  667. uint8_t ucBytes[ 2 ];
  668. /* The function result value. */
  669. uint32_t ulFATEntry;
  670. FF_Error_t xError = FF_ERR_NONE;
  671. BaseType_t xIndex;
  672. #if ( ffconfigWRITE_BOTH_FATS != 0 )
  673. const BaseType_t xNumFATs = pxIOManager->xPartition.ucNumFATS;
  674. #else
  675. const BaseType_t xNumFATs = 1;
  676. #endif
  677. /* This routine will only change 12 out of 16 bits.
  678. * Get the current 16-bit value, 4 bits shall be preserved. */
  679. ulFATEntry = prvGetFAT12Entry( pxIOManager, &xError, pxFATBuffers, ulFATSector );
  680. if( FF_isERR( xError ) == pdFALSE )
  681. {
  682. if( ( ulCluster & 0x0001 ) != 0 )
  683. {
  684. ulFATEntry &= 0x000F;
  685. ulValue = ( ulValue << 4 );
  686. ulValue &= 0xFFF0;
  687. }
  688. else
  689. {
  690. ulFATEntry &= 0xF000;
  691. ulValue &= 0x0FFF;
  692. }
  693. ulFATEntry |= ulValue;
  694. /* Write at offset 0 in the array ucBytes. */
  695. FF_putShort( ucBytes, 0, ( uint16_t ) ulFATEntry );
  696. for( xIndex = 0;
  697. xIndex < xNumFATs;
  698. xIndex++, ulFATSector += pxIOManager->xPartition.ulSectorsPerFAT )
  699. {
  700. /* Write the last byte in the first sector. */
  701. pxBuffer = FF_GetBuffer( pxIOManager, ulFATSector, FF_MODE_WRITE );
  702. {
  703. if( pxBuffer == NULL )
  704. {
  705. xError = ( FF_Error_t ) ( FF_ERR_DEVICE_DRIVER_FAILED | FF_PUTFATENTRY );
  706. break;
  707. }
  708. FF_putChar( pxBuffer->pucBuffer, ( uint16_t ) ( pxIOManager->usSectorSize - 1 ), ucBytes[ 0 ] );
  709. }
  710. xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  711. if( FF_isERR( xError ) )
  712. {
  713. break;
  714. }
  715. /* Write the first byte in the subsequent sector. */
  716. pxBuffer = FF_GetBuffer( pxIOManager, ulFATSector + 1, FF_MODE_WRITE );
  717. {
  718. if( pxBuffer == NULL )
  719. {
  720. xError = ( FF_Error_t ) ( FF_ERR_DEVICE_DRIVER_FAILED | FF_PUTFATENTRY );
  721. break;
  722. }
  723. FF_putChar( pxBuffer->pucBuffer, 0x0000, ucBytes[ 1 ] );
  724. }
  725. xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  726. if( FF_isERR( xError ) )
  727. {
  728. break;
  729. }
  730. } /* for ( xIndex = 0; xIndex < xNumFATs; xIndex++ ) */
  731. }
  732. return xError;
  733. }
  734. #endif /* if ( ffconfigFAT12_SUPPORT != 0 ) */
  735. /**
  736. * @private
  737. * @brief Writes a new Entry to the FAT Tables.
  738. *
  739. * @param pxIOManager IOMAN object.
  740. * @param ulCluster Cluster Number to be modified.
  741. * @param ulValue The value to store.
  742. **/
  743. FF_Error_t FF_putFATEntry( FF_IOManager_t * pxIOManager,
  744. uint32_t ulCluster,
  745. uint32_t ulValue,
  746. FF_FATBuffers_t * pxFATBuffers )
  747. {
  748. FF_Buffer_t * pxBuffer;
  749. uint32_t ulFATOffset;
  750. uint32_t ulFATSector = 0;
  751. uint32_t ulFATSectorEntry;
  752. uint32_t ulFATEntry;
  753. uint32_t ulLBAAdjust;
  754. uint32_t ulRelClusterEntry = 0;
  755. BaseType_t xIndex;
  756. FF_Error_t xError = FF_ERR_NONE;
  757. #if ( ffconfigWRITE_BOTH_FATS != 0 )
  758. const BaseType_t xNumFATs = pxIOManager->xPartition.ucNumFATS;
  759. #else
  760. const BaseType_t xNumFATs = 1;
  761. #endif
  762. FF_Assert_Lock( pxIOManager, FF_FAT_LOCK );
  763. /* Avoid corrupting the disk. */
  764. if( ( ulCluster == 0ul ) || ( ulCluster >= pxIOManager->xPartition.ulNumClusters ) )
  765. {
  766. /* find a more specific error code. */
  767. xError = ( FF_Error_t ) ( FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE | FF_PUTFATENTRY );
  768. }
  769. else
  770. {
  771. if( pxIOManager->xPartition.ucType == FF_T_FAT32 )
  772. {
  773. ulFATOffset = ulCluster * 4;
  774. }
  775. else if( pxIOManager->xPartition.ucType == FF_T_FAT16 )
  776. {
  777. ulFATOffset = ulCluster * 2;
  778. }
  779. else /* pxIOManager->xPartition.ucType == FF_T_FAT12 */
  780. {
  781. ulFATOffset = ulCluster + ( ulCluster / 2 );
  782. }
  783. ulFATSector = pxIOManager->xPartition.ulFATBeginLBA + ( ulFATOffset / pxIOManager->xPartition.usBlkSize );
  784. ulFATSectorEntry = ulFATOffset % pxIOManager->xPartition.usBlkSize;
  785. ulLBAAdjust = ulFATSectorEntry / ( ( uint32_t ) pxIOManager->usSectorSize );
  786. ulRelClusterEntry = ulFATSectorEntry % pxIOManager->usSectorSize;
  787. ulFATSector = FF_getRealLBA( pxIOManager, ulFATSector );
  788. ulFATSector += ulLBAAdjust;
  789. }
  790. #if ( ffconfigFAT12_SUPPORT != 0 )
  791. if( ( pxIOManager->xPartition.ucType == FF_T_FAT12 ) &&
  792. ( FF_isERR( xError ) == pdFALSE ) &&
  793. ( ulRelClusterEntry == ( uint32_t ) ( ( pxIOManager->usSectorSize - 1 ) ) ) )
  794. {
  795. /* The special case in which one FAT12 entries is divided over 2 sectors.
  796. * Treat this in a separate function. */
  797. xError = prvPutFAT12Entry( pxIOManager, ulCluster, ulValue, pxFATBuffers, ulFATSector );
  798. /* Return xError. */
  799. }
  800. else
  801. #endif /* ffconfigFAT12_SUPPORT */
  802. if( FF_isERR( xError ) == pdFALSE )
  803. {
  804. /* Handle FAT16, FAT32, and FAT12 (in case the entry lies on a single sector). */
  805. for( xIndex = 0;
  806. xIndex < xNumFATs;
  807. xIndex++, ulFATSector += pxIOManager->xPartition.ulSectorsPerFAT )
  808. {
  809. pxBuffer = prvGetFromFATBuffers( pxIOManager, pxFATBuffers, xIndex, ulFATSector, &xError, FF_MODE_WRITE );
  810. if( FF_isERR( xError ) )
  811. {
  812. xError = FF_GETERROR( xError ) | FF_PUTFATENTRY;
  813. break;
  814. }
  815. if( pxIOManager->xPartition.ucType == FF_T_FAT32 )
  816. {
  817. /* Clear the top 4 bits. */
  818. ulValue &= 0x0fffffff;
  819. FF_putLong( pxBuffer->pucBuffer, ulRelClusterEntry, ulValue );
  820. }
  821. else if( pxIOManager->xPartition.ucType == FF_T_FAT16 )
  822. {
  823. FF_putShort( pxBuffer->pucBuffer, ulRelClusterEntry, ( uint16_t ) ulValue );
  824. }
  825. else
  826. {
  827. ulFATEntry = ( uint32_t ) FF_getShort( pxBuffer->pucBuffer, ulRelClusterEntry );
  828. if( ( ulCluster & 0x0001 ) != 0 )
  829. {
  830. ulFATEntry &= 0x000F;
  831. ulValue = ( ulValue << 4 );
  832. ulValue &= 0xFFF0;
  833. }
  834. else
  835. {
  836. ulFATEntry &= 0xF000;
  837. ulValue &= 0x0FFF;
  838. }
  839. FF_putShort( pxBuffer->pucBuffer, ulRelClusterEntry, ( uint16_t ) ( ulFATEntry | ulValue ) );
  840. }
  841. if( ( xIndex < ffconfigBUF_STORE_COUNT ) && ( pxFATBuffers != NULL ) )
  842. {
  843. /* Store it for later use. */
  844. pxFATBuffers->pxBuffers[ xIndex ] = pxBuffer;
  845. pxFATBuffers->ucMode = FF_MODE_WRITE;
  846. }
  847. else
  848. {
  849. xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  850. if( FF_isERR( xError ) )
  851. {
  852. break;
  853. }
  854. }
  855. }
  856. }
  857. /* FF_putFATEntry() returns just an error code, not an address. */
  858. return xError;
  859. } /* FF_putFATEntry() */
  860. /*-----------------------------------------------------------*/
  861. /**
  862. * @private
  863. * @brief Finds a Free Cluster and returns its number.
  864. *
  865. * @param pxIOManager IOMAN Object.
  866. *
  867. * @return The number of the cluster found to be free.
  868. * @return 0 on error.
  869. **/
  870. #if ( ffconfigFAT12_SUPPORT != 0 )
  871. static uint32_t prvFindFreeClusterSimple( FF_IOManager_t * pxIOManager,
  872. FF_Error_t * pxError )
  873. {
  874. FF_Error_t xError = FF_ERR_NONE;
  875. uint32_t ulCluster = 0;
  876. uint32_t ulFATEntry;
  877. FF_FATBuffers_t xFATBuffers;
  878. FF_InitFATBuffers( &xFATBuffers, FF_MODE_READ );
  879. for( ulCluster = pxIOManager->xPartition.ulLastFreeCluster;
  880. ulCluster < pxIOManager->xPartition.ulNumClusters;
  881. ulCluster++ )
  882. {
  883. ulFATEntry = FF_getFATEntry( pxIOManager, ulCluster, &xError, &xFATBuffers );
  884. if( FF_isERR( xError ) )
  885. {
  886. break;
  887. }
  888. if( ulFATEntry == 0 )
  889. {
  890. pxIOManager->xPartition.ulLastFreeCluster = ulCluster;
  891. break;
  892. }
  893. }
  894. {
  895. FF_Error_t xTempError;
  896. xTempError = FF_ReleaseFATBuffers( pxIOManager, &xFATBuffers );
  897. if( FF_isERR( xError ) == pdFALSE )
  898. {
  899. xError = xTempError;
  900. }
  901. }
  902. if( ( FF_isERR( xError ) == pdFALSE ) &&
  903. ( ulCluster == pxIOManager->xPartition.ulNumClusters ) )
  904. {
  905. /* There is no free cluster any more. */
  906. ulCluster = 0;
  907. xError = FF_FINDFREECLUSTER | FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE;
  908. }
  909. *pxError = xError;
  910. return ulCluster;
  911. }
  912. #endif /* if ( ffconfigFAT12_SUPPORT != 0 ) */
  913. /*-----------------------------------------------------------*/
  914. uint32_t FF_FindFreeCluster( FF_IOManager_t * pxIOManager,
  915. FF_Error_t * pxError,
  916. BaseType_t xDoClaim )
  917. {
  918. FF_Error_t xError = FF_ERR_NONE;
  919. FF_Buffer_t * pxBuffer = NULL;
  920. uint32_t x, ulCluster;
  921. uint32_t ulFATSectorEntry;
  922. uint32_t ulEntriesPerSector;
  923. uint32_t ulFATEntry = 1;
  924. const BaseType_t xEntrySize = ( pxIOManager->xPartition.ucType == FF_T_FAT32 ) ? 4 : 2;
  925. const uint32_t uNumClusters = pxIOManager->xPartition.ulNumClusters;
  926. BaseType_t xTakeLock = FF_Has_Lock( pxIOManager, FF_FAT_LOCK ) == pdFALSE;
  927. if( xTakeLock )
  928. {
  929. FF_LockFAT( pxIOManager );
  930. }
  931. ulCluster = pxIOManager->xPartition.ulLastFreeCluster;
  932. #if ( ffconfigFAT12_SUPPORT != 0 )
  933. /* FAT12 tables are too small to optimise, and would make it very complicated! */
  934. if( pxIOManager->xPartition.ucType == FF_T_FAT12 )
  935. {
  936. ulCluster = prvFindFreeClusterSimple( pxIOManager, &xError );
  937. }
  938. else
  939. #endif
  940. {
  941. #if ( ffconfigFSINFO_TRUSTED != 0 )
  942. {
  943. /* If 'ffconfigFSINFO_TRUSTED', the contents of the field 'ulLastFreeCluster' is trusted.
  944. * Only ready it in case of FAT32 and only during the very first time, i.e. when
  945. * ulLastFreeCluster is still zero. */
  946. if( ( pxIOManager->xPartition.ucType == FF_T_FAT32 ) && ( pxIOManager->xPartition.ulLastFreeCluster == 0ul ) )
  947. {
  948. pxBuffer = FF_GetBuffer( pxIOManager, pxIOManager->xPartition.ulFSInfoLBA, FF_MODE_READ );
  949. if( pxBuffer == NULL )
  950. {
  951. xError = ( FF_Error_t ) ( FF_ERR_DEVICE_DRIVER_FAILED | FF_FINDFREECLUSTER );
  952. }
  953. else
  954. {
  955. if( ( FF_getLong( pxBuffer->pucBuffer, 0 ) == 0x41615252 ) &&
  956. ( FF_getLong( pxBuffer->pucBuffer, 484 ) == 0x61417272 ) )
  957. {
  958. ulCluster = FF_getLong( pxBuffer->pucBuffer, 492 );
  959. }
  960. xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  961. pxBuffer = NULL;
  962. }
  963. }
  964. }
  965. #endif /* if ( ffconfigFSINFO_TRUSTED != 0 ) */
  966. if( FF_isERR( xError ) == pdFALSE )
  967. {
  968. uint32_t ulFATSector;
  969. uint32_t ulFATOffset;
  970. ulEntriesPerSector = pxIOManager->usSectorSize / xEntrySize;
  971. ulFATOffset = ulCluster * xEntrySize;
  972. /* Start from a sector where the first free entry is expected,
  973. * and iterate through every FAT sector. */
  974. for( ulFATSector = ( ulFATOffset / pxIOManager->xPartition.usBlkSize );
  975. ulFATSector < pxIOManager->xPartition.ulSectorsPerFAT;
  976. ulFATSector++ )
  977. {
  978. pxBuffer = FF_GetBuffer( pxIOManager, pxIOManager->xPartition.ulFATBeginLBA + ulFATSector, FF_MODE_READ );
  979. if( pxBuffer == NULL )
  980. {
  981. xError = ( FF_Error_t ) ( FF_ERR_DEVICE_DRIVER_FAILED | FF_FINDFREECLUSTER );
  982. break;
  983. }
  984. for( x = ( ulCluster % ulEntriesPerSector ); x < ulEntriesPerSector; x++ )
  985. {
  986. /* Double-check: don't use non-existing clusters */
  987. if( ulCluster >= uNumClusters )
  988. {
  989. xError = ( FF_Error_t ) ( FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE | FF_FINDFREECLUSTER );
  990. break;
  991. }
  992. ulFATSectorEntry = ulFATOffset % pxIOManager->xPartition.usBlkSize;
  993. if( pxIOManager->xPartition.ucType == FF_T_FAT32 )
  994. {
  995. ulFATEntry = FF_getLong( pxBuffer->pucBuffer, ulFATSectorEntry );
  996. /* Clear the top 4 bits. */
  997. ulFATEntry &= 0x0fffffff;
  998. }
  999. else
  1000. {
  1001. ulFATEntry = ( uint32_t ) FF_getShort( pxBuffer->pucBuffer, ulFATSectorEntry );
  1002. }
  1003. if( ulFATEntry == 0x00000000 )
  1004. {
  1005. /* Break and return 'ulCluster' */
  1006. break;
  1007. }
  1008. ulFATOffset += xEntrySize;
  1009. ulCluster++;
  1010. }
  1011. xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  1012. pxBuffer = NULL;
  1013. if( FF_isERR( xError ) )
  1014. {
  1015. break;
  1016. }
  1017. if( ulFATEntry == 0x00000000 )
  1018. {
  1019. /* And break from the outer loop. */
  1020. break;
  1021. }
  1022. }
  1023. if( ( FF_isERR( xError ) == pdFALSE ) &&
  1024. ( ulFATSector == pxIOManager->xPartition.ulSectorsPerFAT ) )
  1025. {
  1026. xError = ( FF_Error_t ) ( FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE | FF_FINDFREECLUSTER );
  1027. }
  1028. } /* if( FF_isERR( xError ) == pdFALSE ) */
  1029. } /* if( pxIOManager->xPartition.ucType != FF_T_FAT12 ) */
  1030. if( FF_isERR( xError ) )
  1031. {
  1032. ulCluster = 0UL;
  1033. }
  1034. if( ( ulCluster != 0UL ) && ( xDoClaim != pdFALSE ) )
  1035. {
  1036. FF_Error_t xTempError;
  1037. /* Found a free cluster! */
  1038. pxIOManager->xPartition.ulLastFreeCluster = ulCluster + 1;
  1039. xTempError = FF_putFATEntry( pxIOManager, ulCluster, 0xFFFFFFFF, NULL );
  1040. if( FF_isERR( xError ) == pdFALSE )
  1041. {
  1042. xError = xTempError;
  1043. }
  1044. if( FF_isERR( xError ) )
  1045. {
  1046. ulCluster = 0UL;
  1047. }
  1048. }
  1049. if( xTakeLock )
  1050. {
  1051. FF_UnlockFAT( pxIOManager );
  1052. }
  1053. *pxError = xError;
  1054. return ulCluster;
  1055. } /* FF_FindFreeCluster */
  1056. /*-----------------------------------------------------------*/
  1057. /**
  1058. * @private
  1059. * @brief Creates a Cluster Chain
  1060. * @return > 0 New created cluster
  1061. * @return = 0 See pxError
  1062. **/
  1063. uint32_t FF_CreateClusterChain( FF_IOManager_t * pxIOManager,
  1064. FF_Error_t * pxError )
  1065. {
  1066. uint32_t ulStartCluster;
  1067. FF_Error_t xError = FF_ERR_NONE;
  1068. FF_LockFAT( pxIOManager );
  1069. {
  1070. ulStartCluster = FF_FindFreeCluster( pxIOManager, &xError, pdTRUE );
  1071. }
  1072. FF_UnlockFAT( pxIOManager );
  1073. if( ulStartCluster != 0L )
  1074. {
  1075. xError = FF_DecreaseFreeClusters( pxIOManager, 1 );
  1076. }
  1077. *pxError = xError;
  1078. return ulStartCluster;
  1079. }
  1080. /*-----------------------------------------------------------*/
  1081. uint32_t FF_GetChainLength( FF_IOManager_t * pxIOManager,
  1082. uint32_t ulStartCluster,
  1083. uint32_t * pulEndOfChain,
  1084. FF_Error_t * pxError )
  1085. {
  1086. uint32_t ulLength = 0;
  1087. FF_FATBuffers_t xFATBuffers;
  1088. FF_Error_t xError = FF_ERR_NONE;
  1089. FF_InitFATBuffers( &xFATBuffers, FF_MODE_READ );
  1090. FF_LockFAT( pxIOManager );
  1091. {
  1092. while( FF_isEndOfChain( pxIOManager, ulStartCluster ) == pdFALSE )
  1093. {
  1094. ulStartCluster = FF_getFATEntry( pxIOManager, ulStartCluster, &xError, &xFATBuffers );
  1095. if( FF_isERR( xError ) )
  1096. {
  1097. ulLength = 0;
  1098. break;
  1099. }
  1100. ulLength++;
  1101. }
  1102. if( pulEndOfChain != NULL )
  1103. {
  1104. /* _HT_
  1105. * ulStartCluster has just been tested as an end-of-chain token.
  1106. * Not sure if the caller expects this. */
  1107. *pulEndOfChain = ulStartCluster;
  1108. }
  1109. xError = FF_ReleaseFATBuffers( pxIOManager, &xFATBuffers );
  1110. }
  1111. FF_UnlockFAT( pxIOManager );
  1112. *pxError = xError;
  1113. return ulLength;
  1114. }
  1115. /*-----------------------------------------------------------*/
  1116. /**
  1117. * @private
  1118. * @brief Free's Disk space by freeing unused links on Cluster Chains
  1119. *
  1120. * @param pxIOManager, IOMAN object.
  1121. * @param ulStartCluster Cluster Number that starts the chain.
  1122. * @param ulCount Number of Clusters from the end of the chain to unlink.
  1123. * @param ulCount 0 Means Free the entire chain (delete file).
  1124. * @param ulCount 1 Means mark the start cluster with EOF.
  1125. *
  1126. * @return 0 On Success.
  1127. * @return -1 If the device driver failed to provide access.
  1128. *
  1129. **/
  1130. FF_Error_t FF_UnlinkClusterChain( FF_IOManager_t * pxIOManager,
  1131. uint32_t ulStartCluster,
  1132. BaseType_t xDoTruncate )
  1133. {
  1134. uint32_t ulFATEntry;
  1135. uint32_t ulCurrentCluster;
  1136. uint32_t ulLength = 0;
  1137. uint32_t ulLastFree = ulStartCluster;
  1138. FF_Error_t xTempError;
  1139. FF_Error_t xError = FF_ERR_NONE;
  1140. FF_FATBuffers_t xFATBuffers;
  1141. BaseType_t xTakeLock = FF_Has_Lock( pxIOManager, FF_FAT_LOCK ) == pdFALSE;
  1142. if( xTakeLock )
  1143. {
  1144. FF_LockFAT( pxIOManager );
  1145. }
  1146. FF_InitFATBuffers( &xFATBuffers, FF_MODE_WRITE );
  1147. ulFATEntry = ulStartCluster;
  1148. /* Free all clusters in the chain! */
  1149. ulCurrentCluster = ulStartCluster;
  1150. ulFATEntry = ulCurrentCluster;
  1151. do
  1152. {
  1153. /* Sector will now be fetched in write-mode. */
  1154. ulFATEntry = FF_getFATEntry( pxIOManager, ulFATEntry, &xError, &xFATBuffers );
  1155. if( FF_isERR( xError ) )
  1156. {
  1157. break;
  1158. }
  1159. if( ( xDoTruncate != pdFALSE ) && ( ulCurrentCluster == ulStartCluster ) )
  1160. {
  1161. xError = FF_putFATEntry( pxIOManager, ulCurrentCluster, 0xFFFFFFFF, &xFATBuffers );
  1162. }
  1163. else
  1164. {
  1165. xError = FF_putFATEntry( pxIOManager, ulCurrentCluster, 0x00000000, &xFATBuffers );
  1166. ulLength++;
  1167. }
  1168. if( FF_isERR( xError ) )
  1169. {
  1170. break;
  1171. }
  1172. if( ulLastFree > ulCurrentCluster )
  1173. {
  1174. ulLastFree = ulCurrentCluster;
  1175. }
  1176. ulCurrentCluster = ulFATEntry;
  1177. } while( FF_isEndOfChain( pxIOManager, ulFATEntry ) == pdFALSE );
  1178. if( FF_isERR( xError ) == pdFALSE )
  1179. {
  1180. if( pxIOManager->xPartition.ulLastFreeCluster > ulLastFree )
  1181. {
  1182. pxIOManager->xPartition.ulLastFreeCluster = ulLastFree;
  1183. }
  1184. }
  1185. xTempError = FF_ReleaseFATBuffers( pxIOManager, &xFATBuffers );
  1186. if( FF_isERR( xError ) == pdFALSE )
  1187. {
  1188. xError = xTempError;
  1189. }
  1190. if( xTakeLock )
  1191. {
  1192. FF_UnlockFAT( pxIOManager );
  1193. }
  1194. if( ulLength != 0 )
  1195. {
  1196. xTempError = FF_IncreaseFreeClusters( pxIOManager, ulLength );
  1197. if( FF_isERR( xError ) == pdFALSE )
  1198. {
  1199. xError = xTempError;
  1200. }
  1201. }
  1202. return xError;
  1203. }
  1204. /*-----------------------------------------------------------*/
  1205. #if ( ffconfigFAT12_SUPPORT != 0 )
  1206. static uint32_t prvCountFreeClustersSimple( FF_IOManager_t * pxIOManager,
  1207. FF_Error_t * pxError )
  1208. {
  1209. FF_Error_t xError = FF_ERR_NONE;
  1210. uint32_t ulIndex;
  1211. uint32_t ulFATEntry;
  1212. uint32_t ulFreeClusters = 0;
  1213. const uint32_t xTotalClusters =
  1214. pxIOManager->xPartition.ulDataSectors / pxIOManager->xPartition.ulSectorsPerCluster;
  1215. for( ulIndex = 0; ulIndex < xTotalClusters; ulIndex++ )
  1216. {
  1217. ulFATEntry = FF_getFATEntry( pxIOManager, ulIndex, &xError, NULL );
  1218. if( FF_isERR( xError ) )
  1219. {
  1220. break;
  1221. }
  1222. if( ulFATEntry == 0UL )
  1223. {
  1224. ulFreeClusters++;
  1225. }
  1226. }
  1227. *pxError = xError;
  1228. return ulFreeClusters;
  1229. }
  1230. #endif /* if ( ffconfigFAT12_SUPPORT != 0 ) */
  1231. /*-----------------------------------------------------------*/
  1232. uint32_t FF_CountFreeClusters( FF_IOManager_t * pxIOManager,
  1233. FF_Error_t * pxError )
  1234. {
  1235. FF_Error_t xError = FF_ERR_NONE;
  1236. FF_Buffer_t * pxBuffer;
  1237. uint32_t ulIndex, x;
  1238. uint32_t ulFATEntry;
  1239. uint32_t ulEntriesPerSector;
  1240. uint32_t ulFreeClusters = 0;
  1241. uint32_t ClusterNum = 0;
  1242. BaseType_t xInfoKnown = pdFALSE;
  1243. BaseType_t xTakeLock = FF_Has_Lock( pxIOManager, FF_FAT_LOCK ) == pdFALSE;
  1244. if( xTakeLock )
  1245. {
  1246. FF_LockFAT( pxIOManager );
  1247. }
  1248. #if ( ffconfigFAT12_SUPPORT != 0 )
  1249. /* FAT12 tables are too small to optimise, and would make it very complicated! */
  1250. if( pxIOManager->xPartition.ucType == FF_T_FAT12 )
  1251. {
  1252. ulFreeClusters = prvCountFreeClustersSimple( pxIOManager, &xError );
  1253. }
  1254. else
  1255. #endif
  1256. {
  1257. /* For FAT16 and FAT32 */
  1258. #if ( ffconfigFSINFO_TRUSTED != 0 )
  1259. {
  1260. /* If 'ffconfigFSINFO_TRUSTED', the contents of the field 'ulFreeClusterCount' is trusted. */
  1261. if( pxIOManager->xPartition.ucType == FF_T_FAT32 )
  1262. {
  1263. pxBuffer = FF_GetBuffer( pxIOManager, pxIOManager->xPartition.ulFSInfoLBA, FF_MODE_READ );
  1264. if( pxBuffer == NULL )
  1265. {
  1266. xError = ( FF_Error_t ) ( FF_ERR_DEVICE_DRIVER_FAILED | FF_COUNTFREECLUSTERS );
  1267. }
  1268. else
  1269. {
  1270. if( ( FF_getLong( pxBuffer->pucBuffer, 0 ) == 0x41615252 ) &&
  1271. ( FF_getLong( pxBuffer->pucBuffer, 484 ) == 0x61417272 ) )
  1272. {
  1273. ulFreeClusters = FF_getLong( pxBuffer->pucBuffer, 488 );
  1274. if( ulFreeClusters != ~0ul )
  1275. {
  1276. xInfoKnown = pdTRUE;
  1277. }
  1278. else
  1279. {
  1280. ulFreeClusters = 0ul;
  1281. }
  1282. }
  1283. xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  1284. pxBuffer = NULL;
  1285. if( xInfoKnown != pdFALSE )
  1286. {
  1287. pxIOManager->xPartition.ulFreeClusterCount = ulFreeClusters;
  1288. }
  1289. }
  1290. }
  1291. }
  1292. #endif /* if ( ffconfigFSINFO_TRUSTED != 0 ) */
  1293. if( ( xInfoKnown == pdFALSE ) && ( pxIOManager->xPartition.usBlkSize != 0 ) )
  1294. {
  1295. if( pxIOManager->xPartition.ucType == FF_T_FAT32 )
  1296. {
  1297. ulEntriesPerSector = pxIOManager->usSectorSize / 4;
  1298. }
  1299. else
  1300. {
  1301. ulEntriesPerSector = pxIOManager->usSectorSize / 2;
  1302. }
  1303. for( ulIndex = 0; ulIndex < pxIOManager->xPartition.ulSectorsPerFAT; ulIndex++ )
  1304. {
  1305. pxBuffer = FF_GetBuffer( pxIOManager, pxIOManager->xPartition.ulFATBeginLBA + ulIndex, FF_MODE_READ );
  1306. if( pxBuffer == NULL )
  1307. {
  1308. xError = ( FF_Error_t ) ( FF_ERR_DEVICE_DRIVER_FAILED | FF_COUNTFREECLUSTERS );
  1309. break;
  1310. }
  1311. #if USE_SOFT_WDT
  1312. {
  1313. /* _HT_ : FF_CountFreeClusters was a little too busy, have it call the WDT and sleep */
  1314. clearWDT();
  1315. if( ( ( ulIndex + 1 ) % 32 ) == 0 )
  1316. {
  1317. FF_Sleep( 1 );
  1318. }
  1319. }
  1320. #endif
  1321. for( x = 0; x < ulEntriesPerSector; x++ )
  1322. {
  1323. if( pxIOManager->xPartition.ucType == FF_T_FAT32 )
  1324. {
  1325. /* Clearing the top 4 bits. */
  1326. ulFATEntry = FF_getLong( pxBuffer->pucBuffer, x * 4 ) & 0x0fffffff;
  1327. }
  1328. else
  1329. {
  1330. ulFATEntry = ( uint32_t ) FF_getShort( pxBuffer->pucBuffer, x * 2 );
  1331. }
  1332. if( ulFATEntry == 0ul )
  1333. {
  1334. ulFreeClusters++;
  1335. }
  1336. /* FAT table might not be cluster aligned. */
  1337. if( ClusterNum > pxIOManager->xPartition.ulNumClusters )
  1338. {
  1339. /* Stop counting if that's the case. */
  1340. break;
  1341. }
  1342. ClusterNum++;
  1343. }
  1344. xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
  1345. pxBuffer = NULL;
  1346. if( FF_isERR( xError ) )
  1347. {
  1348. break;
  1349. }
  1350. if( ClusterNum > pxIOManager->xPartition.ulNumClusters )
  1351. {
  1352. /* Break out of 2nd loop too ^^ */
  1353. break;
  1354. }
  1355. /* ulFreeClusters is -2 because the first 2 fat entries in the table are reserved. */
  1356. if( ulFreeClusters > pxIOManager->xPartition.ulNumClusters )
  1357. {
  1358. ulFreeClusters = pxIOManager->xPartition.ulNumClusters;
  1359. }
  1360. } /* for( ulIndex = 0; ulIndex < pxIOManager->xPartition.ulSectorsPerFAT; ulIndex++ ) */
  1361. }
  1362. }
  1363. if( xTakeLock )
  1364. {
  1365. FF_UnlockFAT( pxIOManager );
  1366. }
  1367. if( FF_isERR( xError ) )
  1368. {
  1369. ulFreeClusters = 0;
  1370. }
  1371. *pxError = xError;
  1372. return ulFreeClusters;
  1373. }
  1374. /*-----------------------------------------------------------*/
  1375. #if ( ffconfig64_NUM_SUPPORT != 0 )
  1376. uint64_t FF_GetFreeSize( FF_IOManager_t * pxIOManager,
  1377. FF_Error_t * pxError )
  1378. {
  1379. FF_Error_t xError = FF_ERR_NONE;
  1380. uint32_t ulFreeClusters;
  1381. uint64_t ulFreeSize = 0;
  1382. if( pxIOManager != NULL )
  1383. {
  1384. if( pxIOManager->xPartition.ulFreeClusterCount == 0ul )
  1385. {
  1386. FF_LockFAT( pxIOManager );
  1387. {
  1388. pxIOManager->xPartition.ulFreeClusterCount = FF_CountFreeClusters( pxIOManager, &xError );
  1389. }
  1390. FF_UnlockFAT( pxIOManager );
  1391. }
  1392. ulFreeClusters = pxIOManager->xPartition.ulFreeClusterCount;
  1393. ulFreeSize = ( uint64_t )
  1394. ( ( uint64_t ) ulFreeClusters * ( uint64_t )
  1395. ( ( uint64_t ) pxIOManager->xPartition.ulSectorsPerCluster *
  1396. ( uint64_t ) pxIOManager->xPartition.usBlkSize ) );
  1397. }
  1398. if( pxError != NULL )
  1399. {
  1400. *pxError = xError;
  1401. }
  1402. return ulFreeSize;
  1403. }
  1404. #else /* if ( ffconfig64_NUM_SUPPORT != 0 ) */
  1405. uint32_t FF_GetFreeSize( FF_IOManager_t * pxIOManager,
  1406. FF_Error_t * pxError )
  1407. {
  1408. FF_Error_t xError = FF_ERR_NONE;
  1409. uint32_t ulFreeClusters;
  1410. uint32_t ulFreeSize = 0;
  1411. if( pxIOManager != NULL )
  1412. {
  1413. if( pxIOManager->xPartition.ulFreeClusterCount == 0ul )
  1414. {
  1415. FF_LockFAT( pxIOManager );
  1416. {
  1417. pxIOManager->xPartition.ulFreeClusterCount = FF_CountFreeClusters( pxIOManager, &xError );
  1418. }
  1419. FF_UnlockFAT( pxIOManager );
  1420. }
  1421. ulFreeClusters = pxIOManager->xPartition.ulFreeClusterCount;
  1422. ulFreeSize = ( uint32_t )
  1423. ( ( uint32_t ) ulFreeClusters * ( uint32_t )
  1424. ( ( uint32_t ) pxIOManager->xPartition.ulSectorsPerCluster *
  1425. ( uint32_t ) pxIOManager->xPartition.usBlkSize ) );
  1426. }
  1427. if( pxError != NULL )
  1428. {
  1429. *pxError = xError;
  1430. }
  1431. return ulFreeSize;
  1432. }
  1433. #endif /* ffconfig64_NUM_SUPPORT */
  1434. /*-----------------------------------------------------------*/