更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
virpartff.h 文件参考

浏览源代码.

函数

FRESULT follow_virentry (FFOBJID *obj, const TCHAR *path)
 
FATFS * f_getfatfs (int vol)
 
FRESULT f_checkname (const TCHAR *path)
 
FRESULT f_boundary (FATFS *fs, DWORD clust)
 
FRESULT f_disvirfs (FATFS *fs)
 
FRESULT f_unregvirfs (FATFS *fs)
 
FRESULT f_regvirfs (FATFS *fs)
 
FRESULT f_scanfat (FATFS *fs)
 
FRESULT f_checkvirpart (FATFS *fs, const TCHAR *path, BYTE vol)
 
FRESULT f_makevirpart (FATFS *fs, const TCHAR *path, BYTE vol)
 
FRESULT f_getvirfree (const TCHAR *path, DWORD *nclst, DWORD *cclst)
 

变量

FAT_VIR_PART g_fatVirPart
 

函数说明

◆ f_boundary()

FRESULT f_boundary ( FATFS *  fs,
DWORD  clust 
)

在文件 virpartff.c165 行定义.

166{
167 FFOBJID obj;
168 FRESULT res;
169 obj.fs = fs;
170 if (fs == NULL) {
171 return FR_INT_ERR;
172 }
173 if (fs->fs_type != FS_FAT32) {
174 return FR_INVAILD_FATFS;
175 }
176 ENTER_FF(fs);
177
178 res = FatfsCheckBoundParam(fs, clust);
179 if (res != FR_OK) {
180 LEAVE_FF(fs, res);
181 }
182 for (;;) {
183 clust = get_fat(&obj, clust);
184 if (clust == 0xFFFFFFFF) {
185 LEAVE_FF(fs, FR_DISK_ERR);
186 }
187 if (clust == 0x0FFFFFFF) {
188 break;
189 }
190 if (clust < 2 || clust >= fs->n_fatent) {
191 LEAVE_FF(fs, FR_INT_ERR);
192 }
193 if (clust >= (fs->st_clst + fs->ct_clst) || clust < fs->st_clst) {
194 LEAVE_FF(fs, FR_CHAIN_ERR);
195 }
196 }
197
198 LEAVE_FF(fs, FR_OK);
199}
static FRESULT FatfsCheckBoundParam(FATFS *fs, DWORD clust)
Definition: virpartff.c:142
函数调用图:
这是这个函数的调用关系图:

◆ f_checkname()

FRESULT f_checkname ( const TCHAR *  path)

在文件 virpartff.c98 行定义.

99{
100 FRESULT res;
101 DIR dj;
102 FATFS fs;
103 TCHAR *label = (TCHAR *)path;
104 DEF_NAMBUF
105
106 (void)memset_s(&fs, sizeof(fs), 0, sizeof(fs));
107 dj.obj.fs = &fs;
108 INIT_NAMBUF(&fs);
109 res = create_name(&dj, &path);
110 /* the last byte of file name can't be a space */
111 if (res == FR_OK && dj.fn[11] == 0x20) {
112 res = FR_INVALID_NAME;
113 return res;
114 }
115
116 FREE_NAMBUF();
117
118 for (; *label != '\0'; label++) {
119 if (label - path > _MAX_ENTRYLENGTH) {
120 res = FR_INVALID_NAME;
121 return res;
122 }
123 if (*label == '/' || *label == '\\') {
124 res = FR_INVALID_NAME;
125 return res;
126 }
127 }
128 return res;
129}
这是这个函数的调用关系图:

◆ f_checkvirpart()

FRESULT f_checkvirpart ( FATFS *  fs,
const TCHAR *  path,
BYTE  vol 
)

在文件 virpartff.c512 行定义.

