欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 单片机 flash 擦写(先擦除 后写任意字节)

单片机 flash 擦写(先擦除 后写任意字节)

2025/3/10 15:32:53 来源:https://blog.csdn.net/qq_20017379/article/details/140957772  浏览:    关键词:单片机 flash 擦写(先擦除 后写任意字节)

很多情况下,我们写扇区病不一定512对齐,甚至有的情况下跨扇区读写,为了满足这个需求,进行判断先擦除再写,并且不影响之前扇区的数据

擦除再写:

#define FLASH_TOTAL      0x50000 // 共320K
#define BLOCK_START_ADDR 0x2F800 // 前190K为COS预留空间
#define PAGE_SIZE        512     // ! 注意这里并不是页大小,而是可以擦除的最小单位/*** @description: 先擦除再写* @detail:* @return {*}* @author: lkc*/
ULONG DRV_FLASHWriteWithErase(UCHAR *pucSrc, ULONG ulDes, ULONG ulBytelen)
{USHORT unalignment_bytes1 = 0, unalignment_bytes2 = 0, totle_len = 0;UCHAR buf1[PAGE_SIZE], buf2[PAGE_SIZE], i;if (ulBytelen <= 0 || ulDes < BLOCK_START_ADDR || (ulDes + ulBytelen) >= FLASH_TOTAL) {return FALSE;}/*判断是否地址PAGESIZEbyte对齐*/if ((ulDes % PAGE_SIZE) != 0) {unalignment_bytes1 = ulDes % PAGE_SIZE; // X1的数据长度,即需要保护的数据DRV_FlashRead(buf1, ulDes - unalignment_bytes1, unalignment_bytes1); // 读取X1的数据到buf1中}/*判断写入长度PAGESIZE字节对齐,*/if (((ulDes + ulBytelen) % PAGE_SIZE) != 0) {unalignment_bytes2 = PAGE_SIZE - (ulDes + ulBytelen) % PAGE_SIZE; // X2的数据长度DRV_FlashRead(buf2, ulDes + ulBytelen, unalignment_bytes2);       // 读取X2的数据到buf2中}/*数据拼接*/totle_len = ulBytelen + unalignment_bytes1 + unalignment_bytes2;/*擦除从地址des-unalignment_bytes1开始的n页,n = totle_len/PAGE_SIZE*/DRV_FLASHEraseN(ulDes - unalignment_bytes1, totle_len / PAGE_SIZE);/*当只有一页*/if (totle_len / PAGE_SIZE == 1) {memcpy(buf1 + unalignment_bytes1, pucSrc, ulBytelen);memcpy(buf1 + unalignment_bytes1 + ulBytelen, buf2, unalignment_bytes2);DRV_FlashWrite(buf1, ulDes - unalignment_bytes1, PAGE_SIZE);} else {for (i = 0; i < totle_len / PAGE_SIZE; i++) {if (i == 0) {memcpy(buf1 + unalignment_bytes1, pucSrc, PAGE_SIZE - unalignment_bytes1);} else if (i == (totle_len / PAGE_SIZE - 1)) {memcpy(buf1, pucSrc + ulBytelen - (PAGE_SIZE - unalignment_bytes2), PAGE_SIZE - unalignment_bytes2);memcpy(buf1 + PAGE_SIZE - unalignment_bytes2, buf2, unalignment_bytes2);} else {memcpy(buf1, pucSrc + PAGE_SIZE - unalignment_bytes1 + (i - 1) * PAGE_SIZE, PAGE_SIZE);}DRV_FlashWrite(buf1, ulDes - unalignment_bytes1 + i * PAGE_SIZE, PAGE_SIZE);} }return SUCCESS;
}

 擦除多扇区:

VOID DRV_FLASHEraseN(ULONG ulAddr, ULONG ulPageN)
{unsigned int i = 0;for (i = 0; i < ulPageN; i++) {DRV_FlashErasePage(ulAddr + i * PAGE_SIZE);}
}

读写擦除接口:

/*** @description: 读取flash* @detail:* @param {UCHAR} *pucBuf 读取buf* @param {ULONG} ulSrcAddr 地址* @param {ULONG} ulBytelen 字节长度* @return {*}* @author: lkc*/
VOID DRV_FlashRead(UCHAR *pucBuf, ULONG ulSrcAddr, ULONG ulBytelen)
{if ((NULL == pucBuf) || (0 == ulBytelen)) {return;}if ((ulSrcAddr + ulBytelen) > FLASH_TOTAL) {return;}// 实现return;
}/*** @description: flash写* @detail:* @param {UCHAR} *pucBuf 写buf* @param {UINT32} ulDstAddr 目的地址* @param {ULONG} ulBytelen 字节长度* @return {*}* @author: lkc*/
VOID DRV_FlashWrite(UCHAR *pucBuf, ULONG ulDstAddr, ULONG ulBytelen)
{if ((NULL == pucBuf) || (0 == ulBytelen)) {return;}if ((ulDstAddr + ulBytelen) > FLASH_TOTAL) {return;}// 实现return;
}/*** @description: flash单页擦除* @detail:* @param {UCHAR} *pucBuf 写buf* @param {UINT32} ulDstAddr 目的地址* @param {ULONG} ulBytelen 字节长度* @return {*}* @author: lkc*/
VOID DRV_FlashErasePage(ULONG ulAddress)
{// 实现return;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词