能帮我写一份fal_flash_stm32f1.c吗?
时间: 2024-05-11 17:18:03 浏览: 179
当然可以,以下是一个简单的fal_flash_stm32f1.c示例代码,你可以根据自己的具体需求进行修改和优化:
```
#include "fal.h"
#include "fal_flash_stm32f1.h"
/* 定义fal_flash_stm32f1设备结构体 */
static struct fal_flash_dev stm32f1_flash = {
.name = "stm32f1_flash",
.addr_start = 0x08000000, /* flash起始地址 */
.addr_end = 0x080FFFFF, /* flash结束地址 */
.page_size = FLASH_PAGE_SIZE, /* flash每页大小 */
.ops = {
.init = fal_flash_stm32f1_init,
.read = fal_flash_stm32f1_read,
.write = fal_flash_stm32f1_write,
.erase = fal_flash_stm32f1_erase,
},
};
/* fal_flash_stm32f1初始化函数 */
int fal_flash_stm32f1_init(void)
{
/* stm32f1_flash设备初始化 */
return fal_flash_dev_register(&stm32f1_flash);
}
/* fal_flash_stm32f1读取函数 */
int fal_flash_stm32f1_read(fal_flash_t dev, uint32_t offset, void *buf, size_t size)
{
uint32_t addr = dev->addr_start + offset;
memcpy(buf, (const void *)addr, size);
return 0;
}
/* fal_flash_stm32f1写入函数 */
int fal_flash_stm32f1_write(fal_flash_t dev, uint32_t offset, const void *buf, size_t size)
{
uint32_t addr = dev->addr_start + offset;
uint32_t end_addr = addr + size;
uint32_t page_addr = addr & ~(dev->page_size - 1);
uint32_t end_page_addr = end_addr & ~(dev->page_size - 1);
uint32_t page_offset = addr - page_addr;
uint32_t *page_buf = (uint32_t *)fal_cache_alloc(dev->page_size);
/* 判断写入的数据是否跨页 */
if (page_addr == end_page_addr) {
/* 不跨页,直接写入数据 */
memcpy((void *)page_buf, (const void *)page_addr, dev->page_size);
memcpy((void *)((uint32_t)page_buf + page_offset), buf, size);
HAL_FLASH_Unlock();
for (uint32_t i = 0; i < dev->page_size / 4; i++) {
HAL_FLASH_Program(
FLASH_TYPEPROGRAM_WORD,
page_addr + i * 4,
*(page_buf + i)
);
}
HAL_FLASH_Lock();
} else {
/* 跨页,需要分别处理 */
uint32_t first_size = dev->page_size - page_offset;
memcpy((void *)page_buf, (const void *)page_addr, dev->page_size);
memcpy((void *)((uint32_t)page_buf + page_offset), buf, first_size);
HAL_FLASH_Unlock();
for (uint32_t i = 0; i < dev->page_size / 4; i++) {
HAL_FLASH_Program(
FLASH_TYPEPROGRAM_WORD,
page_addr + i * 4,
*(page_buf + i)
);
}
HAL_FLASH_Lock();
for (uint32_t i = 0; i < (end_addr - end_page_addr) / 4; i++) {
HAL_FLASH_Unlock();
HAL_FLASH_Program(
FLASH_TYPEPROGRAM_WORD,
end_page_addr + i * 4,
*((uint32_t *)buf + first_size / 4 + i)
);
HAL_FLASH_Lock();
}
}
fal_cache_free(page_buf);
return 0;
}
/* fal_flash_stm32f1擦除函数 */
int fal_flash_stm32f1_erase(fal_flash_t dev, uint32_t offset, size_t size)
{
uint32_t addr = dev->addr_start + offset;
uint32_t end_addr = addr + size;
uint32_t page_addr = addr & ~(dev->page_size - 1);
uint32_t end_page_addr = end_addr & ~(dev->page_size - 1);
/* 判断擦除的数据是否跨页 */
if (page_addr == end_page_addr) {
/* 不跨页,直接擦除 */
HAL_FLASH_Unlock();
FLASH_ErasePage(page_addr);
HAL_FLASH_Lock();
} else {
/* 跨页,需要分别处理 */
HAL_FLASH_Unlock();
FLASH_ErasePage(page_addr);
HAL_FLASH_Lock();
for (uint32_t addr = page_addr + dev->page_size; addr < end_page_addr; addr += dev->page_size) {
HAL_FLASH_Unlock();
FLASH_ErasePage(addr);
HAL_FLASH_Lock();
}
HAL_FLASH_Unlock();
FLASH_ErasePage(end_page_addr);
HAL_FLASH_Lock();
}
return 0;
}
```
阅读全文