Chinaunix首页 | 论坛 | 博客
  • 博客访问: 99766
  • 博文数量: 14
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 206
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-28 09:37
个人简介

记录我自己的成长....

文章分类

全部博文(14)

文章存档

2014年(2)

2013年(12)

我的朋友

分类: 其他平台

2014-11-17 13:00:48

  一个项目中用到了nandflash,开始的时候,没有用文件系统的打算,就在代码中直接操作nandflash,后来由于项目的变动,时间比较充足,就萌生了移植文件系统的想法。yaffs2就进入了我的视野,下面就对我在移植yaffs文件的过程进行总结。

1、在yaffs官方主页上,看了三个文档,分别是How Yaffs WorksThe Yaffs Direct Interface, 。在yaffs port Guide文件中有一个简历环境的描述,这样来确定用yaffs文件包中那些文件会被用到。个人觉得,这部分需要一些花费一些精力。我已经将这个文件包抽取出来,保存到一个目录中,可以直接使用,文件包在下载目录中。
2、调试部分,在调试之前你必须要有一个稳定的硬件环境,尤其是SDRAM,我的调试时间,基本上是花在了调试SDRAM上,这也是我之前对硬件调试不认真造成的,就是LPC4088出来的DQM脚和SDRAM的DQM脚接反了。在写8位数据的时候,其实修改的是16位的数据,造成一部分数据莫名其妙的被修改了。当时我一直怀疑是SDRAM的时序问题。所以花费了很多时间,不能解决这个问题。这个问题的表现是“发现yaffs的bug”。之后我只好认认真真的看数据手册,于是我感觉可能是DQM这块有问题。后来发现确实有问题。
   另外一个问题是编译器的问题,就是对位域的处理,我用的keil4.72编译的。在yaffsfs.c中第920行一个循环中,如代码:

点击(此处)折叠或打开

  1. for (i = 0; i < YAFFSFS_N_HANDLES; i++) {
  2.                     fdx = &yaffsfs_fd[i];
  3.                     tmp = fdx->inodeId; //
  4.                     if (tmp == 0xFFF)
  5.                         tmp = -1;
  6.                     if (fdx->handleCount > 0 &&
  7.                      /*fdx->inodeId*/tmp >= 0 &&
  8.                      yaffsfs_inode[fdx->inodeId].iObj
  9.                      == obj) {
  10.                         if (!fdx->shareRead)
  11.                             sharedReadAllowed = 0;
  12.                         if (!fdx->shareWrite)
  13.                             sharedWriteAllowed = 0;
  14.                         if (fdx->reading)
  15.                             alreadyReading = 1;
  16.                         if (fdx->writing)
  17.                             alreadyWriting = 1;
  18.                     }
  19.                 }
其中fdx->inodeId是一个12bit的变量,它最初被复制为-1,也就是0xFFF,但是keil4.72下,图中代码第6行被作为了一个整形无符号数来处理。因此我改动了这部分代码,4-7行。增加了一个变量。
3、与flash的接口,主要集中在yaffs_nand_drv.c中,只要填充下面这个函数即可:

点击(此处)折叠或打开

  1. struct yaffs_dev *yflash2_install_drv( char *name, int start_b, int end_b)
  2. {
  3.     struct yaffs_dev *dev = NULL;
  4.     struct yaffs_param *param;
  5.     struct yaffs_driver *drv;
  6.     struct yaffs_tags_handler *tag;
  7.     char* name_copy = NULL;
  8.         
  9.     dev = malloc(sizeof(*dev));

  10.     if(!dev)
  11.         return NULL;
  12.     
  13.     param = &dev->param;
  14.     memset(dev, 0, sizeof(*dev));

  15.     name_copy = strdup(name);    
  16.     param->name=name_copy;
  17.     
  18.     if(!param->name||!dev)
  19.         {
  20.             free(dev);
  21.             free(name_copy);
  22.             return NULL;
  23.     }

  24.     drv = &dev->drv;

  25.     drv->drv_write_chunk_fn = yaffs_nand_drv_WriteChunk;
  26.     drv->drv_read_chunk_fn     = yaffs_nand_drv_ReadChunk;
  27.     drv->drv_erase_fn             = yaffs_nand_drv_EraseBlock;
  28.     drv->drv_mark_bad_fn         = yaffs_nand_drv_MarkBad;
  29.     drv->drv_check_bad_fn     = yaffs_nand_drv_CheckBad;
  30.     drv->drv_initialise_fn    = yaffs_nand_drv_Initialise;
  31.     drv->drv_deinitialise_fn = yaffs_nand_drv_Deinitialise;
  32.     dev->driver_context = (void *) 1;


  33.     param->total_bytes_per_chunk = 2048;
  34.     param->chunks_per_block             = 64;
  35.     param->spare_bytes_per_chunk = 64;
  36.     param->start_block                         = start_b;
  37.     param->end_block                            = end_b;
  38.     param->is_yaffs2                             = 1;
  39.     param->use_nand_ecc                        = 0;

  40.     param->n_reserved_blocks             = 10;
  41.     param->wide_tnodes_disabled        = 0;
  42.     param->refresh_period                 = 1000;
  43.     param->n_caches                             = 5; // Use caches

  44.     param->enable_xattr                     = 10;

  45.     tag = &dev->tagger;



  46.     yaffs_add_device(dev);

  47.     
  48.     return dev;
  49. }
从28行到36行,就是flash的接口函数,yaffs就是通过这些接口来操作nand,39到45行时根据flash的规格和你对flash的分区来设定。

4、用户接口部分
在使用之前yaffs之前,先要调用int yaffs_start_up(void)函数,部分我也做了修改,我是将flash分成2个分区,我的flash的总共有1024个块。第一分区是sys分区,从0-255块,共256块。第二分区是user分区,除第一分区之外的剩余块,即从256-1023块,代码如下:

点击(此处)折叠或打开

  1. int yaffs_start_up(void)
  2. {
  3.     static int start_up_called = 0;

  4.     if(start_up_called)
  5.         return 0;
  6.     start_up_called = 1;

  7.     /* Call the OS initialisation (eg. set up lock semaphore */
  8.     yaffsfs_OSInitialisation();
  9.     if (yflash2_install_drv("/sys", 0, 255) == NULL) //32M size
  10.         return YAFFS_FAIL;
  11.     if (yflash2_install_drv("/user", 256, 1023) == NULL) //86M size
  12.         return YAFFS_FAIL;


  13.     return YAFFS_OK;
  14. }
这部分代码在yaffscfg2k.c中。
在此之后,就可以mount分区,进行读写等文件操作了。

5、参考代码,
  yaffs2文件包,后续会提供一个keil的工程,包含yaffs,并将yaffs文件包单独出来。keil工程是针对lpc4088的。后续会提供stm32的包。目前这部分还需要整理。
   下载地址



阅读(3266) | 评论(0) | 转发(0) |
0

上一篇:keil 下 malloc的使用

下一篇:没有了

给主人留下些什么吧!~~