⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sa_flash.c

📁 eCos1.31版
💻 C
字号:
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <errno.h>#include <sys/mman.h>#include <sys/ioctl.h>#define FLASH_SZ (4 * 1024 * 1024)#define FLASH_BLOCK_SZ (256 * 1024)volatile void *flash_base;int  driver_fd;/*  * sync PCI transactions */static voidpci_sync(void){    volatile unsigned int x;    x = *(unsigned int *)flash_base;}static voidflash_write_mode(void){    pci_sync();    *(volatile int *)flash_base = 0x40404040;}static voidflash_normal_mode(void){    pci_sync();    *(volatile int *)flash_base = 0xffffffff;}/* *  Check to see if there is some flash at the location specified. */static intflash_verify(void) {    volatile unsigned int *fp = (volatile unsigned int *)flash_base;     unsigned int mfg, id ;    flash_normal_mode();    /* read the manufacturer's id. */    pci_sync();    *fp = 0x90909090;    mfg = *fp;    if (mfg != 0x89898989) {	flash_normal_mode();	return 0;    }     id = *(fp + 1) ;    flash_normal_mode();    if (id < 0xA1A1A1A1)	return 0;    return 1;}static unsigned intflash_read_dword(int offset){    /* swap initial 32 byte blocks when accessing flash from PCI */    if (offset < 32)	offset += 32;    else if (offset < 64)	offset -= 32;    offset &= ~3;  /* dword alignment */    return *(volatile unsigned int *)(flash_base + offset);}static intflash_write_dword(int offset, unsigned int data) {     volatile unsigned int *fp;     int status;    /* swap initial 32 byte blocks when accessing flash from PCI */    if (offset < 32)	offset += 32;    else if (offset < 64)	offset -= 32;    offset &= ~3;  /* dword alignment */    fp = (volatile unsigned int *)(flash_base + offset) ;    flash_write_mode();      /* write the data */    *fp = data;    /* wait till done */    do {	pci_sync();	*fp = 0x70707070;	status = *fp;    } while ((status & 0x80808080) != 0x80808080);      *fp = 0x50505050; /* Clear status register */    flash_normal_mode();    if ( (status & 0x02020202) != 0) {        fprintf(stderr,"WRITE LOCKED %08x :", status);        return 0;    }    if ( (status & 0x10101010) != 0) {        fprintf(stderr,"WRITE FAILURE %08x :", status);        return 0;    }    return 1;}static intflash_erase_block(int block) {    volatile unsigned int *fp;    int status;    fp = (volatile unsigned int *)(flash_base + (block * FLASH_BLOCK_SZ));    /* write delete block command followed by confirm */    pci_sync();    *fp = 0x20202020;    pci_sync();    *fp = 0xd0d0d0d0;    /* wait till done */    do {	pci_sync();	*fp = 0x70707070;	status = *fp;    } while ((status & 0x80808080) != 0x80808080);      *fp = 0x50505050; /* Clear status register */    flash_normal_mode();    if ( (status & 0x02020202) != 0) {        fprintf(stderr,"ERASE LOCKED %08x :", status);        return 0;    }    if ( (status & 0x20202020) != 0) {        fprintf(stderr,"ERASE FAILURE %08x :", status);        return 0;    }    return 1;}intmain(int argc, char *argv[]){    int in_fd = STDIN_FILENO, i=0, got, offset, extra;    int buf[256];    int fw = 1, fv = 1, fr = 0, verbose = 0;    char *name = NULL;    int block = 0;    if ( argc > 2 ) {        if ( '-' == argv[1][0] && 'b' == argv[1][1] && 0 == argv[1][3] ) {            char c = argv[1][2];            if (      '0' <= c && c <= '9') block = c - '0';            else if ( 'a' <= c && c <= 'f') block = c - 'a' + 10;            else if ( 'A' <= c && c <= 'F') block = c - 'A' + 10;            else argc = 1; /* get usage message below */            argv++, argc--;        }    }    switch (argc) {    case 1:	in_fd = STDIN_FILENO;        fv = 0; /* Cannot rewind stdin, so do not verify */	break;    case 2:        if ( '-' == argv[1][0] ) {            if ( 'r' != argv[1][1] || 0 != argv[1][2]) goto usage;            fr = 1;            fw = fv = 0;            break;        }        name = argv[1];        in_fd = open(argv[1], O_RDONLY);	if (in_fd < 0) {	    fprintf(stderr, "Can't open %s", argv[1]);	    perror(": ");	    exit(1);	}	break;    case 3:        if ( '-' != argv[1][0] || 0 != argv[1][2]) goto usage;        if (      'v' == argv[1][1] )              fw = 0;        else if ( 'V' == argv[1][1] )              fw = 0, verbose = 1;        else if ( 'w' == argv[1][1] )              fv = 0;        else                                       goto usage;        name = argv[2];	in_fd = open(argv[2], O_RDONLY);	if (in_fd < 0) {	    fprintf(stderr, "Can't open %s", argv[2]);	    perror(": ");	    exit(1);	}	break;    default:    usage:	fprintf(stderr, "Usage:          sa_flash [filename]\n");	fprintf(stderr, "Block number:   sa_flash -bN [filename]\n");	fprintf(stderr, "Write only:     sa_flash [-bN] -w    filename\n");	fprintf(stderr, "Verify only:    sa_flash [-bN] -v|-V filename\n");	fprintf(stderr, "Read to stdout: sa_flash [-bN] -r\n");	exit(1);    }    driver_fd = open("/dev/safl", O_RDWR);    if (driver_fd < 0) {	perror("Can't open device: ");	exit (1);    }    flash_base = mmap(NULL, FLASH_SZ, PROT_READ|PROT_WRITE,		      MAP_SHARED, driver_fd, 0);    if (flash_base == NULL) {	perror("mmap failed: ");	close(driver_fd);	return 0;    }    if (!flash_verify()) {	fprintf(stderr, "Couldn't find flash.\n");	exit(1);    }        if ( fw ) {        if ( ! flash_erase_block(block) ) {            fprintf(stderr,"Erase error block %x\n", block);            exit(1);        }        extra = 0;        offset = block * FLASH_BLOCK_SZ;        while ((got = read(in_fd, ((char *)buf) + extra, sizeof(buf) - extra)) > 0) {            got += extra;            extra = got & 3;            got /= 4;            for (i = 0; i < got; ++i, offset += 4)                if ( ! flash_write_dword(offset, buf[i]) )                    fprintf(stderr,"Write error offset %06x\n",offset);            if (extra)                buf[0] = buf[i];            printf("*"); fflush(stdout);        }        if (extra)            if ( ! flash_write_dword(offset, buf[i]) )                fprintf(stderr,"Write error offset %06x\n",offset);        printf("\n");    }    flash_normal_mode();    if ( fv ) {        int badwords = 0;        int skipping = 0;        close( in_fd );	in_fd = open(name, O_RDONLY);	if (in_fd < 0) {	    fprintf(stderr, "Can't re-open %s", argv[2]);	    perror(": ");	    exit(1);	}        extra = 0;        offset = block * FLASH_BLOCK_SZ;        while ((got = read(in_fd, ((char *)buf) + extra, sizeof(buf) - extra)) > 0) {            got += extra;            extra = got & 3;            got /= 4;            for (i = 0; i < got; ++i, offset += 4) {                int data = flash_read_dword(offset);                if ( data != buf[i] ) {                    badwords++;                    if ( !skipping ) {                        fprintf(stderr, "Bad data at offset %06x: %08x read %08x wanted\n",                                offset, data, buf[i] );                        if ( !verbose && badwords > 15 ) {                            skipping = 1;                            fprintf(stderr, "(Too many errors, skipping...)\n");                        }                    }                }            }            if (extra)                buf[0] = buf[i];            printf("+"); fflush(stdout);        }        if (extra) {            int data = flash_read_dword(offset);            if ( data != buf[0] ) {                fprintf(stderr, "End data at offset %06x: %08x read %08x wanted\n",                        offset, data, buf[0] );            }        }        printf("\n");        if ( badwords )            fprintf(stderr, "Bad data: %d bad words out of %d (end offset %06x)\n",                    badwords, offset/4, offset );    }    flash_normal_mode();    if ( fr ) {        for ( offset = block * FLASH_BLOCK_SZ;              offset < (block+1) * FLASH_BLOCK_SZ;              offset += 4 ) {            for ( i = 0; i < (sizeof(buf)/sizeof(int)); ++i, offset += 4 ) {                buf[i] = flash_read_dword(offset);            }            if ( sizeof(buf) != write( STDOUT_FILENO, buf, sizeof(buf) ) ) {                perror("Stdout write failed: ");                exit(1);            }            fprintf(stderr,"r");            fflush(stderr);        }        fprintf(stderr,"\n");    }    munmap((void *)flash_base, FLASH_SZ);    close(driver_fd);    return 0;}/* * Local variables: *  compile-command: "cc -g -O2 -Wall sa_flash.c -o sa_flash" * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -