加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

arm板子写flash(2)

发布时间:2020-12-15 19:54:16 所属栏目:百科 来源:网络整理
导读:arm板子写flash(2) imx6arm板子写spiflash的代码第一篇博客地址在下面,这里主要写一下测试,我们不知道我们写进入的数据是否正确,前面把写进入的数据读出去进行打印,当文件为几兆字节时,密密麻麻的二级制怎么看, 这里测试写入一些exe,pdf文件进行测

arm板子写flash(2)

imx6arm板子写spiflash的代码第一篇博客地址在下面,这里主要写一下测试,我们不知道我们写进入的数据是否正确,前面把写进入的数据读出去进行打印,当文件为几兆字节时,密密麻麻的二级制怎么看, 这里测试写入一些exe,pdf文件进行测试。
http://www.voidcn.com/article/p-fnzxdeto-bpg.html

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <string.h>
/* * write a file to spi_flash */
#define W25_WRITE_ENABLE 0x06
#define W25_WRITE_DISABLE 0x04
#define W25_READ_STATUS_1 0x05
#define W25_READ_STATUS_2 0x35
#define W25_WRITE_STATUS 0x01
#define w25_WRITE_SATTUS_ENABLE 0x50
#define W25_READ_DATA 0x03
#define W25_READ_FAST_DATA 0x0B
#define W25_ERASE_SECTOR 0x20
#define W25_ERASE_BLOCK 0xD8
#define W25_ERASE_CHIP 0xc7
#define W25_PAGE_PROGRAM 0x02
#define W25_CHIP_ID 0x9F
#define RDSR_CNT 1000

#define W25_SR_BUSY 0x01
#define FLASH_MAX_SIZE (8*1024*1024) 
#define ONE_SELECTOR_SIZE (4*1024)
#define WRITE_READ_ONCE_SIZE 256
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

static const char* spi_device = "/dev/spidev2.2";
static unsigned char mode;
static unsigned char bits = 8;
static unsigned int speed = 3000000;
static unsigned short delay;
static unsigned char buf[256] = {0};
static unsigned char rxbuffer[1];   
static unsigned char txbuffer[260];

static int getFileSize(const char* name);
static void dis_array(const char* info,const unsigned char* buf,unsigned int len);
static int w25_write_read(int fd,const char* wbuf,unsigned int wlen,const char* rbuf,unsigned int rlen);
static int wait_for_idle(int fd);
static int write_spiflash(int fd,char* buf,int offset,int address_one,int address_two,int address_three);
static int write_spiflash_finally(int fd,int num,int address_three);
static void read_spiflash(int fd,int address_three);
static void read_spiflash_savefile(int fd,FILE* savefd,int address_three);
static void write_enable(int fd);
static void selector_erase(int fd,int address_three);
static void print_chipID(int fd);
static void write_status_register(int fd);
static void read_spiflash_savefile_finally(int fd,int  address_one,int address_three);

