### 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)" ; // 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]);