xref: /nrf52832-nimble/rt-thread/components/dfs/filesystems/uffs/src/inc/uffs/uffs_public.h (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2   This file is part of UFFS, the Ultra-low-cost Flash File System.
3 
4   Copyright (C) 2005-2009 Ricky Zheng <[email protected]>
5 
6   UFFS is free software; you can redistribute it and/or modify it under
7   the GNU Library General Public License as published by the Free Software
8   Foundation; either version 2 of the License, or (at your option) any
9   later version.
10 
11   UFFS is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   or GNU Library General Public License, as applicable, for more details.
15 
16   You should have received a copy of the GNU General Public License
17   and GNU Library General Public License along with UFFS; if not, write
18   to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19   Boston, MA  02110-1301, USA.
20 
21   As a special exception, if other files instantiate templates or use
22   macros or inline functions from this file, or you compile this file
23   and link it with other works to produce a work based on this file,
24   this file does not by itself cause the resulting work to be covered
25   by the GNU General Public License. However the source code for this
26   file must still be made available in accordance with section (3) of
27   the GNU General Public License v2.
28 
29   This exception does not invalidate any other reasons why a work based
30   on this file might be covered by the GNU General Public License.
31 */
32 
33 /**
34  * \file uffs_public.h
35  * \brief public data structures for uffs
36  * \author Ricky Zheng
37  */
38 
39 #ifndef _UFFS_PUBLIC_H_
40 #define _UFFS_PUBLIC_H_
41 
42 #include "uffs/uffs_types.h"
43 #include "uffs/uffs_core.h"
44 #include "uffs/uffs.h"
45 #include "uffs/uffs_pool.h"
46 
47 #ifdef __cplusplus
48 extern "C"{
49 #endif
50 
51 #ifndef ARRAY_SIZE
52 # define ARRAY_SIZE(ar) (sizeof(ar) / sizeof(ar[0]))
53 #endif
54 
55 #ifndef offsetof
56 # define offsetof(T, x) ((size_t) &((T *)0)->x)
57 #endif
58 #ifndef container_of
59 #define container_of(p, T, x) ((T *)((char *)(p) - offsetof(T,x)))
60 #endif
61 
62 /**
63  * \def MAX_FILENAME_LENGTH
64  * \note Be careful: it's part of the physical format (see: uffs_FileInfoSt.name)
65  *    !!DO NOT CHANGE IT AFTER FILE SYSTEM IS FORMATED!!
66  */
67 #define MAX_FILENAME_LENGTH         128
68 
69 /** \note 8-bits attr goes to uffs_dirent::d_type */
70 #define FILE_ATTR_DIR       (1 << 7)    //!< attribute for directory
71 #define FILE_ATTR_WRITE     (1 << 0)    //!< writable
72 
73 
74 /**
75  * \structure uffs_FileInfoSt
76  * \brief file/dir entry info in physical storage format
77  */
78 struct uffs_FileInfoSt {
79     u32 attr;               //!< file/dir attribute
80     u32 create_time;
81     u32 last_modify;
82     u32 access;
83     u32 reserved;
84     u32 name_len;           //!< length of file/dir name
85     char name[MAX_FILENAME_LENGTH];
86 }; //6*4 + sizeof(name) = 24 + 128 = 152 Bytes
87 typedef struct uffs_FileInfoSt uffs_FileInfo;
88 
89 /**
90  * \struct uffs_ObjectInfoSt
91  * \brief object info
92  */
93 typedef struct uffs_ObjectInfoSt {
94     uffs_FileInfo info;
95     u32 len;                //!< length of file
96     u16 serial;             //!< object serial num
97 } uffs_ObjectInfo;
98 
99 
100 /**
101  * \struct uffs_TagStoreSt
102  * \brief uffs tag, 8 bytes, will be store in page spare area.
103  */
104 struct uffs_TagStoreSt {
105 	u32 dirty:1;		//!< 0: dirty, 1: clear
106 	u32 valid:1;		//!< 0: valid, 1: invalid
107 	u32 type:2;			//!< block type: #UFFS_TYPE_DIR, #UFFS_TYPE_FILE, #UFFS_TYPE_DATA
108 	u32 block_ts:2;		//!< time stamp of block;
109 	u32 data_len:12;	//!< length of page data
110 	u32 serial:14;		//!< serial number
111 
112 	u32 parent:10;		//!< parent's serial number
113 	u32 page_id:6;		//!< page id
114 	u32 reserved:4;		//!< reserved, for UFFS2
115 	u32 tag_ecc:12;		//!< tag ECC
116 };
117 
118 #define TAG_ECC_DEFAULT (0xFFF)	//!< 12-bit '1'
119 
120 
121 /**
122  * \struct uffs_TagsSt
123  */
124 struct uffs_TagsSt {
125 	struct uffs_TagStoreSt s;		/* store must be the first member */
126 
127 	/** data_sum for file or dir name */
128 	u16 data_sum;
129 
130 	/** internal used */
131 	u8 seal_byte;			//!< seal byte.
132 };
133 
134 /**
135  * \struct uffs_MiniHeaderSt
136  * \brief the mini header resides on the head of page data
137  */
138 struct uffs_MiniHeaderSt {
139 	u8 status;
140 	u8 reserved;
141 	u16 crc;
142 };
143 
144 
145 /** uffs_TagsSt.dirty */
146 #define TAG_VALID		0
147 #define TAG_INVALID		1
148 
149 /** uffs_TagsSt.valid */
150 #define TAG_DIRTY		0
151 #define TAG_CLEAR		1
152 
153 #define TAG_IS_DIRTY(tag) (*((u32 *) &((tag)->s)) != 0xFFFFFFFF)	// tag is dirty if first 4 bytes not all 0xFF
154 #define TAG_IS_VALID(tag) ((tag)->s.valid == TAG_VALID)
155 #define TAG_IS_SEALED(tag) ((tag)->seal_byte != 0xFF)
156 
157 #define TAG_IS_GOOD(tag) (TAG_IS_SEALED(tag) && TAG_IS_VALID(tag))
158 
159 #define TAG_VALID_BIT(tag) (tag)->s.valid
160 #define TAG_DIRTY_BIT(tag) (tag)->s.dirty
161 #define TAG_SERIAL(tag) (tag)->s.serial
162 #define TAG_PARENT(tag) (tag)->s.parent
163 #define TAG_PAGE_ID(tag) (tag)->s.page_id
164 #define TAG_DATA_LEN(tag) (tag)->s.data_len
165 #define TAG_TYPE(tag) (tag)->s.type
166 #define TAG_BLOCK_TS(tag) (tag)->s.block_ts
167 #define SEAL_TAG(tag) (tag)->seal_byte = 0
168 
169 int uffs_GetFirstBlockTimeStamp(void);
170 int uffs_GetNextBlockTimeStamp(int prev);
171 UBOOL uffs_IsSrcNewerThanObj(int src, int obj);
172 
173 
174 #include "uffs_device.h"
175 
176 
177 
178 /********************************** debug & error *************************************/
179 #define UFFS_MSG_NOISY		-1
180 #define UFFS_MSG_NORMAL		0
181 #define UFFS_MSG_SERIOUS	1
182 #define UFFS_MSG_DEAD		2
183 #define UFFS_MSG_NOMSG		100
184 
185 #define TENDSTR "\n"
186 
187 #if !defined(RT_THREAD)
188 struct uffs_DebugMsgOutputSt;
189 URET uffs_InitDebugMessageOutput(struct uffs_DebugMsgOutputSt *ops, int msg_level);
190 void uffs_DebugSetMessageLevel(int msg_level);
191 
192 void uffs_DebugMessage(int level, const char *prefix, const char *suffix, const char *errFmt, ...);
193 void uffs_AssertCall(const char *file, int line, const char *msg, ...);
194 #else
195 
196 #define UFFS_DBG_LEVEL  UFFS_MSG_NORMAL
197 
198 #ifdef CONFIG_ENABLE_UFFS_DEBUG_MSG
199 #define uffs_DebugMessage(level, prefix, suffix, errFmt, ...) do { \
200 	if (level >= UFFS_DBG_LEVEL) \
201 		rt_kprintf(prefix errFmt suffix, ##__VA_ARGS__); \
202 } while(0)
203 
204 #define uffs_AssertCall(file, line, msg, ...) \
205 	rt_kprintf("ASSERT %s:%d - :" msg "\n", (const char *)file, (int)line, ##__VA_ARGS__)
206 #else
207 #define uffs_DebugMessage(level, prefix, suffix, errFmt, ...)
208 #define uffs_AssertCall(file, line, msg, ...)
209 #endif //CONFIG_ENABLE_UFFS_DEBUG_MSG
210 #endif //RT_THREAD
211 
212 #ifdef _COMPILER_DO_NOT_SUPPORT_MACRO_VALIST_REPLACE_
213 /* For those compilers do not support valist parameter replace in macro define */
214 void uffs_Perror(int level, const char *fmt, ...);
215 void uffs_PerrorRaw(int level, const char *fmt, ...);
216 UBOOL uffs_Assert(UBOOL expr, const char *fmt, ...);
217 #else
218 
219 #if !defined(RT_THREAD)
220 #define uffs_Perror(level, fmt, ... ) \
221 	uffs_DebugMessage(level, PFX, TENDSTR, fmt, ## __VA_ARGS__)
222 
223 #define uffs_PerrorRaw(level, fmt, ... ) \
224 	uffs_DebugMessage(level, NULL, NULL, fmt, ## __VA_ARGS__)
225 
226 #else
227 
228 #ifdef CONFIG_ENABLE_UFFS_DEBUG_MSG
229 
230 #define uffs_Perror(level, fmt, ... ) do{\
231 	if (level >= UFFS_DBG_LEVEL) \
232 		rt_kprintf(PFX fmt TENDSTR, ##__VA_ARGS__); \
233 } while(0)
234 
235 #define uffs_PerrorRaw(level, fmt, ... ) do{\
236 	if (level >= UFFS_DBG_LEVEL) \
237 		rt_kprintf(fmt, ##__VA_ARGS__); \
238 } while(0)
239 #else
240 #define uffs_Perror(level, fmt, ... )
241 #define uffs_PerrorRaw(level, fmt, ... )
242 #endif // CONFIG_ENABLE_UFFS_DEBUG_MSG
243 #endif // RT_THREAD
244 
245 #define uffs_Assert(expr, msg, ...) \
246 	((expr) ? U_TRUE : (uffs_AssertCall(__FILE__, __LINE__, msg, ## __VA_ARGS__), U_FALSE))
247 
248 #endif //_COMPILER_DO_NOT_SUPPORT_MACRO_VALIST_REPLACE_
249 
250 #define uffs_Panic() \
251 	do { \
252 		uffs_AssertCall(__FILE__, __LINE__, "Bam !!\n"); \
253 		while(1); \
254 	} while(0)
255 
256 /********************************** NAND **********************************************/
257 //NAND flash specific file must implement these interface
258 URET uffs_LoadPageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag);
259 URET uffs_WritePageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag);
260 URET uffs_MakePageValid(uffs_Device *dev, int block, int page, uffs_Tags *tag);
261 UBOOL uffs_IsBlockBad(uffs_Device *dev, uffs_BlockInfo *bc);
262 
263 /********************************** Public defines *****************************/
264 /**
265  * \def UFFS_ALL_PAGES
266  * \brief UFFS_ALL_PAGES if this value presented, that means the objects are all pages in the block
267  */
268 #define UFFS_ALL_PAGES (0xffff)
269 
270 /**
271  * \def UFFS_INVALID_PAGE
272  * \brief macro for invalid page number
273  */
274 #define UFFS_INVALID_PAGE	(0xfffe)
275 
276 /**
277  * \def UFFS_INVALID_BLOCK
278  * \brief macro for invalid block number
279  */
280 #define UFFS_INVALID_BLOCK	(0xfffe)
281 
282 
283 URET uffs_NewBlock(uffs_Device *dev, u16 block, uffs_Tags *tag, uffs_Buf *buf);
284 URET uffs_BlockRecover(uffs_Device *dev, uffs_BlockInfo *old, u16 newBlock);
285 URET uffs_PageRecover(uffs_Device *dev,
286 					  uffs_BlockInfo *bc,
287 					  u16 oldPage,
288 					  u16 newPage,
289 					  uffs_Buf *buf);
290 int uffs_FindFreePageInBlock(uffs_Device *dev, uffs_BlockInfo *bc);
291 u16 uffs_FindBestPageInBlock(uffs_Device *dev, uffs_BlockInfo *bc, u16 page);
292 u16 uffs_FindFirstFreePage(uffs_Device *dev, uffs_BlockInfo *bc, u16 pageFrom);
293 u16 uffs_FindPageInBlockWithPageId(uffs_Device *dev, uffs_BlockInfo *bc, u16 page_id);
294 
295 u8 uffs_MakeSum8(const void *p, int len);
296 u16 uffs_MakeSum16(const void *p, int len);
297 URET uffs_CreateNewFile(uffs_Device *dev, u16 parent, u16 serial, uffs_BlockInfo *bc, uffs_FileInfo *fi);
298 
299 int uffs_GetBlockFileDataLength(uffs_Device *dev, uffs_BlockInfo *bc, u8 type);
300 UBOOL uffs_IsPageErased(uffs_Device *dev, uffs_BlockInfo *bc, u16 page);
301 int uffs_GetFreePagesCount(uffs_Device *dev, uffs_BlockInfo *bc);
302 UBOOL uffs_IsDataBlockReguFull(uffs_Device *dev, uffs_BlockInfo *bc);
303 UBOOL uffs_IsThisBlockUsed(uffs_Device *dev, uffs_BlockInfo *bc);
304 
305 int uffs_GetBlockTimeStamp(uffs_Device *dev, uffs_BlockInfo *bc);
306 
307 int uffs_GetDeviceUsed(uffs_Device *dev);
308 int uffs_GetDeviceFree(uffs_Device *dev);
309 int uffs_GetDeviceTotal(uffs_Device *dev);
310 
311 URET uffs_LoadMiniHeader(uffs_Device *dev, int block, u16 page, struct uffs_MiniHeaderSt *header);
312 
313 
314 /* some functions from uffs_fd.c */
315 void uffs_FdSignatureIncrease(void);
316 URET uffs_DirEntryBufInit(void);
317 URET uffs_DirEntryBufRelease(void);
318 uffs_Pool * uffs_DirEntryBufGetPool(void);
319 int uffs_DirEntryBufPutAll(uffs_Device *dev);
320 
321 
322 /************************************************************************/
323 /*  init functions                                                                     */
324 /************************************************************************/
325 URET uffs_InitDevice(uffs_Device *dev);
326 URET uffs_ReleaseDevice(uffs_Device *dev);
327 
328 URET uffs_InitFileSystemObjects(void);
329 URET uffs_ReleaseFileSystemObjects(void);
330 
331 
332 #ifdef __cplusplus
333 }
334 #endif
335 #endif	// _UFFS_PUBLIC_H_
336 
337