在应用程序中操作NorFlash

相对于操作NandFlash,操作NorFlash相对简单,因为基本不需要考虑坏块,NorFlash也没有OOB区域,也跟ECC没有一毛钱关系。它的读写擦除相对容易。

 

int dealwithnor()

{



//    glob_t mtdbuf;

    struct mtd_info_user mtd;

    struct erase_info_user erase;

    int blocks = 0;

    int i = 0;  //用于控制擦除的块的个数

    int k = 0;

    int written = 0;  //已写入的字节数,只初始化一次

    unsigned int size = StateOfImage.st_size;  //应该是镜像的实际大小,因为内存中大于镜像的空间的内容不可预知

    unsigned int result = 0;

    unsigned int DevNum = 0;    //设备的数量

    unsigned int StartDev = 0;  //从第startDev开始擦除

    char DevName[20] = {0};

    unsigned int AllSize = 0;

    #define MAXPARTITIONS 40

    struct DeviceInfo

    {

        int fd;

        char dir[20];

        uint32_t size;     // Total size of the MTD

        uint32_t erasesize;

        

    }DevInfo[MAXPARTITIONS];//用来存储设备信息



    bzero(DevInfo, sizeof(struct DeviceInfo));





/* 这是一种方法,但是有一个缺点,当mtd设备大于10个是,通过glob搜索出来的结果

   会出问题,下面采用会采用第二种方法 */

//    if(searchmtd(&mtdbuf) != 0){



//        DEBUG("Sorry! Can not find mtd device\n");

//        return 1;   //返回大于零的数,表示升级失败

//    }

//    else

//    {

//        int fd;

//        

//        DEBUG("find %d mtd devices \n",mtdbuf.gl_pathc);

//        DevNum = mtdbuf.gl_pathc;



//        for(i=0; i<DevNum; i++)

//        {

//            fd = safeOpen (mtdbuf.gl_pathv[i],O_SYNC | O_RDWR);

//            if(fd < 0)

//            {

//                printf("failt to open\n");

//                return 1;

//            }

//            bzero(&mtd, sizeof(struct mtd_info_user));

//            if (ioctl(fd, MEMGETINFO,&mtd) < 0)

//            {

//                DEBUG("ioctl(): %m\n");

//                DEBUG("This doesn't seem to be a valid MTD flash device!\n");

//                return 1;

//            }

//            

//            strcpy(DevInfo[i].dir, mtdbuf.gl_pathv[i]);

//            DevInfo[i].fd = fd;

//            DevInfo[i].size = mtd.size;

//            DevInfo[i].erasesize = mtd.erasesize;

//        }



//        globfree(&mtdbuf);

//        for(i=0; i<DevNum; i++)

//        {

//            printf("\n\tinfo of %s\n",DevInfo[i].dir);

//            printf("%s.fd:            %d\n",DevInfo[i].dir, DevInfo[i].fd);

//            printf("%s.size:          %d\n",DevInfo[i].dir,DevInfo[i].size);

//            printf("%s.erasesize:     %d\n",DevInfo[i].dir,DevInfo[i].erasesize);

//        }

//    }





/* 下面是第二种方法,这种方法克服了第一种方法的缺陷,不受mtd设备数量的限制 */







    for(i=0; i<MAXPARTITIONS; i++)

    {

        int fd;

        sprintf(DevName, "%s%d", "/dev/mtd",i);



        if((fd = open (DevName,O_SYNC | O_RDWR)) > 0)

        {

            bzero(&mtd, sizeof(struct mtd_info_user));

            if (ioctl(fd, MEMGETINFO,&mtd) < 0)

            {

                DEBUG("ioctl(): %m\n");

                DEBUG("This doesn't seem to be a valid MTD flash device!\n");

                return 1;

            }

            strcpy(DevInfo[i].dir, DevName);

            DevInfo[i].fd = fd;

            DevInfo[i].size = mtd.size;

            DevInfo[i].erasesize = mtd.erasesize;

        }

        else

        {

            DevNum = i;

            break;

        }

        

    }



    for(i=0; i<DevNum; i++)

    {

        printf("\n\tinfo of %s\n",DevInfo[i].dir);

        printf("%s.fd:            %d\n",DevInfo[i].dir, DevInfo[i].fd);

        printf("%s.size:          %d\n",DevInfo[i].dir,DevInfo[i].size);

        printf("%s.erasesize:     %d\n",DevInfo[i].dir,DevInfo[i].erasesize);

        AllSize += DevInfo[i].size;

     }



    if(AllSize < StateOfImage.st_size)

    {

        DEBUG("ERROR!! all device size is less than ImageSize\n");

        return 1;

    }

            

    for(i=StartDev; i<DevNum; i++)

    {



      /**

       * 先进行擦除操作 

       */

        int j = 0;

        g_AllImgSize = DevInfo[i].size;

        g_AllImgWrite = 0;

        erase.start = 0; 

        blocks = DevInfo[i].size / mtd.erasesize;  //计算要擦除的块的个数

        erase.length = mtd.erasesize;

        printf ("\nbegin to erase block %s\n", DevInfo[i].dir);

        for (j= 1; j <= blocks; j++)

        {

            fprintf(stderr, "\rErasing blocks: %d/%d (%d%%)", j, blocks, (int)PERCENTAGE (j, blocks));

            g_percentage = 100 * ((float)g_AllImgWrite / g_AllImgSize);

              if (ioctl(DevInfo[i].fd, MEMERASE, &erase) < 0)

              {

                DEBUG("\n");

                DEBUG("While erasing blocks 0x%.8x-0x%.8x on %s\n",\

                (unsigned int) erase.start, (unsigned int) (erase.start + erase.length), DevInfo[i].dir);

                /*return "Error while erasing blocks";*/

                return 1;

            }

            g_AllImgWrite += erase.length;

            erase.start += mtd.erasesize;

        }

        printf("\n\rErased blocks: %d/%d (100%%)\n", blocks, blocks); 



        /**

         * 再进行写操作 

         */

        printf ("\nbegin to write block %s\n\n", DevInfo[i].dir);

        g_AllImgWrite = 0;

        k = BUFSIZE;

        while (size)

        {

            if (size < BUFSIZE)

            {

                k = size;

            } 

            printf("\033[1A");

            printf("\r%s usage: %dk/%dk (%d%%)\n",\

            DevInfo[i].dir, KB (g_AllImgWrite + k), KB (DevInfo[i].size), (int)PERCENTAGE (g_AllImgWrite + k, DevInfo[i].size)); 

            fprintf(stderr, "Writing data: %dk/%ldk (%d%%)", KB (written + k), KB (StateOfImage.st_size), (int)PERCENTAGE (written + k, StateOfImage.st_size));

            result = write(DevInfo[i].fd, &upPack[written], k);

            if (k != result)

            {

                DEBUG ("\n");

                if (result < 0)

                {

                    DEBUG("While writing data to 0x%.8x-0x%.8x on %s\n", written, written + k, DevInfo[i].dir);

                      return 1;

                }

                DEBUG("Short write count returned while writing to x%.8x-0x%.8x on %s: %d/%d bytes written to flash\n", \

                        written,written + k, DevInfo[i].dir, written + result, DevInfo[i].size);

                return 1;

            }



            written += k;

            size -= k;

            

             g_AllImgWrite += k;

            if(g_AllImgWrite >= DevInfo[i].size)

            {   

                g_AllImgWrite = 0;

                printf("\n");

                break;

            }

            

        } 

        printf("Wrote %d / %ldk bytes\n", written, (unsigned long int)(StateOfImage.st_size));        

        

    }



    munmap(upPack, UPGRADE_SHM_SIZE);

    for(i=0; i<DevNum; i++)

    {

        close (DevInfo[i].fd);

        printf("%s is closed!\n",DevInfo[i].dir);

    }



    return 0;

}

你可能感兴趣的:(Flash)