文章目录
如果我们不想使用文件系统,要直接读写spi flash,直接调用read和write就行了,但是read和write是读写一个扇区的,不能随机地址读写,如果要随机读写一个地址,需要对其进行封装一下。
这里直接上代码了,代码也比较简单,就不注释了。
#include "spi_flash.h"
#include <rtthread.h>
#define SPI_FLASH_SECTOR_MAX_SIZE 4096
static struct rt_mutex spi_flash_mutex;
static unsigned char flash_buf[SPI_FLASH_SECTOR_MAX_SIZE];
static rt_device_t spi_flash_dev;
static struct rt_device_blk_geometry spi_flash_geometry;
rt_err_t spi_flash_init(const char *flash_name)
{
rt_err_t res = RT_ERROR;
rt_mutex_init(&spi_flash_mutex, "flash_mtx", RT_IPC_FLAG_FIFO);
spi_flash_dev = rt_device_find(flash_name);
if (!spi_flash_dev) {
rt_kprintf("find %s failed!\n", flash_name);
return res;
}
res = rt_device_open(spi_flash_dev, RT_DEVICE_OFLAG_RDWR);
if (res != RT_EOK) {
rt_kprintf("open spi_flash_dev failed!\n");
return res;
}
rt_kprintf("initialize spiFlash success!\n");
res = rt_device_control(spi_flash_dev, RT_DEVICE_CTRL_BLK_GETGEOME, &spi_flash_geometry);
rt_kprintf("block_size : %d, bytes_per_sector : %d, sector_count : %d\n",
spi_flash_geometry.block_size, spi_flash_geometry.bytes_per_sector, spi_flash_geometry.sector_count);
return res;
}
rt_err_t spi_flash_read(rt_uint8_t flash_id, rt_uint32_t addr, rt_uint8_t *buffer, rt_uint32_t buffer_len)
{
rt_device_t flash_dev;
struct rt_device_blk_geometry *geometry;
rt_uint32_t sector = 0;
rt_uint32_t offset = 0;
rt_uint32_t remain = 0;
rt_mutex_take(&spi_flash_mutex, RT_WAITING_FOREVER);
flash_dev = spi_flash_dev;
geometry = &spi_flash_geometry;
if (flash_dev == RT_NULL) {
rt_mutex_release(&spi_flash_mutex);
return -RT_ERROR;
}
sector = addr/geometry->bytes_per_sector;
offset = addr%geometry->bytes_per_sector;
remain = geometry->bytes_per_sector - offset;
if (remain >= buffer_len)
remain = buffer_len;
if (sector >= geometry->sector_count || buffer_len > geometry->bytes_per_sector) {
rt_kprintf("spi_flash_read failed. sector : %d >= %d, buffer_len : %d > %d\n",
sector, geometry->sector_count, buffer_len, geometry->bytes_per_sector);
rt_mutex_release(&spi_flash_mutex);
return -RT_ERROR;
}
while (1) {
rt_device_read(flash_dev, sector, flash_buf, 1);
rt_memcpy(buffer, &flash_buf[offset], remain);
if (remain == buffer_len) {
break;
} else {
buffer += remain;
buffer_len -= remain;
offset = 0;
++sector;
if (buffer_len > geometry->bytes_per_sector)
remain = geometry->bytes_per_sector;
else
remain = buffer_len;
}
}
rt_mutex_release(&spi_flash_mutex);
return RT_EOK;
}
rt_err_t spi_flash_write(rt_uint8_t flash_id, rt_uint32_t addr, rt_uint8_t *buffer, rt_uint32_t buffer_len)
{
rt_err_t res = -RT_ERROR;
rt_device_t flash_dev;
struct rt_device_blk_geometry *geometry;
rt_uint32_t sector = 0, offset = 0, remain = 0;
rt_mutex_take(&spi_flash_mutex, RT_WAITING_FOREVER);
flash_dev = spi_flash_dev;
geometry = &spi_flash_geometry;
if (flash_dev == RT_NULL) {
rt_mutex_release(&spi_flash_mutex);
return -RT_ERROR;
}
sector = addr/geometry->bytes_per_sector;
offset = addr%geometry->bytes_per_sector;
remain = geometry->bytes_per_sector - offset;
if (remain >= buffer_len)
remain = buffer_len;
while (1) {
if (sector >= geometry->sector_count) {
rt_kprintf("bsk_flash_write failed. sector : %d >= %d\n", sector, geometry->sector_count);
return -RT_ERROR;
}
rt_device_read(flash_dev, sector, flash_buf, 1);
rt_memcpy(&flash_buf[offset], buffer, remain);
rt_device_write(flash_dev, sector, flash_buf, 1);
if (remain == buffer_len) {
break;
} else {
buffer += remain;
buffer_len -= remain;
offset = 0;
++sector;
if (buffer_len > geometry->bytes_per_sector)
remain = geometry->bytes_per_sector;
else
remain = buffer_len;
}
}
res = RT_EOK;
ERR:
rt_mutex_release(&spi_flash_mutex);
return res;
}
rt_err_t spi_flash_erase(rt_uint8_t flash_id, rt_uint32_t sector)
{
rt_device_t flash_dev;
flash_dev = spi_flash_dev;
if (flash_dev == RT_NULL) {
return -RT_ERROR;
}
return rt_device_control(flash_dev, RT_DEVICE_CTRL_BLK_ERASE, §or);
}
FINSH_FUNCTION_EXPORT_ALIAS(spi_flash_erase, flash_erase, spi_flash_erase)
void flash_rd_test(int flash_id, int sector)
{
rt_uint32_t i;
rt_device_t flash_dev;
struct rt_device_blk_geometry *geometry;
flash_dev = spi_flash_dev;
geometry = &spi_flash_geometry;
if (flash_dev == RT_NULL) {
return ;
}
rt_device_read(flash_dev, sector, flash_buf, 1);
rt_kprintf("read sector : %d\n", sector);
for (i = 0; i < geometry->bytes_per_sector; ++i) {
if (i%64 == 0) {
rt_kprintf("\n");
}
rt_kprintf("%x ", flash_buf[i]);
}
rt_kprintf("\n");
}
FINSH_FUNCTION_EXPORT(flash_rd_test, flash_rd_test(flash_id,sector))
void flash_wr_test(int flash_id, int sector, rt_uint8_t value)
{
unsigned char buf[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
rt_device_t flash_dev;
struct rt_device_blk_geometry *geometry;
flash_dev = spi_flash_dev;
geometry = &spi_flash_geometry;
if (flash_dev == RT_NULL) {
return ;
}
spi_flash_write(flash_id, sector*geometry->bytes_per_sector, buf, 10);
}
FINSH_FUNCTION_EXPORT(flash_wr_test, flash_wr_test(id, sector, value))