📄 uffs_public.c
字号:
// * \param[in] newPage new page number
// * \param[in] buf new page data buffer
// * \note the new data and length should be set to buf before this function invoked
// */
//URET uffs_PageRecover(uffs_Device *dev,
// uffs_blockInfo *bc,
// int oldPage,
// int newPage,
// uffs_Buf *buf)
//{
// uffs_Tags *oldTag, *newTag;
// uffs_pageSpare *newSpare;
//
// if(newPage < 0 || newPage >= dev->attr->pages_per_block) {
// uffs_Perror(UFFS_ERR_SERIOUS, PFX "new page number outof range!\n");
// return U_FAIL;
// }
//
// uffs_LoadBlockInfo(dev, bc, oldPage);
// uffs_LoadBlockInfo(dev, bc, newPage);
//
// oldTag = &(bc->spares[oldPage].tag);
// newTag = &(bc->spares[newPage].tag);
//
// newSpare = &(bc->spares[newPage]);
//
// newSpare->expired = 1; // make it expired firstly
//
// newTag->fdn = oldTag->fdn;
// newTag->blockTimeStamp = oldTag->blockTimeStamp;
// newTag->fsn = oldTag->fsn;
// newTag->pageID = oldTag->pageID;
// newTag->dirty = 0;
// newTag->dataLength = buf->dataLen;
// newTag->checkSum = 0xff; //set check sum with 0xff first.
// newTag->valid = 1;
//
// uffs_WriteDataToNewPage(dev, bc->blockNum, newPage, newTag, buf);
//
// return U_SUCC;
//}
/**
* calculate sum of data, 8bit version
* \param[in] p data pointer
* \param[in] len length of data
* \return return sum of data, 8bit
*/
u8 uffs_MakeSum8(void *p, int len)
{
u8 ret = 0;
u8 *data = (u8 *)p;
if (!p) return 0;
while(len > 0) {
ret += *data++;
len--;
}
return ret;
}
/**
* calculate sum of datam, 16bit version
* \param[in] p data pointer
* \param[in] len length of data
* \return return sum of data, 16bit
*/
u16 uffs_MakeSum16(void *p, int len)
{
u8 ret_lo = 0;
u8 ret_hi = 0;
u8 *data = (u8 *)p;
if (!p) return 0;
while(len > 0) {
ret_lo += *data;
ret_hi ^= *data;
data++;
len--;
}
return (ret_hi << 8) | ret_lo;
}
/**
* create a new file on a free block
* \param[in] dev uffs device
* \param[in] father father dir serial num
* \param[in] serial serial num of this new file
* \param[in] bc block information
* \param[in] fi file information
* \note father, serial, bc must be provided before, and all information in fi should be filled well before.
*/
URET uffs_CreateNewFile(uffs_Device *dev, u16 father, u16 serial, uffs_blockInfo *bc, uffs_fileInfo *fi)
{
uffs_Tags *tag;
uffs_Buf *buf;
fi->createTime = fi->lastModify = uffs_GetCurDateTime();
uffs_LoadBlockInfo(dev, bc, 0);
tag = &(bc->spares[0].tag);
tag->father = father;
tag->serial = serial;
tag->dataLength = sizeof(uffs_fileInfo);
tag->dataSum = uffs_MakeSum16(fi->name, fi->name_len);
buf = uffs_BufGet(dev, father, serial, 0);
if(buf == NULL) {
uffs_Perror(UFFS_ERR_SERIOUS, PFX"get buf fail.\n");
return U_FAIL;
}
memcpy(buf->data, fi, tag->dataLength);
buf->dataLen = tag->dataLength;
return uffs_BufPut(dev, buf);
}
/**
* \brief calculate data length of a file block
* \param[in] dev uffs device
* \param[in] bc block info
*/
int uffs_GetBlockFileDataLength(uffs_Device *dev, uffs_blockInfo *bc, u8 type)
{
u16 pageID;
u16 i;
uffs_Tags *tag;
int size = 0;
u16 page;
u16 lastPage = dev->attr->pages_per_block - 1;
//@ Need to speed up this procedure!
uffs_LoadBlockInfo(dev, bc, lastPage);
tag = &(bc->spares[lastPage].tag);
if(type == UFFS_TYPE_FILE) {
if(tag->pageID == (lastPage - 1) &&
tag->dataLength == dev->com.pgDataSize) {
size = dev->com.pgDataSize * (dev->attr->pages_per_block - 1);
return size;
}
}
if(type == UFFS_TYPE_DATA) {
if(tag->pageID == lastPage &&
tag->dataLength == dev->com.pgDataSize) {
size = dev->com.pgDataSize * dev->attr->pages_per_block;
return size;
}
}
//normal procedure....
uffs_LoadBlockInfo(dev, bc, UFFS_ALL_PAGES);
tag = &(bc->spares[0].tag);
if(tag->type == UFFS_TYPE_FILE) {
pageID = 1; //In file header block, file data pageID from 1
i = 1; //search from page 1
}
else {
pageID = 0; //in normal file data block, pageID from 0
i = 0; //in normal file data block, search from page 0
}
for(; i < dev->attr->pages_per_block; i++) {
tag = &(bc->spares[i].tag);
if(pageID == tag->pageID) {
page = uffs_FindBestPageInBlock(dev, bc, i);
size += bc->spares[page].tag.dataLength;
pageID++;
}
}
return size;
}
/**
* get free pages number
* \param[in] dev uffs device
* \param[in] bc block info
*/
int uffs_GetFreePagesCount(uffs_Device *dev, uffs_blockInfo *bc)
{
int count = 0;
int i;
for(i = dev->attr->pages_per_block - 1; i >= 0; i--) {
uffs_LoadBlockInfo(dev, bc, i);
if(uffs_IsPageErased(dev, bc, (u16)i) == U_TRUE) {
count++;
}
else break;
}
return count;
}
/**
* \brief Is the block erased ?
* \param[in] dev uffs device
* \param[in] bc block info
* \param[in] page page number to be check
* \retval U_TRUE block is erased, ready to use
* \retval U_FALSE block is dirty, maybe use by file
*/
UBOOL uffs_IsPageErased(uffs_Device *dev, uffs_blockInfo *bc, u16 page)
{
uffs_Tags *tag;
uffs_LoadBlockInfo(dev, bc, page);
tag = &(bc->spares[page].tag);
if(tag->dirty == TAG_CLEAR &&
tag->valid == TAG_INVALID
#if defined(ENABLE_TAG_CHECKSUM) && ENABLE_TAG_CHECKSUM == 1
&& tag->checkSum == 0xff
#endif
) {
return U_TRUE;
}
return U_FALSE;
}
/**
* \brief Is this block the last block of file ? (no free pages, and full filled with full pageID)
*/
UBOOL uffs_IsDataBlockReguFull(uffs_Device *dev, uffs_blockInfo *bc)
{
uffs_LoadBlockInfo(dev, bc, dev->attr->pages_per_block - 1);
if(bc->spares[dev->attr->pages_per_block - 1].tag.pageID == (dev->attr->pages_per_block - 1) &&
bc->spares[dev->attr->pages_per_block - 1].tag.dataLength == dev->com.pgDataSize) {
return U_TRUE;
}
return U_FALSE;
}
/**
* get partition used (bytes)
*/
int uffs_GetDeviceUsed(uffs_Device *dev)
{
return (dev->par.end - dev->par.start + 1 - dev->tree.badCount
- dev->tree.erasedCount) * dev->attr->block_data_size;
}
/**
* get partition free (bytes)
*/
int uffs_GetDeviceFree(uffs_Device *dev)
{
return dev->tree.erasedCount * dev->attr->block_data_size;
}
/**
* get partition total size (bytes)
*/
int uffs_GetDeviceTotal(uffs_Device *dev)
{
return (dev->par.end - dev->par.start + 1) * dev->attr->block_data_size;
}
/** \brief transfer the standard uffs_Tags to uffs_Tags_8
* \param[in] tag standard uffs_Tags
* \param[out] tag_8 small tag to fit into 8 bytes spare space
*/
void uffs_TransferToTag8(uffs_Tags *tag, uffs_Tags_8 *tag_8)
{
tag_8->dirty = tag->dirty;
tag_8->valid = tag->valid;
tag_8->type = tag->type;
tag_8->blockTimeStamp = tag->blockTimeStamp;
tag_8->pageID = tag->pageID;
tag_8->father = tag->father & 0xFF;
tag_8->serial = tag->serial & 0xFF;
tag_8->dataLength = tag->dataLength & 0xFF;
tag_8->dataSum = tag->dataSum;
tag_8->blockStatus = tag->blockStatus;
}
/** \brief transfer the small uffs_Tags_8 to standard uffs_Tags
* \param[out] tag standard uffs_Tags
* \param[in] tag_8 small tag to fit into 8 bytes spare space
*/
void uffs_TransferFromTag8(uffs_Tags *tag, uffs_Tags_8 *tag_8)
{
tag->dirty = tag_8->dirty;
tag->valid = tag_8->valid;
tag->type = tag_8->type;
tag->blockTimeStamp = tag_8->blockTimeStamp;
tag->pageID = tag_8->pageID;
tag->father = tag_8->father;
tag->serial = tag_8->serial;
tag->dataLength = tag_8->dataLength;
tag->dataSum = tag_8->dataSum;
tag->blockStatus = tag_8->blockStatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -