相对于操作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; }