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

📄 arm7tdmi.c

📁 arm7的JTAG调试工具源码
💻 C
📖 第 1 页 / 共 3 页
字号:

	if(pc == NULL)
		return XJERR_INVALID_PARAMATER;

	//In DEBUG state?
	if(arm7tdmi_status.state == ARM7TDMI_DEBUG_STATE)
		return XJERR_TARGET_HALTED;

	//Select scan chain 2
	status = arm7tdmi_connect_scanchain(2);
	if(status != XJ_OK)
		return status;

	//Check DEBUG status register
	arm7tdmi_ice_read(ARM7TDMI_ICE_DBGSTAT, &dbgstat);
	if(dbgstat & 0x1){
		arm7tdmi_status.state = ARM7TDMI_DEBUG_STATE;
		if (dbgstat & 0x10)
			arm7tdmi_status.from = ARM7TDMI_FROM_THUMB;
		else
			arm7tdmi_status.from = ARM7TDMI_FROM_ARM;
	}else
		return XJERR_TARGET_RUNNING;

	/*
	 * Try to obtain the value of PC when entering DEBUG state. The obtained
	 * value of PC indicates the next instruction to be executed on exit from
	 * DEBUG state.
	 */

	//Select scan chain 1
	status = arm7tdmi_connect_scanchain(1);
	if(status != XJ_OK)
		return status;


	if(arm7tdmi_status.from == ARM7TDMI_FROM_ARM){	//Enter DEBUG from ARM state

		//Step 1 - Read R0 

		//STR R0, [R0] = 0xE5800000					
		shift_in[0] = 0xE5800000;					//Instruction 1
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		/* 
		 * After the ARM7TDMI core has entered debug state from breakpt/watchpt,
		 * the first time the 33rd bit is captured and scanned out, its value 
		 * tells the debugger if the core entered debug state due to a breakpoint
		 * (bit 33 clear) or a watchpoint (bit 33 set).
		 */
		if(shift_out[1] & 0x1)
			arm7tdmi_status.by = ARM7TDMI_BY_WATCHPT;
		else
			arm7tdmi_status.by = ARM7TDMI_BY_BREAKPT;

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					//Instruction 2
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					//Instruction 3
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);
		r0 = shift_out[0];

		//Step 2 - Move PC to R0

		//MOV R0, PC = 0xE1A0000F
		shift_in[0] = 0xE1A0000F;					//Instruction 4
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);	

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//Step 3 - Read the value of PC from R0

		//STR R0, [R0] = 0xE5800000
		shift_in[0] = 0xE5800000;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);
		*pc = shift_out[0];

		/*
		 * Entry into DEBUG state from a breakpoint/watchpoint advances the 
		 * PC by four addresses. Each instruction executed in DEBUG state 
		 * advances the PC by one address. 
		 *
		 * To move the value of PC to R0, 4 instructions have been executed in D
		 * EBUG state. So,  the value of PC which indicates the next instruction
		 * should be executed on exit from DEBUG state is
		 *			pc - 4 x (4 + 4)
		 */
		*pc -= 32;

	}else{		//Enter DEBUG from THUMB state

		//Step 1 - Read R0 

		//STR R0, [R0] = 0x60006000
		shift_in[0] = 0x60006000;					//Instruction 1
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		/* 
		 * After the ARM7TDMI core has entered debug state from breakpt/watchpt,
		 * the first time the 33rd bit is captured and scanned out, its value 
		 * tells the debugger if the core entered debug state due to a breakpoint
		 * (bit 33 clear) or a watchpoint (bit 33 set).
		 */
		if(shift_out[1] & 0x1)
			arm7tdmi_status.by = ARM7TDMI_BY_WATCHPT;
		else
			arm7tdmi_status.by = ARM7TDMI_BY_BREAKPT;

		//NOP 
		shift_in[0] = 0x1C001C00;					//Instruction 2
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;					//Instruction 3
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//R0
		shift_in[0] = 0x1C001C00;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);
		r0 = shift_out[0];

		//Step 2 - Move PC to R0

		//MOV R0, PC = 0x46784678
		shift_in[0] = 0x46784678;					//Instruction 4			
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//Step 3 - Read the value of PC from R0

		//STR R0, [R0] = 0x60006000
		shift_in[0] = 0x60006000;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);
		*pc = shift_out[0];

		/*
		 * Entry into DEBUG state from a breakpoint/watchpoint advances the 
		 * PC by four addresses. Each instruction executed in DEBUG state 
		 * advances the PC by one address. 
		 *
		 * To move the value of PC to R0, 4 instructions have been executed in D
		 * EBUG state. So,  the value of PC which indicates the next instruction
		 * should be executed on exit from DEBUG state is
		 *			pc - 2 x (4 + 4)
		 */	
		*pc -= 16;

		//Step4 - Switch from THUMB state to ARM state

		/*
		 * When enter DEBUG state, we make ARM7TDMI enter ARM state before any
		 * further debug is performed. When leave from DEBUG state, we make
		 * ARM7TDMI return to THUMB state before the normal operation is resumed.
		 */

		//BX PC = 0x47784778
		shift_in[0] = 0x47784778;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);
	}

	//LastStep - Restore R0
	arm7tdmi_core_wri_reg(ARM7TDMI_R0, r0);

	return XJ_OK;
}