513{
514 FRESULT res;
515 WORD i;
516 DWORD virSect;
517 DWORD tmp;
518 BYTE pdrv;
519 BYTE *work = NULL;
520 CHAR label[_MAX_ENTRYLENGTH + 1];
521 DWORD *labelTmp = NULL; /* to clear the compilation warning */
522
523 if (fs == NULL || (disk_status(fs->pdrv) & STA_NOINIT)) {
524 return FR_INVAILD_FATFS; /* The object is invalid */
525 }
526
527 /* Lock the filesystem object */
528 res = mount_volume(&path, &fs, FA_WRITE); /* Update the filesystem info to the parent fs */
529 if (res != FR_OK) {
530 LEAVE_FF(fs, res);
531 }
532
533 if (ISCHILD(fs)) {
534 LEAVE_FF(fs, FR_INT_ERR);
535 }
536 /* Data will be save at the last reserve sector ,which is the front one of the fat base sector */
537 virSect = fs->fatbase - 1;
538
539 pdrv = LD2PD(vol); /* Driver index */
540
541 work = (BYTE *)ff_memalloc(SS(fs));
542 if (work == NULL) {
543 LEAVE_FF(fs, FR_NOT_ENOUGH_CORE);
544 }
545 /* Check and vertify partition information */
546 if (disk_read(pdrv, work, virSect, 1) != RES_OK) {
547 res = FR_DISK_ERR;
548 goto EXIT;
549 } /* Load VBR */
550
551 res = FatfsCheckStart(work, fs, vol);
552 if (res != FR_OK) {
553 goto EXIT;
554 }
555 /* Check the virtual parition amount if matched current setting or not */
556 fs->vir_amount = work[VR_PartitionCnt];
557 res = f_regvirfs(fs);
558 if (res != FR_OK) {
559 goto EXIT;
560 }
561
562 for (i = 0; i < _MAX_VIRVOLUMES; i++) {
563 if (i < work[VR_PartitionCnt]) {
564 if (work[VR_PARTITION + i * VR_ITEMSIZE + VR_Available] != 0x80) {
565 (void)f_unregvirfs(fs);
566 res = FR_MODIFIED;
567 goto EXIT;
568 }
569 } else {
570 if (work[VR_PARTITION + i * VR_ITEMSIZE + VR_Available] != 0x00) {
571 (void)f_unregvirfs(fs);
572 res = FR_MODIFIED;
573 goto EXIT;
574 }
575 break;
576 }
577
578 (void)memset_s(label, sizeof(label), 0, sizeof(label));
579
580 tmp = ld_dword(work + VR_PARTITION + i * VR_ITEMSIZE + VR_Entry + 0);
581 labelTmp = (DWORD *)label;
582 *labelTmp = tmp;
583 tmp = ld_dword(work + VR_PARTITION + i * VR_ITEMSIZE + VR_Entry + 4);
584 *((DWORD * )(label + 4)) = tmp;
585 tmp = ld_dword(work + VR_PARTITION + i * VR_ITEMSIZE + VR_Entry + 8);
586 *((DWORD * )(label + 8)) = tmp;
587 tmp = ld_dword(work + VR_PARTITION + i * VR_ITEMSIZE + VR_Entry + 12);
588 *((DWORD * )(label + 12)) = tmp;
589
590 if (f_checkname(label) != FR_OK) {
591 (void)f_unregvirfs(fs);
592 res = FR_MODIFIED;
593 goto EXIT;
594 }
595 (void)memcpy_s((CHILDFS(fs, i))->namelabel, _MAX_ENTRYLENGTH + 1, label, _MAX_ENTRYLENGTH + 1);
596
597 FatfsSetChildClst(work, fs, i);
598
599 /* External SD setting has overlimit the whole partition cluster amount */
600 if ((QWORD)(CHILDFS(fs, i))->st_clst + (QWORD)((CHILDFS(fs, i))->ct_clst) > (QWORD)fs->n_fatent) {
601 (void)f_unregvirfs(fs);
602 res = FR_MODIFIED;
603 goto EXIT;
604 }
605
606 res = FatfsCheckPartClst(fs, i);
607 if (res != FR_OK) {
608 goto EXIT;
609 }
610 if (i == (work[VR_PartitionCnt] - 1)) {
611 /*
612 * If the external SD virtual partition percent exceeds the error tolerance based on current virtual
613 * partition percent setting
614 */
615 res = FatfsCheckPercent(fs, i);
616 if (res != FR_OK) {
617 goto EXIT;
618 }
619 }
620 }
621EXIT:
622 ff_memfree(work);
623 LEAVE_FF(fs, res);
624}
char CHAR
Definition: los_typedef.h:63
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void
FRESULT f_checkname(const TCHAR *path)
Definition: virpartff.c:98
static FRESULT FatfsCheckPercent(FATFS *fs, WORD i)
Definition: virpartff.c:454
FRESULT f_unregvirfs(FATFS *fs)
Definition: virpartff.c:224
static FRESULT FatfsCheckStart(BYTE *work, FATFS *fs, BYTE vol)
Definition: virpartff.c:415
static FRESULT FatfsCheckPartClst(FATFS *fs, WORD i)
Definition: virpartff.c:470
static void FatfsSetChildClst(BYTE *work, FATFS *fs, WORD i)
Definition: virpartff.c:489
FRESULT f_regvirfs(FATFS *fs)
Definition: virpartff.c:296
函数调用图:
这是这个函数的调用关系图:

◆ f_disvirfs()

FRESULT f_disvirfs ( FATFS *  fs)

在文件 virpartff.c208 行定义.

209{
210 if (ISCHILD(fs)) {
211 return FR_INVAILD_FATFS;
212 }
213
214 if (fs->vir_amount > _MAX_VIRVOLUMES) {
215 return FR_INT_ERR;
216 }
217
218 ENTER_FF(fs);
219
220 (void)f_unregvirfs(fs);
221 LEAVE_FF(fs, FR_OK);
222}
函数调用图:
这是这个函数的调用关系图:

◆ f_getfatfs()

FATFS * f_getfatfs ( int  vol)

在文件 virpartff.c131 行定义.

132{
133 FATFS *fs = NULL;
134 if (vol < 0 || vol >= FF_VOLUMES) {
135 fs = NULL;
136 } else {
137 fs = FatFs[vol];
138 }
139 return fs;
140}
FATFS * FatFs[FF_VOLUMES]

◆ f_getvirfree()

FRESULT f_getvirfree ( const TCHAR *  path,
DWORD *  nclst,
DWORD *  cclst 
)

在文件 virpartff.c767 行定义.

768{
769 FATFS *fs = NULL;
770 FRESULT res;
771 DWORD clst, link;
772 DWORD nfree;
773 UINT i;
774 DIR dj;
775
776 /* Find volume to Update the global FSINFO */
777 res = mount_volume(&path, &fs, 0);
778 if (res != FR_OK) {
779 LEAVE_FF(fs, res);
780 }
781
782 /* Following the entry keyword, decide to replace the PARENT FATFS to CHILD FATFS or not */
783 dj.obj.fs = fs;
784 if (ISVIRPART(fs)) {
785 /* Check the virtual partition top directory, and match the virtual fs */
786 res = follow_virentry(&dj.obj, path);
787 if (res == FR_INT_ERR) {
788 LEAVE_FF(fs, res);
789 }
790 if (res == FR_OK) {
791 fs = dj.obj.fs;
792 }
793 } else {
794 /* Virtual Partition Feature was off, deny this operation */
795 LEAVE_FF(fs, FR_DENIED);
796 }
797
798 /* If current FATFS is a CHILD FATFS */
799 if (ISCHILD(fs)) {
800 /* If CHILD FATFS' free_clst is invaild, the scan the FAT and update it */
801 if (fs->free_clst > fs->ct_clst) {
802 dj.obj.fs = fs;
803 fs->free_clst = fs->ct_clst;
804 for (clst = fs->st_clst; clst < fs->st_clst + fs->ct_clst; clst++) {
805 link = get_fat(&dj.obj, clst);
806 if (link == 0) {
807 continue;
808 }
809 fs->free_clst--;
810 }
811 }
812 *nclst = fs->free_clst;
813 *cclst = fs->ct_clst;
814 LEAVE_FF(fs, FR_OK);
815 } else {
816 nfree = 0;
817 if (fs->ct_clst == 0xFFFFFFFF) {
818 LEAVE_FF(fs, FR_DENIED);
819 }
820 for (i = 0; i < fs->vir_amount; i++) {
821 if (CHILDFS(fs, i)->free_clst > CHILDFS(fs, i)->ct_clst) {
822 dj.obj.fs = CHILDFS(fs, i);
823 CHILDFS(fs, i)->free_clst = CHILDFS(fs, i)->ct_clst;
824 for (clst = CHILDFS(fs, i)->st_clst; clst < CHILDFS(fs, i)->st_clst + CHILDFS(fs, i)->ct_clst; clst++) {
825 link = get_fat(&dj.obj, clst);
826 if (link == 0) {
827 continue;
828 }
829 CHILDFS(fs, i)->free_clst--;
830 }
831 }
832 nfree += CHILDFS(fs, i)->free_clst;
833 }
834 *nclst = fs->free_clst - nfree;
835 *cclst = fs->ct_clst;
836 LEAVE_FF(fs, FR_OK);
837 }
838}
FRESULT follow_virentry(FFOBJID *obj, const TCHAR *path)
Definition: virpartff.c:64
函数调用图:
这是这个函数的调用关系图:

