📄 prog.c
字号:
/* ---------------------------------------------------------------------------- * prog.c * this module contains top ATMEL programming functions * * Copyright 2003/2004 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ----------------------------------------------------------------------------*/#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <sys/stat.h>#include <ctype.h>#include "isp-at89.h"/* Buffer functions *//* This function disassembles the buffer and print the result to stdout. * To reach also code isles, such as interrupt routines, additional * code entry points could be defined. The main entry point and the * interrupt vectors are added here. Others will be added during * disassembing. Range checks will be done inside addCodeEntry functions. */voiddisassembleBufferToScreen(struct MemChunk *Buffer, int Type){ struct MemoryMap *MemMap; int celist[] = { 0x0000, 0x0003, 0x000B, 0x0013, 0x001B, 0x0023, 0x002B }; if (Buffer) { if ((MemMap = memchunk_GetMemoryMap(Buffer))) { printf(_(" Disassemble %s (%04xh-%04xh, %d bytes).\n"), getMemoryName(Type), Buffer->header.address, Buffer->header.address + Buffer->header.length, Buffer->header.length); addCodeEntryList(MemMap, celist, sizeof(celist) / sizeof(int)); disassembler_pass1(MemMap, Buffer); /* set hard entry codes again because they are defined through * microprocessor hardware and are alwys there even if they * used or not. disassembler_pass1 will remove entry marks if * the concerning address is passing by. */ addCodeEntryList(MemMap, celist, sizeof(celist) / sizeof(int)); disassembler_pass2(MemMap, Buffer); disassembler_pass3(MemMap, Buffer); free(MemMap); } }}/* This helper function prints an address range with the comment * "unsused memory" on screen. The arguments are start and end * address of this range. * This function is used by DumpBufferToScreen() below only. */voiddumpUnusedMemory(int start, int end){ switch (end - start) { case 0: break; case 1: printf ("%04x : ", start); printf (_("memory not used\n")); break; default: printf ("%04x-%04x: ", start, end - 1); printf (_("memory not used\n")); break; }}/* This function dumps the contens of a Buffer in human readable form * to screen. The format is similar to most hex editors: * <address range> <hex values> <ascii translation> * The function tries to detect unused memory areas and will print them * in a space saving manner. This causes a clear and readable output. */voiddumpBufferToScreen(struct MemChunk *Buffer, int Type){ int curaddr = 0, n, m, arg; struct MemoryMap *MemMap; struct MemChunk *Chunk; char LB[80]; char *args[] = { &LB[0], &LB[5], &LB[10], &LB[13], &LB[16], &LB[19], &LB[22], &LB[25], &LB[28], &LB[31], &LB[34], &LB[37], &LB[40], &LB[43], &LB[46], &LB[49], &LB[52], &LB[55], &LB[58] }; int celist[] = { 0x0000, 0x0003, 0x000B, 0x0013, 0x001B, 0x0023, 0x002B }; if (Buffer) { if ((MemMap = memchunk_GetMemoryMap(Buffer))) { addCodeEntryList(MemMap, celist, sizeof(celist) / sizeof(int)); disassembler_pass1(MemMap, Buffer); /* mark code areas */ disassembler_pass2(MemMap, Buffer); /* mark unused memory areas */ printf(_(" Dump %s (%04xh-%04xh, %d bytes) to Screen.\n"), getMemoryName(Type), Buffer->header.address, Buffer->header.address + Buffer->header.length, Buffer->header.length); while ((Chunk = memchunk_FindNext (Buffer, curaddr))) { dumpUnusedMemory (curaddr, Chunk->header.address); curaddr = Chunk->header.address; for (arg=0, n=0; n < Chunk->header.length; n++) { if (arg == 0) snprintf(args[STARTADR], 5, "%04x", curaddr + n); if ((MemMap->flags[curaddr + n] & ADR_FREE)) { if (arg > 0) { for (; arg < 16; arg++) snprintf(args[D0 + arg], 3, " "); /* close current row */ n--; /* operate on current byte again in next loop */ } else { /* save the start address and then calculate the end of the unused memory block */ for (m=n; n < Chunk->header.length && (MemMap->flags[curaddr + n] & ADR_FREE); n++); dumpUnusedMemory (m, n--); /* Print unused memory range to screen */ } } else { snprintf(args[D0 + arg], 3, "%02x", Chunk->data[n]); args[ASCSTR][arg++] = isprint(Chunk->data[n]) ? Chunk->data[n] : '.'; args[ASCSTR][arg] = 0; /* close string */ } if (arg > 15) { /* row full, then print it to screen */ snprintf(args[ENDADR], 5, "%04x", curaddr + n); if (strcmp(args[STARTADR], args[ENDADR]) == 0) printf("%s : ", args[STARTADR]); else printf("%s-%s: ", args[STARTADR], args[ENDADR]); printf("%s %s %s %s ", args[D0], args[D1], args[D2], args[D3]); printf("%s %s %s %s ", args[D4], args[D5], args[D6], args[D7]); printf("%s %s %s %s ", args[D8], args[D9], args[D10], args[D11]); printf("%s %s %s %s ", args[D12], args[D13], args[D14], args[D15]); printf(" >%s<\n", args[ASCSTR]); arg = 0; /* start with column 0 again in next row */ } } /* set curaddr to the end of the current MemChunk. From this address on * the next MemChunk is searched to feed the next loop. */ curaddr = Chunk->header.address + Chunk->header.length; } free (MemMap); /* MemMap not needed any longer, free memory */ } }}voidwriteBufferToFile(struct MemChunk *Buffer, char* FileName, int Type){ int fd; if (Buffer) { if ((fd = openDataFile(FileName)) != ERROR) { printf(_(" Writing %s (%04xh-%04xh, %d bytes) to file '%s'.\n"), getMemoryName(Type), Buffer->header.address, Buffer->header.address + Buffer->header.length, Buffer->header.length, FileName); if ((write(fd, Buffer->data, Buffer->header.length)) != Buffer->header.length) printf(_("-- ERROR: Problems writing datafile: %s\n"), strerror(errno)); else printf(_(" - datafile written!\n")); close(fd); Buffer = (struct MemChunk*) ((char*) Buffer + sizeof(struct MemChunkHeader) + Buffer->header.length); if (Buffer->header.length) printf(_("-- WARNING: Buffer has more than one MemChunk, only first one written to file\n")); } }}voidwriteBufferToMemory(struct ProgrammingData *pdata, struct MemChunk *Buffer){ struct MemChunk *Chunk; unsigned short int cstart, clength, cend = 0; int cnr = 0, n, fd; if (Buffer) { /* prepare interface to use for comunication with MC */ if (pdata->memory == MEM_INTERN || pdata->memory == MEM_EEPROM) { if ((fd = parport_gethandle(pdata->ppdevname)) == ERROR) return; if ((atmel_checkDevice(fd)) == ERROR) { printf (_(" -- ERROR: No ATMEL microprocessor present.\n")); parport_release(fd); return; } if (pdata->flags.erase) { atmel_eraseChip(fd); printf(_(" Erasing %s - done.\n"), getMemoryName(pdata->memory)); } } else { printf (_(" -- ERROR: External memory not supported yet.\n")); return; } /* write data to memory */ printf(_(" Writing %s:\n"), getMemoryName(pdata->memory)); while ((Chunk = memchunk_FindNext (Buffer, cend))) { cstart = Chunk->header.address; clength = Chunk->header.length; /* define some helpers */ cend = cstart + clength; cnr++; /* increase chunk number */ for (n = 0; n < clength; n++) { switch (pdata->memory) { case MEM_INTERN: atmel_writeCodeMemory(fd, cstart + n, Chunk->data[n]); break; case MEM_EXTERN: break; case MEM_EEPROM: atmel_writeDataMemory(fd, cstart + n, Chunk->data[n]); break; } if (((cstart + n) & 0x07) == 0) { printf("\r"); printf(_(" + chunk #%d (%04xh-%04xh), address: %04xh"), cnr, cstart, cend, cstart + n); fflush(stdout); } } printf("\r"); printf(_(" + chunk #%d (%04xh-%04xh), address: %04xh"), cnr, cstart, cend, cstart + n); printf("\n"); } printf(_(" - Programm complete!\n")); /* clean up interface */ if (pdata->memory == MEM_INTERN || pdata->memory == MEM_EEPROM) parport_release(fd); }}struct MemChunk*readMemoryToBuffer(struct ProgrammingData *pdata){ unsigned short int cstart, clength, cend; int n, fd; struct MemChunk *Buffer, *Chunk; /* prepare interface to use for comunication with MC */ if (pdata->memory == MEM_INTERN || pdata->memory == MEM_EEPROM) { if ((fd = parport_gethandle(pdata->ppdevname)) == ERROR) return NULL; if ((atmel_checkDevice(fd)) == ERROR) { printf (_(" -- ERROR: No ATMEL microprocessor present.\n")); parport_release(fd); return NULL; } } else { printf (_(" -- ERROR: External memory not supported yet.\n")); return NULL; } /* read data from memory */ printf(_(" Reading %s:\n"), getMemoryName(pdata->memory)); cstart = 0; clength = getMemorySize(pdata->memory); /* define some helpers */ cend = cstart + clength; if ((Buffer = memchunk_Alloc(clength)) > 0) { Chunk = Buffer; Chunk->header.address = cstart; Chunk->header.length = clength; for (n = 0; n < clength; n++){ switch (pdata->memory) { case MEM_INTERN: Chunk->data[n] = atmel_readCodeMemory(fd, cstart + n); break; case MEM_EXTERN: break; case MEM_EEPROM: Chunk->data[n] = atmel_readDataMemory(fd, cstart + n); break; } if (((cstart + n) & 0xff) == 0) { printf("\r"); printf(_(" + chunk #1 (%04xh-%04xh), address: %04xh"), cstart, cend, cstart + n); fflush(stdout); } } printf("\r"); printf(_(" + chunk #1 (%04xh-%04xh), address: %04xh"), cstart, cend, cstart + n); printf("\n"); /* Chunk is from datatype struct MemChunk with a length != sizeof(unsigned char) * so that it must be casted twice to increment it correctly */ Chunk = (struct MemChunk *) ((unsigned char *) Chunk + sizeof(struct MemChunkHeader) + Chunk->header.length); Chunk->header.address = 0; Chunk->header.length = 0; } /* clean up interface */ if (pdata->memory == MEM_INTERN || pdata->memory == MEM_EEPROM) parport_release (fd); return Buffer;}/* This function opens an existing datafile and loads its contents * into the buffer. The return value is the count of bytes read. * If the file is bigger than maxsize, the return value is ERROR. * this value will also be returned in any other error case. */struct MemChunk*readFileToBuffer (char *name, int maxsize){ struct stat stat_buf; struct MemChunk *Buffer, *Chunk; int fd, fs, val = 0; fs = getFileStatus(name); switch (fs) { case FST_FILE: stat(name, &stat_buf); printf(_(" Reading File %s (%d bytes).\n"), name, (int) stat_buf.st_size); if ((fd = open(name, O_RDONLY )) >= 0) { if ((Buffer = memchunk_Alloc(stat_buf.st_size))) { Chunk = Buffer; Chunk->header.address = 0; Chunk->header.length = stat_buf.st_size; val = read(fd, Chunk->data, Chunk->header.length); close (fd); if (val == Chunk->header.length) { /* Chunk is from datatype struct MemChunk with a length != sizeof(unsigned char) * so that it must be casted twice to increment it correctly */ Chunk = (struct MemChunk *) ((unsigned char *) Chunk + sizeof(struct MemChunkHeader) + Chunk->header.length); Chunk->header.address = 0; Chunk->header.length = 0; if (hex2bin (Buffer) == OK) { if (memchunk_GetProgramSize(Buffer) <= maxsize) return Buffer; else printf (_("-- ERROR: Program %s too long - size is limited to %d bytes.\n"), name, maxsize); } printf (_("-- ERROR: Intel Hex File corrupt!\n")); memchunk_Free (Buffer); } else { printf (_("-- ERROR: Can't read %s: %s\n"), name, strerror(errno)); memchunk_Free(Buffer); } } else { printf (_("-- ERROR: Can't allocate %d bytes of memory.\n"), (int) stat_buf.st_size); close (fd); } } else printf (_("-- ERROR: Can't open %s: %s\n"), name, strerror(errno)); return NULL; break; case FST_NOARG: printf (_("-- ERROR: missing filename for datafile.\n")); break; case FST_NOEXIST: default: printf (_("-- ERROR: %s doesn't exist or is not a regular file.\n"), name); } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -