1.基于Platform写flash操作 platform_device_write(p_device->handle, offset, buf1, p_device->page_size 按照Nandflash原理 坏块Block只要有一页是坏的话,那整个Block就是坏的。同时在操作读写操作时,必须先检查坏块,并跳过这个Block
- Platform_STATUS platform_device_write(PLATFORM_DEVHANDLE deviceid,
- uint32_t offset,
- uint8_t *buf,
- uint32_t len)
- {
- IFPRINT(platform_write("platform_device_write(handle=0x%x, offset=%d, len=%d, buf=0x%x) called n",
- deviceid, offset, len, buf));
- /* Check general args */
- if (buf == NULL || len == 0) {
- platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT;
- return Platform_EINVALID;
- }
- #if (PLATFORM_NAND_WRITE_IN || PLATFORM_NOR_WRITE_IN)
- if ((deviceid == PLATFORM_DEVID_MT29F1G08ABCHC) || (deviceid == PLATFORM_DEVID_NORN25Q032A))
- {
- NAND_ADDR addr;
- NAND_ADDR StartAddress;
- Platform_STATUS retval = Platform_EOK;
- PLATFORM_DEVICE_info *p_device;
- int32_t block, page;
- int32_t bufindex;
- int32_t index;
- int32_t useable_page_size;
- int32_t block_size;
- uint32_t noraddress;
- uint8_t *pBlock = NULL;
- uint8_t *pPage = NULL;
- if (deviceid == PLATFORM_DEVID_MT29F1G08ABCHC) {
- p_device = &gDeviceNand;
- }
- else {
- p_device = &gDeviceNor;
- }
- /* Calculate the usable page area.. Its the size of the page */
- useable_page_size = p_device->page_size;
- /* allocate a buffer big enough to hold one block (must include spare area) */
- block_size = p_device->page_size * p_device->page_count;
- pBlock = Osal_platformMalloc(platform_roundup(block_size, PLATFORM_CACHE_LINE_SIZE),
- PLATFORM_CACHE_LINE_SIZE);
- if ( !pBlock ){
- platform_errno = PLATFORM_ERRNO_OOM;
- retval = Platform_EFAIL;
- goto FLASHWRITE_ERROR;
- }
- /* allocate a buffer big enough to hold one page of the flash */
- pPage = Osal_platformMalloc(platform_roundup(p_device->page_size, PLATFORM_CACHE_LINE_SIZE),
- PLATFORM_CACHE_LINE_SIZE);
- if ( !pPage ){
- platform_errno = PLATFORM_ERRNO_OOM;
- retval = Platform_EFAIL;
- goto FLASHWRITE_ERROR;
- }
- /* Get starting address */
- addr.uiColumnAddr= 0;
- if (platform_offset_to_blocknpage(deviceid, offset, &addr.uiBlockAddr, &addr.uiPageAddr) != Platform_EOK) {
- retval = Platform_EUNSUPPORTED;
- goto FLASHWRITE_ERROR;
- }
- /*
- * We can now write the file to flash. The basic algorithm is this:
- * Read the bad block table
- * While we have data to write do
- * skip block if bad
- * read the block (page level)
- * erase the block (block level)
- * write the block (page level)
- */
- /* set index to start of the data to write */
- bufindex = 0;
- /* Initialize the starting block we will be using */
- block = addr.uiBlockAddr;
- StartAddress.uiBlockAddr = addr.uiBlockAddr;
- StartAddress.uiPageAddr = addr.uiPageAddr;
- StartAddress.uiColumnAddr = 0;
- while (len) {
- /* Skip bad blocks */
- if (p_device->bblist) {
- if (p_device->bblist[block] == 0x00) {
- /* Block is bad, skip to next good one */
- IFPRINT(platform_write( "platform_device_write: Skipping bad block %d. n", block));
- block++;
- while (p_device->bblist[block] == 0x00) {
- block++;
- }
- }
- }
- /* Make sure we didn't exceed number of blocks */
- if (block > p_device->block_count) {
- IFPRINT(platform_write( "Due to bad blocks, you have run out of room in the Flash for this image. n"));
- platform_errno = PLATFORM_ERRNO_NOFREEBLOCKS;
- retval = Platform_EFAIL;
- goto FLASHWRITE_ERROR;
- }
- IFPRINT(platform_write( "platform_device_write: Writing block %d n", block));
- /*
- * Read the block..
- * may need to preserve what we don't actually write out.
- */
- for (page=0, index = 0; page < p_device->page_count;
- page ++, index +=p_device->page_size) {
- addr.uiBlockAddr = block;
- addr.uiPageAddr = page;
- addr.uiColumnAddr= 0;
- if (p_device->handle == PLATFORM_DEVID_MT29F1G08ABCHC) {
- #if (PLATFORM_NAND_WRITE_IN)
- if (readNandPage (&gDeviceNand, addr, (uint8_t *)(pBlock + index)) != SUCCESS) {
- retval = Platform_EFAIL;
- IFPRINT(platform_write( "platform_device_write: Error reading block %d page %d. n", block, page));
- goto FLASHWRITE_ERROR;
- }
- #endif
- }
- else {
- #if (PLATFORM_NOR_WRITE_IN)
- (void) platform_blocknpage_to_offset(p_device->handle, &noraddress, addr.uiBlockAddr, addr.uiPageAddr);
- if (nor_read (&gDeviceNor, noraddress, p_device->page_size, (uint8_t *)(pBlock + index)) != SUCCESS) {
- retval = Platform_EFAIL;
- platform_write( "platform_device_write: Error reading block %d page %d. n", block, page);
- goto FLASHWRITE_ERROR;
- }
- #endif
- }
- }
- /* erase the block */
- if (p_device->handle == PLATFORM_DEVID_MT29F1G08ABCHC) {
- #if (PLATFORM_NAND_WRITE_IN)
- if (nandFlashBlockErase (&gDeviceNand, block) != SUCCESS) {
- IFPRINT(platform_write( "platform_device_write: Could not erase block %d. n", block));
- retval = Platform_EFAIL;
- goto FLASHWRITE_ERROR;
- }
- #endif
- }
- else {
- #if (PLATFORM_NOR_WRITE_IN)
- if (nor_erase (&gDeviceNor, block) != SUCCESS) {
- IFPRINT(platform_write( "platform_device_write: Could not erase block %d. n", block));
- retval = Platform_EFAIL;
- goto FLASHWRITE_ERROR;
- }
- #endif
- }
- /*
- 写块操作
- */
- for (page = 0, index = 0; page < p_device->page_count;
- page ++, index +=p_device->page_size) {
- IFPRINT(platform_write( "platform_device_write: Writing to block %d page %d n", block, page));
- if (block == StartAddress.uiBlockAddr && page < StartAddress.uiPageAddr) {
- /* if we are within the first block we are writing, then we may have a start
- * page other than page 0, so re-write what was there.
- */
- memcpy(pPage, (pBlock+bufindex), useable_page_size);
- }
- else
- if (len == 0) {
- /* we wrote all the data, so write back any pages we pre-read that are left */
- memcpy(pPage, (pBlock+bufindex), useable_page_size);
- }
- else
- if (len < useable_page_size) {
- /* we have less than a full page of data */
- memset(pPage, 0xFF, p_device->page_size);
- memcpy(pPage, (buf+bufindex), len);
- len = 0;
- }
- else {
- /* get a full page of data */
- memcpy(pPage, (buf+bufindex), useable_page_size);
- len -= useable_page_size;
- bufindex += useable_page_size;
- }
- /* 写页*/
- addr.uiBlockAddr = block;
- addr.uiPageAddr = page;
- addr.uiColumnAddr= 0;
- if (p_device->handle == PLATFORM_DEVID_MT29F1G08ABCHC) {
- #if (PLATFORM_NAND_WRITE_IN)
- if (wri电子发烧友Page (&gDeviceNand, addr, pPage) != SUCCESS) {
- IFPRINT(platform_write( "platform_device_write: Error writing block %d page %d. n", block, page));
- retval = Platform_EFAIL;
- goto FLASHWRITE_ERROR;
- }
- #endif
- }
- else {
- #if (PLATFORM_NOR_WRITE_IN)
- (void) platform_blocknpage_to_offset(p_device->handle, &noraddress, addr.uiBlockAddr, addr.uiPageAddr);
- if (nor_write(&gDeviceNor, noraddress, p_device->page_size, pPage) != SUCCESS) {
- IFPRINT(platform_write( "platform_device_write: Error writing block %d page %d. n", block, page));
- retval = Platform_EFAIL;
- goto FLASHWRITE_ERROR;
- }
- #endif
- }
- }
- block++;
- }
-
- FLASHWRITE_ERROR:
- if (pBlock) {
- Osal_platformFree( pBlock, platform_roundup(block_size, PLATFORM_CACHE_LINE_SIZE) );
- }
- if (pPage) {
- Osal_platformFree( pPage, platform_roundup(p_device->page_size, PLATFORM_CACHE_LINE_SIZE));
- }
- return retval;
- }
- #endif
- #if (PLATFORM_EEPROM_IN) && (PLATFORM_EEPROM_WRITE_IN)
- if (deviceid == PLATFORM_DEVID_EEPROM50) {
- if (i2cEepromWriteByteAddr(offset, 0x50, buf, len, I2C_RELEASE_BUS) != I2C_RET_OK) {
- IFPRINT(platform_write("platform_device_write: EEPROM write for address 0x%x failedn", 0x50));
- platform_errno = PLATFORM_ERRNO_EEPROM;
- return ( (Platform_STATUS) Platform_EFAIL);
- }
- return Platform_EOK;
- }
- if (deviceid == PLATFORM_DEVID_EEPROM51) {
- if (i2cEepromWriteByteAddr(offset, 0x51, buf, len, I2C_RELEASE_BUS) != I2C_RET_OK) {
- IFPRINT(platform_write("platform_device_write: EEPROM write for address 0x%x failedn", 0x51));
- platform_errno = PLATFORM_ERRNO_EEPROM;
- return ( (Platform_STATUS) Platform_EFAIL);
- }
- return Platform_EOK;
- }
- #endif
- return Platform_EUNSUPPORTED;
复制代码
2.基于Platform读Nandflash操作 platform_device_read(p_device->handle, offset, buf2, p_device->page_size
- Platform_STATUS platform_device_read(PLATFORM_DEVHANDLE deviceid,
- uint32_t offset,
- uint8_t *buf,
- uint32_t len)
- {
- IFPRINT(platform_write("platform_device_read(handle=0x%x, offset=%d, len=%d, buf=0x%x) called n",
- deviceid, offset, len, buf));
- if (buf == NULL || len == 0) {
- platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT;
- return Platform_EINVALID;
- }
- #if (PLATFORM_NAND_IN)
- if (deviceid == PLATFORM_DEVID_MT29F1G08ABCHC) {
- NAND_ADDR addr;
- uint32_t read_len = 0;
- addr.uiColumnAddr= 0;
- for (read_len = 0; read_len < len; read_len += gDeviceNand.page_size)
- {
- if (platform_offset_to_blocknpage(deviceid, offset+read_len, &addr.uiBlockAddr, &addr.uiPageAddr) != Platform_EOK) {
- return Platform_EUNSUPPORTED;
- }
- if (readNandPage (&gDeviceNand, addr, &buf[read_len]) != SUCCESS) {
- return ( (Platform_STATUS) Platform_EFAIL);
- }
- }
-
- return Platform_EOK;
- }
- #endif
- #if (PLATFORM_NOR_IN)
- if (deviceid == PLATFORM_DEVID_NORN25Q032A) {
- if (nor_read (&gDeviceNor, offset, len, buf) != SUCCESS) {
- return ( (Platform_STATUS) Platform_EFAIL);
- }
- return Platform_EOK;
- }
- #endif
- #if (PLATFORM_EEPROM_IN)
- if (deviceid == PLATFORM_DEVID_EEPROM50) {
- if (i2cEepromRead (offset, len, buf, 0x50) != I2C_RET_OK) {
- IFPRINT(platform_write("platform_eeprom_read: EEPROM read failedn"));
- return ( (Platform_STATUS) Platform_EFAIL);
- }
- return Platform_EOK;
- }
- if (deviceid == PLATFORM_DEVID_EEPROM51) {
- if (i2cEepromRead (offset, len, buf, 0x51) != I2C_RET_OK) {
- IFPRINT(platform_write("platform_eeprom_read: EEPROM read failedn"));
- return ( (Platform_STATUS) Platform_EFAIL);
- }
- return Platform_EOK;
- }
- #endif
- return Platform_EUNSUPPORTED;
- }
复制代码
2.1 Nandflash 读操作
- #if (PLATFORM_NAND_READ_IN)
- uint32_t readNandPage(PLATFORM_DEVICE_info *p_device, NAND_ADDR address, uint8_t* puchBuffer)
- {
- int32_t i = 0;
- uint8_t *puchSpareAreaBuf;
- // uint8_t puchSpareAreaBuf[64];
- uint8_t *pBuffer_loc;
- uint32_t uiAddr;
- uint32_t ret_val = SUCCESS;
- // uint8_t status;
- int32_t iIteration;
- int32_t byte_count = 0;
- /* ECC locations for the micron nand device */
- uint8_t eccLoc[4*NAND_MAX_NUM_ECC_BYTES] = { 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46
- };
- uint8_t eccCalc[4*NAND_MAX_NUM_ECC_BYTES];
- uint8_t eccCode[4*NAND_MAX_NUM_ECC_BYTES];
- if(puchBuffer == NULL)
- return NULL_POINTER_ERROR;
- pBuffer_loc = nandPageBuf;
- puchSpareAreaBuf = nandPageBuf + BYTES_PER_PAGE;
- if (NandReadSpareArea(p_device, address.uiBlockAddr, address.uiPageAddr, puchSpareAreaBuf) != SUCCESS)
- return FAIL;
- platform_delay(10);
- /*
- * Send address of the block + page to be read
- * Address cycles = 4, Block shift = 10, Page Shift = 6
- */
- for (iIteration = 0; iIteration < 4; iIteration++) {
- uiAddr = PACK_ADDR(byte_count, address.uiPageAddr, address.uiBlockAddr);
- /***********************READ A Command***************************************/
- NandCmdSet(NAND_PAGE_READ); // First cycle send 0
- platform_delay(10);
- NandAleSet((uiAddr >> 0u) & 0xFF); // CA0-CA7 1st Cycle; column addr
- NandAleSet((uiAddr >> 8u) & 0x0F); // CA8-CA11 and Upper Nibble Low 2nd Cycle; colum addr
- NandAleSet((uiAddr >> 16u) & 0xFF); // PA0-PA5 and BA9 -BA8 3rd Cycle;Page addr & Block addr
- NandAleSet((uiAddr >> 24u) & 0xFF); // BA7 to BA0 4th Cycle; Block addr
- NandCmdSet(0x30); // Last cycle send 30h command
- platform_delay(EMIF16_WAIT_PIN_POLL_ST_DLY);
- /* Wait for Ready Busy Pin to go HIGH */
- ret_val = NandWaitRdy(EMIF16_NAND_PROG_TIMEOUT);
- if (ret_val != SUCCESS) {
- platform_errno = PLATFORM_ERRNO_DEV_TIMEOUT;
- return FAIL;
- }
- /* Start 4-bit ECC HW calculation for read */
- CSL_FINS(hEmif16Cfg->NANDFCTL, EMIF16_NANDFCTL_4BIT_ECC_ST , 1);
- /* Read the data to the destination buffer and detect error */
- NandReadDataBytes(512, pBuffer_loc);
- platform_delay(10);
- /* Calculate the 4-bit ECC bytes for read */
- NandCalculate4bitECC(TRUE, &eccCalc[iIteration*10]);
- CSL_FINS(hEmif16Cfg->NANDFCTL, EMIF16_NANDFCTL_4BIT_ECC_ST , 0);
- for (i = 0; i < NAND_MAX_NUM_ECC_BYTES; i++)
- {
- eccCode[(iIteration * 10) + i] = puchSpareAreaBuf[eccLoc[(iIteration * 10) + i]];
- }
- if (NandCorrect4bitECC(pBuffer_loc, &eccCode[iIteration * 10]) < 0)
- {
- return FAIL;
- }
- pBuffer_loc += 512;
- byte_count += 512;
- }
- memcpy(puchBuffer, nandPageBuf, gDeviceNand.page_size);
- return SUCCESS;
- }
复制代码
读操作完全按页操作,手册可以见前文。
总结:Nandflash操作 无非是读,写,擦除等。一般需要先判断坏块,(擦除完成后,看标志位是否为0xFF,要是为0x00则为坏块),需要单独存放在坏块列表中。在以后的操作中需要比较坏块列表中Block的地址。
0
|
|
|
|