📄 ff.lst
字号:
224 /*-----------------------------------------------------------------------*/
225 /* Change window offset */
226 /*-----------------------------------------------------------------------*/
227
228 static
229 FRESULT move_window (
230 FATFS *fs, /* File system object */
231 DWORD sector /* Sector number to make apperance in the fs->win[] */
232 ) /* Move to zero only writes back dirty window */
233 {
234 1 DWORD wsect;
235 1
236 1
237 1 wsect = fs->winsect;
238 1 if (wsect != sector) { /* Changed current window */
239 2 #if !_FS_READONLY
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 5
240 2 if (fs->wflag) { /* Write back dirty window if needed */
241 3 if (disk_write(fs->drive, fs->win, wsect, 1) != RES_OK)
242 3 return FR_DISK_ERR;
243 3 fs->wflag = 0;
244 3 if (wsect < (fs->fatbase + fs->sects_fat)) { /* In FAT area */
245 4 BYTE nf;
246 4 for (nf = fs->n_fats; nf > 1; nf--) { /* Refrect the change to all FAT copies */
247 5 wsect += fs->sects_fat;
248 5 disk_write(fs->drive, fs->win, wsect, 1);
249 5 }
250 4 }
251 3 }
252 2 #endif
253 2 if (sector) {
254 3 if (disk_read(fs->drive, fs->win, sector, 1) != RES_OK)
255 3 return FR_DISK_ERR;
256 3 fs->winsect = sector;
257 3 }
258 2 }
259 1
260 1 return FR_OK;
261 1 }
262
263
264
265
266 /*-----------------------------------------------------------------------*/
267 /* Clean-up cached data */
268 /*-----------------------------------------------------------------------*/
269 #if !_FS_READONLY
270 static
271 FRESULT sync ( /* FR_OK: successful, FR_DISK_ERR: failed */
272 FATFS *fs /* File system object */
273 )
274 {
275 1 FRESULT res;
276 1
277 1
278 1 res = move_window(fs, 0);
279 1 if (res == FR_OK) {
280 2 /* Update FSInfo sector if needed */
281 2 if (fs->fs_type == FS_FAT32 && fs->fsi_flag) {
282 3 fs->winsect = 0;
283 3 mem_set(fs->win, 0, 512);
284 3 ST_WORD(fs->win+BS_55AA, 0xAA55);
285 3 ST_DWORD(fs->win+FSI_LeadSig, 0x41615252);
286 3 ST_DWORD(fs->win+FSI_StrucSig, 0x61417272);
287 3 ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust);
288 3 ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust);
289 3 disk_write(fs->drive, fs->win, fs->fsi_sector, 1);
290 3 fs->fsi_flag = 0;
291 3 }
292 2 /* Make sure that no pending write process in the physical drive */
293 2 if (disk_ioctl(fs->drive, CTRL_SYNC, (void*)NULL) != RES_OK)
294 2 res = FR_DISK_ERR;
295 2 }
296 1
297 1 return res;
298 1 }
299 #endif
300
301
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 6
302
303
304 /*-----------------------------------------------------------------------*/
305 /* FAT access - Read value of a FAT entry */
306 /*-----------------------------------------------------------------------*/
307
308 static
309 DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Interal error, Else:Cluster status */
310 FATFS *fs, /* File system object */
311 DWORD clst /* Cluster# to get the link information */
312 )
313 {
314 1 UINT wc, bc;
315 1 DWORD fsect;
316 1
317 1
318 1 if (clst < 2 || clst >= fs->max_clust) /* Range check */
319 1 return 1;
320 1
321 1 fsect = fs->fatbase;
322 1 switch (fs->fs_type) {
323 2 case FS_FAT12 :
324 2 bc = clst; bc += bc / 2;
325 2 if (move_window(fs, fsect + (bc / SS(fs)))) break;
326 2 wc = fs->win[bc & (SS(fs) - 1)]; bc++;
327 2 if (move_window(fs, fsect + (bc / SS(fs)))) break;
328 2 wc |= (WORD)fs->win[bc & (SS(fs) - 1)] << 8;
329 2 return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
330 2
331 2 case FS_FAT16 :
332 2 if (move_window(fs, fsect + (clst / (SS(fs) / 2)))) break;
333 2 return LD_WORD(&fs->win[((WORD)clst * 2) & (SS(fs) - 1)]);
334 2
335 2 case FS_FAT32 :
336 2 if (move_window(fs, fsect + (clst / (SS(fs) / 4)))) break;
337 2 return LD_DWORD(&fs->win[((WORD)clst * 4) & (SS(fs) - 1)]) & 0x0FFFFFFF;
338 2 }
339 1
340 1 return 0xFFFFFFFF; /* An error occured at the disk I/O layer */
341 1 }
342
343
344
345
346 /*-----------------------------------------------------------------------*/
347 /* FAT access - Change value of a FAT entry */
348 /*-----------------------------------------------------------------------*/
349 #if !_FS_READONLY
350 static
351 FRESULT put_fat (
352 FATFS *fs, /* File system object */
353 DWORD clst, /* Cluster# to be changed in range of 2 to fs->max_clust - 1 */
354 DWORD val /* New value to mark the cluster */
355 )
356 {
357 1 UINT bc;
358 1 BYTE *p;
359 1 DWORD fsect;
360 1 FRESULT res;
361 1
362 1
363 1 if (clst < 2 || clst >= fs->max_clust) { /* Range check */
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 7
364 2 res = FR_INT_ERR;
365 2
366 2 } else {
367 2 fsect = fs->fatbase;
368 2 switch (fs->fs_type) {
369 3 case FS_FAT12 :
370 3 bc = clst; bc += bc / 2;
371 3 res = move_window(fs, fsect + (bc / SS(fs)));
372 3 if (res != FR_OK) break;
373 3 p = &fs->win[bc & (SS(fs) - 1)];
374 3 *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
375 3 bc++;
376 3 fs->wflag = 1;
377 3 res = move_window(fs, fsect + (bc / SS(fs)));
378 3 if (res != FR_OK) break;
379 3 p = &fs->win[bc & (SS(fs) - 1)];
380 3 *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
381 3 break;
382 3
383 3 case FS_FAT16 :
384 3 res = move_window(fs, fsect + (clst / (SS(fs) / 2)));
385 3 if (res != FR_OK) break;
386 3 ST_WORD(&fs->win[((WORD)clst * 2) & (SS(fs) - 1)], (WORD)val);
387 3 break;
388 3
389 3 case FS_FAT32 :
390 3 res = move_window(fs, fsect + (clst / (SS(fs) / 4)));
391 3 if (res != FR_OK) break;
392 3 ST_DWORD(&fs->win[((WORD)clst * 4) & (SS(fs) - 1)], val);
393 3 break;
394 3
395 3 default :
396 3 res = FR_INT_ERR;
397 3 }
398 2 fs->wflag = 1;
399 2 }
400 1
401 1 return res;
402 1 }
403 #endif /* !_FS_READONLY */
404
405
406
407
408 /*-----------------------------------------------------------------------*/
409 /* FAT handling - Remove a cluster chain */
410 /*-----------------------------------------------------------------------*/
411 #if !_FS_READONLY
412 static
413 FRESULT remove_chain (
414 FATFS *fs, /* File system object */
415 DWORD clst /* Cluster# to remove a chain from */
416 )
417 {
418 1 FRESULT res;
419 1 DWORD nxt;
420 1
421 1
422 1 if (clst < 2 || clst >= fs->max_clust) { /* Check the range of cluster# */
423 2 res = FR_INT_ERR;
424 2
425 2 } else {
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 8
426 2 res = FR_OK;
427 2 while (clst < fs->max_clust) { /* Not a last link? */
428 3 nxt = get_fat(fs, clst); /* Get cluster status */
429 3 if (nxt == 0) break; /* Empty cluster? */
430 3 if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */
431 3 if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */
432 3 res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */
433 3 if (res != FR_OK) break;
434 3 if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */
435 4 fs->free_clust++;
436 4 fs->fsi_flag = 1;
437 4 }
438 3 clst = nxt; /* Next cluster */
439 3 }
440 2 }
441 1
442 1 return res;
443 1 }
444 #endif
445
446
447
448
449 /*-----------------------------------------------------------------------*/
450 /* FAT handling - Stretch or Create a cluster chain */
451 /*-----------------------------------------------------------------------*/
452 #if !_FS_READONLY
453 static
454 DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */
455 FATFS *fs, /* File system object */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -