Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1679175
  • 博文数量: 124
  • 博客积分: 4078
  • 博客等级: 中校
  • 技术积分: 3943
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-21 11:28
个人简介

新博客:http://sparkandshine.net/

文章分类

全部博文(124)

分类: 嵌入式

2011-11-22 14:29:21

摘要:

    本文给出若干在分析Coffee文件系统遇到的问题(解决及待解决),如找不到创建新文件的方法,语法方面的问题。


一、创建新文件方法

    最近在分析Coffee文件系统,没找到创建一个新文件的方法,很是纳闷。有函数cfs_open、cfs_close、cfs_read、cfs_write、cfs_seek、cfs_remove,但没有创建文件相关的函数。通常的设计,会在打开文件进行判断,若文件不存在会创建新文件,但coffee文件系统的cfs_open(const char *name, int flags)只有3个标志:CFS_READ、CFS_WRITE、CFS_APPEND,也没有类似Linux中打开文件O_CREAT的标志。于是深入源码,cfs_open函数(文件路径contiki/core/cfs/cfs_coffee.c)在找不到name对应文件的情况下,就退出了。文件都创建不了,何谈读出写入。

解决:

    感谢网友回复,提示我cfs_open包含着创建文件。我已深入分析cfs_open源码,并整理成文档:

Contiki学习笔记:Coffee文件系统打开文件cfs_open

Contiki学习笔记:Coffee文件系统创建文件

新问题:
    但调试过程中,发现新的问题。创建新文件主体函数reserve调用find_contiguous_pages函数,寻找满足的页,find_contiguous_pages调用HDR_FREE(hdr)宏判断物理页是否可用(若物理页文件头file_header中flags的A位为0,则返回真),问题就在这里,Coffee格式化(擦除)时整个文件头都是0xFF,也就是说格式化后的flags每一位都是1,显然HDR_FREE(hdr)返回1,没法创建文件。

    我尝试着把HDR_FREE(hdr)改成!HDR_FREE(hdr),返回正确fd。但读写时又有新的问题,写入数据与读出数据不同(我怀疑压根就没写入)。所以呢,接下来把cfs_read和cfs_write也分析清楚,必要时将FLASH读写擦函数也分析下。


二、语法问题

在contiki\core\cfs\cfs_coffee.c文件下的merge_log函数,有这么一条语句,以致编译出错,如下:

  1. char buf[hdr.log_record_size == 0 ? COFFEE_PAGE_SIZE : hdr.log_record_size];

错误提示如下(开发环境是IAR):

    C语言语法规则,声明数组应该是:数组名[常量表达式],显然上面不是常量表达式。奇怪的是,我在InstantContiki 2.5环境下,居然可以编译通过(随便找一个硬件平台编译)。如此看来,这个问题应该是跟编译器相关了。

    像这样的问题,在Contiki源码中,多处出现,罗列如下:

  1. uint16_t indices[batch_size]; //在文件cfs-coffee.c的get_record_index函数

  2. uint16_t indices[preferred_batch_size]; //在文件cfs-coffee.c的find_next_record函数

  3. char copy_buf[log_record_size];

 初步解决:

    我的解决方法是,索性将这条语句简化为:char buf[COFFEE_PAGE_SIZE]; 编译就通过了,但可能会带来副作用。


三、CFS_APPEND并不包含CFS_WIRTE

    Coffee官方论文[1]声称指定了CFS_APPEND意味着指向CFS_WRITE,从源码分析,显然必须得指定CFS_WRITE才能写入。Coffee写入文件cfs_write,首先得判断fd的有效性和写权限检查,如下:

  1. if(!(FD_VALID(fd) && FD_WRITABLE(fd)))
  2. {
  3.     return - 1;
  4. }

  5. #define FD_WRITABLE(fd) (coffee_fd_set[(fd)].flags & CFS_WRITE)

    FD_WRITABLE判断该文件是否以CFS_WRITE打开,可见如果想从文件末尾写,则需同时指定CFS_WRITE和CFS_APPEND。

解决:

(1) 记住这个用法,当需要从文件末尾写时,同时指定CFS_WRITE和CFS_APPEND

(2)修改FD_WRITABLE宏,使CFS_APPEND隐含着CFS_WRITE,修改后如下:

  1. #define FD_WRITABLE(fd) (coffee_fd_set[(fd)].flags & CFS_WRITE & CFS_APPEND)


其他没发现的问题……


请不吝啬给予指教!可以发邮件,也可以直接在本文末尾回复(匿名也可回复),不胜感激。


参考资料:

[1] Tsiftes Nicolas,Dunkels Adam,He Zhitao.Enabling large-scale storage in sensor networks with the coffee file system[J].International Conference on Information Processing in Sensor Networks.2009,349-360

阅读(4590) | 评论(4) | 转发(0) |
给主人留下些什么吧!~~

Jelline2011-12-19 14:18:05

匿名: open的时候如果flag是CFS_WRITE就会创建新的文件,详见cfs_coffee.c代码。
我最近也在研究coffee,有机会多交流.....
不小心把你的一条评论删除了,我已分析cfs_open函数,也分析了创建文件技术细节,还关于file_header的flags还有一些疑问,想请教您。请问我联系联系你呢。我邮箱Jelline@126.com

Jelline2011-12-13 19:47:11

匿名: 问题2的话,是c编译器的问题,貌似新的标准编译器不支持,如果像你那样修改是会存在问题的,当自己配置log大小时会遇到问题(即log大小小于page size时),合并.....
谢谢你的回复。
我用的IDE是IAR Embedded Workbench for ARM,声称是高度优化的C/C++的ARM编译器。解决这个问题,你有什么建议吗?

Jelline2011-12-13 19:38:36

匿名: open的时候如果flag是CFS_WRITE就会创建新的文件,详见cfs_coffee.c代码。
我最近也在研究coffee,有机会多交流.....
谢谢你的回复。太好了,我最近也正在看Coffee,今天正好在分析cfs_write,不过还没分析完。
另,我用单步调度cfs_open("T1", CFS_WRITE),返回的是-1,后续的调试也是错的。我先好好分析下cfs_write源码

2011-12-13 13:18:50

open的时候如果flag是CFS_WRITE就会创建新的文件,详见cfs_coffee.c代码。
我最近也在研究coffee,有机会多交流