📄 jtag.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 + -