◆ f_makevirpart()

FRESULT f_makevirpart ( FATFS *  fs,
const TCHAR *  path,
BYTE  vol 
)

在文件 virpartff.c668 行定义.

669{
670 FRESULT res;
671 DWORD virSect;
672 DWORD startBaseSect, countBaseSect;
673 DWORD tmp;
674 CHAR label[_MAX_ENTRYLENGTH + 1];
675 DWORD *labelTmp = NULL; /* to clear the compilation warning */
676 UINT i;
677 BYTE pdrv;
678 BYTE *work = NULL;
679 DOUBLE virpartper = 0.0;
680
681 if (fs == NULL || (disk_status(fs->pdrv) & STA_NOINIT)) {
682 return FR_INVAILD_FATFS; /* The object is invalid */
683 }
684
685 /* Lock the filesystem object */
686 res = mount_volume(&path, &fs, FA_WRITE); /* Update the filesystem info to the parent fs */
687 if (res != FR_OK) {
688 LEAVE_FF(fs, res);
689 }
690
691 /* Only available in FAT32 filesystem */
692 if (ISCHILD(fs)) {
693 LEAVE_FF(fs, FR_INVAILD_FATFS);
694 }
695 /* Data will be save at the last reserve sector,which is the front one of the fat base sector */
696 virSect = fs->fatbase - 1;
697 /* Search the fs index, which same as the volume index */
698 pdrv = LD2PD(vol); /* Driver index */
699 countBaseSect = LD2PC(vol); /* Volume Base Sectors Count */
700 startBaseSect = LD2PS(vol); /* Volume Base Start Sector */
701
702 fs->vir_amount = g_fatVirPart.virtualinfo.virpartnum;
703 res = f_regvirfs(fs);
704 if (res != FR_OK) {
705 LEAVE_FF(fs, res);
706 }
707
708 work = (BYTE *)ff_memalloc(SS(fs));
709 if (work == NULL) {
710 LEAVE_FF(fs, FR_NOT_ENOUGH_CORE);
711 }
712 /* Data Cluster is begin from the Cluster #3 to the last cluster */
713 /* Cluster #0 #1 is for VBR, reserve sectors and fat */
714 /* Cluster #2 is for root directory */
715 (void)memset_s(work, SS(fs), 0, SS(fs));
716
717 for (i = 0; i < fs->vir_amount; i++) {
718 /* Copy the Entry label and write to work sector's buffer */
719 (void)memset_s(label, sizeof(label), 0, sizeof(label));
720 (void)memcpy_s(label, _MAX_ENTRYLENGTH + 1, g_fatVirPart.virtualinfo.virpartname[i], _MAX_ENTRYLENGTH + 1);
721 labelTmp = (DWORD *)label;
722 tmp = *labelTmp;
723 st_dword(work + VR_PARTITION + i * VR_ITEMSIZE + VR_Entry + 0, tmp);
724 tmp = *((DWORD * )(label + 4));
725 st_dword(work + VR_PARTITION + i * VR_ITEMSIZE + VR_Entry + 4, tmp);
726 tmp = *((DWORD * )(label + 8));
727 st_dword(work + VR_PARTITION + i * VR_ITEMSIZE + VR_Entry + 8, tmp);
728 tmp = *((DWORD * )(label + 12));
729 st_dword(work + VR_PARTITION + i * VR_ITEMSIZE + VR_Entry + 12, tmp);
730
731 virpartper += g_fatVirPart.virtualinfo.virpartpercent[i];
732
733 (void)memcpy_s((CHILDFS(fs, i))->namelabel, _MAX_ENTRYLENGTH + 1, g_fatVirPart.virtualinfo.virpartname[i],
734 _MAX_ENTRYLENGTH + 1);
735 FatfsClacPartInfo(fs, virpartper, i);
736 (CHILDFS(fs, i))->last_clst = (CHILDFS(fs, i))->st_clst - 1;
737 work[VR_PARTITION + i * VR_ITEMSIZE + VR_Available] = 0x80;
738 }
739
740 /* Set the data to sector */
741 work[VR_PartitionCnt] = fs->vir_amount;
742 work[VR_PartitionFSType] = fs->fs_type;
743 st_dword(work + VR_PartitionStSec, startBaseSect);
744 st_dword(work + VR_PartitionCtSec, countBaseSect);
745 st_word(work + VR_PartitionClstSz, fs->csize);
746 st_dword(work + VR_PartitionCtClst, fs->n_fatent);
747 for (i = 0; i < fs->vir_amount; i++) {
748 st_dword(work + VR_PARTITION + i * VR_ITEMSIZE + VR_StartClust,
749 (CHILDFS(fs, i))->st_clst);
750 st_dword(work + VR_PARTITION + i * VR_ITEMSIZE + VR_CountClust,
751 (CHILDFS(fs, i))->ct_clst);
752 }
753
754 /* ASCII for Keyword "LITE" */
755 st_dword(work + VR_VertifyString, 0x4C495445);
756
757 /* Write into the data area */
758 if (disk_write(pdrv, work, virSect, 1) != RES_OK) {
759 (void)f_unregvirfs(fs);
760 res = FR_DISK_ERR;
761 }
762
763 ff_memfree(work);
764 LEAVE_FF(fs, res);
765}
double DOUBLE
Definition: los_typedef.h:62
static void FatfsClacPartInfo(FATFS *fs, DOUBLE virpartper, UINT i)
Definition: virpartff.c:626
FAT_VIR_PART g_fatVirPart
函数调用图:
这是这个函数的调用关系图:

◆ f_regvirfs()

FRESULT f_regvirfs ( FATFS *  fs)

在文件 virpartff.c296 行定义.

297{
298 UINT i;
299 FATFS *pfs = NULL;
300
301 if (fs == NULL || ISCHILD(fs)) {
302 return FR_INVAILD_FATFS;
303 }
304
305 if (fs->vir_amount > _MAX_VIRVOLUMES) {
306 return FR_INT_ERR;
307 }
308
309 fs->parent_fs = (void *)fs; /* Relink to itself */
310 /* Mark the FATFS object is PARENT */
311 fs->st_clst = 0xFFFFFFFF;
312 fs->ct_clst = 0xFFFFFFFF;
313 /* Allocate a space for linking to the child FATFS */
314 fs->child_fs = (void **)ff_memalloc(fs->vir_amount * sizeof(void *));
315 if (fs->child_fs == NULL) {
316 return FR_NOT_ENOUGH_CORE;
317 }
318 fs->vir_avail = FS_VIRENABLE; /* Mark the PARENT object is enable for now */
319
320 /* Set the CHILD object field */
321 for (i = 0; i < fs->vir_amount; i++) {
322 pfs = ff_memalloc(sizeof(FATFS)); /* Allocate a memeory for current child FATFS object */
323 if (pfs == NULL) { /* If allocate failed, must call 'f_unregvirfs' to free the previous FATFS object memory */
324 goto ERROUT;
325 }
326 FatfsSetParentFs(pfs, fs);
327 *(fs->child_fs + i) = (void *)pfs;
328 }
329
330 return FR_OK;
331ERROUT:
332 while (i > 0) {
333 --i;
334 ff_memfree(*(fs->child_fs + i));
335 }
336 ff_memfree(fs->child_fs);
337 fs->child_fs = NULL;
338
339 return FR_NOT_ENOUGH_CORE;
340}
static void FatfsSetParentFs(FATFS *pfs, FATFS *fs)
Definition: virpartff.c:250
函数调用图:
这是这个函数的调用关系图:

◆ f_scanfat()

FRESULT f_scanfat ( FATFS *  fs)

在文件 virpartff.c383 行定义.

384{
385 FRESULT res;
386 DWORD clst;
387 DWORD link;
388 FFOBJID obj;
389
390 res = FatfsCheckScanFatParam(fs);
391 if (res != FR_OK) {
392 return res;
393 }
394
395 ENTER_FF(fs);
396 res = FR_OK;
397 obj.fs = fs;
398
399 fs->free_clst = fs->ct_clst;
400 for (clst = fs->st_clst; clst < fs->st_clst + fs->ct_clst; clst++) {
401 link = get_fat(&obj, clst);
402 if (link == 0xFFFFFFFF) {
403 LEAVE_FF(fs, FR_DISK_ERR);
404 }
405 if (link == 0) {
406 continue;
407 }
408 fs->free_clst--;
409 }
410 fs->last_clst = fs->st_clst - 1;
411
412 LEAVE_FF(fs, res);
413}
static FRESULT FatfsCheckScanFatParam(FATFS *fs)
Definition: virpartff.c:342
函数调用图:
这是这个函数的调用关系图:

◆ f_unregvirfs()

FRESULT f_unregvirfs ( FATFS *  fs)

在文件 virpartff.c224 行定义.

225{
226 UINT i;
227
228 if (fs == NULL || ISCHILD(fs)) {
229 return FR_INVAILD_FATFS;
230 }
231
232 fs->vir_avail = FS_VIRDISABLE;
233 /* PARENT FATFS has linked to CHILD FATFS already */
234 if (fs->child_fs != NULL) {
235 /* Followed the CHILD FATFS and free the memory */
236 for (i = 0; i < fs->vir_amount; i++) {
237 if (CHILDFS(fs, i) != NULL) {
238 ff_memfree(CHILDFS(fs, i));
239 }
240 }
241 /* Free the 'child_fs' feild */
242 ff_memfree(fs->child_fs);
243 fs->child_fs = NULL;
244 fs->vir_amount = 0xFFFFFFFF;
245 }
246
247 return FR_OK;
248}
这是这个函数的调用关系图:

◆ follow_virentry()

FRESULT follow_virentry ( FFOBJID *  obj,
const TCHAR *  path 
)

在文件 virpartff.c64 行定义.

65{
66 TCHAR keyword[FF_MAX_LFN + 1] = {0};
67 FATFS *fs = obj->fs;
68 INT len;
69 UINT i;
70
71 (void)memset_s(keyword, sizeof(keyword), 0, sizeof(keyword));
72 /* Search and copy the first segment in path */
73 for (len = 0; *path != '/' && *path != '\\' && *path != '\0' && len < FF_MAX_LFN; path++, len++) {
74 keyword[len] = *path;
75 }
76
77 if (len == 0 || len > _MAX_ENTRYLENGTH) {
78 return FR_DENIED;
79 }
80
81 /*
82 * Compare the segment does match one for virtual partitions' entry or not,
83 * replace the FATFS if the result is positive
84 */
85 for (i = 0; i < fs->vir_amount; i++) {
86 if (!CHILDFS(fs, i)) {
87 return FR_INT_ERR;
88 }
89 if (memcmp((CHILDFS(fs, i))->namelabel, keyword, _MAX_ENTRYLENGTH + 1) == 0) {
90 obj->fs = CHILDFS(fs, i);
91 return FR_OK;
92 }
93 }
94
95 return FR_DENIED;
96}
int memcmp(const void *str1, const void *str2, size_t n)
Definition: memcmp.c:37
函数调用图:
这是这个函数的调用关系图:

变量说明

◆ g_fatVirPart

FAT_VIR_PART g_fatVirPart
extern