以前年搞过一次,将yaffs2移植到低版本的uboot上,刚好前段时间又有需求移植到ucos上,记录一下

yaffs2移植专题:

使用的是2017-08-11更新的版本yaffs2-c1422c2.tar,路径:http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=snapshot;h=c1422c27f5f17c68acf261209292c7489085df6b;sf=tgz
    yaffs2移植实地址模式YDI主要适配os,以及flash的读写接口。
    yaffs2重要的结构体:
    yaffs_dev:            总的结构,需分配空间
    yaffs_param:        属性结构,param = &dev->param;包含分区名,nand的页,块等属性,起始地址,结束地址,保留块数量,tag等
    yaffs_driver:    驱动对接接口, drv = &dev->drv;主要:drv_write_chunk_fn,drv_read_chunk_fn,drv_erase_fn,drv_mark_bad_fn,drv_check_bad_fn...需要全部实现。
    最后由yaffs_add_device(dev);添加进去,所以可以支持多个分区,多次yaffs_add_device(devN);
    完成后可以用yaffs_mount(ROOT_PATH);注意ROOT_PATH必须和param的分区名对应,否则找不到。
    测试过程可以通过yaffs_set_trace(YAFFS_TRACE_ALWAYS | YAFFS_TRACE_ERROR | YAFFS_TRACE_BUG | 0);设置需要调试的模块信息。
    完成后即可用yaffs_access,yaffs_open,yaffs_write,yaffs_read,yaffs_close,yaffs_flush等接口正常操作。

调试过程注意nand flash本身是否存在坏块,烧写之前进行erase擦除,不要使用scrub命令擦除,否则可能会将烧写内容写异常。