/*
 * arm7tdmi_exit_dbgstat() - 
 *		This route is used to exit from the DEBUG state and return to the
 *		normal SYSTEM state. The input pc indicates the next instruction
 *		to be exectued on exit from DEBUG state. After some operations in
 *		the DEBUG state, this route can be used to exit from the DEBUG state
 *		and resume the execution of program under debug.
 *
 *		Please modify this function carefully.
 *
 *		@pc:	the value of pc which indicates the next instruction to
 *				be executed on exit from DEBUG state.
 */
int arm7tdmi_exit_dbgstat(u32 pc)
{
	int status;
	u32 r0;
	u32 shift_in[2];
	u32 shift_out[2];

	//In SYSTEM state?
	if(arm7tdmi_status.state == ARM7TDMI_SYSTEM_STATE)
		return XJ_OK;
	
	//Clear the DEBUGRQ flag in DBGCTRL register 
	status = arm7tdmi_connect_scanchain(2);
	if(status != XJ_OK)
		return status;

	status = arm7tdmi_ice_write(ARM7TDMI_ICE_DBGCTRL, 0x0);
	if(status != XJ_OK)
		return status;

	//Select scan chain 1
	status = arm7tdmi_connect_scanchain(1);
	if(status != XJ_OK)
		return status;

	if(arm7tdmi_status.from == ARM7TDMI_FROM_ARM){	//Enter DEBUG from ARM state

		//Step 1 - Read R0 & Write the new value of PC to R0

		pc &= 0xFFFFFFFC;	//Align
		status = arm7tdmi_core_rd_reg(ARM7TDMI_R0, &r0);
		status = arm7tdmi_core_wri_reg(ARM7TDMI_R0, pc);

		//Step 2 - Move R0 to PC

		//MOV PC, R0 = 0xE1A0F000					
		shift_in[0] = 0xE1A0F000;				
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					//Instruct 1
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					//Instruct 2
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//Step 3 - Restore R0

		//MOV R0, #0 = 0xE3A00000
		shift_in[0] = 0xE3A00000;					//Instruct 3
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					//Instruct 4
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					//Instruct 5
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//LDR R0, [R0] = 0xE5900000
		shift_in[0] = 0xE5900000;					//Instruct 6
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					//Instruct 7
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					//Instruct 8
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//R0 - put the value of R0 to the data bus
		shift_in[0] = r0;
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//Write the value obtained from data bus to R0
		shift_in[0] = ARM7TDMI_NOP;
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//Step 4 - Set SYSTEM speed flag

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					//Instruct 9	
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP + SYSTEM SPEED
		shift_in[0] = ARM7TDMI_NOP;					//Instruct 10		
		shift_in[1] = ARM7TDMI_SYSTEM_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		/*
		 * After move the new value to register PC, 10 instructions have been
		 * executed so far. To exit from DEBUG state and resume the normal 
		 * operation of the program under debug, 10 instructions backwards.
		 */

		//B -10 = 0xEAFFFFF6
		shift_in[0] = 0xEAFFFFF6;					//Final branch
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

	}else{	//Enter DEBUG from THUMB state

		//Step 1 - Read R0 & Write the new value of PC to R0

		pc &= 0xFFFFFFFE;	//Align
		status = arm7tdmi_core_rd_reg(ARM7TDMI_R0, &r0);
		status = arm7tdmi_core_wri_reg(ARM7TDMI_R0, pc + 1);

		//Step 2 - Switch from ARM state back to THUMB state first

		//BX R0 = 0xE12FFF10
		shift_in[0] = 0xE12FFF10;
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP
		shift_in[0] = ARM7TDMI_NOP;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//Step 3 - Sbbtract R0 by 1
		
		//SUB R0, #1 = 0x38013801
		shift_in[0] = 0x38013801;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//Step 4 - Move R0 to PC
		
		//MOV PC, R0 = 0x46874687
		shift_in[0] = 0x46874687;					
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;						//Instruct 1
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

		//NOP 
		shift_in[0] = 0x1C001C00;						//Instruct 2
		shift_in[1] = ARM7TDMI_DEBUG_SPEED;
		arm7tdmi_acs_sc1(shift_in, shift_out);

⌨️ 快捷键说明

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