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