/* * return file size (bytes) */
static int getFileSize(const char* name){
    FILE * pFile = fopen(name,"rb+");
    if(pFile == NULL){
        printf("cout errorn");
        return -1;
    }
    fseek(pFile,0,SEEK_END);
    int length = ftell(pFile);
    fclose(pFile);

    return length;
}
/* * print some useful information * @info equla TAG * @buf print buf @len length */
static void dis_array(const char* info,unsigned int len){
    int i =  0;
    printf("%s :",info);
    for(i = 0; i< len ; i++){
        printf("%02x ",buf[i]);
    }
    printf("n");
} 
/* * write and read */
static int w25_write_read(int fd,unsigned int rlen){

    int ret = 0;
    struct spi_ioc_transfer tr[2] = {
        {
            .tx_buf = (unsigned long)wbuf,.rx_buf = 0,.len = wlen,.speed_hz = speed,},{
            .tx_buf = 0,.rx_buf = (unsigned long)rbuf,.len = rlen,};

    ret = ioctl(fd,SPI_IOC_MESSAGE(2),tr);

    return ret;
}
/* * before every command do judge of status register */
 static int wait_for_idle(int fd){
    int i = 0 ;
    unsigned char strg = 0;
    unsigned char tempcmd = W25_READ_STATUS_1;
    int ret = 0;

    for (i=0;i<RDSR_CNT ; i++){
        ret = w25_write_read(fd,&tempcmd,sizeof(tempcmd ),&strg,sizeof(strg));
        if(ret < 0 ){
            printf("get status register value error n");
            goto exit;
        }
        if(strg & W25_SR_BUSY){
            //printf("wait for idle ...n");
            usleep(20);
            continue;
        }else{
            break;
        }
    }
    if( i == RDSR_CNT){
        printf("/dev/spidev2.2 is too busy now -------------------------------n");
        ret = -1;
        goto exit;
    }
        return 0;
    exit:
        return ret;

}
/* * wirte data to spi 256 bytes (a page) */
static int write_spiflash(int fd,int address_three){

    txbuffer[0] = W25_PAGE_PROGRAM;     
    txbuffer[1] = address_one;
    txbuffer[2] = address_two;
    txbuffer[3] = address_three;
    for(int i = 0 ;i< WRITE_READ_ONCE_SIZE; i++){
        txbuffer[i+4] = buf[i+offset];
    }
    //dis_array("Write 256 bytes",txbuffer,sizeof(txbuffer));
    wait_for_idle( fd );
    write_enable(fd);
    w25_write_read( fd,sizeof(txbuffer),rxbuffer,0);
    printf("write selector %02x%02x%02x ok n",address_one,address_two,address_three);
}

/* * write data to spi less than 256,file finally size is less to 256 */
static int write_spiflash_finally(int fd,int address_three){
    txbuffer[0] = W25_PAGE_PROGRAM;     
    txbuffer[1] = address_one;
    txbuffer[2] = address_two;
    txbuffer[3] = address_three;
    for(int i=0;i<num;i++){
        txbuffer[i+4] = buf[i+offset];
    }
    wait_for_idle( fd );
    write_enable(fd);
    w25_write_read( fd,(4+num),address_three);
}


/* * read data from spi 256 print or not */
static void read_spiflash(int fd,int address_three){
    unsigned char tempcmd[4] = {0};
    wait_for_idle( fd );
    tempcmd[0] = W25_READ_DATA;
    tempcmd[1] = address_one;
    tempcmd[2] = address_two;
    tempcmd[3] = address_three;
    w25_write_read(fd,tempcmd,4,buf,sizeof(buf));
    //dis_array("Read 256 bytes",sizeof(buf));
}

/* * read data to save a file to test */
static void read_spiflash_savefile(int fd,sizeof(buf));
    fwrite(buf,ARRAY_SIZE(buf),1,savefd  );
}

/* * read data to save a file to test */
static void read_spiflash_savefile_finally(int fd,num,savefd  );
}   
/* * write enable,before erase,write should do this */
static void write_enable(int fd){
    unsigned char tempcmd = W25_WRITE_ENABLE;
    write(fd,sizeof(tempcmd));
}
/* * erase 4KB * @parm address_one address A23-A16 * @parm address_two address A15-A8 * @parm address_two address A7-A0 */
static void selector_erase(int fd,int address_three){
    unsigned char tempcmd[4] = {0};
    wait_for_idle( fd );
    write_enable(fd);
    tempcmd[0] = W25_ERASE_SECTOR;
    tempcmd[1] = address_one;
    tempcmd[2] = address_two;
    tempcmd[3] = address_three;
    write( fd,4);
    printf("Erase_Sector: %02x%02x%02x selector erase done ..n",address_three);
}
/* * print_chip_id */
static void print_chipID(int fd){
    unsigned char tempbuf[3] = {0};
    unsigned char tempcmd = W25_CHIP_ID;
    w25_write_read( fd,tempbuf,3);
    dis_array("chip_ID: ManufactureID MemoryTypeID CapacityID ",3);
}
/* * write status register,not do will create some no-konwun consequencce,don`t kown */
static void write_status_register(int fd){
    unsigned char tempcmd[3] = {0};
    wait_for_idle( fd );
    write_enable(fd);
    tempcmd[0] = W25_WRITE_STATUS;
    tempcmd[1] = 0;
    tempcmd[2] = 0;
    write(fd,3 );
}

