FLASH操作
1.FAL组件
FAL组件的安装在我的其他章节中已经介绍过了,主要是先要将FLASH分块(区),然后在分块(区)中去处理。
->下面是我的分区,因为用到了串口升级功能,所以分了好多区(块)。
->这里面的设置放在了.h文件里面
//
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WORD, "bootloader", "onchip_flash", 0, 14 * 1024, 0}, \
{FAL_PART_MAGIC_WORD, "bootflag", "onchip_flash", 14 * 1024, 2 * 1024, 0}, \
{FAL_PART_MAGIC_WORD, "app", "onchip_flash", 16 * 1024, 184 * 1024, 0}, \
{FAL_PART_MAGIC_WORD, "eeprom", "onchip_flash", 200 * 1024, 12 * 1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */
-> 分块处理函数
// 块擦除函数
fal_partition_erase_all(fal_partition_find("bootflag")); //
// 块擦除函数,可以看到擦除的对象是*part部分起始地址为0偏移地址为块长度的区域
int fal_partition_erase_all(const struct fal_partition *part)
{
return fal_partition_erase(part, 0, part->len);
}
// 块擦除函数的区域操作,做地址偏移
int fal_partition_erase(const struct fal_partition *part, uint32_t addr, size_t size)
{
int ret = 0;
const struct fal_flash_dev *flash_dev = NULL;
//assert(part);
if (addr + size > part->len)
{
log_e("Partition erase error! Partition address out of bound.");
return -1;
}
flash_dev = fal_flash_device_find(part->flash_name);
if (flash_dev == NULL)
{
log_e("Partition erase error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name);
return -1;
}
ret = flash_dev->ops.erase(part->offset + addr, size); // error
if (ret < 0)
{
log_e("Partition erase error! Flash device(%s) erase error!", part->flash_name);
}
return ret;
}
// 块读取函数,读取到某指针(数组)
int fal_partition_read(const struct fal_partition *part, uint32_t addr, uint8_t *buf, size_t size)
{
int ret = 0;
const struct fal_flash_dev *flash_dev = NULL;
assert(part);
assert(buf);
if (addr + size > part->len)
{
log_e("Partition read error! Partition address out of bound.");
return -1;
}
flash_dev = fal_flash_device_find(part->flash_name);
if (flash_dev == NULL)
{
log_e("Partition read error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name);
return -1;
}
ret = flash_dev->ops.read(part->offset + addr, buf, size);
if (ret < 0)
{
log_e("Partition read error! Flash device(%s) read error!", part->flash_name);
}
return ret;
}
// 块写入函数,从某指针(数组)写入
int fal_partition_write(const struct fal_partition *part, uint32_t addr, const uint8_t *buf, size_t size)
{
int ret = 0;
const struct fal_flash_dev *flash_dev = NULL;
assert(part);
assert(buf);
if (addr + size > part->len)
{
log_e("Partition write error! Partition address out of bound.");
return -1;
}
flash_dev = fal_flash_device_find(part->flash_name);
if (flash_dev == NULL)
{
log_e("Partition write error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name);
return -1;
}
ret = flash_dev->ops.write(part->offset + addr, buf, size);
if (ret < 0)
{
log_e("Partition write error! Flash device(%s) write error!", part->flash_name);
}
return ret;
}
直接操作FLASH
相对于FAL,我比较喜欢直接操作FLASH,感觉更灵活。
FLASH 读
// FLASH读取函数
//addr-> 读取的地址
//buf读取数据保存的指针(数组)
//读取数据的大小(字节byte)
int stm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
{
size_t i;
if ((addr + size) > STM32_FLASH_END_ADDRESS)
{
LOG_E("read outrange flash size! addr is (0x%p)", (void *)(addr + size));
return -RT_EINVAL;
}
for (i = 0; i < size; i++, buf++, addr++)
{
*buf = *(rt_uint8_t *) addr;
}
return size;
}
FLASH 写
//不用擦除的写
//addr -> 写的起始地址
//buf -> 写入数据来源指针(数组)
//size -> 写入大小(字节byte)
int stm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
{
rt_err_t result = RT_EOK;
rt_uint32_t end_addr = addr + size;
if (addr % 4 != 0)
{
LOG_E("write addr must be 4-byte alignment");
return -RT_EINVAL;
}
if ((end_addr) > STM32_FLASH_END_ADDRESS)
{
LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size));
return -RT_EINVAL;
}
HAL_FLASH_Unlock();
while (addr < end_addr)
{
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, *((rt_uint32_t *)buf)) == HAL_OK)
{
if (*(rt_uint32_t *)addr != *(rt_uint32_t *)buf)
{
result = -RT_ERROR;
break;
}
addr += 4;
buf += 4;
}
else
{
result = -RT_ERROR;
break;
}
}
HAL_FLASH_Lock();
if (result != RT_EOK)
{
return result;
}
return size;
}
3.FAL组件对FLASH操作及FAL组件与FLASH底层之间的关系
调用关系
//
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size)
{
return stm32_flash_read(stm32_onchip_flash.addr + offset, buf, size);
}
static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size)
{
return stm32_flash_write(stm32_onchip_flash.addr + offset, buf, size);
}
static int fal_flash_erase(long offset, size_t size)
{
return stm32_flash_erase(stm32_onchip_flash.addr + offset, size);
}
OVER TY