www.pudn.com > STM32F4_bootloader.zip > app4.c, change:2014-01-07,size:10365b


/*----------------------------------------------------------------------/ 
/ Low level disk I/O module function checker 
/-----------------------------------------------------------------------/ 
/ WARNING: The data on the target drive will be lost! 
*/ 
 
#include <stdio.h> 
#include <string.h> 
#include "ff.h" 
#include "diskio.h" 
 
 
static 
DWORD pn ( 
    DWORD pns 
) 
{ 
    static DWORD lfsr; 
    UINT n; 
 
 
    if (pns) { 
        lfsr = pns; 
        for (n = 0; n < 32; n++) pn(0); 
    } 
    if (lfsr & 1) { 
        lfsr >>= 1; 
        lfsr ^= 0x80200003; 
    } else { 
        lfsr >>= 1; 
    } 
    return lfsr; 
} 
 
 
int test_diskio ( 
    BYTE pdrv,      /* Physical drive number to be checked (all data on the drive will be lost) */ 
    UINT ncyc,      /* Number of test cycles */ 
    DWORD* buff,    /* Pointer to the working buffer */ 
    UINT sz_buff    /* Size of the working buffer in unit of byte */ 
) 
{ 
    UINT n, cc, ns; 
    DWORD sz_drv, lba, lba2, pns = 1; 
    WORD sz_sect, sz_eblk; 
    BYTE *pbuff = (BYTE*)buff; 
    DSTATUS ds; 
    DRESULT dr; 
 
 
 
    printf("test_diskio(%u, %u, 0x%08X, 0x%08X)\n", pdrv, ncyc, (UINT)buff, sz_buff); 
 
    if (sz_buff < _MAX_SS + 4) { 
        printf("Insufficient work area to test.\n"); 
        return 1; 
    } 
 
    for (cc = 1; cc <= ncyc; cc++) { 
        printf("**** Test cycle %u of %u start ****\n", cc, ncyc); 
 
        /* Initialization */ 
        printf(" disk_initalize(%u)", pdrv); 
        ds = disk_initialize(pdrv); 
        if (ds & STA_NOINIT) { 
            printf(" - failed.\n"); 
            return 2; 
        } else { 
            printf(" - ok.\n"); 
        } 
 
        /* Get drive size */ 
        printf("**** Get drive size ****\n"); 
        printf(" disk_ioctl(%u, GET_SECTOR_COUNT, 0x%08X)", pdrv, (UINT)&sz_drv); 
        sz_drv = 0; 
        dr = disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_drv); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
            return 3; 
        } 
        if (sz_drv < 128) { 
            printf("Failed: Insufficient drive size to test.\n"); 
            return 4; 
        } 
        printf(" Number of sectors on the drive %u is %lu.\n", pdrv, sz_drv); 
 
#if _MAX_SS != _MIN_SS 
        /* Get sector size */ 
        printf("**** Get sector size ****\n"); 
        printf(" disk_ioctl(%u, GET_SECTOR_SIZE, 0x%X)", pdrv, (UINT)&sz_sect); 
        sz_sect = 0; 
        dr = disk_ioctl(pdrv, GET_SECTOR_SIZE, &sz_sect); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
            return 5; 
        } 
        printf(" Size of sector is %u bytes.\n", sz_sect); 
#else 
        sz_sect = _MAX_SS; 
#endif 
 
        /* Get erase block size */ 
        printf("**** Get block size ****\n"); 
        printf(" disk_ioctl(%u, GET_BLOCK_SIZE, 0x%X)", pdrv, (UINT)&sz_eblk); 
        sz_eblk = 0; 
        dr = disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_eblk); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
        } 
        if (dr == RES_OK || sz_eblk >= 2) { 
            printf(" Size of the erase block is %u sectors.\n", sz_eblk); 
        } else { 
            printf(" Size of the erase block is unknown.\n"); 
        } 
 
        /* Single sector write test */ 
        printf("**** Single sector write test 1 ****\n"); 
        lba = 0; 
        for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n] = (BYTE)pn(0); 
        printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba); 
        dr = disk_write(pdrv, pbuff, lba, 1); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
            return 6; 
        } 
        printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv); 
        dr = disk_ioctl(pdrv, CTRL_SYNC, 0); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
            return 7; 
        } 
        memset(pbuff, 0, sz_sect); 
        printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba); 
        dr = disk_read(pdrv, pbuff, lba, 1); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
            return 8; 
        } 
        for (n = 0, pn(pns); n < sz_sect && pbuff[n] == (BYTE)pn(0); n++) ; 
        if (n == sz_sect) { 
            printf(" Data matched.\n"); 
        } else { 
            printf("Failed: Read data differs from the data written.\n"); 
            return 10; 
        } 
        pns++; 
 
        /* Multiple sector write test */ 
        printf("**** Multiple sector write test ****\n"); 
        lba = 1; ns = sz_buff / sz_sect; 
        if (ns > 4) ns = 4; 
        for (n = 0, pn(pns); n < (UINT)(sz_sect * ns); n++) pbuff[n] = (BYTE)pn(0); 
        printf(" disk_write(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns); 
        dr = disk_write(pdrv, pbuff, lba, ns); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
            return 11; 
        } 
        printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv); 
        dr = disk_ioctl(pdrv, CTRL_SYNC, 0); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
            return 12; 
        } 
        memset(pbuff, 0, sz_sect * ns); 
        printf(" disk_read(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns); 
        dr = disk_read(pdrv, pbuff, lba, ns); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
            return 13; 
        } 
        for (n = 0, pn(pns); n < (UINT)(sz_sect * ns) && pbuff[n] == (BYTE)pn(0); n++) ; 
        if (n == (UINT)(sz_sect * ns)) { 
            printf(" Data matched.\n"); 
        } else { 
            printf("Failed: Read data differs from the data written.\n"); 
            return 14; 
        } 
        pns++; 
 
        /* Single sector write test (misaligned memory address) */ 
        printf("**** Single sector write test 2 ****\n"); 
        lba = 5; 
        for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n+3] = (BYTE)pn(0); 
        printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+3), lba); 
        dr = disk_write(pdrv, pbuff+3, lba, 1); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
            return 15; 
        } 
        printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv); 
        dr = disk_ioctl(pdrv, CTRL_SYNC, 0); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
            return 16; 
        } 
        memset(pbuff+5, 0, sz_sect); 
        printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+5), lba); 
        dr = disk_read(pdrv, pbuff+5, lba, 1); 
        if (dr == RES_OK) { 
            printf(" - ok.\n"); 
        } else { 
            printf(" - failed.\n"); 
            return 17; 
        } 
        for (n = 0, pn(pns); n < sz_sect && pbuff[n+5] == (BYTE)pn(0); n++) ; 
        if (n == sz_sect) { 
            printf(" Data matched.\n"); 
        } else { 
            printf("Failed: Read data differs from the data written.\n"); 
            return 18; 
        } 
        pns++; 
 
        /* 4GB barrier test */ 
        printf("**** 4GB barrier test ****\n"); 
        if (sz_drv >= 128 + 0x80000000 / (sz_sect / 2)) { 
            lba = 6; lba2 = lba + 0x80000000 / (sz_sect / 2); 
            for (n = 0, pn(pns); n < (UINT)(sz_sect * 2); n++) pbuff[n] = (BYTE)pn(0); 
            printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba); 
            dr = disk_write(pdrv, pbuff, lba, 1); 
            if (dr == RES_OK) { 
                printf(" - ok.\n"); 
            } else { 
                printf(" - failed.\n"); 
                return 19; 
            } 
            printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2); 
            dr = disk_write(pdrv, pbuff+sz_sect, lba2, 1); 
            if (dr == RES_OK) { 
                printf(" - ok.\n"); 
            } else { 
                printf(" - failed.\n"); 
                return 20; 
            } 
            printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv); 
            dr = disk_ioctl(pdrv, CTRL_SYNC, 0); 
            if (dr == RES_OK) { 
            printf(" - ok.\n"); 
            } else { 
                printf(" - failed.\n"); 
                return 21; 
            } 
            memset(pbuff, 0, sz_sect * 2); 
            printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba); 
            dr = disk_read(pdrv, pbuff, lba, 1); 
            if (dr == RES_OK) { 
                printf(" - ok.\n"); 
            } else { 
                printf(" - failed.\n"); 
                return 22; 
            } 
            printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2); 
            dr = disk_read(pdrv, pbuff+sz_sect, lba2, 1); 
            if (dr == RES_OK) { 
                printf(" - ok.\n"); 
            } else { 
                printf(" - failed.\n"); 
                return 23; 
            } 
            for (n = 0, pn(pns); pbuff[n] == (BYTE)pn(0) && n < (UINT)(sz_sect * 2); n++) ; 
            if (n == (UINT)(sz_sect * 2)) { 
                printf(" Data matched.\n"); 
            } else { 
                printf("Failed: Read data differs from the data written.\n"); 
                return 24; 
            } 
        } else { 
            printf(" Test skipped.\n"); 
        } 
        pns++; 
 
        printf("**** Test cycle %u of %u completed ****\n\n", cc, ncyc); 
    } 
 
    return 0; 
} 
 
 
 
int main (int argc, char* argv[]) 
{ 
    int rc; 
    DWORD buff[512];  /* 2048 byte working buffer */ 
 
    /* Check function/compatibility of the physical drive #0 */ 
    rc = test_diskio(0, 1, buff, sizeof buff); 
    if (res) { 
        printf("Sorry the function/compatibility test failed.\nFatFs will not work on this disk driver.\n"); 
    } else { 
        printf("Congratulations! The disk I/O layer works well.\n"); 
    } 
 
    return rc; 
}