美文网首页我爱编程
STM32F417ZGT6 移植RL-FLASH FS

STM32F417ZGT6 移植RL-FLASH FS

作者: annge | 来源:发表于2018-02-15 16:31 被阅读0次

一般学习中使用FatFS可能多一点,使用上差别不是太大,但是FatFs没有,磨损均衡,坏块,ECC等管理,作为学习移植文件系统,问题不大,但在用到实际项目上去的话,这是肯定不行的,FLASH在产生坏块后,文件系统会受到破坏导致数据的丢失和产品的不稳定,RL-FlashFs是专门针对Flash芯片的文件系统,类似的还有国外一个开源的SPI-ffs,是专门针对小型化SPI FLASH的一种文件系统。

平台配置

FLASH:W29N1GV 128MB SLC NAND

控制器:STM32F417ZGT6

接口:STM32的FSMC接口

软件平台:MDK4.74(选4.74的原因是5版本以后的RL-FlashFs变成了一个pack,依赖于RTX,因为现在使用了QPN框架,暂时不想用RTX就不去掉这个依赖了)

CubeMx配置:

image

根据自己FLASH的数据手册来进行配置吧

其余的部分大可参照安富莱的教程,记录一下自己遇到的坑,其他朋友也可以参考一下

1.配置时不使用STM32的硬件ECC。

2.读取时的页大小 = Page Size + Spare area Size(我这边是2048 + 64 = 2112)

3.ST官方的库里面的读取函数都是整页读取的,移植时要自己写字节读取函数

以下是移植用到的API


uint8_t FSMC_NAND_Write_Page(uint8_t *_pBuffer, uint32_t _ulPageNo, uint16_t _usAddrInPage, uint16_t _usByteCount)

{

  __IO uint32_t index = 0U;

  uint32_t tickstart = 0U;

  /* Process Locked */

  __HAL_LOCK(&hnand1); 

  /* Check the NAND controller state */

  if(hnand1.State == HAL_NAND_STATE_BUSY)

  {

    return HAL_BUSY;

  }

  hnand1.State = HAL_NAND_STATE_BUSY;

/* Send write page command sequence */

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | CMD_AREA)) = NAND_CMD_AREA_A;

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | CMD_AREA)) = NAND_CMD_WRITE0;

/* (hnand->Config.PageSize) > 512 */

{

//(((hnand1.Config.BlockSize)*(hnand1.Config.BlockNbr)) <= 65535U)

// 1024 Blocks = 1024 * 64 pages * 2K Bytes

{

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | ADDR_AREA)) = ADDR_1ST_CYCLE(_usAddrInPage);

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | ADDR_AREA)) = ADDR_2ND_CYCLE(_usAddrInPage);

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | ADDR_AREA)) = ADDR_1ST_CYCLE(_ulPageNo);

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | ADDR_AREA)) = ADDR_2ND_CYCLE(_ulPageNo);

}

}

  for(uint16_t i = 0; i < 40; i++);

/* Write data to memory */

for(; index < _usByteCount; index++)

{

*(__IO uint8_t *)NAND_DEVICE1 = *(uint8_t *)_pBuffer++;

}

for(uint16_t i = 0; i < 40; i++);

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;

/* Read status until NAND is ready */

while(HAL_NAND_Read_Status(&hnand1) != NAND_READY)

{

/* Get tick */

tickstart = HAL_GetTick();

if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)

{

return ERR_NAND_HW_TOUT;

}

}

uint32_t status = HAL_NAND_Read_Status(&hnand1);

  /* Update the NAND controller state */

  hnand1.State = HAL_NAND_STATE_READY;

  /* Process unlocked */

  __HAL_UNLOCK(&hnand1);

  if(status == NAND_READY)

{

return RTV_NOERR;

}

else if(status == NAND_ERROR)

{

return ERR_NAND_PROG;

}

return RTV_NOERR;

}

uint8_t FSMC_NAND_Read_Page(uint8_t *_pBuffer, uint32_t _ulPageNo, uint16_t _usAddrInPage, uint16_t _usByteCount)

{

  __IO uint32_t index = 0U;

  uint32_t tickstart = 0U;

  /* Process Locked */

  __HAL_LOCK(&hnand1); 

  /* Check the NAND controller state */

  if(hnand1.State == HAL_NAND_STATE_BUSY)

  {

    return HAL_BUSY;

  }

  hnand1.State = HAL_NAND_STATE_BUSY;

/* Send write page command sequence */

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | CMD_AREA)) = NAND_CMD_AREA_A;

/* (hnand->Config.PageSize) > 512 */

{

//(((hnand1.Config.BlockSize)*(hnand1.Config.BlockNbr)) <= 65535U)

// 1024 Blocks = 1024 * 64 pages * 2K Bytes

{

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | ADDR_AREA)) = ADDR_1ST_CYCLE(_usAddrInPage); //Ò³ÄÚµØÖ·µÍ8

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | ADDR_AREA)) = ADDR_2ND_CYCLE(_usAddrInPage); //Ò³ÄÚµØÖ·¸ß8

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | ADDR_AREA)) = ADDR_1ST_CYCLE(_ulPageNo);    //Ò³µØÖ·¸ß8

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | ADDR_AREA)) = ADDR_2ND_CYCLE(_ulPageNo);    //Ò³µØÖ·µÍ8

}

}

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | CMD_AREA))  = NAND_CMD_AREA_TRUE1;

  for(uint16_t i = 0; i < 40; i++);

/* Read status until NAND is ready */

while(HAL_NAND_Read_Status(&hnand1) != NAND_READY)

{

/* Get tick */

tickstart = HAL_GetTick();

if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)

{

return ERR_NAND_HW_TOUT;

}

}

/* Go back to read mode */

*(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | CMD_AREA)) = ((uint8_t)0x00);

__DSB();

/* ¶ÁÊý¾Ýµ½»º³åÇøpBuffer */

for(index = 0; index < _usByteCount; index++)

{

*(uint8_t *)_pBuffer++ = *(uint8_t *)(NAND_DEVICE1); 

}

hnand1.State = HAL_NAND_STATE_READY;

__HAL_UNLOCK(&hnand1);

return RTV_NOERR;

}

uint8_t NAND_IsBadBlock(uint32_t _ulBlockNo)

{

uint8_t ucFlag;

/* Èç¹ûNAND Flash³ö³§Ç°ÒѾ­±êעΪ»µ¿éÁË£¬Ôò¾ÍÈÏΪÊÇ»µ¿é */

FSMC_NAND_Read_Page(&ucFlag, _ulBlockNo * NAND_BLOCK_SIZE, NAND_PAGE_SIZE + BBM_OFFSET, 1);

if (ucFlag != 0xFF)

{

return 1;

}

FSMC_NAND_Read_Page(&ucFlag, _ulBlockNo * NAND_BLOCK_SIZE + 1, NAND_PAGE_SIZE + BBM_OFFSET, 1);

if (ucFlag != 0xFF)

{

return 1;

}

return 0; /* ÊǺÿé */

}

uint8_t FSMC_NAND_EraseBlock(uint32_t _ulBlockNo)

{

  uint32_t tickstart = 0U;

  /* Process Locked */

  __HAL_LOCK(&hnand1);

  /* Check the NAND controller state */

  if(hnand1.State == HAL_NAND_STATE_BUSY)

  {

    return HAL_BUSY;

  }

  /* Update the NAND controller state */

  hnand1.State = HAL_NAND_STATE_BUSY; 

  /* Send Erase block command sequence */

  *(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | CMD_AREA)) = NAND_CMD_ERASE0;

_ulBlockNo <<= 6;

  *(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | ADDR_AREA)) = ADDR_1ST_CYCLE(_ulBlockNo);

  *(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | ADDR_AREA)) = ADDR_2ND_CYCLE(_ulBlockNo >> 8);   

  *(__IO uint8_t *)((uint32_t)(NAND_DEVICE1 | CMD_AREA)) = NAND_CMD_ERASE1;

  /* Update the NAND controller state */

  hnand1.State = HAL_NAND_STATE_READY;

  /* Get tick */

  tickstart = HAL_GetTick();

  /* Read status until NAND is ready */

  while(HAL_NAND_Read_Status(&hnand1) != NAND_READY)

  {

    if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)

    {

      /* Process unlocked */

      __HAL_UNLOCK(&hnand1);   

      return ERR_NAND_HW_TOUT;

    }

  }   

uint32_t status = HAL_NAND_Read_Status(&hnand1);

  /* Process unlocked */

  __HAL_UNLOCK(&hnand1);   

  if(status == NAND_READY)

{

return RTV_NOERR;

}

else if(status == NAND_ERROR)

{

return ERR_NAND_PROG;

}

return RTV_NOERR;

}

uint8_t NAND_Format(void)

{

for(uint16_t i = 0; i < 1024; i++)

{

FSMC_NAND_EraseBlock(i);

}

return NAND_OK;

}

void NAND_Init(void)

{

MX_FSMC_Init();

HAL_NAND_Reset(&hnand1);

}

void NAND_UnInit(void)

{

HAL_NAND_MspDeInit(&hnand1);

}

相关文章

  • STM32F417ZGT6 移植RL-FLASH FS

    一般学习中使用FatFS可能多一点,使用上差别不是太大,但是FatFs没有,磨损均衡,坏块,ECC等管理,作为学习...

  • node

    fs const fs = require('fs'); const data = fs.readFileSync...

  • 删除

    fs sdavd隐藏 fs sdavd隐藏 fs sdavd隐藏 fs sdavd隐藏 fs sdavd隐藏 va...

  • fs

    1.fs.open ,fs.write, fs.close 2. fs.writeFile 和fs.writeFi...

  • Nodejs

    1、fs文件系统 *.js const fs = require("fs"); // 读取 fs.readFile...

  • 初步认识node.js

    fs系统模块:读取文件: // node 读取文件const fs = require('fs');fs.read...

  • fs.Dirent 类目录项,通过读取目录返回

    fs.Dirent 类#[http://nodejs.cn/api/fs.html#fs_class_fs_dir...

  • node系统模块

    1.file system 文件系统 fs 使用: var fs = require(‘fs’); 2.fs.Di...

  • fs.Dir 类目录流

    fs.Dir 类#[http://nodejs.cn/api/fs.html#fs_class_fs_dir] 表...

  • nodejs copy视频到当前目录(stream)

    方法一: var fs=require('fs'); var readStream=fs.createReadSt...

网友评论

    本文标题:STM32F417ZGT6 移植RL-FLASH FS

    本文链接:https://www.haomeiwen.com/subject/htkutftx.html