📄 prog89s52-1.0.c
字号:
(*map).data = realloc((*map).data, requiredblocks*BLOCKSIZE) ; if(!((*map).data)) { msg(0, "Failed to allocate %i bytes for internal memory map. A memory dump will not be produced\n", requiredblocks*BLOCKSIZE) ; domemfile = 0 ; return ; } /* initialise all bytes to FF */ for(index = (*map).blocks*BLOCKSIZE; index < requiredblocks*BLOCKSIZE; index ++) ((*map).data)[index] = 0xFF ; (*map).blocks = requiredblocks ; } /* copy the data from record to memory map */ for(index = 0; index < thisrec.length; index++) ((*map).data)[thisrec.address + index] = thisrec.data[index] ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Dump the internal memory map as an Intel HEX file */void writehexfile(memmap map) { int lastusedaddress ; int blockcount ; int blockindex ; short byteindex ; FILE *hexfile ; unsigned char checksum ; if((hexfile = fopen(map.filename, "w")) == NULL) { msg(0, "Unable to open HEX file %s for writing. A HEX file will not be produced\n", map.filename) ; free(map.data) ; return ; } /* locate the last programmed (not 0xFF) address - subsequent blocks will not be included in the file */ for(lastusedaddress = (map.blocks*BLOCKSIZE)-1; lastusedaddress >= 0; lastusedaddress --) if(map.data[lastusedaddress ] != 0xFF) break ; blockcount = (lastusedaddress == -1) ? 0 : (int)ceil((float)lastusedaddress / BLOCKSIZE) ; msg(50, "Writing %.2f of %.2fKB of read memory to HEX file %s\n", (blockcount*BLOCKSIZE)/1024.0, (map.blocks*BLOCKSIZE)/1024.0, map.filename) ; for(blockindex = 0; blockindex < blockcount; blockindex++) { fprintf(hexfile, ":%02X%04X00", BLOCKSIZE, blockindex*BLOCKSIZE) ; /* metadata: all records are PAGESIZE (256 bytes) long */ checksum = BLOCKSIZE + (((blockindex*BLOCKSIZE) >> 8) & 0x00FF) + ((blockindex*BLOCKSIZE) & 0x00FF) ; for(byteindex = 0; byteindex < BLOCKSIZE; byteindex++) { /* write all bytes in sequence */ fprintf(hexfile, "%02X", map.data[blockindex*BLOCKSIZE+ byteindex]) ; checksum += map.data[blockindex*BLOCKSIZE+ byteindex] ; } checksum = 1 + ~checksum ; fprintf(hexfile, "%02X\n", checksum) ; /* append checksum */ } fprintf(hexfile, ":00000001FF") ; /* EOF record */ free(map.data) ; fclose(hexfile) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* dump the internal memory map to a text file */void writememfile(memmap map, char *title, ...) { FILE *memfile ; unsigned int line ; char *hexstring ; char charstring[BLOCKSIZE+1] ; int bytecount ; va_list argp ; va_start(argp, title) ; time_t now ; if((memfile = fopen(map.filename, "w")) == NULL) { msg(0, "Unable to open memory dump file %s for writing. A memory dump will not be produced\n", map.filename) ; free(map.data) ; return ; } vfprintf(memfile, title, argp) ; /* output header information - title is provided printf-style */ va_end(argp) ; now = time(NULL) ; fprintf(memfile, "%s", ctime(&now)) ; if((map.blocks*BLOCKSIZE)/1024) fprintf(memfile, "Memory size %.1fKB\n", (map.blocks*BLOCKSIZE)/(float)1024) ; /* > 1k */ else fprintf(memfile, "Memory size %iB\n", (map.blocks*BLOCKSIZE)) ; /* < 1k */ fprintf(memfile, "Unwritten memory locations are 0xFF\n\n") ; msg(100, "Memory dump:\n") ; for(line = 0; line < map.blocks; line++) { hexstring = binstring(map.data + line*BLOCKSIZE, BLOCKSIZE) ; if(!hexstring) break ; /* scan the current block & copy to charstring, replace any unprintable characters with '.' */ for(bytecount = 0; bytecount < BLOCKSIZE; bytecount ++) { if(map.data[(line*BLOCKSIZE) + bytecount] < 32 || map.data[(line*BLOCKSIZE) + bytecount] > 126) /* unprintable */ charstring[bytecount] = '.' ; else /* printable*/ charstring[bytecount] = (char)(map.data[(line*BLOCKSIZE) + bytecount]) ; charstring[BLOCKSIZE] = 0 ; } msg(100, "%04X\t%s\t%s\n", line*BLOCKSIZE, hexstring, charstring) ; fprintf(memfile, "%04X\t%s\t%s\n", line*BLOCKSIZE, hexstring, charstring) ; free(hexstring) ; } msg(100, "End of memory dump\n") ; fprintf(memfile, "\nEnd of memory dump.\n") ; free(map.data) ; fclose(memfile) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* outputs progress indication every 10% */void progress(int current, int max) { static int nominal = 0 ; int actual ; if(!current && !max) { nominal = 0 ; return ; } actual = 10*((int)(10*current/(float)max)) ; if(nominal != actual) { nominal = actual ; msg(30, "%i%% ", nominal) ; if(nominal == 100) msg(30, "\n") ; fflush(stdout) ; } }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Read a byte from the flash in the byte mode */unsigned char readflashbyte(unsigned short address) { unsigned char data ; byteout(0x20) ; /* read opcode */ byteout((address >> 8) & 0xFF) ; /* address MSB */ byteout(address & 0xFF) ; /* address LSB */ data = bytein() ; msg(80, "Read %i (0x%02X) from program location %i (0x%04X)\n", data, data, address, address) ; return(data) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Write a byte to the flash memory in the byte mode */void writeflashbyte(unsigned short address, unsigned char data) { byteout(0x40) ; /* write opcode */ byteout((address >> 8) & 0xFF) ; /* address MSB */ byteout(address & 0xFF) ; /* address LSB */ byteout(data) ; /* data */ msg(80, "Wrote %i (0x%02X) to program location %i (0x%04X)\n", data, data, address, address) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Read a 256-byte page from the flash memory into the provided buffer */#define PAGESIZE 256void readflashpage(unsigned short address, unsigned char *buffer) { short index ; msg(80, "Reading one %i byte page from program location %i (0x%04X)\n", PAGESIZE, address&0xFF00, address&0xFF00) ; byteout(0x30) ; /* page write opcode */ byteout((address >> 8) & 0xFF) ; /* address MSB */ for(index = 0; index < PAGESIZE; index++) { buffer[index] = bytein() ; } msg(80, "Read completed\n") ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Fill the memory map from the part's program memory */void readtomemmap(memmap map) { short pagecount ; short pageindex ; pagecount = (map.blocks * BLOCKSIZE) / PAGESIZE ; msg(20, "Reading %iKB of program memory from part\n", (map.blocks*BLOCKSIZE)/1024) ; for(pageindex = 0; pageindex < pagecount; pageindex++) { msg(50, "Page %i of %i\n", pageindex+1, pagecount) ; if(verbosity < 50) progress(pageindex+1, pagecount) ; readflashpage(pageindex*PAGESIZE, map.data+pageindex*PAGESIZE) ; } }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Write a record to the part */int writerecord(record thisrec) { unsigned int byteindex ; unsigned char response ; time_t starttime ; msg(80, "Writing %i bytes to address %X\n", thisrec.length, thisrec.address) ; for(byteindex = 0; byteindex < thisrec.length; byteindex++) { writeflashbyte(thisrec.address+byteindex, thisrec.data[byteindex]) ; starttime = time(NULL) ; while(time(NULL) <= starttime+1 && response != thisrec.data[byteindex]) response = readflashbyte(thisrec.address+byteindex) ; /* read back the contents of the address untill we verify the write or time out */ if(response == thisrec.data[byteindex]) msg(80, "Byte %i of %i written and verified\n", byteindex+1, thisrec.length) ; else { msg(0, "Timed out waiting for verification of write (read %i, expected %i)\n", response, thisrec.data[byteindex]) ; msg(0, "Writing to address %X was unsuccessful\n", thisrec.address+byteindex) ; return(1) ; } } return(0) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Erase the on-chip flash */int erase(void) { unsigned char response = 0 ; time_t starttime ; if(domock) { msg(20, "Erase program memory in Simulation mode: Nothing will be written to the part\n") ; return(0) ; } else msg(20, "Erase program memory\n") ; byteout(0xAC) ; /* chip erase instruction */ byteout(0x80) ; byteout(0x00) ; byteout(0x00) ; starttime = time(NULL) ; /* begin timeing */ msg(80, "Polling program memory address location 0 for vlaue 0xFF to indicate that erase is complete\n") ; while(time(NULL) <= starttime+1 && response != 0xFF) response = readflashbyte(0) ; /* wait untill we read 0xFF (erased) or time out waiting */ if(response == 0xFF) msg(50, "Program memory successfully erased\n") ; else { msg(0, "Timed out waiting for completion of program memory erase (read %i, expected %i)\n", response, 0xFF) ; msg(0, "Program memory is not correctly erased\n") ; return(1) ; } return(0) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Count the number of records in the hex file */int countrecords(int hexfd) { int records = 0 ; char buffer ; ssize_t readbytes ; lseek(hexfd, 0, SEEK_SET) ; do { readbytes = read(hexfd, &buffer, 1) ; if(readbytes == -1) { msg(0, "File read error whilest scanning HEX file. File will not be processed further\n") ; perror("read") ; return(1) ; } if(buffer == ':') records ++ ; } while(readbytes) ; return(records) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Read the hex file */int readhexfile(int hexfd) { int recordend = 0 ; int recordstart = 0 ; int recordnum = 1 ; int recordcount ; record thisrec ; char *datastring ; if(domock) msg(20, "Processing HEX file in Simulation mode: Nothing will be written to the part\n") ; else msg(20, "Writing to program memory\n") ; if((recordcount = countrecords(hexfd)) == -1) return(-1) ; do { thisrec = readrecord(hexfd, recordstart, &recordend) ; recordstart = recordend ; if(verbosity < 50) progress(recordnum, recordcount) ; switch(thisrec.status) { /* check the status of the record read */ case OK: msg(100, "Record %i read successfully\n", recordnum) ; break ; case ERROR: msg(0, "Record %i contains an error (see above). This error is non-fatal and processing of the file will continue\n", recordnum) ; break ; case END: msg(50, "Processing of HEX file completed\n") ; break ; case ABORT: msg(0, "A fatal error (see above) was encountered at record %i. Processing of the file will be aborted\n", recordnum) ; break ; case IGNORE: msg(0, "Record %i will be ignored for the reasons shown above\n", recordnum) ; break ; } /* process the record data */ if(thisrec.status == OK || thisrec.status == ERROR) { if(verbosity >= 50) { /* output data to be written to the terminal */ datastring = binstring(thisrec.data, thisrec.length) ; msg(50, "Record %i of %i:\t%s\n", recordnum, recordcount, datastring) ; free(datastring) ; } if(domemfile) makememmap(thisrec, &mapfromfile) ; /* include the current record in the memory map if required */ if(!domock) { if(writerecord(thisrec)) return(1) ; } } recordnum ++ ; } while(thisrec.status != END && thisrec.status != ABORT) ; if(thisrec.status == ABORT) return(1) ; return(0) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*/int main(int argc, char *argv[]) { int hexfd ; /* parse program arguments */ if(parseargs(argc, argv)) { msg(0, "Execution aborted due to missing arguments\n") ; exit(1) ; } /* output usefull messages */ msg(50, "prog89s %s by TOMi. Build date %s at %s.\n", VERSION, __DATE__, __TIME__) ; if(delay) msg(50, "Delay %iuS. Programming speed is approximately %.1fkbps, minimum recommended crystal frequency is %.2fMHz\n", delay, 1/((float)delay*0.002), 16/((float)delay*2)) ; else msg(50, "Programming speed is unregulated. Minimum recommended crystal frequency is 8Mhz\n") ; /* open HEX file if needed */ if(doprogram) { hexfd = openfile() ; if(hexfd < 0) { msg(0, "Execution aborted due to file read error\n") ; exit(1) ; } } /* open the connection and prepare the part for programming */ openport() ; mode(PROGRAM) ; if(doreset) { /* simply reset the device - no other operations */ usleep(1000) ; msg(20, "Target reset\n") ; goto QUIT ; } if(!domock) { if(initprog()) goto QUIT ; } /* perform operations as required */ if(doreadid) readid() ; if(doreadlocks) readlocks() ; if(docopytomemfile || docopytohexfile) readtomemmap(mapfrompart) ; if(doerase || (doprogram && !donoerase)) if(erase()) goto QUIT ; if(doprogram) if(readhexfile(hexfd)) goto QUIT ; if(dowritelocks) writelocks(dowritelocks) ; /* Place the part into run mode and close all ports and files */ if(domemfile) writememfile(mapfromfile, "Memory Dump created by prog89s from Intel HEX file %s\n", hexfilename) ; if(docopytomemfile) writememfile(mapfrompart, "Memory Dump of microcontroller program flash, created by prog89s\n") ; if(docopytohexfile) writehexfile(mapfrompart) ; msg(20, "All operations completed successfully\n") ; QUIT: mode(RUN) ; closeport() ; close(hexfd) ; }/*--------------------------------------------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -