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

📄 jtag.cpp

📁 Source Code of jlinkserver for Segger JLink
💻 CPP
字号:
/** Wrapper over the JTAG library
*/


#include "stdafx.h"

using namespace std;

static void debugCom(const char* s) {
	cout << s;
}

/** Create a new JTAG port
*/
JTAG::JTAG() {
	JLINKARM_Open();
	JLINKARM_SetSpeed(-50);
//	JLINKARM_SetSpeed(2000);
}

void JTAG::StartLogging() {
	JLINKARM_EnableLogCom(debugCom);
}

JTAG::~JTAG() {
	JLINKARM_Close();
}

/** Send a command to the flash
*/
void JTAG::FlashCommand(unsigned int command, unsigned int page) {
	JLINKARM_WriteU32(EFC_BASE + 0x64, ((command & 0x0F) | ((page & 0x3FF) << 8) | (0x5A << 24)));

	unsigned int status;

	while (true) {
		
		status = ReadU32(EFC_BASE + 0x68);

		if (status & (1 << 0)) break;
	}
}

static void dumpMemory(unsigned int address, unsigned int size) {
	for (unsigned int i = 0; i < size; i += 16) {
		printf("%08X  ", address + i);
		unsigned char buffer[16];

		JLINKARM_ReadMem(address + i, 16, buffer);
		for (unsigned int j = 0; j < 16; j++) {
			printf("%02X ", buffer[j]);
		}

		for (unsigned int j = 0; j < 16; j++) {
			unsigned char ch = buffer[j];

			if ((ch >= ' ') && (ch <= 127)) {
				printf("%c", ch);
			}
			else {
				printf(".");
			}
		}
		printf("\n");
	}
		

}
/** Write to flash
*/
void JTAG::FlashWrite(unsigned int address, unsigned int size, void* buffer) {
	address = address & 0x000FFFFF;
	unsigned int* pointer = (unsigned int*)buffer;
	unsigned int remaining = (size + 3) / 4;
	unsigned int orig = address;



	int offset = 0;
	while (remaining) {
		unsigned int page = address / PAGE_SIZE;

		unsigned int wordsToWrite = ((((page + 1) * PAGE_SIZE) - address) / 4);
		if (wordsToWrite > remaining) wordsToWrite = remaining;

		fprintf(stdout, "\rWriting to %08X", address);
		fflush(stdout);

//		printf("\nDumping memory\n");
//		dumpMemory(page * PAGE_SIZE, PAGE_SIZE);

		// Write the data
		for (unsigned int i = 0; i < wordsToWrite; i++) {
			WriteU32(address, *pointer++);
			address += 4;
		}
		FlashCommand(WP, page);

//		printf("\nDumping memory\n");
//		dumpMemory(page * PAGE_SIZE, PAGE_SIZE);


		// Adjust the remaining count
		remaining -= wordsToWrite;
	}
	

}


/** Erase the flash
*/
inline void JTAG::EraseFlash() {
	dumpMemory(0, 16);
	FlashCommand(EA, 0);
	dumpMemory(0, 16);
}

void JTAG::InitialiseForFlashing() {
	Initialise();
	// Initialise the flash mode register
	WriteU32(EFC_BASE + 0x60, 0x00320180);

	MapRam(0);

	EraseFlash();
}

/** Download the file into flash
*/
void JTAG::FlashDownload(ELF* elf) {
	InitialiseForFlashing();


	printf("Downloading...");
	fflush(stdout);

	// Don't erase before writing
	WriteU32(EFC_BASE + 0x60, ReadU32(EFC_BASE + 0x60) | (1 << 7));

	for (int i = 0; i < elf->header.e_phnum; i++) {
		Elf32_Phdr* hdr = &elf->programHeaders[i];
		// Don't put anything in low memory - it is mapped either to ram or flash, or something
		// that has no size
		if ((hdr->p_type == PT_LOAD) && (hdr->p_filesz > 0) && (hdr->p_paddr >= 0x00100000)) {
			void* buffer = elf->ProgramSegment(i);
//			SwapWords((unsigned char*)buffer, hdr->p_memsz);
			FlashWrite(hdr->p_paddr, hdr->p_filesz, buffer);
			delete[] buffer;
		}
	}
	fprintf(stdout, "...Done\n");

}

static void SwapWords(unsigned char* buffer, unsigned int size) {
	for (unsigned int i = 0; i < size; i += 4) {
		unsigned char b0;
		
		b0 = buffer[i];
		buffer[i] = buffer[i+3];
		buffer[i+3] = b0;

		b0 = buffer[i+1];
		buffer[i+1] = buffer[i+2];
		buffer[i+2] = b0;
	}
}

void JTAG::RamDownload(ELF* elf) {
	Initialise();
	MapRam(1);


	for (int i = 0; i < elf->header.e_phnum; i++) {
		Elf32_Phdr* hdr = &elf->programHeaders[i];
		if (hdr->p_type == PT_LOAD) {
			void* buffer = elf->ProgramSegment(i);
//			SwapWords((unsigned char*)buffer, hdr->p_memsz);
			JLINKARM_WriteMem(hdr->p_vaddr, hdr->p_memsz, buffer);
			delete[] buffer;
		}
	}
}

void JTAG::MapRam(int flag) {
	U32 dataBefore;
	U32 dataWrite;
	U32 dataAfter;
	U8 status;

	JLINKARM_WriteU32(0, 0);

	JLINKARM_ReadMemU32(0, 1, &dataBefore, &status);

	dataWrite = ~dataBefore;
	JLINKARM_WriteU32(0, dataWrite);

	JLINKARM_ReadMemU32(0, 1, &dataAfter, &status);
	if (flag) {
		if (dataAfter != dataWrite) {
			JLINKARM_WriteU32(0xffffff00, 0x00000001);
		}	
	}
	else {
		if (dataAfter == dataWrite) {
			JLINKARM_WriteU32(0xffffff00, 0x00000001);
		}	
	}

}

/** Initialise the clocks
*/
void JTAG::Initialise() {
	int status;

	do {
		status = JLINKARM_Halt();
		JLINKARM_ClrError();
	}
	while (status);


	JLINKARM_ResetPullsRESET(1);
	JLINKARM_ResetPullsTRST(1);
	JLINKARM_Reset();
	JLINKARM_WriteU32(0xFFFFFC20, 0x00000601);
	JLINKARM_WriteU32(0xFFFFFC2C, 0x00191C05);
	JLINKARM_WriteU32(0xFFFFFC30, 0x00000007);
}

void JTAG::Go() {

	JLINKARM_Go();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -