JTAG的工作原理及相关的代码
什么是JTAG
JTAG是如何工作的?
通过你的PC控制JTAG
并口
#define lpt_addr 0x378 #define TCK 0x01 void toggle_TCK() { outport(lpt_addr, 0); outport(lpt_addr, TCK); outport(lpt_addr, 0); }
通过JTAG TAP控制器
// first sync everybody to the test-logic-reset state for(i=0; i<5; i++) JTAG_clock(TMS); // now that everybody is in a known and identical state, we can move together to another state // let's go to Shift-IR JTAG_clock(0); JTAG_clock(TMS); JTAG_clock(TMS); JTAG_clock(0); JTAG_clock(0);
// Because the bits are shifted through in a chain, we must start sending the data for the device that is at the end of the chain // so we send the 10 FPGA IR bits first JTAG_clock(0); JTAG_clock(1); JTAG_clock(0); JTAG_clock(0); JTAG_clock(0); JTAG_clock(0); JTAG_clock(0); JTAG_clock(0); JTAG_clock(0); JTAG_clock(0); // then send the 5 CPU IR bits JTAG_clock(0); JTAG_clock(0); JTAG_clock(1); JTAG_clock(0); JTAG_clock(0 | TMS); // last bit needs to have TMS active (to exit shift-IR)
查询JTAG链
统计JTAG链条上的设备数量
// go to reset state for(i=0; i<5; i++) JTAG_clock(TMS); // go to Shift-IR JTAG_clock(0); JTAG_clock(TMS); JTAG_clock(TMS); JTAG_clock(0); JTAG_clock(0); // Send plenty of ones into the IR registers // That makes sure all devices are in BYPASS! for(i=0; i<999; i++) JTAG_clock(1); JTAG_clock(1 | TMS); // last bit needs to have TMS active, to exit shift-IR // we are in Exit1-IR, go to Shift-DR JTAG_clock(TMS); JTAG_clock(TMS); JTAG_clock(0); JTAG_clock(0); // Send plenty of zeros into the DR registers to flush them for(i=0; i<1000; i++) JTAG_clock(0); // now send ones until we receive one back for(i=0; i<1000; i++) if(JTAG_clock(1)) break; nbDevices = i; printf("There are %d device(s) in the JTAG chain\n", nbDevices);
获取JTAG链条上的设备的ID
// go to reset state (that loads IDCODE into IR of all the devices) for(i=0; i<5; i++) JTAG_clock(TMS); // go to Shift-DR JTAG_clock(0); JTAG_clock(TMS); JTAG_clock(0); JTAG_clock(0); // and read the IDCODES for(i=0; i < nbDevices; i++) { printf("IDCODE for device %d is %08X\n", i+1, JTAG_read(32)); }
执行边界扫描
attribute INSTRUCTION_LENGTH of EP1C3T100 : entity is 10; attribute INSTRUCTION_OPCODE of EP1C3T100 : entity is "BYPASS (1111111111), "& "EXTEST (0000000000), "& "SAMPLE (0000000101), "& "IDCODE (0000000110), "& "USERCODE (0000000111), "& "CLAMP (0000001010), "& "HIGHZ (0000001011), "& "CONFIG_IO (0000001101)"; attribute INSTRUCTION_CAPTURE of EP1C3T100 : entity is "0101010101"; attribute IDCODE_REGISTER of EP1C3T100 : entity is "0000"& --4-bit Version "0010000010000001"& --16-bit Part Number (hex 2081) "00001101110"& --11-bit Manufacturer's Identity "1"; --Mandatory LSB attribute BOUNDARY_LENGTH of EP1C3T100 : entity is 339;
attribute BOUNDARY_REGISTER of EP1C3T100 : entity is --BSC group 0 for I/O pin 100 "0 (BC_1, IO100, input, X)," & "1 (BC_1, *, control, 1)," & "2 (BC_1, IO100, output3, X, 1, 1, Z)," & --BSC group 1 for I/O pin 99 "3 (BC_1, IO99, input, X)," & "4 (BC_1, *, control, 1)," & "5 (BC_1, IO99, output3, X, 4, 1, Z)," & ... ... ... --BSC group 112 for I/O pin 1 "336 (BC_1, IO1, input, X)," & "337 (BC_1, *, control, 1)," & "338 (BC_1, IO1, output3, X, 337, 1, Z)" ;
<ode verilog>
// go to reset state for(i=0; i<5; i++) JTAG_clock(TMS);
// go to Shift-IR JTAG_clock(0); JTAG_clock(TMS); JTAG_clock(TMS); JTAG_clock(0); JTAG_clock(0);
// Assuming that IR is 10 bits long, // that there is only one device in the chain, // and that SAMPLE code = 0000000101b JTAG_clock(1); JTAG_clock(0); JTAG_clock(1); JTAG_clock(0); JTAG_clock(0); JTAG_clock(0); JTAG_clock(0); JTAG_clock(0); JTAG_clock(0); JTAG_clock(0 or TMS); // last bit needs to have TMS active, to exit shift-IR
// we are in Exit1-IR, go to Shift-DR JTAG_clock(TMS); JTAG_clock(TMS); JTAG_clock(0); JTAG_clock(0);
// read the boundary-scan chain bits in an array called BSB JTAG_read(BSB, 339); printf("Status of pin 99 = %d\n, BSB[3]);
</code>