fal_flash_stm32f1
时间: 2023-09-16 16:07:13 浏览: 46
fal_flash_stm32f1是一个用于在STM32F1系列微控制器上进行Flash存储器编程的开源库。它提供了一组API,可以用于擦除、编程和读取Flash存储器,以及管理Flash存储器的擦除和编程保护。fal_flash_stm32f1库支持多种芯片型号和Flash存储器大小,并且可以与其他库和工具链一起使用,包括STM32CubeMX和Keil MDK等。该库可以在GitHub上获取,并且使用BSD3许可证发布,因此可以免费用于商业和非商业用途。
相关问题
fal_flash_stm32f1.c
fal_flash_stm32f1.c 是一份针对 STMicroelectronics STM32F1 系列微控制器的 fal(Flash Abstraction Layer)驱动程序,用于在嵌入式系统中对 STM32F1 系列芯片的闪存进行读写操作。该驱动程序实现了对 STM32F1 系列芯片内部 Flash 的分页、擦除和编程等操作,以及对 Flash 的保护机制进行控制。
能帮我写一份fal_flash_stm32f1.c吗?
当然可以,以下是一个简单的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;
}
```