int main(int argc,char* argv[]){
    int ret = 0;
    int fd;
    char* fileName ;
    int erase_selector_number = 0;
    int write_selector_number = 0;

    if(argc != 2){
        printf("Usage: %s %sn",argv[0],"fileName");
        return -1;
    }else{
        fileName = argv[1];
    }

    fd = open(spi_device,O_RDWR);
    if (fd < 0){
        printf("open /dev/spidev errorn ");
    }

    /* * spi mode */
     ret = ioctl(fd,SPI_IOC_WR_MODE,&mode);
    if (ret == -1){
        printf("set spi mode errorn");
    }
    ret = ioctl(fd,SPI_IOC_RD_MODE,&mode);
    if (ret == -1){
        printf("get spi mode errorn");
    }

    /* * bits per word */
    ret = ioctl(fd,SPI_IOC_WR_BITS_PER_WORD,&bits);
    if (ret == -1){
        printf("set bits per word errorn");
    }
    ret = ioctl(fd,SPI_IOC_RD_BITS_PER_WORD,&bits);
    if (ret == -1){
        printf("get bits per word errorn");
    }

    /* * max speed hz */
    ret = ioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,&speed);
    if (ret == -1){
        printf("set max speed errorn");
    }
    ret = ioctl(fd,SPI_IOC_RD_MAX_SPEED_HZ,&speed);
    if (ret == -1){
        printf("get max speed errorn");
    }

    /* * print useful info */
    printf("spi mode: %dn",mode);
    printf("spi bits per words : %d n",bits);
    printf("spi max speed : %dhz (%dkHz)n",speed,speed/1000);

    /* * open written file covert to bytes[] */
    int length =  getFileSize(fileName);
    //file size must less than 8M
    if(length  > FLASH_MAX_SIZE){
        printf("The Flash Max Size is 8*1024*1024,your written file size = %dMn",length/1024/1024);
        return -2;
    }
    FILE *filefd;
    filefd = fopen(fileName,"rw+");
    unsigned char filebuf[length];
    fread(filebuf,sizeof(char),length,filefd);
    fclose(filefd);
    printf("Written file size = %dKB n",length/1024);
    //dis_array("Written_file_info",filebuf,sizeof(filebuf));

    /* * get chip id */
    print_chipID(fd);
    //write status register
    write_status_register(fd);

    /* *once erase suitable selector */
    erase_selector_number = (length/ONE_SELECTOR_SIZE + 1);
    printf("Now begin erase foresee size = %d,please waiting... n",erase_selector_number);
    int tempa_erase,tempb_erase,tempc_erase = 0,seletor_times = 0;
    for(int i = 0 ; i< erase_selector_number ; i++){
        tempa_erase =  i / 16;
        tempb_erase = (i % 16) * 16;
        selector_erase( fd,tempa_erase,tempc_erase );
        seletor_times++;
    }
    printf("Erase subitable selector done,erase_times = %dn",seletor_times);

    /* * now begin write */
    write_selector_number = length/WRITE_READ_ONCE_SIZE + 1;
    int all_selector_write = write_selector_number - 1;
    int finally_size = length % WRITE_READ_ONCE_SIZE;
    printf("now begin write,write_selector_number = %dn",write_selector_number);
    int tempa_write,tempb_write,tempc_write = 0,write_times = 0;
    for(int i=0;i<write_selector_number;i++){
        tempa_write = i /256;
        tempb_write = i%256;
        if(i < all_selector_write){
            write_spiflash( fd,i*256,tempa_write,tempc_write);
        }else{
            write_spiflash_finally(fd,finally_size,tempc_write);
        }
        write_times++;
    }
    printf("writed done,write_times = %dn",write_times);


    /* * 这里是新增加的测试部分 * now read to test */
    FILE* savefd;
    char* backup = "backup";
    char saveName[30];
    strcpy(saveName,backup);
    strcat(saveName,fileName);
    savefd = fopen(saveName,"ab+");
    int tempa_read,tempb_read,tempc_read = 0;
    for(int i = 0 ;i<write_selector_number ;i++){
        tempa_read = i /256;
        tempb_read = i%256;
        if(i < all_selector_write){
            read_spiflash_savefile( fd,savefd,tempa_read,tempc_read);
        }else{
            read_spiflash_savefile_finally( fd,tempc_read);
        }
    }
    fclose(savefd);

    close(fd);

    return ret; 

    exit:
        printf("error exit........................n");
        return ret;
}

经过测试,上面的程序可以完全正确的写入数据到flash,测试了exe文件,pdf文件, bmp文件

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读