• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "prt_fs.h"
32 #include "prt_sem.h"
33 #include "pthread.h"
34 
35 struct fs_cfg {
36     char *mount_point;
37     struct PartitionCfg partCfg;
38 };
39 
PRT_CurTaskIDGet()40 U32 PRT_CurTaskIDGet()
41 {
42     return 0; /* 0, return success */
43 }
44 
pthread_mutex_lock(pthread_mutex_t * mutex)45 int pthread_mutex_lock(pthread_mutex_t *mutex)
46 {
47     return 0; /* 0, return success */
48 }
49 
pthread_mutex_unlock(pthread_mutex_t * mutex)50 int pthread_mutex_unlock(pthread_mutex_t *mutex)
51 {
52     return 0; /* 0, return success */
53 }
54 
55 #define FLASH_PARTITION_DATA0       0
56 
57 typedef struct {
58     const char *partitionDescription;
59     U32 partitionStartAddr;
60     U32 partitionLength;
61     U32 partitionOptions;
62 } HalLogicPartition;
63 
64 HalLogicPartition g_halPartitions[] = {
65     [FLASH_PARTITION_DATA0] = {
66         .partitionDescription = "littlefs",
67         .partitionStartAddr = 0,
68         .partitionLength = 0x800000, // size is 8M
69     },
70 };
71 
72 #define FLASH_SECTOR_SIZE   512
73 
VirtFlashErase(int pdrv,U32 offSet,U32 size)74 S32 VirtFlashErase(int pdrv, U32 offSet, U32 size)
75 {
76     U32 startAddr = offSet;
77     U32 partitionEnd;
78 
79     partitionEnd = g_halPartitions[pdrv].partitionStartAddr + g_halPartitions[pdrv].partitionLength;
80     if (startAddr >= partitionEnd) {
81         printf("flash over erase, 0x%x, 0x%x\r\n", startAddr, partitionEnd);
82         printf("flash over write\r\n");
83         return -1; /* -1, return failure */
84     }
85     if ((startAddr + size) > partitionEnd) {
86         printf("flash over write, new len is %d\r\n", size);
87         return -1; /* -1, return failure */
88     }
89 
90     int count = size / FLASH_SECTOR_SIZE;
91     U32 p = offSet;
92 
93     for (int i = 0; i < count; i++) {
94         W25qxxEraseSector(p);
95         p += FLASH_SECTOR_SIZE;
96     }
97 
98     return 0; /* 0, return success */
99 }
100 
VirtFlashWrite(int pdrv,U32 offSet,const void * buf,U32 bufLen)101 S32 VirtFlashWrite(int pdrv, U32 offSet, const void *buf, U32 bufLen)
102 {
103     U32 startAddr = offSet;
104     U32 partitionEnd;
105 
106     partitionEnd = g_halPartitions[pdrv].partitionStartAddr + g_halPartitions[pdrv].partitionLength;
107     if (startAddr >= partitionEnd) {
108         printf("flash over write, 0x%x, 0x%x\r\n", startAddr, partitionEnd);
109         return -1; /* -1, return failure */
110     }
111     if ((startAddr + bufLen) > partitionEnd) {
112         printf("flash over write, new len is %d\r\n", bufLen);
113         return -1; /* -1, return failure */
114     }
115 
116     W25qxxWrite(buf, startAddr, bufLen);
117 
118     return 0; /* -1, return success */
119 }
120 
VirtFlashRead(int pdrv,U32 offSet,void * buf,U32 bufLen)121 S32 VirtFlashRead(int pdrv, U32 offSet, void *buf, U32 bufLen)
122 {
123     U32 startAddr = offSet;
124     U32 partitionEnd;
125 
126     partitionEnd = g_halPartitions[pdrv].partitionStartAddr + g_halPartitions[pdrv].partitionLength;
127     if (startAddr >= partitionEnd) {
128         printf("flash over read, 0x%x, 0x%x\r\n", startAddr, partitionEnd);
129         return -1; /* -1, return failure */
130     }
131     if ((startAddr + bufLen) > partitionEnd) {
132         printf("flash over read, new len is %d\r\n", bufLen);
133         return -1; /* -1, return failure */
134     }
135 
136     W25qxxRead(buf, startAddr, bufLen);
137     return 0; /* -1, return success */
138 }
139 
LfsLowLevelInit(void)140 static S32 LfsLowLevelInit(void)
141 {
142     S32 ret;
143     struct fs_cfg fs[OS_LFS_MAX_MOUNT_SIZE] = {0};
144 
145     S32 lengthArray = g_halPartitions[FLASH_PARTITION_DATA0].partitionLength;
146     S32 addrArray = g_halPartitions[FLASH_PARTITION_DATA0].partitionStartAddr;
147     ret = PRT_DiskPartition("flash0", "littlefs", &lengthArray, &addrArray, 1);
148     printf("%s: DiskPartition %s\n", __func__, (ret == 0) ? "succeed" : "failed");
149     if (ret != 0) {
150         return -1; /* -1, return failure */
151     }
152 
153     fs[0].mount_point = "/data";
154     fs[0].partCfg.partNo = FLASH_PARTITION_DATA0;
155     fs[0].partCfg.blockSize = 4096; /* 4096, lfs block size */
156     fs[0].partCfg.blockCount = 2048; /* 2048, lfs block count */
157     fs[0].partCfg.readFunc = VirtFlashRead;
158     fs[0].partCfg.writeFunc = VirtFlashWrite;
159     fs[0].partCfg.eraseFunc = VirtFlashErase;
160 
161     fs[0].partCfg.readSize = 256; /* 256, lfs read size */
162     fs[0].partCfg.writeSize = 256; /* 256, lfs prog size */
163     fs[0].partCfg.cacheSize = 256; /* 256, lfs cache size */
164     fs[0].partCfg.lookaheadSize = 16; /* 16, lfs lookahead size */
165     fs[0].partCfg.blockCycles = 1000; /* 1000, lfs block cycles */
166 
167     ret = PRT_PartitionFormat("flash0", "littlefs", &fs[0].partCfg);
168     printf("%s: PartitionFormat %s\n", __func__, (ret == 0) ? "succeed" : "failed");
169     if (ret != 0) {
170         return -1; /* -1, return failure */
171     }
172 
173     ret = mount(NULL, fs[0].mount_point, "littlefs", 0, &fs[0].partCfg);
174     printf("%s: mount fs on '%s' %s\n", __func__, fs[0].mount_point, (ret == 0) ? "succeed" : "failed");
175     if (ret != 0) {
176         return -1; /* -1, return failure */
177     }
178 
179     ret = mkdir(fs[0].mount_point, 0777); /* 0777, set dir permissions */
180     printf("%s: mkdir '%s' %s\n", __func__, fs[0].mount_point, (ret == 0) ? "succeed" : "failed");
181     if (ret != 0) {
182         return -1; /* -1, return failure */
183     }
184 
185 #if (defined(OSCFG_TEST))
186     LfsTest();
187 #endif
188     return 0; /* -1, return success */
189 }
190 
FsInit(void)191 int FsInit(void)
192 {
193     W25qxxInit();
194 
195     S32 ret = PRT_VfsInit();
196     if (ret < 0) {
197         printf("VfsInit failed!\n");
198         return ret;
199     }
200 
201     return LfsLowLevelInit();
202 }
203