/* flash_binary */ int ICACHE_FLASH_ATTR flash_binary(char * pbData, int cbSize, int iPartition) { /* initialization */ SpiFlashOpResult eFlashOperationStatus = SPI_FLASH_RESULT_ERR; int iRet = 0; erase_block(partition[iPartition].iOffset + cbFlashedSize); /* source assumed to be 4 byte aligned */ eFlashOperationStatus = spi_flash_write((partition[iPartition].iOffset + cbFlashedSize), (uint32 *)pbData, cbSize); if (SPI_FLASH_RESULT_OK == eFlashOperationStatus) { cbFlashedSize += cbSize; iRet = cbSize; goto lblCleanup; } else { #ifdef FLASH_DEBUG os_printf("flash_binary: SpiFlashOpResult %d\n", iRet); #endif iRet = 0; goto lblCleanup; } lblCleanup: return iRet; }
int _main(int argc, char * argv[]) { int start; int count; if (1 >= argc) { fprintf(stderr,"You must specify a device\n"); printf("Help : %s <device name > <start> <count> <unlock:1,lock :0> \n", argv[0]); return 16; } if (argc > 2) start = strtol(argv[2], NULL, 0); else start = 0; if (argc > 3) count = strtol(argv[3], NULL, 0); else count = 1; printf("L: %d \n",__LINE__); erase_block(argv[1],start,count); return 0; }
void update_screen(UART_instance_t * this_uart, int deg, float kp, float ki, float kd, float digit, k_value_t k_value) { // Print the pendulum print_degrees(this_uart, deg); // Print the constants set_x(this_uart, 32); set_y(this_uart, 16); delay(); char buffer[64]; sprintf(buffer, "%07.3f\r\n%07.3f\r\n%07.3f", kp, ki, kd); UART_polled_tx_string( this_uart, (const uint8_t *)&buffer); // Clear the digit block erase_block(this_uart, 112, 16, 159, 56); // Print the digit increment/decrement set_x(this_uart, 112); delay(); char digit_buffer[16]; sprintf(digit_buffer, "%07.3f", digit); if (k_value == KP) { set_y(this_uart, 16); } else if (k_value == KI) { set_y(this_uart, 24); } else { set_y(this_uart, 32); } UART_polled_tx_string( this_uart, (const uint8_t *)&digit_buffer); }
void print_degrees(UART_instance_t * this_uart, int deg) { static uint8_t old_x_pixel = 0; static uint8_t old_y_pixel = 0; if (old_x_pixel > 80) { erase_block(this_uart, 75, 127, old_x_pixel+5, old_y_pixel-5); } else if (old_x_pixel < 80) { erase_block(this_uart, 85, 127, old_x_pixel-5, old_y_pixel-5); } else { erase_block(this_uart, 75, 127, 85, old_y_pixel-10); } deg += 90.0; //Convert to range 0 to 180 degrees //Set location of degree printout set_x(this_uart, 64); set_y(this_uart, 64); delay(); //Convert int to char array char buffer[4]; sprintf(buffer, "%03d", deg); //Print degrees UART_send( this_uart, (const uint8_t *)&buffer, sizeof(buffer) ); //Get locations of x and y pixels for head of the pendulum uint8_t x_pixel = 80 - cos(deg * PI / 180) * 50; uint8_t y_pixel = 127 - sin(deg * PI / 180) * 50; //Draw pendulum draw_line(this_uart, 80, 127, x_pixel, y_pixel); draw_circle(this_uart, x_pixel, y_pixel, 5); old_x_pixel = x_pixel; old_y_pixel = y_pixel; }
/* * IMPROVE: It would be best to choose the block with the most deleted sectors, * because if we fill that one up first it'll have the most chance of having * the least live sectors at reclaim. */ static int find_free_block(struct partition *part) { int block, stop; block = part->current_block == -1 ? jiffies % part->total_blocks : part->current_block; stop = block; do { if (part->blocks[block].free_sectors && block != part->reserved_block) return block; if (part->blocks[block].state == BLOCK_UNUSED) erase_block(part, block); if (++block >= part->total_blocks) block = 0; } while (block != stop); return -1; }
static int mark_sector_deleted(struct partition *part, u_long old_addr) { int block, offset, rc; u_long addr; size_t retlen; u16 del = const_cpu_to_le16(SECTOR_DELETED); block = old_addr / part->block_size; offset = (old_addr % part->block_size) / SECTOR_SIZE - part->header_sectors_per_block; addr = part->blocks[block].offset + (HEADER_MAP_OFFSET + offset) * sizeof(u16); rc = part->mbd.mtd->write(part->mbd.mtd, addr, sizeof(del), &retlen, (u_char*)&del); if (!rc && retlen != sizeof(del)) rc = -EIO; if (rc) { printk(KERN_WARNING PREFIX "error writing '%s' at " "0x%lx\n", part->mbd.mtd->name, addr); if (rc) goto err; } if (block == part->current_block) part->header_cache[offset + HEADER_MAP_OFFSET] = del; part->blocks[block].used_sectors--; if (!part->blocks[block].used_sectors && !part->blocks[block].free_sectors) rc = erase_block(part, block); err: return rc; }
static int reclaim_block(struct partition *part, u_long *old_sector) { int block, best_block, score, old_sector_block; int rc; /* we have a race if sync doesn't exist */ if (part->mbd.mtd->sync) part->mbd.mtd->sync(part->mbd.mtd); score = 0x7fffffff; /* MAX_INT */ best_block = -1; if (*old_sector != -1) old_sector_block = *old_sector / part->block_size; else old_sector_block = -1; for (block=0; block<part->total_blocks; block++) { int this_score; if (block == part->reserved_block) continue; /* * Postpone reclaiming if there is a free sector as * more removed sectors is more efficient (have to move * less). */ if (part->blocks[block].free_sectors) return 0; this_score = part->blocks[block].used_sectors; if (block == old_sector_block) this_score--; else { /* no point in moving a full block */ if (part->blocks[block].used_sectors == part->data_sectors_per_block) continue; } this_score += part->blocks[block].erases; if (this_score < score) { best_block = block; score = this_score; } } if (best_block == -1) return -ENOSPC; part->current_block = -1; part->reserved_block = best_block; pr_debug("reclaim_block: reclaiming block #%d with %d used " "%d free sectors\n", best_block, part->blocks[best_block].used_sectors, part->blocks[best_block].free_sectors); if (part->blocks[best_block].used_sectors) rc = move_block_contents(part, best_block, old_sector); else rc = erase_block(part, best_block); return rc; }
static int move_block_contents(struct partition *part, int block_no, u_long *old_sector) { void *sector_data; u16 *map; size_t retlen; int i, rc = -ENOMEM; part->is_reclaiming = 1; sector_data = kmalloc(SECTOR_SIZE, GFP_KERNEL); if (!sector_data) goto err3; map = kmalloc(part->header_size, GFP_KERNEL); if (!map) goto err2; rc = part->mbd.mtd->read(part->mbd.mtd, part->blocks[block_no].offset, part->header_size, &retlen, (u_char*)map); if (!rc && retlen != part->header_size) rc = -EIO; if (rc) { printk(KERN_NOTICE PREFIX "error reading '%s' at " "0x%lx\n", part->mbd.mtd->name, part->blocks[block_no].offset); goto err; } for (i=0; i<part->data_sectors_per_block; i++) { u16 entry = le16_to_cpu(map[HEADER_MAP_OFFSET + i]); u_long addr; if (entry == SECTOR_FREE || entry == SECTOR_DELETED) continue; if (entry == SECTOR_ZERO) entry = 0; /* already warned about and ignored in build_block_map() */ if (entry >= part->sector_count) continue; addr = part->blocks[block_no].offset + (i + part->header_sectors_per_block) * SECTOR_SIZE; if (*old_sector == addr) { *old_sector = -1; if (!part->blocks[block_no].used_sectors--) { rc = erase_block(part, block_no); break; } continue; } rc = part->mbd.mtd->read(part->mbd.mtd, addr, SECTOR_SIZE, &retlen, sector_data); if (!rc && retlen != SECTOR_SIZE) rc = -EIO; if (rc) { printk(KERN_NOTICE PREFIX "'%s': Unable to " "read sector for relocation\n", part->mbd.mtd->name); goto err; } rc = rfd_ftl_writesect((struct mtd_blktrans_dev*)part, entry, sector_data); if (rc) goto err; } err: kfree(map); err2: kfree(sector_data); err3: part->is_reclaiming = 0; return rc; }
void rewrite_line(char line) { char y = (TEXT_LINES-line)*8; erase_block(0,y+1,MAX_X,y+8); set_text_position(0,y+8); }
int main(int argc, char **argv) { unsigned long startofs = 0, part_size = 0; unsigned long ezones = 0, ezone = 0, bad_zones = 0; unsigned char unit_factor = 0xFF; long MediaUnit1 = -1, MediaUnit2 = -1; long MediaUnitOff1 = 0, MediaUnitOff2 = 0; unsigned char oobbuf[16]; struct mtd_oob_buf oob = {0, 16, oobbuf}; char *mtddevice, *nftl; int c, do_inftl = 0, do_bbt = 0; printf("$Id: nftl_format.c,v 1.24 2005/11/07 11:15:13 gleixner Exp $\n"); if (argc < 2) usage(1); nftl = "NFTL"; while ((c = getopt(argc, argv, "?hib")) > 0) { switch (c) { case 'i': nftl = "INFTL"; do_inftl = 1; break; case 'b': do_bbt = 1; break; case 'h': case '?': usage(0); break; default: usage(1); break; } } mtddevice = argv[optind++]; if (argc > optind) { startofs = strtoul(argv[optind++], NULL, 0); } if (argc > optind) { part_size = strtoul(argv[optind++], NULL, 0); } // Open and size the device if ((fd = open(mtddevice, O_RDWR)) < 0) { perror("Open flash device"); return 1; } if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { perror("ioctl(MEMGETINFO)"); close(fd); return 1; } switch (meminfo.erasesize) { case 0x1000: case 0x2000: case 0x4000: case 0x8000: break; default: printf("Unrecognized Erase size, 0x%x - I'm confused\n", meminfo.erasesize); close(fd); return 1; } writebuf[0] = malloc(meminfo.erasesize * 5); if (!writebuf[0]) { printf("Malloc failed\n"); close(fd); return 1; } writebuf[1] = writebuf[0] + meminfo.erasesize; writebuf[2] = writebuf[1] + meminfo.erasesize; writebuf[3] = writebuf[2] + meminfo.erasesize; readbuf = writebuf[3] + meminfo.erasesize; memset(writebuf[0], 0xff, meminfo.erasesize); memset(writebuf[1], 0x00, meminfo.erasesize); memset(writebuf[2], 0x5a, meminfo.erasesize); memset(writebuf[3], 0xa5, meminfo.erasesize); memset(BadUnitTable, ZONE_GOOD, MAX_ERASE_ZONES); if (part_size == 0 || (part_size > meminfo.size - startofs)) /* the user doest not or incorrectly specify NFTL partition size */ part_size = meminfo.size - startofs; erase.length = meminfo.erasesize; ezones = part_size / meminfo.erasesize; if (ezones > MAX_ERASE_ZONES) { /* Ought to change the UnitSizeFactor. But later. */ part_size = meminfo.erasesize * MAX_ERASE_ZONES; ezones = MAX_ERASE_ZONES; unit_factor = 0xFF; } /* If using device BBT then parse that now */ if (do_bbt) { checkbbt(); do_oobcheck = 0; do_rwecheck = 0; } /* Phase 1. Erasing and checking each erase zones in the NFTL partition. N.B. Erase Zones not used by the NFTL partition are untouched and marked ZONE_GOOD */ printf("Phase 1. Checking and erasing Erase Zones from 0x%08lx to 0x%08lx\n", startofs, startofs + part_size); for (ezone = startofs / meminfo.erasesize; ezone < (ezones + startofs / meminfo.erasesize); ezone++) { if (BadUnitTable[ezone] != ZONE_GOOD) continue; if ((BadUnitTable[ezone] = erase_block(ezone)) == ZONE_GOOD) { if (MediaUnit1 == -1) { MediaUnit1 = ezone; } else if (MediaUnit2 == -1) { MediaUnit2 = ezone; } } else { bad_zones++; } } printf("\n"); /* N.B. from dump of M-System original chips, NumEraseUnits counts the 2 Erase Unit used by MediaHeader and the FirstPhysicalEUN starts from the MediaHeader */ if (do_inftl) { unsigned long maxzones, pezstart, pezend, numvunits; INFTLhdr = (struct INFTLMediaHeader *) (writebuf[0]); strcpy(INFTLhdr->bootRecordID, "BNAND"); INFTLhdr->NoOfBootImageBlocks = cpu_to_le32(0); INFTLhdr->NoOfBinaryPartitions = cpu_to_le32(0); INFTLhdr->NoOfBDTLPartitions = cpu_to_le32(1); INFTLhdr->BlockMultiplierBits = cpu_to_le32(0); INFTLhdr->FormatFlags = cpu_to_le32(0); INFTLhdr->OsakVersion = cpu_to_le32(OSAK_VERSION); INFTLhdr->PercentUsed = cpu_to_le32(PERCENTUSED); /* * Calculate number of virtual units we will have to work * with. I am calculating out the known bad units here, not * sure if that is what M-Systems do... */ MediaUnit2 = MediaUnit1; MediaUnitOff2 = 4096; maxzones = meminfo.size / meminfo.erasesize; pezstart = startofs / meminfo.erasesize + 1; pezend = startofs / meminfo.erasesize + ezones - 1; numvunits = (ezones - 2) * PERCENTUSED / 100; for (ezone = pezstart; ezone < maxzones; ezone++) { if (BadUnitTable[ezone] != ZONE_GOOD) { if (numvunits > 1) numvunits--; } } INFTLhdr->Partitions[0].virtualUnits = cpu_to_le32(numvunits); INFTLhdr->Partitions[0].firstUnit = cpu_to_le32(pezstart); INFTLhdr->Partitions[0].lastUnit = cpu_to_le32(pezend); INFTLhdr->Partitions[0].flags = cpu_to_le32(INFTL_BDTL); INFTLhdr->Partitions[0].spareUnits = cpu_to_le32(0); INFTLhdr->Partitions[0].Reserved0 = INFTLhdr->Partitions[0].firstUnit; INFTLhdr->Partitions[0].Reserved1 = cpu_to_le32(0); } else { NFTLhdr = (struct NFTLMediaHeader *) (writebuf[0]); strcpy(NFTLhdr->DataOrgID, "ANAND"); NFTLhdr->NumEraseUnits = cpu_to_le16(part_size / meminfo.erasesize); NFTLhdr->FirstPhysicalEUN = cpu_to_le16(MediaUnit1); /* N.B. we reserve 2 more Erase Units for "folding" of Virtual Unit Chain */ NFTLhdr->FormattedSize = cpu_to_le32(part_size - ( (5+bad_zones) * meminfo.erasesize)); NFTLhdr->UnitSizeFactor = unit_factor; } /* Phase 2. Writing NFTL Media Headers and Bad Unit Table */ printf("Phase 2.a Writing %s Media Header and Bad Unit Table\n", nftl); pwrite(fd, writebuf[0], 512, MediaUnit1 * meminfo.erasesize + MediaUnitOff1); for (ezone = 0; ezone < (meminfo.size / meminfo.erasesize); ezone += 512) { pwrite(fd, BadUnitTable + ezone, 512, (MediaUnit1 * meminfo.erasesize) + 512 * (1 + ezone / 512)); } #if 0 printf(" MediaHeader contents:\n"); printf(" NumEraseUnits: %d\n", le16_to_cpu(NFTLhdr->NumEraseUnits)); printf(" FirstPhysicalEUN: %d\n", le16_to_cpu(NFTLhdr->FirstPhysicalEUN)); printf(" FormattedSize: %d (%d sectors)\n", le32_to_cpu(NFTLhdr->FormattedSize), le32_to_cpu(NFTLhdr->FormattedSize)/512); #endif printf("Phase 2.b Writing Spare %s Media Header and Spare Bad Unit Table\n", nftl); pwrite(fd, writebuf[0], 512, MediaUnit2 * meminfo.erasesize + MediaUnitOff2); for (ezone = 0; ezone < (meminfo.size / meminfo.erasesize); ezone += 512) { pwrite(fd, BadUnitTable + ezone, 512, (MediaUnit2 * meminfo.erasesize + MediaUnitOff2) + 512 * (1 + ezone / 512)); } /* UCI #1 for newly erased Erase Unit */ memset(oobbuf, 0xff, 16); oobbuf[11] = oobbuf[10] = oobbuf[9] = 0; oobbuf[8] = (do_inftl) ? 0x00 : 0x03; oobbuf[12] = oobbuf[14] = 0x69; oobbuf[13] = oobbuf[15] = 0x3c; /* N.B. The Media Header and Bad Erase Unit Table are considered as Free Erase Unit by M-System i.e. their Virtual Unit Number == 0xFFFF in the Unit Control Information #0, but their Block Status is BLOCK_USED (0x5555) in their Block Control Information */ /* Phase 3. Writing Unit Control Information for each Erase Unit */ printf("Phase 3. Writing Unit Control Information to each Erase Unit\n"); for (ezone = MediaUnit1; ezone < (ezones + startofs / meminfo.erasesize); ezone++) { /* write UCI #1 to each Erase Unit */ if (BadUnitTable[ezone] != ZONE_GOOD) continue; oob.start = (ezone * meminfo.erasesize) + 512 + (do_inftl * 512); if (ioctl(fd, MEMWRITEOOB, &oob)) printf("MEMWRITEOOB at %lx: %s\n", (unsigned long)oob.start, strerror(errno)); } exit(0); }
int main (void) { char x, y; //char a = 0; ioinit(); //Setup IO pins and defaults USART_Init( MYUBRR); rprintf_devopen(put_char); /* init rrprintf */ //set_data(0x55); //PORTC |= ((1 << RESET) | (1 << EN) | (1 << R_W) | (1 << CS1) | (1 << CS2) | (1 << RS));//all high //while(1); /* while(1) { PORTC &= ~((1 << EN) | (1 << R_W) | (1 << CS1) | (1 << CS2));//down delay_ms(500); //PORTC |= ((1 << EN) | (1 << R_W) | (1 << CS1) | (1 << CS2));//all high PORTC |= ((1 << RESET) | (1 << EN) | (1 << R_W) | (1 << CS1) | (1 << CS2) | (1 << RS));//all high delay_ms(500); } */ /* DDRC = 0b00000001; while(1) { PORTC |= 0b00000001; delay_1uS(); PORTC &= 0b11111110; delay_1uS(); } */ //Reset the display //PORTC = 0b11110111; PORTC &= ~(1 << RESET); delay_ms(50); PORTC |= (1 << RESET); delay_ms(500); clear_screen(); set_page(0); set_x(0); display_on(); //set display start line to 0 //set control lines PORTC &= ~((1 << EN) | (1 << R_W) | (1 << RS));//down set_port_out(); //set_data(0xC0); set_data(0xC0); delay_us(4); PORTC |= (1 << EN);//up delay_us(4); PORTC &= ~(1 << EN);//down delay_us(4); PORTC |= ((1 << EN) | (1 << R_W) | (1 << RS));//all high set_port_in(); delay_us(4); x_offset = 0; set_page(0); //Backlight on PORTB &= (~(1<<BL_EN)); //demo(); //put_char('X'); while(1) { if(RX_in != RX_read) { x = RX_array[RX_read]; RX_read++; if(RX_read >= 256) RX_read = 0; //Backspace=================================================== if(x == 8) del_char(0); //Special commands else if (x == 124) { //make sure the next byte is there while(RX_in == RX_read); //0, clear screen====================================================== if(RX_array[RX_read] == 0) { clear_screen(); RX_read++; if(RX_read >= 256) RX_read = 0; } //Backlight on/off else if(RX_array[RX_read] == 2) { y = PINB; if (y & (1<<BL_EN)) PORTB &= (~(1<<BL_EN)); else PORTB |= (1<<BL_EN); RX_read++; } //demo mode else if(RX_array[RX_read] == 4) { RX_in = 0, RX_read = 0; demo(); clear_screen(); RX_in = 0; } else { //set x or y========================================================= if((RX_array[RX_read] == 24) | (RX_array[RX_read] == 25)) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte if (RX_array[RX_read-1] == 24) x_offset = RX_array[RX_read]; else if (RX_array[RX_read-1] == 25) y_offset = RX_array[RX_read]; RX_read++; if(RX_read >= 256) RX_read = 0; if (x_offset > 127) x_offset = 127; if (y_offset > 63) y_offset = 63; } //set pixel========================================================= if (RX_array[RX_read] == 16) { //need 3 bytes for (y = 0; y < 3; y++) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte } pixel(RX_array[RX_read], RX_array[RX_read-2], RX_array[RX_read-1]); RX_read++; if(RX_read >= 256) RX_read = 0; } //<ctrl>c, circle====================================================== if(RX_array[RX_read] == 3) { //need 4 bytes for (y = 0; y < 4; y++) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte } circle(RX_array[RX_read], RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1]); RX_read++; if(RX_read >= 256) RX_read = 0; } //<ctrl>e, erase block====================================================== if(RX_array[RX_read] == 5) { //need 4 bytes for (y = 0; y < 4; y++) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte } erase_block(RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1], RX_array[RX_read]); RX_read++; if(RX_read >= 256) RX_read = 0; } //<ctrl>o, box, running out of meaningful letters====================================================== if(RX_array[RX_read] == 15) { //need 4 bytes for (y = 0; y < 4; y++) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte } box(RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1], RX_array[RX_read]); RX_read++; if(RX_read >= 256) RX_read = 0; } //<ctrl>L, line======================================================== else if (RX_array[RX_read] == 12) { //need 5 bytes for (y = 0; y < 5; y++) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte } line(RX_array[RX_read], RX_array[RX_read-4], RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read+-1]); RX_read++; if(RX_read >= 256) RX_read = 0; } } } //print character to the screen=============================================== else { del_char(1); //put_char('L'); print_char(1, x); } //set_data(0xFF); //set_port_in(); //display_on(); //y = PINB; //PORTB = y; } } }
static int reclaim_block(struct partition *part, u_long *old_sector) { int block, best_block, score, old_sector_block; int rc; if (part->mbd.mtd->sync) part->mbd.mtd->sync(part->mbd.mtd); score = 0x7fffffff; best_block = -1; if (*old_sector != -1) old_sector_block = *old_sector / part->block_size; else old_sector_block = -1; for (block=0; block<part->total_blocks; block++) { int this_score; if (block == part->reserved_block) continue; if (part->blocks[block].free_sectors) return 0; this_score = part->blocks[block].used_sectors; if (block == old_sector_block) this_score--; else { if (part->blocks[block].used_sectors == part->data_sectors_per_block) continue; } this_score += part->blocks[block].erases; if (this_score < score) { best_block = block; score = this_score; } } if (best_block == -1) return -ENOSPC; part->current_block = -1; part->reserved_block = best_block; pr_debug("reclaim_block: reclaiming block #%d with %d used " "%d free sectors\n", best_block, part->blocks[best_block].used_sectors, part->blocks[best_block].free_sectors); if (part->blocks[best_block].used_sectors) rc = move_block_contents(part, best_block, old_sector); else rc = erase_block(part, best_block); return rc; }
int main (void) { char x, y, a; ioinit(); //Setup IO pins and defaults USART_Init( MYUBRR); rprintf_devopen(put_char); /* init rrprintf */ //reset the display delay_ms(1); PORTC |= (1<<RST); //initialize the display display_init(); clear_screen(); //Backlight on PORTB &= (~(1<<BL_EN)); while(1) { if(RX_in != RX_read) { x = RX_array[RX_read]; RX_read++; if(RX_read >= 256) RX_read = 0; //Backspace=================================================== if(x == 8) del_char(0); //Special commands else if (x == 124) { //make sure the next byte is there while(RX_in == RX_read); //0, clear screen====================================================== if(RX_array[RX_read] == 0) { clear_screen(); RX_read++; if(RX_read >= 256) RX_read = 0; } //Backlight on/off else if(RX_array[RX_read] == 2) { y = PINB; if (y & (1<<BL_EN)) PORTB &= (~(1<<BL_EN)); else PORTB |= (1<<BL_EN); RX_read++; } //demo mode else if(RX_array[RX_read] == 4) { RX_in = 0, RX_read = 0; demo(); clear_screen(); RX_in = 0; } else { //set x or y========================================================= if((RX_array[RX_read] == 24) | (RX_array[RX_read] == 25)) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte if (RX_array[RX_read-1] == 24) x_offset = RX_array[RX_read]; else if (RX_array[RX_read-1] == 25) y_offset = RX_array[RX_read]; RX_read++; if(RX_read >= 256) RX_read = 0; if (x_offset > 159) x_offset = 159; if (y_offset > 127) y_offset = 127; } //set pixel========================================================= if (RX_array[RX_read] == 16) { //need 3 bytes for (y = 0; y < 3; y++) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte } pixel(RX_array[RX_read], RX_array[RX_read-2], RX_array[RX_read-1]); RX_read++; if(RX_read >= 256) RX_read = 0; } //<ctrl>c, circle====================================================== if(RX_array[RX_read] == 3) { //need 4 bytes for (y = 0; y < 4; y++) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte } circle(RX_array[RX_read], RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1]); RX_read++; if(RX_read >= 256) RX_read = 0; } //<ctrl>e, erase block====================================================== if(RX_array[RX_read] == 5) { //need 4 bytes for (y = 0; y < 4; y++) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte } erase_block(RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1], RX_array[RX_read]); RX_read++; if(RX_read >= 256) RX_read = 0; } //<ctrl>o, box, running out of meaningful letters====================================================== if(RX_array[RX_read] == 15) { //need 4 bytes for (y = 0; y < 4; y++) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte } box(RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1], RX_array[RX_read]); RX_read++; if(RX_read >= 256) RX_read = 0; } //<ctrl>L, line======================================================== else if (RX_array[RX_read] == 12) { //need 5 bytes for (y = 0; y < 5; y++) { RX_read++; if(RX_read >= 256) RX_read = 0; while(RX_in == RX_read);//wait for byte } line(RX_array[RX_read], RX_array[RX_read-4], RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read+-1]); RX_read++; if(RX_read >= 256) RX_read = 0; } } } //print character to the screen=============================================== else { del_char(1); print_char(1, x); } } } }
void eraseFlashMemory(int moduleNumber, bool simulate, bool verbose) { int i; int status; bool errorOccured = true; int loopCounter = 0; unsigned long vmeaddr; unsigned long vme_virt_addr; int fbase; printlog("erasing flash memory", true, !quiet); while (errorOccured && (loopCounter < MAXLOOPS)) { loopCounter++; printlog("attempt #: ", true, verbose); printlogInt(loopCounter, verbose); errorOccured = false; vmeaddr = moduleNumber * MODULE_LENGTH ; vme_virt_addr = (unsigned long) openvme((void *)vmeaddr, VME_LENGTH, verbose); fbase = vme_virt_addr + FLASHBASE; select_range(vme_virt_addr, 0+RANGENUMBER, verbose); for (i = 0; i <= 7; i++) { printlog("block #: ", true, verbose); printlogInt(i, verbose); if (!simulate) { status = erase_block(fbase, i, verbose); } else { status = 0; } if (status == 0) { printlog(" successfully erased", false, verbose); } else { printlog(" can\'t be erased", false, verbose); errorOccured = true; } } if (!errorOccured) { select_range(vme_virt_addr, 1+RANGENUMBER, verbose); for (i = 0; i <= 7; i++) { printlog("block #: ", true, verbose); printlogInt(i, verbose); if (!simulate) { status = erase_block(fbase, i, verbose); } else { status = 0; } if (status == 0) { printlog(" successfully erased", false, verbose); } else { printlog(" can\'t be erased", false, verbose); errorOccured = true; } } } read_array(fbase); closevme(verbose); sleep(2); } if(errorOccured) { printlog("Error erasing flash memory, aborting", true, verbose); closeLog(verbose); exit(1); } }
int main (void) { char x, y, temp, q; ioinit(); //Setup IO pins and defaults //USART_Init( MYUBRR); set_baud(6);//115200 rprintf_devopen(put_char); /* init rrprintf */ //check for existing preset values============================================================== temp = EEPROM_read((unsigned int)BPS); if ((temp < 1) | (temp > 6))//BPS will only be 1-6 { cli();//Disable Interrupts EEPROM_write((unsigned int) BPS, 6); EEPROM_write((unsigned int) BACKLIGHT, 100); EEPROM_write((unsigned int) SPLASH, 1); EEPROM_write((unsigned int) REV, 0); sei();//Enable Interrupts BL_dutycycle = 100; baud_rate = 6; splash_screen = 1; reverse = 0; } else { baud_rate = temp; BL_dutycycle = EEPROM_read((unsigned int)BACKLIGHT); splash_screen = EEPROM_read((unsigned int)SPLASH); reverse = EEPROM_read((unsigned int)REV); } //Reset the display PORTC &= ~(1 << RESET); delay_ms(50); PORTC |= (1 << RESET); //delay_ms(500); clear_screen(); set_page(0); set_x(0); display_on(); //set display start line to 0 //set control lines PORTC &= ~((1 << EN) | (1 << R_W) | (1 << RS));//down set_data(0xC0); //set_data(0xFF); delay(); PORTC |= (1 << EN);//up delay(); PORTC &= ~(1 << EN);//down delay(); PORTC |= ((1 << EN) | (1 << R_W) | (1 << RS));//all high delay(); x_offset = 0; set_page(0); DDRB |= (1<<BL_EN);//set PB2 as output set_backlight(BL_dutycycle); //Logo========================================================== if (splash_screen == 1) { y = 40; for (q = 0; q < 30; q++) { temp = logo[q]; for (x = 56; x < 64; x++) { if (temp & 0x80) pixel(1,x,y); temp <<= 1; } q++; temp = logo[q]; for (x = 64; x < 72; x++) { if (temp & 0x80) pixel(1,x,y); temp <<= 1; } y--; } } pixel(0,0,0);//cheat RX_in = 0; delay_ms(1000); clear_screen(); if (RX_in > 0)//revert to 115200 { print_char(1,'1'); print_char(1,'1'); print_char(1,'5'); print_char(1,'2'); print_char(1,'0'); print_char(1,'0'); baud_rate = 6; set_baud(6);//115200 cli(); EEPROM_write((unsigned int) BPS, 6); sei();//Enable Interrupts } else (set_baud(baud_rate)); delay_ms(1000); clear_screen(); //main loop=================================================== while(1) { if(RX_in != RX_read) { x = RX_array[RX_read]; RX_read++; if(RX_read >= 416) RX_read = 0; //Backspace=================================================== if(x == 8) del_char(0); //Special commands else if (x == 124) { //make sure the next byte is there while(RX_in == RX_read); //0, clear screen====================================================== if(RX_array[RX_read] == 0)//^@ { clear_screen(); RX_read++; if(RX_read >= 416) RX_read = 0; } //demo mode else if(RX_array[RX_read] == 4)//^d { RX_in = 0, RX_read = 0; demo(); clear_screen(); RX_in = 0; } //reverse mode else if(RX_array[RX_read] == 18)//^r { reverse ^= 1; clear_screen(); RX_read++; if(RX_read >= 416) RX_read = 0; cli(); EEPROM_write((unsigned int) REV, reverse); sei(); } //toggle spasl screen else if(RX_array[RX_read] == 19)//^s { splash_screen ^= 1; //clear_screen(); RX_read++; if(RX_read >= 416) RX_read = 0; cli(); EEPROM_write((unsigned int) SPLASH, splash_screen); sei(); } else { //set backlight (0 to 100)========================================================= if(RX_array[RX_read] == 2)//^b { RX_read++; if(RX_read >= 416) RX_read = 0; while(RX_in == RX_read);//wait for byte BL_dutycycle = RX_array[RX_read]; RX_read++; if(RX_read >= 416) RX_read = 0; set_backlight(BL_dutycycle); cli(); EEPROM_write((unsigned int) BACKLIGHT, BL_dutycycle); sei(); } //change baud rate========================================================= if(RX_array[RX_read] == 7)//^g { RX_read++; if(RX_read >= 416) RX_read = 0; while(RX_in == RX_read);//wait for byte //if (RX_array[RX_read] == '1') USART_Init( 1000000/2400-1);//4800 //else if (RX_array[RX_read] == '2') USART_Init( 1000000/4800-1);//9600 //else if (RX_array[RX_read] == '3') USART_Init( 1000000/9600-1);//19200 //else if (RX_array[RX_read] == '4') USART_Init( 1000000/19200-1);//38400 //else if (RX_array[RX_read] == '5') USART_Init( 1000000/28800-1);//57600 //else if (RX_array[RX_read] == '6') USART_Init( 1000000/57600-1);//115200 if ((RX_array[RX_read] > '0') * (RX_array[RX_read] < '7')) baud_rate = (RX_array[RX_read]) - 48; set_baud(baud_rate); cli(); EEPROM_write((unsigned int) BPS, baud_rate); sei(); RX_read++; if(RX_read >= 416) RX_read = 0; } //set x or y========================================================= if((RX_array[RX_read] == 24) | (RX_array[RX_read] == 25))//^x or ^y { RX_read++; if(RX_read >= 416) RX_read = 0; while(RX_in == RX_read);//wait for byte if (RX_array[RX_read-1] == 24) x_offset = RX_array[RX_read]; else if (RX_array[RX_read-1] == 25) y_offset = RX_array[RX_read]; RX_read++; if(RX_read >= 416) RX_read = 0; if (x_offset > 159) x_offset = 159; if (y_offset > 127) y_offset = 127; } //set pixel========================================================= if (RX_array[RX_read] == 16)//^p { //need 3 bytes for (y = 0; y < 3; y++) { RX_read++; if(RX_read >= 416) RX_read = 0; while(RX_in == RX_read);//wait for byte } pixel(RX_array[RX_read], RX_array[RX_read-2], RX_array[RX_read-1]); RX_read++; if(RX_read >= 416) RX_read = 0; } //<ctrl>c, circle====================================================== if(RX_array[RX_read] == 3)//^c { //need 4 bytes for (y = 0; y < 4; y++) { RX_read++; if(RX_read >= 416) RX_read = 0; while(RX_in == RX_read);//wait for byte } circle(RX_array[RX_read], RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1]); RX_read++; if(RX_read >= 416) RX_read = 0; } //<ctrl>e, erase block====================================================== if(RX_array[RX_read] == 5)//^e { //need 4 bytes for (y = 0; y < 4; y++) { RX_read++; if(RX_read >= 416) RX_read = 0; while(RX_in == RX_read);//wait for byte } erase_block(RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1], RX_array[RX_read]); RX_read++; if(RX_read >= 416) RX_read = 0; } //box====================================================== if(RX_array[RX_read] == 15)//^o { //need 4 bytes for (y = 0; y < 4; y++) { RX_read++; if(RX_read >= 416) RX_read = 0; while(RX_in == RX_read);//wait for byte } box(RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1], RX_array[RX_read]); RX_read++; if(RX_read >= 416) RX_read = 0; } //line======================================================== else if (RX_array[RX_read] == 12)//^l { //need 5 bytes for (y = 0; y < 5; y++) { RX_read++; if(RX_read >= 416) RX_read = 0; while(RX_in == RX_read);//wait for byte } line(RX_array[RX_read], RX_array[RX_read-4], RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read+-1]); RX_read++; if(RX_read >= 416) RX_read = 0; } } } //print character to the screen=============================================== else { del_char(1); print_char(1, x); } } } //demo(); }
int main(int argc, char **argv) { unsigned long startofs = 0, part_size = 0; unsigned long ezones = 0, ezone = 0, bad_zones = 0; unsigned char unit_factor = 0xFF; long MediaUnit1 = -1, MediaUnit2 = -1; unsigned char oobbuf[16]; struct mtd_oob_buf oob = {0, 16, oobbuf}; printf("$Id: nftl_format.c,v 1.1.1.1 2006-07-11 09:31:28 andy Exp $\n"); if (argc < 2) { fprintf(stderr, "Usage: %s <mtddevice> [<start offset> [<size>]]\n", argv[0]); return 1; } if (argc > 2) { startofs = strtoul(argv[2], NULL, 0); } if (argc > 3) { part_size = strtoul(argv[3], NULL, 0); } // Open and size the device if ((fd = open(argv[1], O_RDWR)) < 0) { perror("Open flash device"); return 1; } if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { perror("ioctl(MEMGETINFO)"); close(fd); return 1; } switch (meminfo.erasesize) { case 0x1000: case 0x2000: case 0x4000: break; default: printf("Unrecognized Erase size, 0x%x - I'm confused\n", meminfo.erasesize); close(fd); return 1; } writebuf[0] = malloc(meminfo.erasesize * 5); if (!writebuf[0]) { printf("Malloc failed\n"); close(fd); return 1; } writebuf[1] = writebuf[0] + meminfo.erasesize; writebuf[2] = writebuf[1] + meminfo.erasesize; writebuf[3] = writebuf[2] + meminfo.erasesize; readbuf = writebuf[3] + meminfo.erasesize; memset(writebuf[0], 0xff, meminfo.erasesize); memset(writebuf[1], 0x00, meminfo.erasesize); memset(writebuf[2], 0x5a, meminfo.erasesize); memset(writebuf[3], 0xa5, meminfo.erasesize); memset(BadUnitTable, ZONE_GOOD, MAX_ERASE_ZONES); if (part_size == 0 || (part_size > meminfo.size - startofs)) /* the user doest not or incorrectly specify NFTL partition size */ part_size = meminfo.size - startofs; erase.length = meminfo.erasesize; ezones = part_size / meminfo.erasesize; if (ezones > MAX_ERASE_ZONES) { /* Ought to change the UnitSizeFactor. But later. */ part_size = meminfo.erasesize * MAX_ERASE_ZONES; ezones = MAX_ERASE_ZONES; unit_factor = 0xFF; } /* Phase 1. Erasing and checking each erase zones in the NFTL partition. N.B. Erase Zones not used by the NFTL partition are untouched and marked ZONE_GOOD */ printf("Phase 1. Checking and erasing Erase Zones from 0x%08lx to 0x%08lx\n", startofs, startofs + part_size); for (ezone = startofs / meminfo.erasesize; ezone < (ezones + startofs / meminfo.erasesize); ezone++) { if ((BadUnitTable[ezone] = erase_block(ezone)) == ZONE_GOOD) { if (MediaUnit1 == -1) { MediaUnit1 = ezone; } else if (MediaUnit2 == -1) { MediaUnit2 = ezone; } } else { bad_zones++; } } printf("\n"); /* N.B. from dump of M-System original chips, NumEraseUnits counts the 2 Erase Unit used by MediaHeader and the FirstPhysicalEUN starts from the MediaHeader */ NFTLhdr = (struct NFTLMediaHeader *) (writebuf[0]); strcpy(NFTLhdr->DataOrgID, "ANAND"); NFTLhdr->NumEraseUnits = cpu_to_le16(part_size / meminfo.erasesize); NFTLhdr->FirstPhysicalEUN = cpu_to_le16(MediaUnit1); /* N.B. we reserve 2 more Erase Units for "folding" of Virtual Unit Chain */ NFTLhdr->FormattedSize = cpu_to_le32(part_size - ( (5+bad_zones) * meminfo.erasesize)); NFTLhdr->UnitSizeFactor = unit_factor; /* Phase 2. Writing NFTL Media Headers and Bad Unit Table */ printf("Phase 2.a Writing NFTL Media Header and Bad Unit Table\n"); pwrite(fd, writebuf[0], 512, MediaUnit1 * meminfo.erasesize); for (ezone = 0; ezone < (meminfo.size / meminfo.erasesize); ezone += 512) { pwrite(fd, BadUnitTable + ezone, 512, (MediaUnit1 * meminfo.erasesize) + 512 * (1 + ezone / 512)); } #if 0 printf(" MediaHeader contents:\n"); printf(" NumEraseUnits: %d\n", le16_to_cpu(NFTLhdr->NumEraseUnits)); printf(" FirstPhysicalEUN: %d\n", le16_to_cpu(NFTLhdr->FirstPhysicalEUN)); printf(" FormattedSize: %d (%d sectors)\n", le32_to_cpu(NFTLhdr->FormattedSize), le32_to_cpu(NFTLhdr->FormattedSize)/512); #endif printf("Phase 2.b Writing Spare NFTL Media Header and Spare Bad Unit Table\n"); pwrite(fd, writebuf[0], 512, MediaUnit2 * meminfo.erasesize); for (ezone = 0; ezone < (meminfo.size / meminfo.erasesize); ezone += 512) { pwrite(fd, BadUnitTable + ezone, 512, (MediaUnit2 * meminfo.erasesize) + 512 * (1 + ezone / 512)); } /* UCI #1 for newly erased Erase Unit */ memset(oobbuf, 0xff, 16); oobbuf[11] = oobbuf[10] = oobbuf[9] = 0; oobbuf[8] = 0x03; oobbuf[12] = oobbuf[14] = 0x69; oobbuf[13] = oobbuf[15] = 0x3c; /* N.B. The Media Header and Bad Erase Unit Table are considered as Free Erase Unit by M-System i.e. their Virtual Unit Number == 0xFFFF in the Unit Control Information #0, but their Block Status is BLOCK_USED (0x5555) in their Block Control Information */ /* Phase 3. Writing Unit Control Information for each Erase Unit */ printf("Phase 3. Writing Unit Control Information to each Erase Unit\n"); for (ezone = cpu_to_le16(NFTLhdr->FirstPhysicalEUN); ezone < (ezones + startofs / meminfo.erasesize); ezone++) { /* write UCI #1 to each Erase Unit */ if (BadUnitTable[ezone] != ZONE_GOOD) continue; oob.start = (ezone * meminfo.erasesize) + 512; if (ioctl(fd, MEMWRITEOOB, &oob)) printf("MEMWRITEOOB at %lx: %s\n", (unsigned long)oob.start, strerror(errno)); } exit(0); }
int main(int argc, char *argv[]) { int pagelen; int ret; int rewind; // bad block, write the same data in next block handle_options(argc, argv); if (legacy || dm365_rbl || omap_bch || omap_hamming) { genecc = 1; fprintf(stderr, "ecc information will be generated and written to the nand\n"); } else genecc = 0; if ((mtd_fd = open(mtd_path, O_RDWR)) == -1) { perror(mtd_path); exit(EXIT_FAIL); } if (ioctl(mtd_fd, MEMGETINFO, &mi) != 0) { perror("MEMGETINFO"); close(mtd_fd); exit(EXIT_FAIL); } // Right now, only support one expected NAND size if (mi.oobsize != 64) { fprintf(stderr, "oobsize %d not supported\n", mi.oobsize); exit(EXIT_FAIL); } if (mi.writesize != 2048) { fprintf(stderr, "writesize %d not supported\n", mi.writesize); exit(EXIT_FAIL); } if (start_off & (mi.writesize - 1)) { fprintf(stderr, "Start offset must be aligned to page size 0x%x\n", mi.writesize); close(mtd_fd); exit(EXIT_FAIL); } pagelen = mi.size - mi.oobsize; if (write_mode) { /* Determine if we are reading from standard input or from a file. */ if (strcmp(image_path, standard_input) == 0) { image_fd = STDIN_FILENO; } else { image_fd = open(image_path, O_RDONLY); } if (image_fd == -1) { perror(image_path); exit(EXIT_FAIL); } if (image_fd == STDIN_FILENO) { if (input_size < 0) input_size = pagelen; } else { input_size = lseek(image_fd, 0, SEEK_END); lseek(image_fd, 0, SEEK_SET); } if (req_length < 0) { req_length = input_size; } else if (req_length > input_size) { fprintf(stderr, "File smaller (%d) than requested length (%d)\n", (int)input_size, req_length); exit(EXIT_FAIL); } DBG("input_size: %d\n", (int)input_size); } if (req_length < 0) { fprintf(stderr, "Must specify length or supply an input file\n"); exit(EXIT_FAIL); } req_pages = (((req_length - 1) / mi.writesize) + 1); block_pages = mi.erasesize / mi.writesize; if (max_off < 0) { max_off = mi.size; } else { if (max_off > mi.size) { max_off = mi.size; fprintf(stderr, "Max offset truncated to device size: 0x%x\n", max_off); } } if (req_pages * mi.writesize > mi.size - start_off) { dump_stats(); fprintf(stderr, "Request would pass the end of device\n"); exit(EXIT_NOSPACE); } if (req_pages * mi.writesize > max_off - start_off) { dump_stats(); fprintf(stderr, "Request would exceed max offset limit\n"); exit(EXIT_NOSPACE); } if (write_mode) { if (genecc) { ret = ioctl(mtd_fd, MTDFILEMODE, (void *) MTD_MODE_RAW); if (ret != 0) { perror ("MTDFILEMODE"); close (mtd_fd); exit (EXIT_FAIL); } else { DBG("Set MTD_MODE_RAW\n"); } genecc_init(); } // allocate block buffer: in-band page size * pages per block block_buf = malloc(mi.writesize * block_pages); if (!block_buf) { fprintf(stderr, "block_buf malloc failed\n"); exit(EXIT_FAIL); } } /* * Main write loop: */ dump_stats(); rewind = 0; // start at beginning of block containing start_off for (block_off = start_off & ~(mi.erasesize - 1); bytes_done < req_length; block_off += mi.erasesize ) { int start_page_num, page_num; int write_pages; loff_t ll_off; block_bytes_done = 0; // check bad block. Have to pass a long long to ioctl. ll_off = block_off; ret = ioctl(mtd_fd, MEMGETBADBLOCK, &ll_off); if (ret < 0) { perror("MEMGETBADBLOCK"); exit(EXIT_FAIL); } if (ret == 1) { fprintf(stderr, "Bad block at 0x%x : ", block_off); if (failbad) { fprintf(stderr, "ABORT\n"); exit(EXIT_BADBLOCK); } else { fprintf(stderr, "skip\n"); continue; } } if (!quiet) { if (erase_mode && write_mode) printf("Erase + write"); else if (erase_mode) printf("Erase"); else if (write_mode) printf("Write"); else exit(EXIT_FAIL); // bug printf(" block at 0x%x\n", block_off); } if (erase_mode) { if (block_off + mi.erasesize > max_off) { fprintf(stderr, "Erasing next block would exceed max offset\n"); dump_stats(); exit(EXIT_NOSPACE); } ret = erase_block(block_off); if (ret < 0) { fprintf(stderr, "Erase block at 0x%x failed\n", block_off); if (mark_block_bad(block_off) < 0) { fprintf(stderr, "Marking block bad failed\n"); // If not marked bad it would be misread, so this is fatal exit(EXIT_FAIL); } else { continue; // try next block } } } if (start_off > block_off) { // first block, starting later than page 0 start_page_num = (start_off - block_off) / mi.writesize; } else { start_page_num = 0; } if (write_mode) { // don't read more image file if skipping a bad block if (!rewind) next_image_block(); } else { // erasing, update count now bytes_done += mi.erasesize - start_page_num * mi.writesize; continue; } /* * UBI assumes it can write to any pages at the end of a PEB which * are all FFs in the in-band data area, so we must not write those * pages as we write (non-FF) ECC and UBI's later write would end up * with corrupt ECC (bitwise ANDed with ours). * * http://www.linux-mtd.infradead.org/doc/ubi.html#L_flasher_algo */ if (ubi) write_pages = block_pages - count_trailing_ff_pages(); else write_pages = block_pages; if (!quiet && write_pages != block_pages) printf("Skip last %d pages of block\n", block_pages - write_pages); rewind = 0; // foreach page in this block, until done for (page_num = start_page_num; page_num < block_pages; ++page_num) { if (block_off + (page_num + 1) * mi.writesize > max_off) { fprintf(stderr, "Writing this page would exceed max offset\n"); dump_stats(); exit(EXIT_NOSPACE); } if (page_num >= write_pages) { /* * Do the UBI mode skip here but stay in the loop so our "done" * counters get incremented appropriately */ DBG("Skipping page %d\n", page_num); ret = 0; } else { ret = write_page(block_off, page_num); } if (ret < 0) { fprintf(stderr, "Write block at 0x%x, page %d failed: ", block_off, page_num); if (failbad) { fprintf(stderr, "ABORT\n"); exit(EXIT_BADBLOCK); } else { fprintf(stderr, "Mark bad and skip\n"); } if (erase_block(block_off) < 0) { fprintf(stderr, "Erase block at 0x%x failed\n", block_off); // This isn't so important as we are about to mark bad } if (mark_block_bad(block_off) < 0) { fprintf(stderr, "Marking block bad at 0x%x failed\n", block_off); // If not marked bad it would be misread, so this is fatal exit(EXIT_FAIL); } rewind = 1; break; } block_bytes_done += mi.writesize; if (bytes_done + block_bytes_done >= req_length) break; } if (!rewind) { bytes_done += block_bytes_done; } } // clean up bch memory if (genecc) { switch (layout) { case GENECC_LAYOUT_LEGACY: break; case GENECC_LAYOUT_DM365_RBL: break; case GENECC_LAYOUT_OMAP_BCH: // free bch struture free_ecc_memory(); break; case GENECC_LAYOUT_OMAP_HAMMINGROMCODE: break; default: break; } } dump_stats(); if (image_fd != -1) close(image_fd); close(mtd_fd); if (mtd_path) free(mtd_path); if (image_path) free(image_path); if (page_buf) free(page_buf); if (block_buf) free(block_buf); return 0; }
static int flash_erase (struct mtd_info *mtd,struct erase_info *instr) { __u32 addr,len; int i,first; #ifdef LART_DEBUG printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len); #endif /* sanity checks */ if (instr->addr + instr->len > mtd->size) return (-EINVAL); /* * check that both start and end of the requested erase are * aligned with the erasesize at the appropriate addresses. * * skip all erase regions which are ended before the start of * the requested erase. Actually, to save on the calculations, * we skip to the first erase region which starts after the * start of the requested erase, and then go back one. */ for (i = 0; i < mtd->numeraseregions && instr->addr >= mtd->eraseregions[i].offset; i++) ; i--; /* * ok, now i is pointing at the erase region in which this * erase request starts. Check the start of the requested * erase range is aligned with the erase size which is in * effect here. */ if (instr->addr & (mtd->eraseregions[i].erasesize - 1)) return (-EINVAL); /* Remember the erase region we start on */ first = i; /* * next, check that the end of the requested erase is aligned * with the erase region at that address. * * as before, drop back one to point at the region in which * the address actually falls */ for (; i < mtd->numeraseregions && instr->addr + instr->len >= mtd->eraseregions[i].offset; i++) ; i--; /* is the end aligned on a block boundary? */ if ((instr->addr + instr->len) & (mtd->eraseregions[i].erasesize - 1)) return (-EINVAL); addr = instr->addr; len = instr->len; i = first; /* now erase those blocks */ while (len) { if (!erase_block (addr)) { instr->state = MTD_ERASE_FAILED; return (-EIO); } addr += mtd->eraseregions[i].erasesize; len -= mtd->eraseregions[i].erasesize; if (addr == mtd->eraseregions[i].offset + (mtd->eraseregions[i].erasesize * mtd->eraseregions[i].numblocks)) i++; } instr->state = MTD_ERASE_DONE; mtd_erase_callback(instr); return (0); }
void erase_block_all(void)//删除所有块 { unsigned int i; for(i=0;i<4096;i++) erase_block(i*32); }