一个 NAND flash写函数
分类:
文章
•
2025-03-17 19:41:34
-
-
一个刚看到时有点晕晕的flash的写函数,后来仔细看了后明白了;附上我的草稿图
-
-
int tls_fls_write(u32 addr, u8 *buf, u32 len)
-
{
-
u8 *cache;
-
int err;
-
u32 sector_addr;
-
u32 sector_num;
-
u32 write_bytes;
-
u32 i;
-
struct tls_fls_drv *drv;
-
-
if (spi_fls == NULL)
-
{
-
TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
-
return TLS_FLS_STATUS_EPERM;
-
}
-
-
if (spi_fls->current_drv == NULL)
-
{
-
TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
-
return TLS_FLS_STATUS_ENODRV;
-
}
-
-
if ((addr >= spi_fls->current_drv->total_size) || (len == 0)
-
|| (buf == NULL))
-
{
-
return TLS_FLS_STATUS_EINVAL;
-
}
-
tls_os_sem_acquire(spi_fls->fls_lock, 0);
-
drv = spi_fls->current_drv;
-
write_bytes =
-
((addr + len) > drv->total_size) ? (drv->total_size - addr) : len;
-
sector_addr = addr/drv->sector_size;
-
sector_num = (addr + write_bytes - 1)/drv->sector_size - sector_addr + 1;
-
-
TLS_DBGPRT_FLASH("write to flash: sector address - %d, sectors - %d.\n", sector_addr, sector_num);
-
-
err = TLS_FLS_STATUS_OK;
-
-
cache = tls_mem_alloc(drv->sector_size);
-
if (cache == NULL)
-
{
-
tls_os_sem_release(spi_fls->fls_lock);
-
TLS_DBGPRT_ERR("allocate sector cache memory(%dB) fail!\n", drv->sector_size);
-
return TLS_FLS_STATUS_ENOMEM;
-
}
-
-
for (i = 0; i < sector_num; i++)
-
{
-
TLS_DBGPRT_FLASH("firstly, read the sector - %d to cache.\n", sector_addr + i);
-
err = drv->read((sector_addr + i) * drv->sector_size, cache, drv->sector_size);
-
if (err != TLS_FLS_STATUS_OK)
-
{
-
tls_os_sem_release(spi_fls->fls_lock);
-
TLS_DBGPRT_ERR("flash read fail(sector %d)!\n", (sector_addr + i));
-
break;
-
}
-
-
if (1 == sector_num){/*flash write only in one sector*/
-
MEMCPY(cache + (addr%drv->sector_size), buf, write_bytes);
-
buf += write_bytes;
-
write_bytes = 0;
-
}else{/*flash write through some sectors*/
-
if (0 == i) {
-
MEMCPY(cache+(addr%drv->sector_size), buf, drv->sector_size - (addr%drv->sector_size));
-
buf += drv->sector_size - (addr%drv->sector_size);
-
write_bytes -= drv->sector_size - (addr%drv->sector_size);
-
} else if (i == (sector_num - 1)) {
-
MEMCPY(cache, buf, write_bytes);
-
buf += write_bytes;
-
write_bytes = 0;
-
} else {
-
MEMCPY(cache, buf, drv->sector_size);
-
buf += drv->sector_size;
-
write_bytes -= drv->sector_size;
-
}
-
}
-
-
TLS_DBGPRT_FLASH("second, erase the sector - %d.\n", sector_addr + i);
-
err = drv->erase(sector_addr + i);
-
if (err != TLS_FLS_STATUS_OK)
-
{
-
tls_os_sem_release(spi_fls->fls_lock);
-
TLS_DBGPRT_ERR("flash erase fail(sector %d)!\n", (sector_addr + i));
-
break;
-
}
-
-
TLS_DBGPRT_FLASH("finnaly, write the data in cache to the sector - %d.\n", sector_addr + i);
-
err = tls_fls_page_write((sector_addr +i) * (drv->sector_size / drv->page_size),
-
cache, drv->sector_size / drv->page_size);
-
if (err != TLS_FLS_STATUS_OK)
-
{
-
tls_os_sem_release(spi_fls->fls_lock);
-
TLS_DBGPRT_ERR("flash write fail(sector %d)!\n", (sector_addr + i));
-
break;
-
}
-
}
-
-
tls_mem_free(cache);
-
tls_os_sem_release(spi_fls->fls_lock);
-
return err;
-
}