#include "yaffs2/yportenv.h"
#include "yaffs2/yaffs_trace.h"
#include "yaffs2/yaffs_guts.h"
#include "yaffs2/yaffs_packedtags2.h"// for mt_nand config(w25n01gv spi nand flash) add by jason.luo at 2017/9/8 11:22:16
#define MTAPP_DEVICE_BASE   0x3000000     //yaffs2 mount addr at 48MB              need fix
#define SIZE_IN_MB 60                                   //flash total size: 128MB, yaffs size 60MB       need fixstatic const char *yaffs_dev_name = "nand";struct yaffs_dev *mtDev;#ifndef RET_CODE
#define RET_CODE s32
#endifstatic  void *p_dev       = NULL;
charsto_flash_info_t flash_info;static int yflash2_GetStartBlock(){int startblock = (MTAPP_DEVICE_BASE/flash_info.blocksize);return startblock;
}static int yflash2_GetNumberOfBlocks(void)
{int nBolocks = (SIZE_IN_MB * 1024 * 1024)/(flash_info.blocksize);return nBolocks;
}static int yflash2_GetEndBlock(){int endblock = yflash2_GetStartBlock() + yflash2_GetNumberOfBlocks();return endblock;
}static u32 yflash2_GetEndAddr(){u32 addr = yflash2_GetEndBlock()*flash_info.blocksize;return addr;
}static int yflash2_Deinitialise(struct yaffs_dev *dev){(void)dev;return 0;
}static int yflash2_WriteChunk(struct yaffs_dev *dev, int nand_chunk, const u8 *data, int data_len,const u8 *oob, int oob_len){int ret = -1;struct mtd_oob_ops ops;if (!data || !data_len) {data = NULL;data_len = 0;}if (!oob || !oob_len) {oob = NULL;oob_len = 0;}u32 addr = ((u32) nand_chunk) * dev->param.total_bytes_per_chunk;if(addr < MTAPP_DEVICE_BASE|| addr > yflash2_GetEndAddr()){return YAFFS_FAIL;}if(data && data_len){ret = charsto_writeonly(p_dev,addr,(u8 *)data,data_len);if(ret){OS_PRINTF("%s %d ret = %d\n",__FUNCTION__,__LINE__,ret);}}if(oob && oob_len){memset(&ops, 0, sizeof(ops));ops.datbuf = NULL;ops.len = 0;ops.ooblen = oob_len;ops.mode = MTD_OOB_AUTO;ops.ooboffs = 0;ops.oobbuf = (u8 *)oob;ret = charsto_write_oob(p_dev,addr,&ops);if(ret){OS_PRINTF("%s %d ret = %d\n",__FUNCTION__,__LINE__,ret);}}if(ret < 0){{OS_PRINTF("%s %d ret = %d\n",__FUNCTION__,__LINE__,ret);return YAFFS_FAIL;}}else{return YAFFS_OK;}
}static int yflash2_Initialise(struct yaffs_dev *dev)
{(void) dev;return YAFFS_OK;
}static int yflash2_CheckBad(struct yaffs_dev *dev, int block_no)
{charsto_flash_bad_block_info_t info;u8 ret = 0;if(block_no < yflash2_GetStartBlock() || block_no > yflash2_GetEndBlock()){return YAFFS_FAIL;}info.addr = block_no;dev_io_ctrl(p_dev, CHARSTO_IOCTRL_IS_BAD_BLOCK, (u32)&info);ret = info.block_is_bad;if(ret == 0)return YAFFS_OK;return YAFFS_FAIL;
}static int yflash2_MarkBad(struct yaffs_dev *dev, int block_no)
{int ret = 0;if(block_no < yflash2_GetStartBlock() || block_no > yflash2_GetEndBlock()){return YAFFS_FAIL;}u32 offset = block_no;dev_io_ctrl(p_dev, CHARSTO_IOCTRL_MARK_BAD_BLOCK,offset);if(ret != 0)return YAFFS_FAIL;return YAFFS_OK;
}static int yflash2_write_chunk_tags (struct yaffs_dev *dev,int nand_chunk, const u8 *data,const struct yaffs_ext_tags *tags){struct mtd_oob_ops ops;int retval = 0;loff_t addr;struct yaffs_packed_tags2 pt;int packed_tags_size = dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);void *packed_tags_ptr = dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt;yaffs_trace(YAFFS_TRACE_MTD,"nandmtd2_write_chunk_tags chunk %d data %p tags %p",nand_chunk, data, tags);addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;/* For yaffs2 writing there must be both data and tags.* If we're using inband tags, then the tags are stuffed into* the end of the data buffer.*/if (!data || !tags)BUG();else if (dev->param.inband_tags) {struct yaffs_packed_tags2_tags_only *pt2tp;pt2tp = (struct yaffs_packed_tags2_tags_only *)(data + dev->data_bytes_per_chunk);yaffs_pack_tags2_tags_only(dev,pt2tp, tags);} else {yaffs_pack_tags2(dev,&pt, tags, !dev->param.no_tags_ecc);}charsto_writeonly(p_dev,addr,(u8 *)data,dev->param.total_bytes_per_chunk);ops.mode = MTD_OOB_AUTO;ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;ops.len = 0;//dev->param.total_bytes_per_chunk;ops.ooboffs = 0;ops.datbuf = NULL;//(u8 *) data;ops.oobbuf = (dev->param.inband_tags) ? NULL : packed_tags_ptr;retval = charsto_write_oob(p_dev, addr, &ops);if (retval == 0)return YAFFS_OK;elsereturn YAFFS_FAIL;
}static int yflash2_read_chunk_tags(struct yaffs_dev *dev,int nand_chunk, u8 *data,struct yaffs_ext_tags *tags){u8 local_spare[128];struct mtd_oob_ops ops;int retval = 0;int local_data = 0;struct yaffs_packed_tags2 pt;loff_t addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;int packed_tags_size =dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);void *packed_tags_ptr =dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt;yaffs_trace(YAFFS_TRACE_ERROR,"nandmtd2_read_chunk_tags chunk %d data %p tags %p",nand_chunk, data, tags);if (dev->param.inband_tags) {if (!data) {local_data = 1;data = yaffs_get_temp_buffer(dev);}}if (dev->param.inband_tags || (data && !tags)){/* Do not allow reads past end of device */if ((addr + dev->param.total_bytes_per_chunk) > flash_info.chipsize)return -1;retval = charsto_read(p_dev, addr,data,dev->param.total_bytes_per_chunk);}else if (tags) {ops.mode = MTD_OOB_AUTO;ops.ooblen = packed_tags_size;ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;ops.ooboffs = 0;ops.datbuf = data;ops.oobbuf = local_spare;retval = charsto_read_oob(p_dev, addr, &ops);}if (dev->param.inband_tags) {if (tags) {struct yaffs_packed_tags2_tags_only *pt2tp;pt2tp =(struct yaffs_packed_tags2_tags_only *)&data[dev->data_bytes_per_chunk];yaffs_unpack_tags2_tags_only(dev,tags, pt2tp);}} else {if (tags) {memcpy(packed_tags_ptr,local_spare,packed_tags_size);yaffs_unpack_tags2(dev,tags, &pt, !dev->param.no_tags_ecc);}}if (local_data)yaffs_release_temp_buffer(dev, data);if (tags && retval == -EBADMSG&& tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED;dev->n_ecc_unfixed++;}if (tags && retval == -EUCLEAN&& tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {tags->ecc_result = YAFFS_ECC_RESULT_FIXED;dev->n_ecc_fixed++;}if (retval == 0)return YAFFS_OK;elsereturn YAFFS_FAIL;}static int yflash2_QueryBlock (struct yaffs_dev *dev, int block_no,enum yaffs_block_state *state,u32 *seq_number){int retval = 0;charsto_flash_bad_block_info_t info;yaffs_trace(YAFFS_TRACE_MTD, "nandmtd2_QueryNANDBlock %d", block_no);info.addr = block_no;dev_io_ctrl(p_dev, CHARSTO_IOCTRL_IS_BAD_BLOCK, (u32)&info);retval = info.block_is_bad;if (retval) {yaffs_trace(YAFFS_TRACE_MTD, "block is bad");*state = YAFFS_BLOCK_STATE_DEAD;*seq_number = 0;} else {struct yaffs_ext_tags t;yflash2_read_chunk_tags(dev,block_no *dev->param.chunks_per_block, NULL,&t);if (t.chunk_used) {*seq_number = t.seq_number;*state = YAFFS_BLOCK_STATE_NEEDS_SCAN;} else {*seq_number = 0;*state = YAFFS_BLOCK_STATE_EMPTY;}}yaffs_trace(YAFFS_TRACE_MTD, "block is bad seq %d state %d",*seq_number, *state);if (retval == 0)return YAFFS_OK;elsereturn YAFFS_FAIL;
}static int yflash2_EraseBlock(struct yaffs_dev *dev, int block_no)
{if(block_no < yflash2_GetStartBlock() || block_no > yflash2_GetEndBlock()){return YAFFS_FAIL;}charsto_erase(p_dev,block_no*128*1024,1);return YAFFS_OK;
}static int yflash2_ReadChunk(struct yaffs_dev *dev, int nand_chunk,u8 *data, int data_len,u8 *oob, int oob_len,enum yaffs_ecc_result *ecc_result_out){int ret = -1;struct mtd_oob_ops ops;u32  addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;if(addr < MTAPP_DEVICE_BASE|| addr > yflash2_GetEndAddr()){return YAFFS_FAIL;}if(data && data_len){ret = charsto_read(p_dev,addr,data,data_len);}if(oob && oob_len){memset(&ops, 0, sizeof(ops));ops.mode = MTD_OOB_AUTO;ops.len = 0;ops.ooblen = oob_len;ops.datbuf = NULL;ops.oobbuf = oob;ret = charsto_read_oob(p_dev,addr,&ops);}if(ret < 0){OS_PRINTF("spi_nand_do_read_ops 0x%x error\n",addr);return YAFFS_FAIL;}*ecc_result_out = YAFFS_ECC_RESULT_NO_ERROR;return YAFFS_OK;
}static struct yaffs_dev *yflash2_install_drv(const char *name,int startblock,int endblock){struct yaffs_param *param;struct yaffs_driver *drv = NULL;struct yaffs_dev *dev = NULL;struct yaffs_tags_handler *tagger = NULL;dev = malloc(sizeof(*dev));if(!dev){return NULL;}memset(dev, 0, sizeof(*dev));dev->param.name = strdup(name);if(!dev->param.name) {free(dev);return NULL;}param = &dev->param;param->total_bytes_per_chunk = flash_info.pagesize;param->chunks_per_block = flash_info.blocksize / flash_info.pagesize;param->spare_bytes_per_chunk = flash_info.oobsize;param->start_block = startblock;        //0X3000000 = 384param->end_block = endblock-1;param->is_yaffs2 = 1;param->use_nand_ecc=1;               //nand ecc or yaffs eccparam->empty_lost_n_found = 1;       //auto emptyparam->n_reserved_blocks = 5;param->refresh_period = 1000;param->n_caches = 10;                   // Use cachesparam->inband_tags = 0;                //must set for yaffs2 big pageparam->no_tags_ecc = 1;drv = &dev->drv;drv->drv_initialise_fn = yflash2_Initialise;drv->drv_deinitialise_fn = yflash2_Deinitialise;drv->drv_write_chunk_fn = yflash2_WriteChunk;drv->drv_read_chunk_fn = yflash2_ReadChunk;drv->drv_erase_fn = yflash2_EraseBlock;drv->drv_mark_bad_fn = yflash2_MarkBad;drv->drv_check_bad_fn = yflash2_CheckBad;tagger = &dev->tagger;tagger->mark_bad_fn = yflash2_MarkBad;tagger->query_block_fn = yflash2_QueryBlock;tagger->write_chunk_tags_fn = yflash2_write_chunk_tags;tagger->read_chunk_tags_fn  = yflash2_read_chunk_tags;yaffs_add_device(dev);return dev;
}int yaffs_start_up(void){static int start_up_called = 0;if(start_up_called){return 0;}start_up_called = 1;yaffsfs_OSInitialisation();//get snf firstp_dev = dev_find_identifier(NULL, DEV_IDT_TYPE, SYS_DEV_TYPE_CHARSTO);//  charsto_flash_info_t flash_info;dev_io_ctrl(p_dev, CHARSTO_IOCTRL_GET_FLASH_INFO, (u32)&flash_info);int start_block = yflash2_GetStartBlock();int end_block = yflash2_GetEndBlock();mtDev = yflash2_install_drv(yaffs_dev_name,start_block,end_block);if(mtDev == NULL){return -1;}return -1;
}int mt_yaffs_start_up(void){
//  yaffs_set_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_ALWAYS | YAFFS_TRACE_BUG | YAFFS_TRACE_BAD_BLOCKS | YAFFS_TRACE_SCAN_DEBUG | YAFFS_TRACE_SCAN);return yaffs_start_up();
}
name对应的是挂载点"/name"
param->inband_tags = 0; OOB存储tag
tagger = &dev->tagger;函数不能偷懒,都得设置起

