读写Flash数据分区
使用基于XTC-Tool的quadflash.h和quadflashlib.h对Flash进行读写,本笔记提供了其代码示例:
-
初始化存储设备:
- 使用
fl_connectToDevice函数连接到特定的闪存设备。 - 设置引导分区大小。
- 获取每页的字节数和每块的页数。
- 使用
-
写入操作 (
massStorageWrite):- 将数据写入到闪存的特定块中。
- 每次写入前,数据被复制到
pageBuffer_g,然后使用fl_writeDataPage函数写入。
-
读取操作 (
massStorageRead):- 从闪存的特定块中读取数据。
- 使用
fl_readDataPage函数读取数据到pageBuffer_g,然后复制到输出缓冲区。
-
计算存储大小 (
massStorageSize):- 计算总共可用于数据存储的块数。
-
主函数 (
main):- 执行初始化。
- 创建测试数据并填充到写缓冲区。
- 写入数据到闪存并计算写入速度。
- 读取数据并计算读取速度。
- 验证读取的数据是否与写入的数据相同。
- 输出测试结果。
get_time() 函数是一个包装函数,它调用 get_reference_time() 来获取当前时间。
由于 get_reference_time() 只能在 C 文件中使用,而不能在 XC 文件中使用,所以 get_time() 提供了一个兼容的接口,使得可以在 XC 文件中间接使用 get_reference_time()。在 C 文件中定义 get_time() 函数时,需要包含 <xcore/hwtimer.h> 头文件。
#include <stdio.h>
#include <xcore/hwtimer.h>
uint32_t get_time()
{
return get_reference_time();
}
Flash数据分区的读写示例代码
#include <xs1.h>
#include <platform.h>
#include <xclib.h>
#include <string.h>
#include <stdio.h>
#include "stdint.h"
#include "print.h"
//Flash_Functions_start
#include <quadflash.h>
#include <quadflashlib.h>
extern uint32_t get_time();
#define FL_QUADDEVICE_UC25HQ40 \
{ \
0, /* UC25HQ16B_QSPI - Just specify 0 as flash_id */\
256, /* page size */\
2048, /* num pages */\
3, /* address size */\
3, /* log2 clock divider */\
0x9F, /* QSPI_RDID */\
0, /* id dummy bytes */\
3, /* id size in bytes */\
0xB36013, /* device id */\
0x20, /* QSPI_SE */\
4096, /* Sector erase is always 4KB */\
0x06, /* QSPI_WREN */\
0x04, /* QSPI_WRDI */\
PROT_TYPE_NONE, /* Protection via SR */\
{{0,0},{0x00,0x00}}, /* QSPI_SP, QSPI_SU */\
0x02, /* QSPI_PP */\
0xEB, /* QSPI_READ_FAST */\
1, /* 1 read dummy byte */\
SECTOR_LAYOUT_REGULAR, /* mad sectors */\
{4096,{0,{0}}}, /* regular sector sizes */\
0x05, /* QSPI_RDSR */\
0x01, /* QSPI_WRSR */\
0x01, /* QSPI_WIP_BIT_MASK */\
}
on tile[0]: fl_QSPIPorts QspiPort =
{
XS1_PORT_1B, /* PORT_SQI_CS */
XS1_PORT_1C, /* PORT_SQI_SCLK */
XS1_PORT_4B, /* PORT_SQI_SIO */
XS1_CLKBLK_1
};
#define MASS_STORAGE_BLOCKLENGTH 256
#define FLASH_PARTITION_SIZE (65536/* page size: 256 */ * 4) // Boot Partition size
fl_QuadDeviceSpec flashSpec[1] = {FL_QUADDEVICE_UC25HQ40};
int pagesPerBlock_g = 0;
int bytesPerPage_g = 0;
unsigned char pageBuffer_g[MASS_STORAGE_BLOCKLENGTH];
void massStorageInit() {
fl_connectToDevice(QspiPort, flashSpec, 1);
fl_setBootPartitionSize(FLASH_PARTITION_SIZE);
bytesPerPage_g = fl_getPageSize();
pagesPerBlock_g = (MASS_STORAGE_BLOCKLENGTH / bytesPerPage_g);
}
int massStorageWrite(unsigned int blockNr, unsigned char buffer[]) {
for(int i = 0; i < pagesPerBlock_g; i++) {
for(int j = 0; j < bytesPerPage_g; j++) {
pageBuffer_g[j] = buffer[i * bytesPerPage_g + j];
}
fl_writeDataPage(blockNr * pagesPerBlock_g + i, buffer);
}
return 0;
}
int massStorageRead(unsigned int blockNr, unsigned char buffer[]) {
for(int i = 0; i < pagesPerBlock_g; i++) {
fl_readDataPage(blockNr * pagesPerBlock_g + i, pageBuffer_g);
for(int j = 0; j < bytesPerPage_g; j++) {
buffer[i * bytesPerPage_g + j] = pageBuffer_g[j];
}
}
return 0;
}
int massStorageSize() {
int x = fl_getNumDataPages();
return x / pagesPerBlock_g;
}
void print_data(const char* label, const unsigned char* data, size_t size) {
printf("%s: ", label);
for (size_t i = 0; i < size; ++i) {
printf("%02X ", data[i]);
}
printf("\n");
}
int main()
{
printf("The Flash data partition read and write test starts\n\n");
// 初始化存储设备
massStorageInit();
int numDataPages = fl_getNumDataPages();
int numBlocks = massStorageSize();
printf("Total number of data pages: %d\n", numDataPages);
printf("Size of each block: %d pages\n", pagesPerBlock_g);
// 创建测试缓冲区并填充数据
unsigned char testWriteBuffer[MASS_STORAGE_BLOCKLENGTH];
for (int i = 0; i < MASS_STORAGE_BLOCKLENGTH; ++i) {
testWriteBuffer[i] = i % 256; // 填充测试数据
}
// 打印写入的数据
print_data("Write Data", testWriteBuffer, MASS_STORAGE_BLOCKLENGTH/16);
// 写入数据到指定块
unsigned int testBlockNr = 0; // 测试块号
uint32_t writeStart = get_time();
massStorageWrite(testBlockNr, testWriteBuffer);
uint32_t writeEnd = get_time();
double writeSpeedBytesPerSec = MASS_STORAGE_BLOCKLENGTH / ((writeEnd - writeStart) / 1e9);
// 打印写入数据的块号、大小和速度(MB/s)
printf("Written block number: %u\n", testBlockNr);
printf("Written block size: %u bytes\n", MASS_STORAGE_BLOCKLENGTH);
printf("Write speed: %.2f MB/s\n", writeSpeedBytesPerSec / 1e6);
printf("Bytes that can be written in 1 second: %.0f bytes\n", writeSpeedBytesPerSec);
// 清除测试缓冲区
unsigned char testReadBuffer[MASS_STORAGE_BLOCKLENGTH] = {0};
// 读取数据
uint32_t readStart = get_time();
massStorageRead(testBlockNr, testReadBuffer);
uint32_t readEnd = get_time();
double readSpeedBytesPerSec = MASS_STORAGE_BLOCKLENGTH / ((readEnd - readStart) / 1e9);
// 打印读取的数据
print_data("Read Data", testReadBuffer, MASS_STORAGE_BLOCKLENGTH/16);
// 打印读取数据的块号、大小和速度(MB/s)
printf("Read block number: %u\n", testBlockNr);
printf("Read block size: %u bytes\n", MASS_STORAGE_BLOCKLENGTH);
printf("Read speed: %.2f MB/s\n", readSpeedBytesPerSec / 1e6);
printf("Bytes that can be read in 1 second: %.0f bytes\n", readSpeedBytesPerSec);
// 验证数据
int isDataValid = (memcmp(testReadBuffer, testWriteBuffer, MASS_STORAGE_BLOCKLENGTH) == 0);
// 输出测试结果
if (isDataValid) {
printf("Mass storage read/write test passed.\n");
} else {
printf("Mass storage read/write test failed.\n");
}
}