⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prog.c

📁 at51系列单片机编程源码
💻 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 + -