yaffs2移植到ucos上相关推荐

  1. ucos移植到stm32上的中断小小改进

    uCosII移植到stm32上的文章和demo已经很多了,细节上建议大家可以看官方的移植文档( 当然是E文的).网上流传的各种移植版本基本都是基于官方的移植版本做了小改进.这些改进基本都限制在更适合自 ...

  2. 将uc/OS移植到stm32F103上

    将uc/OS移植到stm32F103上 一.嵌入式实时操作系统(RTOS) 1.定义 2.实时任务 3.特征 二.使用CubeMX建立STM32F103C8T6HAL库 三.移植uC/OS-III 四 ...

  3. Lua移植到arm上 并实现在arm上 可以让lua脚本调c语言,C语言调用lua脚本

    Lua移植到arm上 并实现在arm上 可以让lua脚本调c语言,C语言调用lua脚本 首先参考http://wiki.chumby.com/index.php?title=Lua&print ...

  4. qt5.3.2移植到arm上出undefined reference to '__sync_sub_and_fetch_4的错

    qt5.3.2移植到arm上出undefined reference to '__sync_sub_and_fetch_4的错.解决办法如下, 使用工具:GCC4.4.1 QT源码:qt5.3.2 前 ...

  5. 将c程序移植到linux,各位大侠:我把原来在linux运行的c程序移植到HPUNIX上出现了错误...

    各位大侠:我把原来在linux运行的c程序移植到HPUNIX上出现了错误 (2012-04-11 00:43:47) 标签: linux c程序 杂谈 各位大侠:我把原来在linux运行的c程序移植到 ...

  6. YAFFS2移植到AliOS Things指南

    摘要: YAFFS2介绍 YAFFS(Yet Another Flash File System)是第一个专门为NAND Flash存储器设计的嵌入式文件系统,适用于大容量的存储设备.YAFFS 是基 ...

  7. Qt工作笔记-Qt creator如何生成dll,以及如何移植到vs上

    首先用Qt Creator创建一个库项目: 在类中添加一个add函数,并实现他: 直接就可以生成为一个dll 因为是使用MinGW的编译器所以会有.a文件: 把程序移动过去! 接着用另外一个项目进行调 ...

  8. STM32F103ZE工程移植到STM32F107VC上软件调试时死循环在while((RCC-CR RCC_CR_PLL2RDY) == 0) { }

    STM32F103ZE工程移植到STM32F107VC上软件调试时死循环在while((RCC->CR & RCC_CR_PLL2RDY) == 0) { }@TOC 第一次移植不知道改 ...

  9. 移植mysql到安卓手机_记录dbnet文本检测转ncnn并移植到安卓上

    目前,文本检测主要分为基于检测网络和分割网络实现,上文(风影:记录densenet-ocr识别网络转ncnn并移植到安卓手机)讲到将yolo3文本检测+densenet识别网络转ncnn推理,并成功移 ...

最新文章

  1. 通过OpenSSL的接口实现Base64编解码
  2. PHP 捕获全局异常
  3. 如何利用 JConsole观察分析Java程序的运行,进行排错调优
  4. Mac 系统和windows 的差别
  5. Java并发(四)——synchronized、volatile
  6. C++ string 成员函数 length() size() 和 C strlen() 的区别
  7. Java高阶知识体系总结(一)
  8. c#如何wmf图片转换成png图片_C#图片格式转换(支持bmp/gif/jpeg/png/tiff/wmf文件)
  9. 关于java的1234
  10. Walletry for mac(日常支出跟踪工具)
  11. windows 建立窗口的程序代码
  12. 基础知识------我所知道的、应该知道的
  13. 【软件测试】——接口测试简介
  14. 跳过数据准备,下秒数据让飞书维格表数据应用更高效
  15. python编程猜数字小游戏(简单)
  16. [XCTF] [NJUPT CTF 2017] maze
  17. 宝石典故之“凤凰血染红的鸡血石”
  18. 教程 | 在Unity中使用 Isometric Tilemap(等距、正交)
  19. 阿里云携手爱迪德,发布中国首个云端DRM解决方案
  20. C语言多维数组做函数参数会退化,数组做函数参数退化问题

热门文章

  1. 时间序列预测12:用电量预测 02 朴素模型多步预测建模
  2. 使用matlab 2018b 图像处理工具箱批量处理操作
  3. element-UI 使用icon图标或者avatar 头像不显示问题 解决
  4. 超调 matlab m文件,基于Matlab的汽车运动控制系统设计.doc
  5. 手机建站软件有哪些?不懂技术也可以手机建站
  6. Central Limit Theorem - 中心极限定理
  7. uImage zImage
  8. 【WFS】WFS 的所有版本都支持以下操作
  9. ublock 基本屏蔽语法规则介绍
  10. 写作之路,以梦为马,不负韶华