新博客:http://sparkandshine.net/
分类: 嵌入式
2012-01-07 16:52:30
摘要:
本文重在讲述file和file_header的联系与区别,首先分别分析了file与file_header结构体,而后介绍两者的联系,最后分析几组易混的成员变量,包括page与log_page、file与file_header的flags、deprecated_eof_hint与end、record_count与log_records。
一、file
结构体file源码如下:
end
指向存放文件的最后一个字节的偏移量,当打开一个文件时,Coffee用蛮力法找到文件末尾(file_header是不存储文件末尾的位置,因为文件长度经常改变)。详情见博文《Contiki学习笔记:Coffee文件系统打开文件cfs_open》。
page
指向物理文件的第一页,即存放文件元数据file_header的页。通常的用法如下:
max_pages
max_pages含义跟file_header->max_pages相同,即为该文件保留的页面数,加载文件load_file函数将file_headermax_pages赋给file的max_pages。
record_count
record_count表示实际的微日志记录数量,不同于file_header的log_records。
references
Contiki提供类多线程编程环境,会有这样的情况,多个线程同时打开一个文件,需要记录引用次数。打开文件cfs_open引用次数++,关闭文件cfs_close引用次数--。
flags
flags两种取值:0和COFFEE_FILE_MODIFIED,即标识该文件是否含有微日志文件。详情见博文《Contiki学习笔记:Coffee文件系统flags标志位》。
注1:
这里用了个小技巧,使得程度更具移植性。因为在cfs-coffee.arch.h,coffee_page_t有可能是8位,也有可能是16位,源码如下:
把INVALID_PAGE定义为coffee_page_t-1,如果coffee_page_t是8位,那么INVALID_PAGE为0xFF,如果coffee_page_t是16位,那么INVALID_PAGE为0xFFFF,可以自适应coffee_page_t类型的变化,更具移植性。关于这个技巧可参见博文《具有可移植的无穷大定义》。
二、file_header
结构体file_header源码如下:
log_page
不同于file->page,log_page指向微日志的第一页(如果配置了微日志)。
log_records
表示日志可以容纳的记录数量(log records denotes the number of records that the log can hold)
log_record_size
log_record_size表示微日志文件大小,如果为0,则设置成默认值(见cfs-coffee-arch.h文件配置#define COFFEE_LOG_SIZE 128)。
max_pages
max_pages指为文件保留着页面数(The max pages field specifies the amount of pages that have been reserved for the file)
deprecated_eof_hint
因为文件头不能存储文件长度(缘于文件长度经常变化着),所以用deprecated_eof_hint指向文件的最后一个字节。文件关闭时,如果文件长度增加则需更新deprecated_eof_hint。事实上,纵观源码,deprecated_eof_hint都没用到,而是用file->end存储文件末尾的位置(打开文件时,用蛮力法扫描得到该文件的末尾位置)。
flags
flags反映了文件当前状态(The flag field tells us the current state),用了6个位,分别是ALOMIV,详情请见博文《Contiki学习笔记:Coffee文件系统flags标志位》。
name
文件名,其中文件长度COFFEE_NAME_LENGTH可配置,在contiki/cpu/平台(如arm/stm32f103)/cfs-coffee-arch.h。
三、file与file_header联系
3.1 联系
file_header存放物理文件的元数据(即描述该物理文件),而file可以理解成物理文件元数据的内存表示,但又不是完全缓存,因为file与file_header成员变量差别甚大。为了提高性能,Contiki具体是这样做的:所有打开的文件都通过文件描述符fd(非负整数,类似于Linux)引用,将file_desc组织成一个数组file_desc coffee_fd_set[COFFEE_FD_SET_SIZE],每个fd对应于一个file_desc(以数组下标的形式),每个file_desc对应于一个file。通过数组file_desc coffee_fd_set[COFFEE_FD_SET_SIZE]下标(即文件描述符fd)就可以访问file,而file存储物理文件的一些信息,这样也就可以访问物理文件了。
3.2 page与log_page
file_page是指向物理文件的第一页,即存放文件元数据file_header的页。而file_header->log_pages指向微日志的第一页(如果配置了微日志)。
3.3 file与file_header的flags
file_header->flags记录的是整个物理文件的相关信息(即元数据),而file->flags只用来标识文件是否有微日志存在。详情请见博文《Contiki学习笔记:Coffee文件系统flags标志位》。
3.4 deprecated_eof_hint与end
file_header->deprecated_eof_hint与file->end都存储文件的末尾的位置,但事实上,纵观源码,file_header->deprecated_eof_hint是没有用到的(这点与官方论文有出入),也就是说物理上没有存储文件的末尾位置,而是每次打开文件时,通过蛮力扫描,得到文件末尾位置,存入file->end。
3.5 record_count与log_records
这两个关系,我也不是搞得很清楚。给我感觉就是,file_header->log_records是指文件创建时的指定的微日志记录数量,默认的情况会是COFFEE_LOG_SIZE/log_record_size(log_record_size默认情况会是COFFEE_PAGE_SIZE,见adjust_log_config函数)。而file->record_count是实际上的微日志记录数量。