1.在设备树中添加flash
&dspi {
fpga_flash@3 {
compatible = "w25q32";
reg = <3>;
spi-max-frequency = <10000000>;
};
};
2.在内核菜单添加对应驱动
│-> Device Drivers
│ -> Memory Technology Device (MTD) support (MTD [=y])
│ (1) -> Self-contained MTD device drivers
│<*> Support most SPI Flash chips (AT26DF, M25P, W25X, …)
3.读写/dev/下flash文件
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#define FLASH_MAX_SIZE (4 * 1024 * 1024)
#define FLASH_PAGE_SIZE (64*1024)
static void pabort(const char *s)
{
perror(s);
abort();
}
static uint32_t mode;
static uint8_t bits = 8;
static uint32_t speed = 10000000;
static uint16_t delay;
/*
* flash 读写配置
*/
static void transfer(int fd, const char* tx, const char* rx, size_t len)
{
int ret = 0;
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = len,
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pabort("can't send spi-flash message");
}
static void print_tip(void)
{
printf("./flash read [read.txt] ----read flash to read.txt \r\n");
printf("./flash write [write.txt] ----write write.txt to flash and read flash to read.txt\r\n");
printf("./flash clean ----flash earse \r\n");
}
static int flash_write(int device_fd, int write_filefd, unsigned int length)
{
int bit = length % FLASH_PAGE_SIZE;
int page = length / FLASH_PAGE_SIZE;
unsigned char filebuf[FLASH_PAGE_SIZE];
while (page--) {
read(write_filefd, filebuf, FLASH_PAGE_SIZE);
write(device_fd, filebuf, FLASH_PAGE_SIZE);
}
if (bit) {
read(write_filefd, filebuf, bit);
write(device_fd, filebuf, bit);
}
return 0;
}
static int flash_read(int device_fd, int read_filefd, unsigned int length)
{
int bit = length % FLASH_PAGE_SIZE;
int page = length / FLASH_PAGE_SIZE;
unsigned char filebuf[FLASH_PAGE_SIZE];
printf("bit = %d\n", bit);
printf("page = %d\n", page);
while (page--) {
read(device_fd, filebuf, FLASH_PAGE_SIZE);
write(read_filefd, filebuf, FLASH_PAGE_SIZE);
}
if (bit) {
read(device_fd, filebuf, bit);
write(read_filefd, filebuf, bit);
}
return 0;
}
/*
* MAIN
*/
int main(int argc, char *argv[])
{
unsigned int length;
int read_filefd, write_filefd, device_fd;
const char *str_cmd = NULL;
char *read_fileName = NULL;
char *write_fileName = NULL;
char *device = "/dev/mtd4";
char cmd_sh[128];
if (3 == argc){
str_cmd = argv[1];
switch (*str_cmd) {
case 'w': //write
write_fileName = argv[2];
device_fd = open(device, O_RDWR);
if (device_fd < 0) {
printf("can't open %s\n", device);
return -1;
}
write_filefd = open(write_fileName, O_RDWR);
if (write_filefd < 0) {
printf("can't open %s\n", read_filefd);
return -1;
}
flash_write(device_fd, write_filefd, FLASH_MAX_SIZE);
close(write_filefd);
close(device_fd);
break;
case 'r': //read
read_fileName = argv[2];
device_fd = open(device, O_RDWR);
if (device_fd < 0) {
printf("can't open %s\n", device);
return -1;
}
read_filefd = open(read_fileName, O_RDWR);
if (read_filefd < 0) {
printf("can't open %s\n", read_filefd);
return -1;
}
flash_read(device_fd, read_filefd, FLASH_MAX_SIZE);
close(read_filefd);
close(device_fd);
break;
default:
print_tip();
break;
}
} else if (2 == argc) {
str_cmd = argv[1];
switch (*str_cmd) {
case 'c': //clean
sprintf(cmd_sh, "flash_erase /dev/mtd4 0 0");
execl("/bin/sh", "sh", "-c", cmd_sh, (char *)0);
printf("flash clean earse\n");
break;
default:
print_tip();
break;
}
} else {
print_tip();
}
return 0;
}