Linux下spi读写flash

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;
}

  • 0
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值