⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uffs_public.c

📁 nandflash文件系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
// * \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 + -