⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash_nor.c

📁 Flash的驱动程序。包括市面上常见的Nor Flash和Nand Flash.基本上所有的Flash只需要简单修改就可以移植到其他应用。
💻 C
📖 第 1 页 / 共 2 页
字号:
{  uint32 page_address;  uint32 page_ptr;  if (page > last_page_id)  {    return NULL;  }  (void)self;  page_address = page << FS_NOR_PAGE_ADDR_BITS;  page_ptr = page_address;  page_ptr += nv_byte_offset;#ifdef FSND_DEBUG  printf("\tpageptr: page address 0x%x\n", page_address);  printf("\tpageptr: absolute page address 0x%x\n", page_ptr);#endif  return (void *)page_ptr;}/***********************************************************************FUNCTION      fs_nor_device_read_pageDESCRIPTION   This function read page data of the given page into the               given buffer DEPENDENCIES  NoneRETURN VALUE  FS_DEVICE_DONE if read read was successful else               FS_DEVICE_FAIL**********************************************************************/intfs_nor_device_read_page (fs_device_t self, page_id page, void *data){  uint32 page_address;  flash_status status;  page_address = page << FS_NOR_PAGE_ADDR_BITS;#ifdef FSND_DEBUG  printf("\tread: page address 0x%x\n", page_address);  printf("\tread: absolute address 0x%x\n",          (page_address + (nv_byte_offset)));#endif  status = fs_nor_device_worded_read ((byte *)data, (dword)page_address,               (dword)(self->page_size (self)));  if (status != FLASH_SUCCESS)    return FS_DEVICE_FAIL;  else    return FS_DEVICE_DONE;} /* End of fs_nor_device_read_page *//***********************************************************************FUNCTION      fs_nor_device_bad_block_checkDESCRIPTION   This function should be called to determine whether              a block is bad or notDEPENDENCIES  NoneRETURN VALUE  FS_DEVICE_OK always, as there is no such thing as a              bad block in NOR flash.SIDE EFFECTS  None**********************************************************************/intfs_nor_device_bad_block_check (fs_device_t self, block_id block){  (void) self;  (void) block;  return FS_DEVICE_OK;} /* End of fs_device_nor_bad_block_check *//***********************************************************************FUNCTION      fs_nor_device_mark_block_badDESCRIPTION   Mark a block as badDEPENDENCIES  NoneRETURN VALUE  FS_DEVICE_FAIL always, as this cannot be done on NOR flash.SIDE EFFECTS  None**********************************************************************/intfs_nor_device_mark_block_bad (fs_device_t self, block_id block){  (void) self;  (void) block;  return FS_DEVICE_FAIL;} /* End of fs_device_nor_mark_block_bad *//***********************************************************************FUNCTION      fs_nor_device_write_partial_pageDESCRIPTION   This function writes a partial page of dataDEPENDENCIES  NoneRETURN VALUE  FS_DEVICE_DONE if write was successful else FS_DEVICE_FAILSIDE EFFECTS  None**********************************************************************/int fs_nor_device_write_partial_page (fs_device_t self, page_id page,      void *data, int offset, int length){  uint32 page_address;  flash_status status;  uint32 write_addr;  page_address = page << FS_NOR_PAGE_ADDR_BITS;  write_addr = page_address + offset;   //lint !e737 offset is always +ve  /* check to make sure the write does not go off the page */  if ((offset + length) > (self->page_size (self)))  //lint !e574 !e737 sign/unsigned mix rel ok  {    return FS_DEVICE_FAIL;  }#ifdef FSND_DEBUG  printf("\twritepp: page address 0x%x length 0x%x\n", page_address, length);  printf("\twritepp: absolute address 0x%x\n", (write_addr + nv_byte_offset));#endif    /* Verify that the requested data is in range.  The user see's the     component as starting at zero, so we only need to check the end. */  if ((write_addr + length) > (nor_device->efs_info.efs_bsize))  {    MSG_MED ("fs_dev: write request out of range", 0, 0, 0);    return FS_DEVICE_FAIL;  }  /* We cannot write while an erase is happening. */  if (fsi_erase_state != FSI_READ_MODE      && fsi_erase_state != FSI_ERASE_SUSPENDED)  {    MSG_MED ("fs_dev: attempt to write while device is erasing", 0,             0, 0);    return FS_DEVICE_FAIL;  }  status = (*nor_device->ops->write) ((byte *)data,   	                                  &fs_dev_base[(nor_device->efs_info.efs_boffset >> 1)],  	                                  (dword)write_addr, (dword)length);  if (status != FLASH_SUCCESS)    return FS_DEVICE_FAIL;  else    return FS_DEVICE_DONE;}/*===========================================================================FUNCTION FS_NOR_DEVICE_START_ERASE_BLOCKDESCRIPTION   Starts an erase operation on a block of the flash.DEPENDENCIES  NoneRETURN VALUE  FS_DEVICE_DONE if erase was successful else FS_DEVICE_FAILSIDE EFFECTS   An erase operation is begun upon the flash.  This operation  must be suspended before writes can occur.===========================================================================*/intfs_nor_device_start_erase_block (fs_device_t self, block_id block){  flash_status status;  uint32 block_address;  int block_size_shift;  uint16 no_of_shifts = 1;  uint32 block_count = self->block_count(self);  /* bail out early if block is invalid */  if (block >= block_count)  {    return FS_DEVICE_FAIL;  }  block_size_shift = self->block_size (self);  while (block_size_shift != 2)  {    block_size_shift >>= 1;    no_of_shifts++;  }  /* Set the block address */  block_address = block << (FS_NOR_PAGE_ADDR_BITS + no_of_shifts);      /* Determine if we have to check if an erase has terminated or     not. */  switch (fsi_erase_state)  {  case FSI_READ_MODE:    break;                                   /* Easy. */  case FSI_ERASING:    /* Must check to see if this erase is still running. */    ERR_FATAL ("not yet written 123", 0, 0, 0);    break;  case FSI_ERASE_SUSPENDED:    MSG_MED ("fsi_dev: Attempt to start erase while erase is suspended",             0, 0, 0);    return FS_FAIL_S;  }  /* If we made it here, then the component is now sitting in read     mode.  Our offset is in bytes from the beginning of EFS, get a     pointer to the real data. */  fsi_erase_location = (nor_device->efs_info.efs_boffset >> 1) + (block_address >> 1);    status = (*nor_device->ops->erase_start) (&fs_dev_base[(nor_device->efs_info.efs_boffset >> 1)],  	                                  (dword)block_address);    if (status != FLASH_SUCCESS)    return FS_DEVICE_FAIL;    fsi_erase_state = FSI_ERASING;    return FS_DEVICE_DONE;} /* End of fs_nor_device_start_erase_block *//*===========================================================================FUNCTION      fs_nor_device_suspend_eraseDESCRIPTION   This function suspends the current erase.DEPENDENCIES  NoneRETURN VALUE  FS_DEVICE_DONE if the erase has completed early.              FS_DEVICE_BUSY if the erase is suspended.              FS_DEVICE_FAIL if the suspend failed.===========================================================================*/int fs_nor_device_suspend_erase (fs_device_t self){  flash_status status;  status = (*nor_device->ops->suspend_erase) (&fs_dev_base[fsi_erase_location]);  if(status == FLASH_SUCCESS) {    /* Erase complete */    fsi_erase_state = FSI_READ_MODE;    return FS_DEVICE_DONE;  }   else if (status == FLASH_OP_NOT_COMPLETE)  {    /* Suspended */    fsi_erase_state = FSI_ERASE_SUSPENDED;    return FS_DEVICE_BUSY;  }  return FS_DEVICE_FAIL;}/*===========================================================================FUNCTION      fs_nor_device_resume_eraseDESCRIPTION   This function resumes the suspended erase.DEPENDENCIES  NoneRETURN VALUE  FS_DEVICE_BUSY if the erase is running again.              FS_DEVICE_FAIL if the resume failed.===========================================================================*/int fs_nor_device_resume_erase (fs_device_t self){  flash_status status;  status = (*nor_device->ops->resume_erase) (&fs_dev_base[fsi_erase_location]);  if(status != FLASH_SUCCESS)  {    return FS_DEVICE_FAIL;  }  fsi_erase_state = FSI_ERASING;  return FS_DEVICE_BUSY;}/*===========================================================================FUNCTION      fs_nor_device_erase_block_statusDESCRIPTION   This function checks and returns the status of the               flash device.DEPENDENCIES  NoneRETURN VALUE  FS_DEVICE_DONE if the erase has completed.              FS_DEVICE_BUSY if the erase is still running.===========================================================================*/int fs_nor_device_erase_block_status(fs_device_t self){  flash_status status;  if(fsi_erase_state == FSI_ERASING ||     fsi_erase_state == FSI_ERASE_SUSPENDED)  {    status = (*nor_device->ops->erase_status)(&fs_dev_base[fsi_erase_location]);      if (status != FLASH_SUCCESS)      return FS_DEVICE_BUSY;    else      fsi_erase_state = FSI_READ_MODE;  }  return FS_DEVICE_DONE;}/*===========================================================================FUNCTION FSI_RAM_PROBEDESCRIPTION  Probes the given address location to see if it is a writable RAM space.DEPENDENCIES  NoneRETURN VALUE  True if a writable area is found, False otherwise.SIDE EFFECTS  None===========================================================================*/boolean fsi_ram_probe (void){#ifdef FS_DEV_UNIT_TEST  return FALSE;#else  volatile word *base;  word saved_val;  extern word stamp_md5_hash;  /* Location to probe, use stamp_md5_hash */  base = fs_dev_base +(((int)&stamp_md5_hash/2));  saved_val = base[0];  base[0] = 0xAA;  if ( (base[0] & 0x00FF) != 0xAA) {    return( FALSE );  }  base[0] = 0xFF;  if ( (base[0] & 0x00FF) != 0xFF ) {    return( FALSE );  }  base[0] = saved_val;  return( TRUE );#endif}/*===========================================================================FUNCTION FS_NOR_DEVICE_WORDED_READDESCRIPTION  Read a sequence of bytes from a word oriented device.  This is  generic to any word sized device.DEPENDENCIES  NoneRETURN VALUE  FS_FAIL_S if the read couldn't be done.  FS_OKAY_S if it succeeded.SIDE EFFECTS  None===========================================================================*/flash_statusfs_nor_device_worded_read (byte *buffer, dword offset, dword count){#ifndef DO_READ_WITH_MEMMOVE  volatile word *wptr;  volatile byte *bptr;#endif /* not DO_READ_WITH_MEMMOVE */  /* Verify that the requested data is in range.  The use see's the     component as starting at zero, so we only need to check the end. */  if ((offset + count) > (nor_device->efs_info.efs_bsize))  {    MSG_MED ("fs_dev: read request out of range", 0, 0, 0);    return FS_FAIL_S;  }  /* We cannot read while an erase is happening. */  if (fsi_erase_state == FSI_ERASING)  {    MSG_MED ("fs_dev: attempt to read while device is erasing", 0,             0, 0);    return FS_FAIL_S;  }#ifdef DO_READ_WITH_MEMMOVE  memmove (buffer, ((byte *) (fs_dev_base + (nor_device->efs_info.efs_boffset >> 1))                    + offset),           count);#else /* not DO_READ_WITH_MEMMOVE */  /* Quickly handle the 0 byte read case. */  if (count == 0)    return FLASH_SUCCESS;  /* The ARM processor doesn't handle misaligned data accesses, so we     must account for that here. */  /* The easy case is if the alignment of the two is the same. */  if (((dword) buffer & 1) == (offset & 1))  {    /* Is there a "byte" at the beginning? */    if ((offset & 1) == 1)    {      *buffer = *((volatile byte *) (fs_dev_base +                                     (nor_device->efs_info.efs_boffset >> 1))                  + offset);      buffer++;      offset++;      count--;    }    /* Copy over any appropriatly aligned data. */    wptr = &fs_dev_base[(nor_device->efs_info.efs_boffset >> 1) + (offset >> 1)];    while (count > 1)    {      *((word *) buffer) = *wptr;      buffer += 2;      wptr   += 1;      count  -= 2;    }    /* There may be one additional byte to copy. */    if (count)    {      *buffer = *((byte *) wptr);   //lint !e794    }  }  /* Otherwise, the two sections of data are misaligned.  There are     two options, either copy the data in byte mode, or perform word     operations and scramble the bytes around manually.  Because both     RAM and the component are 16 bits wide, we gain much by doing the     scrambling. */  else  {    /* Simple byte copy. */    bptr = ((byte *) &fs_dev_base[(nor_device->efs_info.efs_boffset >> 1)]) + offset;    while (count-- > 0)    {      *buffer++ = *bptr++;    }  }#endif /* not DO_READ_WITH_MEMMOVE */  return FLASH_SUCCESS;}/***********************************************************************  Functions that return hardcoded device values**********************************************************************/char *fs_nor_device_name (fs_device_t self){  (void)self;  return (char *)nor_device->name;}uint32fs_nor_device_block_count (fs_device_t self){  (void)self;  return nor_device->efs_info.efs_blk_count;}uint32fs_nor_device_block_size (fs_device_t self){  (void)self;  return (nor_device->efs_info.efs_blk_bsize/512);}uint32fs_nor_device_page_size (fs_device_t self){  (void)self;  return 512;}static fs_device_write_style_tfs_nor_device_get_write_style (fs_device_t self){  (void) self;  return nor_device->efs_info.efs_write_style;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -