2013년 8월 10일 토요일

[번역] Arduino를 Arm 개발 보드를 위한 Jtag 프로그래머로 사용하기

아쉽게도 Jtag 장비가 없지만, Arduino 보드와 Netduino 보드는 가지고 있다.

Netduino 가 제공하는 개발 환경도 좋지만, 지금은 펌웨어를 직접 개발해야 하는 상황인지라,

기존에 있던 펌웨어를 지우고 새로운 펌웨어를 Flash 메모리에 써어 넣어야 한다.

그래서 Arduino 보드를 Jtag 프로그래머로 사용하면 가능할 것 같아 찾아 보았다.

하지만, 세 가지의 문제점이 있다고 이야기 되고 있다.

첫째는 Arduino 보드의 I/O 전압과 Arm 보드의 Jtag 핀의 전압 차이이다.

이 문제는 간단히 전압 강하용 저항을 삽입하거나 Level Converter용 IC를 사용하는  있다.

구체적으로 이야기 하자면 대부분의 Arduino 보드는 5V TTL 호환 I/O를 구성되어 있고

Arm 보드의 핀은 3.3V, 혹은 1.8V에서 동작한다.

언듯 생각해 보아도 5V에서 3.3V혹은 1.8V로의 전압 하강은

간단히 저항으로 해결될 수 있는 부분이지만,

3.3V 혹은 1.8V의 전압을 5V로 전압 상승하는 부분은 저항으로 해결 될 수 없다.

이 부분에 대한 해결책으로 아무래도 양방향성 전압 변환기를 사용하는 것 밖에 없는 것 같다.

고속의 신호를 스위칭 할 수 있는 MOSFET을 이용하거나

NC7SZ384 - http://www.fairchildsemi.com/pf/NC/NC7SZ384.html

I2C 신호선의 Level 변환에 사용되는 IC등을 사용하는 것이다.

LTC4300A-2 http://www.linear.com/pc/productDetail.jsp?navId=H0,C1,C1007,C1070,P2296

PCA9306  http://focus.ti.com/docs/prod/folders/print/pca9306.html

둘째는 전송 속도에 관한 문제이다.

Arduino 보드는 PC와 시리얼로 연결된다.

그래서 아마도 115200bps이상의 속도는 나오지 못할 것이다.

결과적으로 Arduino 보드를 이용하면 디버깅은 조금 느릴 것이다.

하지만, 업로드와 플레시 메모리 쓰기 정도에는 적절할 것이다.

셋째는 구현 소프트 웨어 이다.

대부분의 Jtag 동글은 USB 전송 위에 SPI 인터페이스 형태로 구현된다.

그 이외의 나머지 부분은 PC상의 소프트웨어에서 구현된다.

대표적인 것들이 OpenOCD와 URJTag등이다.

위와 같은 사항을 염두해 둔다면

문제가 되는 것은 Arduino 보드의 펌웨어를 작성하는 것이다.

이것도 이미 구현되어 있다.




https://github.com/zoobab/tjtag-arduino

위의 링크에 가면 Arduino를 위한 소프트웨어와 PC에서 사용할 수 있는

소프트웨어를 다운로드 받을 수 있다.

하지만, 실제로 프로그램을 실행한 결과 모든 Arm 플렛폼과 메모리를 지원하는 것은 아닌것 같다.

지원하는 플렛폼은

    { 0x0471017F, 5, "Broadcom BCM4702 Rev 1 CPU" },
    { 0x9470417F, 8, "Broadcom BCM4704 KPBG Rev 9 CPU"},      // Tornado  WRT150N
    { 0x0470417F, 8, "Broadcom BCM4704 Rev 8 CPU" },          // BCM4704 chip (used in the WRTSL54GS units)
    { 0x1471217F, 8, "Broadcom BCM4712 Rev 1 CPU" },
    { 0x2471217F, 8, "Broadcom BCM4712 Rev 2 CPU" },
    { 0x1471617F, 8, "Broadcom BCM4716 Rev 1 CPU" },          // Eko BCM4718A1KFBG
    { 0x0478517F, 8, "Broadcom BCM4785 Rev 1 CPU" },          // Tornado WRT350N
    { 0x0535017F, 8, "Broadcom BCM5350 Rev 1 CPU" },
    { 0x0535217F, 8, "Broadcom BCM5352 Rev 1 CPU" },
    { 0x1535417F, 8, "Broadcom BCM5354 KFBG Rev 1 CPU" },     // Tornado - WRT54G GV8/GSV7
    { 0x2535417F, 8, "Broadcom BCM5354 KFBG Rev 2 CPU" },     // Tornado - Gv8/GSv7
    { 0x3535417F, 8, "Broadcom BCM5354 KFBG Rev 3 CPU" },     // Tornado - WRG54G2
    { 0x0334517F, 5, "Broadcom BCM3345 KPB Rev 1 CPU" },      // Eko QAMLink  BCM3345 KPB SB4200
    { 0x0536517F, 8, "Broadcom BCM5365 Rev 1 CPU" },          // BCM5365 Not Completely Verified Yet
    { 0x1536517F, 8, "Broadcom BCM5365 Rev 1 CPU" },          // Eko....ASUS WL 500 G Deluxe
    { 0x0634517F, 5, "Broadcom BCM6345 Rev 1 CPU" },          // BCM6345 Not Completely Verified Yet
    { 0x0634817F, 5, "Broadcom BCM6348 Rev 1 CPU" },
    { 0x0633817F, 5, "Broadcom BCM6338 Rev 1 CPU" },  // Speedtouch
    { 0x0635817F, 5, "Broadcom BCM6358 Rev 1 CPU" },          // brjtag Fully Tested
    { 0x0636817F, 5, "Broadcom BCM6368 Rev 1 CPU" },          // brjtag
    { 0x1432117F, 5, "Broadcom BCM4321 RADIO STOP" },         // Radio JP3 on a WRT300N V1.1
    { 0x3432117F, 5, "Broadcom BCM4321L RADIO STOP"},         // EKO Radio on WRT300n
    { 0x0000100F, 5, "TI AR7WRD TNETD7300GDU Rev 1 CPU" },    // TI AR7WRD Only Partially Verified
    { 0x102002E1, 5, "BRECIS MSP2007-CA-A1 CPU" },            // BRECIS chip - Not Completely Verified Yet
    { 0x0B52D02F, 5, "TI TNETV1060GDW CPU" },                 // Fox WRTP54G
    { 0x00217067, 5, "Linkstation 2 with RISC K4C chip" },    // Not verified
    { 0x00000001, 5, "Atheros AR531X/231X CPU" },             // WHR-HP-AG108
    { 0x19277013, 7, "XScale IXP42X 266mhz" },                // GW2348-2 Eko Gateworks Avila GW234X (IXP42X 266MHz) BE
    { 0x19275013, 7, "XScale IXP42X 400mhz" },
    { 0x19274013, 7, "XScale IXP42X 533mhz" },
    { 0x10940027, 4, "ARM 940T"}, // Eko  Linksys BEFSX41
    { 0x07926041, 4, "Marvell Feroceon 88F5181" },
    { 0x1438000D, 5, "LX4380"},

이다. 대부분이 Broadcom의 씨피유이다.

지원하는 메모리는 다음과 같다.

  /* AMD, Spansion */
    { 0x00C2, 0x22DA, size1MB, CMD_TYPE_AMD, "MX29LV800BTC 512kx16 TopB  (1MB)"   ,15,size32K,    1,size16K,    2,size4K,   1,size8K  },
    { 0x00C2, 0x225B, size1MB, CMD_TYPE_AMD, "MX29LV800BTC 512kx16 BotB  (1MB)"   ,1,size8K,      2,size4K,     1,size16K,  15,size32K },

    { 0x0001, 0x2249, size2MB, CMD_TYPE_AMD, "AMD 29lv160DB 1Mx16 BotB   (2MB)"   ,1,size16K,    2,size8K,     1,size32K,  31,size64K }, /* bypass */
    { 0x0001, 0x22c4, size2MB, CMD_TYPE_AMD, "AMD 29lv160DT 1Mx16 TopB   (2MB)"   ,31,size64K,   1,size32K,    2,size8K,   1,size16K  },
    { 0x007F, 0x2249, size2MB, CMD_TYPE_AMD, "EON EN29LV160A 1Mx16 BotB  (2MB)"   ,1,size16K,    2,size8K,     1,size32K,  31,size64K }, /* bypass */
    { 0x007F, 0x22C4, size2MB, CMD_TYPE_AMD, "EON EN29LV160A 1Mx16 TopB  (2MB)"   ,31,size64K,   1,size32K,    2,size8K,   1,size16K  },
    { 0x0004, 0x2249, size2MB, CMD_TYPE_AMD, "MBM29LV160B 1Mx16 BotB     (2MB)"   ,1,size16K,    2,size8K,     1,size32K,  31,size64K },
    { 0x0004, 0x22c4, size2MB, CMD_TYPE_AMD, "MBM29LV160T 1Mx16 TopB     (2MB)"   ,31,size64K,   1,size32K,    2,size8K,   1,size16K  },
    { 0x00C2, 0x2249, size2MB, CMD_TYPE_AMD, "MX29LV160CB 1Mx16 BotB     (2MB)"   ,1,size16K,    2,size8K,     1,size32K,  31,size64K },
    { 0x00C2, 0x22c4, size2MB, CMD_TYPE_AMD, "MX29LV160CT 1Mx16 TopB     (2MB)"   ,31,size64K,   1,size32K,    2,size8K,   1,size16K  },
    { 0x00EC, 0x2275, size2MB, CMD_TYPE_AMD, "K8D1716UTC  1Mx16 TopB     (2MB)"   ,31,size64K,    8,size8K,     0,0,        0,0        },
    { 0x00EC, 0x2277, size2MB, CMD_TYPE_AMD, "K8D1716UBC  1Mx16 BotB     (2MB)"   ,8,size8K,      31,size64K,   0,0,        0,0        }, /* bypass */
    { 0x0020, 0x2249, size2MB, CMD_TYPE_AMD, "ST M29W160EB 1Mx16 BotB    (2MB)"   ,1,size16K,    2,size8K,     1,size32K,  31,size64K },
    { 0x0020, 0x22c4, size2MB, CMD_TYPE_AMD, "ST M29W160ET 1Mx16 TopB    (2MB)"   ,31,size64K,   1,size32K,    2,size8K,   1,size16K  },
    { 0x00C2, 0x0014, size2MB, CMD_TYPE_SPI, "Macronix MX25L160A         (2MB) Serial"   ,32,size64K,   0,0,          0,0,        0,0        }, /* new */
    { 0x001f, 0x2600, size2MB, CMD_TYPE_SPI, "Atmel AT45DB161B           (2MB) Serial"   ,512,sizeA4K,   0,0,          0,0,        0,0        }, /* new */
    { 0x0040, 0x0000, size2MB, CMD_TYPE_SPI, "Atmel AT45DB161B           (2MB) Serial"   ,512,sizeA4K,   0,0,          0,0,        0,0        }, /* new */

    { 0x00EC, 0x22A0, size4MB, CMD_TYPE_AMD, "K8D3216UTC  2Mx16 TopB     (4MB)"   ,63,size64K,    8,size8K,     0,0,        0,0        },
    { 0x00EC, 0x22A2, size4MB, CMD_TYPE_AMD, "K8D3216UBC  2Mx16 BotB     (4MB)"   ,8,size8K,      63,size64K,   0,0,        0,0        },

    { 0x00C2, 0x2015, size2MB, CMD_TYPE_SPI, "Macronix MX25L1605D        (2MB) Serial"   ,32,size64K,    0,0,          0,0,        0,0 }, /* new */
    { 0x00C2, 0x2016, size4MB, CMD_TYPE_SPI, "Macronix MX25L3205D        (4MB) Serial"   ,64,size64K,    0,0,          0,0,        0,0 }, /* new */
    { 0x00C2, 0x2017, size8MB, CMD_TYPE_SPI, "Macronix MX25L6405D        (8MB) Serial"   ,128,size64K,   0,0,          0,0,        0,0 }, /* new */


    { 0x0020, 0x2015, size2MB, CMD_TYPE_SPI, "STMicro M25P16             (2MB) Serial"   ,32,size64K,   0,0, 0,0, 0,0 }, /* new */
    { 0x0020, 0x2016, size4MB, CMD_TYPE_SPI, "STMicro M25P32             (4MB) Serial"   ,64,size64K,   0,0, 0,0, 0,0 }, /* new */
    { 0x0020, 0x2017, size8MB, CMD_TYPE_SPI, "STMicro M25P64             (8MB) Serial"   ,128,size64K,  0,0, 0,0, 0,0 }, /* new */
    { 0x0020, 0x2018, size16MB, CMD_TYPE_SPI, "STMicro M25P128           (16MB) Serial"  ,32,size256K,  0,0, 0,0, 0,0 }, /* new */


    { 0x0001, 0x2200, size4MB, CMD_TYPE_AMD, "AMD 29lv320MB 2Mx16 BotB   (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },
    { 0x0001, 0x227E, size4MB, CMD_TYPE_AMD, "AMD 29lv320MT 2Mx16 TopB   (4MB)"   ,63,size64K,   8,size8K,     0,0,        0,0        },
    { 0x0001, 0x2201, size4MB, CMD_TYPE_AMD, "AMD 29lv320MT 2Mx16 TopB   (4MB)"   ,63,size64K,   8,size8K,     0,0,        0,0        },
    { 0x0098, 0x009C, size4MB, CMD_TYPE_AMD, "TC58FVB321 2Mx16 BotB      (4MB)"   ,1,size16K,    2,size8K,     1,size32K,  63,size64K },
    { 0x0098, 0x009A, size4MB, CMD_TYPE_AMD, "TC58FVT321 2Mx16 TopB      (4MB)"   ,63,size64K,   1,size32K,    2,size8K,   1,size16K  },
    { 0x001F, 0x00C0, size4MB, CMD_TYPE_AMD, "AT49BV/LV16X 2Mx16 BotB    (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },
    { 0x001F, 0x00C2, size4MB, CMD_TYPE_AMD, "AT49BV/LV16XT 2Mx16 TopB   (4MB)"   ,63,size64K,   8,size8K,     0,0,        0,0        },
    { 0x0004, 0x2253, size4MB, CMD_TYPE_AMD, "MBM29DL323BE 2Mx16 BotB    (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },
    { 0x0004, 0x2250, size4MB, CMD_TYPE_AMD, "MBM29DL323TE 2Mx16 TopB    (4MB)"   ,63,size64K,   8,size8K,     0,0,        0,0        },
    { 0x0001, 0x22f9, size4MB, CMD_TYPE_AMD, "AMD 29lv320DB 2Mx16 BotB   (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },
    { 0x0001, 0x22f6, size4MB, CMD_TYPE_AMD, "AMD 29lv320DT 2Mx16 TopB   (4MB)"   ,63,size64K,   8,size8K,     0,0,        0,0        },
    { 0x0004, 0x22F9, size4MB, CMD_TYPE_AMD, "MBM29LV320BE 2Mx16 BotB    (4MB)"   ,1,size16K,    2,size8K,     1,size32K,  63,size64K },
    { 0x0004, 0x22F6, size4MB, CMD_TYPE_AMD, "MBM29LV320TE 2Mx16 TopB    (4MB)"   ,63,size64K,   1,size32K,    2,size8K,   1,size16K  },
    { 0x00C2, 0x22A8, size4MB, CMD_TYPE_AMD, "MX29LV320B 2Mx16 BotB      (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },
    { 0x00C2, 0x00A8, size4MB, CMD_TYPE_AMD, "MX29LV320B 2Mx16 BotB      (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },
    { 0x00C2, 0x00A7, size4MB, CMD_TYPE_AMD, "MX29LV320T 2Mx16 TopB      (4MB)"   ,63,size64K,   8,size8K,     0,0,        0,0        },
    { 0x00C2, 0x22A7, size4MB, CMD_TYPE_AMD, "MX29LV320T 2Mx16 TopB      (4MB)"   ,63,size64K,   8,size8K,     0,0,        0,0        },
    { 0x0020, 0x22CB, size4MB, CMD_TYPE_AMD, "ST 29w320DB 2Mx16 BotB     (4MB)"   ,1,size16K,    2,size8K,     1,size32K,  63,size64K },
    { 0x0020, 0x22CA, size4MB, CMD_TYPE_AMD, "ST 29w320DT 2Mx16 TopB     (4MB)"   ,63,size64K,   1,size32K,    2,size8K,   1,size16K  },

    { 0x00C2, 0x22C9, size16MB, CMD_TYPE_AMD, "MX29LV640B 4Mx16 TopB     (16MB)"  ,127,size64K,  8,size8K,      0,0,        0,0        },
    { 0x00C2, 0x22CB, size16MB, CMD_TYPE_AMD, "MX29LV640B 4Mx16 BotB     (16MB)"  ,8,size8K,     127,size64K,   0,0,        0,0        },


    { 0x00DA, 0x22BA, size4MB, CMD_TYPE_AMD, "W19B(L)320ST   2Mx16 TopB  (4MB)"   ,63,size64K,   8,size8K,     0,0,        0,0        }, /* new */
    { 0x00DA, 0x222A, size4MB, CMD_TYPE_AMD, "W19B(L)320SB   2Mx16 BotB  (4MB)"   ,8,size8K,   63,size64K,     0,0,        0,0        }, /* new */
    { 0x22DA, 0x222A, size4MB, CMD_TYPE_AMD, "W19B(L)320SB   2Mx16 BotB  (4MB)"   ,8,size8K,   63,size64K,     0,0,        0,0        },

    { 0x0020, 0x225C, size4MB, CMD_TYPE_AMD, "M29DW324DT 2Mx16 TopB      (4MB)"   ,63,size64K,   8,size8K,     0,0,        0,0        }, /* new */
    { 0x0020, 0x225D, size4MB, CMD_TYPE_AMD, "M29DW324DB 2Mx16 BotB      (4MB)"   ,8,size8K,   63,size64K,     0,0,        0,0        }, /* new */

    { 0x0098, 0x0057, size8MB, CMD_TYPE_AMD, "TC58FVM6T2A  4Mx16 TopB    (8MB)"   ,127,size64K,   8,size8K,     0,0,        0,0       }, /* new */
    { 0x0098, 0x0058, size8MB, CMD_TYPE_AMD, "TC58FVM6B2A  4Mx16 BopB    (8MB)"   ,8,size8K,   127,size64K,     0,0,        0,0       }, /* new */

    { 0x00EC, 0x22E0, size8MB, CMD_TYPE_AMD, "K8D6316UTM  4Mx16 TopB     (8MB)"   ,127,size64K,    8,size8K,     0,0,        0,0        }, /* new */
    { 0x00EC, 0x22E2, size8MB, CMD_TYPE_AMD, "K8D6316UBM  4Mx16 BotB     (8MB)"   ,8,size8K,      127,size64K,   0,0,        0,0        }, /* new */

    /* BSC */
    { 0x0089, 0x8891, size2MB, CMD_TYPE_BSC, "Intel 28F160B3 1Mx16 BotB  (2MB)"   ,8,size8K,     31,size64K,   0,0,        0,0        },
    { 0x0089, 0x8890, size2MB, CMD_TYPE_BSC, "Intel 28F160B3 1Mx16 TopB  (2MB)"   ,31,size64K,   8,size8K,     0,0,        0,0        },
    { 0x0089, 0x88C3, size2MB, CMD_TYPE_BSC, "Intel 28F160C3 1Mx16 BotB  (2MB)"   ,8,size8K,     31,size64K,   0,0,        0,0        },
    { 0x0089, 0x88C2, size2MB, CMD_TYPE_BSC, "Intel 28F160C3 1Mx16 TopB  (2MB)"   ,31,size64K,   8,size8K,     0,0,        0,0        },

    { 0x0089, 0x8897, size4MB, CMD_TYPE_BSC, "Intel 28F320B3 2Mx16 BotB  (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },
    { 0x0089, 0x8896, size4MB, CMD_TYPE_BSC, "Intel 28F320B3 2Mx16 TopB  (4MB)"   ,63,size64K,   8,size8K,     0,0,        0,0        },
    { 0x0089, 0x88C5, size4MB, CMD_TYPE_BSC, "Intel 28F320C3 2Mx16 BotB  (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },
    { 0x0089, 0x88C4, size4MB, CMD_TYPE_BSC, "Intel 28F320C3 2Mx16 TopB  (4MB)"   ,63,size64K,   8,size8K,     0,0,        0,0        },
    { 0x00b0, 0x00e3, size4MB, CMD_TYPE_BSC, "Sharp 28F320BJE 2Mx16 BotB (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },

    { 0x0089, 0x8899, size8MB, CMD_TYPE_BSC, "Intel 28F640B3 4Mx16 BotB  (8MB)"   ,8,size8K,     127,size64K,  0,0,        0,0        },
    { 0x0089, 0x8898, size8MB, CMD_TYPE_BSC, "Intel 28F640B3 4Mx16 TopB  (8MB)"   ,127,size64K,  8,size8K,     0,0,        0,0        },
    { 0x0089, 0x88CD, size8MB, CMD_TYPE_BSC, "Intel 28F640C3 4Mx16 BotB  (8MB)"   ,8,size8K,     127,size64K,  0,0,        0,0        },
    { 0x0089, 0x88CC, size8MB, CMD_TYPE_BSC, "Intel 28F640C3 4Mx16 TopB  (8MB)"   ,127,size64K,  8,size8K,     0,0,        0,0        },

    /* SCS */
    { 0x00b0, 0x00d0, size2MB, CMD_TYPE_SCS, "Intel 28F160S3/5 1Mx16     (2MB)"   ,32,size64K,   0,0,          0,0,        0,0        },

    { 0x0089, 0x0016, size4MB, CMD_TYPE_SCS, "Intel 28F320J3 2Mx16       (4MB)"   ,32,size128K,  0,0,          0,0,        0,0        },
    { 0x0089, 0x0014, size4MB, CMD_TYPE_SCS, "Intel 28F320J5 2Mx16       (4MB)"   ,32,size128K,  0,0,          0,0,        0,0        },
    { 0x00b0, 0x00d4, size4MB, CMD_TYPE_SCS, "Intel 28F320S3/5 2Mx16     (4MB)"   ,64,size64K,   0,0,          0,0,        0,0        },

    { 0x0089, 0x0017, size8MB, CMD_TYPE_SCS, "Intel 28F640J3 4Mx16       (8MB)"   ,64,size128K,  0,0,          0,0,        0,0        },
    { 0x0089, 0x0015, size8MB, CMD_TYPE_SCS, "Intel 28F640J5 4Mx16       (8MB)"   ,64,size128K,  0,0,          0,0,        0,0        },

    { 0x0089, 0x0018, size16MB, CMD_TYPE_SCS, "Intel 28F128J3 8Mx16      (16MB)"  ,128,size128K, 0,0,          0,0,        0,0        },

    /* SST */

    { 0x00BF, 0x234B, size2MB, CMD_TYPE_SST, "SST39VF1601 1Mx16 BotB     (2MB)"   ,8,size8K,    31,size64K,          0,0,        0,0        },
    { 0x00BF, 0x234A, size2MB, CMD_TYPE_SST, "SST39VF1602 1Mx16 TopB     (2MB)"   ,31,size64K,    8,size8K,          0,0,        0,0        },

    { 0x00BF, 0x235B, size4MB, CMD_TYPE_SST, "SST39VF3201 2Mx16 BotB     (4MB)"   ,8,size8K,   63,size64K,          0,0,        0,0        },
    { 0x00BF, 0x235A, size4MB, CMD_TYPE_SST, "SST39VF3202 2Mx16 TopB     (4MB)"   ,63,size64K,   8,size8K,          0,0,        0,0        },

    { 0x00BF, 0x236B, size8MB, CMD_TYPE_SST, "SST39VF6401 4Mx16 BotB     (8MB)"   ,8,size8K,   127,size64K,          0,0,        0,0        },
    { 0x00BF, 0x236A, size8MB, CMD_TYPE_SST, "SST39VF6402 4Mx16 TopB     (8MB)"   ,127,size64K,   8,size8K,          0,0,        0,0        },
    { 0x00BF, 0x236D, size8MB, CMD_TYPE_SST, "SST39VF6401B 4Mx16 BotB    (8MB)"   ,8,size8K,   127,size64K,          0,0,        0,0        },
    { 0x00BF, 0x236C, size8MB, CMD_TYPE_SST, "SST39VF6402B 4Mx16 TopB    (8MB)"   ,127,size64K,   8,size8K,          0,0,        0,0        },

//  See Spansion hack details for reasoning for the unusual vendid
    { 0x017E, 0x1A00, size4MB, CMD_TYPE_AMD, "Spansion S29GL032M BotB    (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },
    { 0x017E, 0x1A01, size4MB, CMD_TYPE_AMD, "Spansion S29GL032M TopB    (4MB)"   ,63,size64K,     8,size8K,   0,0,        0,0        },
    { 0x017E, 0x1000, size8MB, CMD_TYPE_AMD, "Spansion S29GL064M BotB    (8MB)"   ,8,size8K,     127,size64K,   0,0,        0,0        },
    { 0x017E, 0x1001, size8MB, CMD_TYPE_AMD, "Spansion S29GL064M TopB    (8MB)"   ,127,size64K,     8,size8K,   0,0,        0,0        },

    { 0x017E, 0x2101, size16MB, CMD_TYPE_AMD, "Spansion S29GL128P U      (16MB)"   ,128,size128K,     0,0,   0,0,        0,0        },
    { 0x017E, 0x1200, size16MB, CMD_TYPE_AMD, "Spansion S29GL128M U      (16MB)"   ,128,size128K,   0,0,      0,0,        0,0         },
    { 0x017E, 0x2201, size32MB, CMD_TYPE_AMD, "Spansion S29GL256P U      (32MB)"   ,256,size128K,     0,0,   0,0,        0,0        },
    { 0x017E, 0x2301, size64MB, CMD_TYPE_AMD, "Spansion S29GL512P U      (64MB)"   ,512,size128K,     0,0,   0,0,        0,0        },
    { 0x017E, 0x2801, size128MB, CMD_TYPE_AMD, "Spansion S29GL01GP U     (128MB)"   ,1024,size128K,     0,0,   0,0,        0,0        },

    { 0x0001, 0x0214, size2MB, CMD_TYPE_SPI, "Spansion S25FL016A         (2MB) Serial"   ,32,size64K,   0,0,          0,0,        0,0        }, /* new */
    { 0x0001, 0x0215, size4MB, CMD_TYPE_SPI, "Spansion S25FL032A         (4MB) Serial"   ,64,size64K,   0,0,          0,0,        0,0        }, /* new */
    { 0x0001, 0x0216, size8MB, CMD_TYPE_SPI, "Spansion S25FL064A         (8MB) Serial"   ,128,size64K,  0,0,          0,0,        0,0        }, /* new */


// Winbond 3-stage ID chips
    { 0xDA7E, 0x0A00, size4MB, CMD_TYPE_AMD, "Winbond W19B320AB BotB     (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },
    { 0xDA7E, 0x0A01, size4MB, CMD_TYPE_AMD, "Winbond W19B320AT TopB     (4MB)"   ,63,size64K,     8,size8K,   0,0,        0,0        },
    { 0x00EF, 0x3016, size4MB, CMD_TYPE_SPI, "Winbond W25X32             (4MB) Serial"   ,64,size64K,   0,0,          0,0,        0,0        }, /* new */
    { 0x00EF, 0x3017, size8MB, CMD_TYPE_SPI, "Winbond W25X64             (8MB) Serial"   ,128,size64K,   0,0,          0,0,        0,0        }, /* new */
// EON
    { 0x007f, 0x22F9, size4MB, CMD_TYPE_AMD, "EON EN29LV320 2Mx16 BotB   (4MB)"   ,8,size8K,    63,size64K,     0,0,  0,0 }, /* wrt54gl v1.1 */
    { 0x007f, 0x22F6, size4MB, CMD_TYPE_AMD, "EON EN29LV320 2Mx16 TopB   (4MB)"   ,63,size64K,  8,size8K,    0,0,   0,0  }, /* bypass */
    { 0x007F, 0x22C9, size8MB, CMD_TYPE_AMD, "EON EN29LV640 4Mx16 TopB   (8MB)"   ,127,size64K, 8,size8K,   0,0,        0,0        }, /* bypass */
    { 0x007F, 0x22Cb, size8MB, CMD_TYPE_AMD, "EON EN29LV640 4Mx16 BotB   (8MB)"   ,8,size8K,    127,size64K,   0,0,        0,0        }, /* bypass */
// Atmel
    { 0x001F, 0x00C8, size4MB, CMD_TYPE_AMD, "AT49BV322A 2Mx16 BotB      (4MB)"   ,8,size8K,     63,size64K,   0,0,        0,0        },
    { 0x001F, 0x00C9, size4MB, CMD_TYPE_AMD, "AT49BV322A(T) 2Mx16 TopB   (4MB)"   ,63,size64K,     8,size8K,   0,0,        0,0        },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

결론적으로 내가 가지고 있는 Netduino Plus 2에는 사용할 수 없다.

뭐 소스코드를 수정하는 방법이 있겠지만, 너무 노력이 많이 들어 간다.

아쉽지만, Jtag 장비를 하나 사야 겠다.

출처 :

http://www.dd-wrt.com/phpBB2/viewtopic.php?p=435578&sid=0c7c7b114dc7239be2620514cecbe2d8

http://electronics.stackexchange.com/questions/9258/is-it-possible-to-make-a-jtag-interface-with-an-arduino

https://github.com/zoobab/tjtag-arduino

http://electronics.stackexchange.com/questions/708/i2c-3-3-to-5-0-v-conversion

2013년 8월 7일 수요일

통근을 위해 고려 중인 자전거

바람을 가르는 카본 자전거까지는 필요없는데

그져 경쾌한 운전이 가능하고 물받이가 달린 통근형 자전거를 알아 보고 있다.

그래서 요즘 살펴 보고 있는 두 개의 모델이 있다.

Surly의 Cross Check와 Masi의 Masi Speciale Commuter


출처 : http://gallery.roaringmousecycles.com/albums/customer-road/Matts_Surly_Cross_Check.jpg



Novara Verita Bike - 2013
$1299.00

출처 : http://www.rei.com/product/837485/novara-verita-bike-2013

문제는 가격이다.

그리고 문제는 구동계이다. 아무래도 평야에서 느긋하게 운행할 것이 아니기 때문에

최소한 최신 소라 변속기 정도는 사용해 주어야 할 것 같다.

1. 소라 변속기.

2. 물받이.

위의 두 가지는 추가적으로 구매해야 할 것 같다.

혹은 아니면 프레임만 구매해서 새로 조립하는 방법도 고려해 보아야 겠다.

현재 공구가 없지만 허브랑 카셋만 쪼이는 공구만 있으면 문제 없을 것 같다.

프레임을 고른다면 Surly사의 Long Haul Trucker의 프레임이 정답인 것 같다.

물받이를 설치하고도 각종 캐리어를 설치할 수 있는 나사 구멍을 제공한다.

그리고 다양한 두께의 타이어를 선택하여 설치할 수 있다.

무엇보다 지오메트리가  Cross Check보다 Long Haul Trucker가 멋있다.



좀더 찾아 본 결과 거의 같은 구성과 지오메트리를 갖는 약간 저렴한 프레임도 있다.




뭐 그래봐야 $30~$40달러 이니 Surly 딱지 값으로 괜찮다고 생각할 수 도 있다.


2013년 7월 15일 월요일

[번역] Micro USB otg 포트 하나로 충전과 기기연결을 동시에

많은 안드로이드 기기들이 하나의 micro USB 포트 만을 가지고 있다.

물리적으로 포트가 하나이기 때문에 한번에 하나의 기기 연결만 가능하다.

하지만, 많은 경우 안드로이드 기기는 불시에 충전해야 만 하는 경우들이 다반사이다.

그래서 USB 표준 스펙에 충전과 기기연결을 동시에 제공해 주는

 Accessory Charger Adapter에 대한 정의를 내리고 있다.

이전에 두 기능을 동시에 제공하는 것은 불가능 하다는 결론으로 글을 쓴 적이 있는데

어느 분이 삼성 기기에 이와 같은 기능을 제공하고 있다는 댓글을 올려 주셔서 조금 찾아 보았다.

현재 안드로이드 기기가 없기 때문에 직접 알아 보는 것은 불가능하여

누군가가 올려 놓은 안드로이드 기기에 USB DAC를 연결하고 충전하는 방법을

안내해 주는 글을 소개하기로 한다.

http://www.head-fi.org/t/595071/android-phones-and-usb-dacs/975

위의 링크를 살펴 보시면

The other points I don't understand and that concern me are, most posts indicate that if I tried to make something I need to use a resistor Short between pins 4 & 5, so the fact that your 'Y' adapter works allowing the audio data to go to the DAC(host mode), and charging voltage/current to run back seems to suggest there's more to your'Y'adapter, is it possible that this resistor is built into the adapter? or that actually no resistance is necessary and that it's incorrect information with regards to Galaxy S3's or Note 2's? again nothings clear or definite.

...(중략) micro USB의 4번핀과 5번핀사이를 쇼트 시키는 저항을 사용할 필요가 있어서 어떤 것을 만들고자 한다면, 사실 Y 자 케이블은 DAC로 전송되는 오디오 데이터를 허용하고 전압/전류를 충전하며 동작한다. 이 저항을 아답터에 장착한는 것은 가능합니까? 혹은 어떤 저항도 필요하지는 않는 것입니까?, Galaxy S3와 Note 2에 관한한 정확한 정보가 없습니다.....

"The ID pin on a Micro-B plug is not connected or is connected to ground by a resistance of greater than Rb_PLUG_ID (100kΩ MIN)."
Other put, if the resistance is lesser than 100 kΩ, it’s a Micro-A plug and the S3 / Note2 acts as a USB host able to interwork with a standard USB DAC.

"Micro USB의 B타입 플러그의 ID 핀(4번핀)을

 Rb_PLUG_ID(최소 100K옴) 이상의 저항을 가지고 그라운드와 연결되거나 연결되지 않는다"

달리 말하며, 저항이 100K옴 보다 작다면

(ID 핀(4번핀)과 Gound핀(5번핀)사이의 저항 값이 100K 옴보다 작다면)

 Micro USB의 A 타입 플러그와 S3/Note2플러그는

표준 USB DAC와 상호 동작하는 것이 가능한 USB 호스트로써 동작한다.


1000


"To inform the PD [Portable Device] that it should act as host and draw current,

the ACA [Accessory Charger Adapter] is required

 to pull the ID pin to ground through a resistance of RID_A (124k)."

http://kinetis.pl/sites/default/files/BC1.2_FINAL.pdf


휴대용 기기에게 호스트로 동작하면서 전류를 공급하도록 알리기 위해선

ID 핀과 Ground 사이에 RID_A(124K옴)의 저항이 연결되는

ACA[Accessory Charger Adapter]가 필요하다.


1000


요약하자면 ID 핀과 Ground 사이에 100k옴 이하의 저항을 연결하면

일반적인 주변 기기를 연결하는 안드로이드 기기로써 동작하고

124K옴을 위의 그림과 같이 연결하는 Y자 케이블을 만들면

Male USB Connector에서는 충전기를 연결하고

Female USB Connector에는 USB DAC와 같은 주변기기 연결 할 수 있도록 해준다.

보수적으로 해석해 보자면 아직 Galaxy S3와 Note 2에서만 확인된 사항인 것 같다.

좀 더 자세한 내용은 아래의 링크를 살펴 보시기 바랍니다.

https://sites.google.com/site/sonicboomworld/my-projects/otg-diagrams


그리고 USB 표준 문서의

Battery Charging Specification
Revision 1.2
December 7, 2010

를 훌터본 결과 다음과 같은 테이블이 포함된 페이지를 볼 수 있다.



보시다 시피 ACA의 연결을 ID 핀에 달린 Pull-down 저항값으로 설정하는 것 같다.

RID_A에 해당하는 값은 122K옴에서 126K옴 사이값이면 되고

이때 OTG 디바이스는 A-Device로써 동작한다고 되어 있다.

그래서 좀더 공격적으로 생각해 보자면 USB otg 타입의 기기이면 위와 같이 시도해

보아도 잘 동작할 것으로 사료된다. 저항값은 122K와 126K옴 사이로 하고 말이다.






2013년 7월 6일 토요일

[작업중] 리눅스 시스템에서 Netduino plus 2의 STM32f4xx를 위한 개발 환경 만들기

1. 서론


리눅스 시스템, 좀 더 구체적으로 데비안 시스템에서

각종 CPU  코어를 위한 toolchain을 이미 제공한다.

http://www.emdebian.org/crosstools.html

위의 링크를 살펴 보면 /etc/apt/source.list에 해당 repository를 추가하면

apt-get 툴을 이용하여 arm-linux-gnueabi-gcc의 설치가 가능하다.

하지만, 해당 패키지와의 의존성이 있는 몇몇 패키지에 문제가 생겨 정상적인 사용이 불가능하다.

그리고 예전에 cortex-m3의 stm32 코어를 사용하였을 때 사용하였던 codesourcery lite 툴은

mentor graphic사에 넘어가서 컴파일러를 사용하려면 내 정보를 제공해야하는 것 같다.

그래서 비슷한 cpu를 사용하는 stm32f4-discovery의 환경 설정을 참고해 보았다.

http://www.st.com/web/en/catalog/tools/FM116/SC959/SS1532/PF252419

참고한 사이트는 다음과 같다.

https://forum.sparkfun.com/viewtopic.php?f11&t=31083

위에서 두, 세 번째 내용을 살펴보면,

https://github.com/texane/stlink/blob/master/doc/tutorial/tutorial.pdf?raw=true

다음의 링크에서 환경설정에 관한 내용을 살펴 볼 수 있다.

하지만, 이것도 오래된 버전이라. 다음 링크로 가보라고 안내해 주고 있다.

https://launchpad.net/gcc-arm-embedded

2. 사전 지식

자, 그럼 진짜로 stm32f4xx를 위한 toolchain을 설치해 보자.

안내서는 우분투 시스템을 상정하고 설명하였다.

나는 데비안 시스템이기 때문에 이건 넘어가고 직접 다운로드해서 사용하는 방법을 취해야 겠다.

https://launchpad.net/gcc-arm-embedded/+download

위의 사이트에서 버전 별로 직접 다운로드 할 수 있게 제공하고 있다.

3. 설치 하기

링크에 가보면 여러 가지의 파일이 존재한다.

현재의 최신 버전은 4.7-2013-q2이다. 계속적으로 업데이트가 진행 되기 때문에

apt-get을 통합 자동 업데이트가 불가능하다면 주기적으로 위의 홈페이지를 방문해야한다.

그럼 그 중에서 Linux installation tarball에 해당하는 파일을 다운로드하자.

참 고맙게도 윈도우, 리눅스, 맥 시스템에서 모두 사용할 수 있도록 제공한다.

우선은 임시적인 작업이기 때문에 작업 디렉토리에 압축을 해제하자.

> cp gcc-arm-none-eabi-4_7-2013q2-20130614-linux-tar.bz2 $(HOME)/workspace/arm_projects
> cd $(HOME)/workspace/arm_projects
> tar jxvf gcc-arm-none-eabi-4_7-2013q2-20130614-linux-tar.bz2

그리고 toolchain의 경로를 전역 변수에 등록하는 작업이 필요하다.

앞서서도 이야기 했지만 emdebian의 toolchain이 완성 되기 까지 임시적인 작업이기 때문에

전역 변수에 등록하는 작업을 $(HOME)/.bashrc에 등록하지는 않을 것이다.

그래서 다음과 같은 내용을 갖는 파일을 생성하자.


======================= toolchain.env ==============================
export PATH=$PATH:$(pwd)/gcc-arm-none-eabi-4_7-2013q2/bin
--------------------------------------------------------------------

그리고 위의 파일은 다음과 같이 실행하여 전역 변수에 toolchain의 경로를 등록한다.


> cd $(HOME)/workspace/arm_projects
> source toolchain.env

3. 개발 환경 갖추기

이제는 Makefile, Startup 파일, Linker script 파일을 만드는 작업이 필요하다.

이 작업을 처음부터 다 이해하고 작성한다는 것은 어려운 일이다.

참고가 될만한 것들을 가져다가 작업을 하도록 하였다.

참고문서는 위에서 언급한 stm32f4 discovery 의 펌웨어 소스코드에서 얻어다 쓰도록 하였다.

3.1. Makefile 설정


Makefile은 각종 소스파일의 컴파일 방법에 대해서 정의하고

오브젝트 파일을 어떻게 합성할 것인지에 대해서 정의한다.

일반적인 Makefile의 간단한 시나리오를 이야기 하자면 다음과 같다.

1. 컴파일러, 링커,  등등의 경로와 실행파일의 지정.

2. 컴파일 할때에 컴파일러에 넘겨주어야할 매개변수 CFLAGS의 정의

3. 소스파일을 컴파일한 오브젝트 파일의 합성 매개변수 LDFLAGS의 정의

4. 이미지 파일이 실제 메모리에 적재될때 각 센션별 특정 위치를 지정하는 링커 스크립트 지정

우선, Makefile의 내용을 일일이 살펴보기에는 너무 버겁다.

앞으로 더 살펴보아야 할 것들이 산적해 있기 때문에 심정적으로 더 힘들다.

그래서 필요한 부분만 살펴 보도록 하자.

앞에서 언급했지만 지금 부터 이야기할 Makefile의 내용은 거의 다 stm32f4 discovery 의 펌웨어

소스코드를 가져다 섰다.

그럼 stm32f4 discovery의 펌웨어 소스코드의 Makefile의 흐름을 먼저 파악해 보자.

3.1.1. 컴파일러와 각종 유틸리의 설정


컴파일러와 각종 유틸리티의 파일명과 첨두어에 대한 설정이 이루어 진다.

그 중에서도 다음사항은 가장 중요하다.

TCHAIN_PREFIX = arm-none-eabi

위의 사항은 컴파일러 달리 이야기 하면  arm을 위한 gcc 의 첨두어를 설정하는 부분이다.

이 사항은 설치된 컴파일러의 상황에 따라 바꾸어 주어야 한다.

그리고

CHIP = STM32F40x_1024k 와

BOARD = STM32F4DISCOVERY

에 해당하는 부분이다.

CHIP은 가지고 있는 보드에 달려 있는 cpu와 BOARD는 개발 보드의 모델명으로

상황에 따라 바꾸어 주어야 한다.

하지만, 아직은 소스코드에서 위의 두 가지 정의를 참조하진 않는다.

그냥 앞으로 생길 수 있는 펌웨어의 갈래를 나뉠 수 있는 가지를 제공하고자 하는 것 같다.

3.1.2. 실행 방식과 인터럽트 백터의 위치 지정


다음은 컴파일된 이미지가 램에 적재되어 실행될 것인지

플래시 메모리에 적재되어 실행 될 것인지를 지정한다.

그리고 인터럽트 벡터 모음집이 플래시 메모리에 있는 것을 사용할 것인지

램에 있는 것을 사용할 것인지 지정한다.

이와 같은 설정은 각각 다음 두 가지 정의문으로 지정한다.

RUN_MODE = FLASH_RUN
#RUN_MODE = RAM_RUN

그리고

VECTOR_TABLE_LOCATION = VECT_TAB_FLASH
#VECTOR_TABLE_LOCATION = VECT_TAB_RAM

이 설정들은 나중에 오브젝트 파일들을 적재할 때 참조가 되는 링커스크립트를

이미지가 적재되는 메모리의 형태에 맞게 선택한다.

여기서는 FLASH 메모리에 이미지가 적재되고 있는 인터럽트 벡터 모음집을 사용하기 때문에

나중에 링커 스크립터로 STM32F40x_1024k_flash.ld 를 사용하게 된다.

또한, RUN_MODE에 따라 오브젝트 파일들이 저장되는 위치가 바뀌게 된다.

그레서 컴파일을 수행하기 이전에 RUN_MODE에 따른 디렉토리를 수동으로 만들던지

> make createdirs

을 실행하여 RUN_MODE에 따른 디렉토리를 자동으로 생성해 주어야 한다.

마지막으로, 최종 결과물의 이름은 다음을 통하여 지정하다.

TARGET = project

위와 같이 지정하면 project.bin, project.elf, project.hex 와 같은 결과물이 생성된다.

3.1.3. 소스 코드의 지정




어쩔 수 없이 쓰게 되는 GIT를 이해하는데 헤깔리는 용어들


스냅샷(snapshot) : 모니터 화면을 순간적으로 카메라로 찍는 다는 개념이 원래의 의미이지만, 여기서는 순간적으로 저장된 모든 내용의 상태를 이야기 한다.

커밋(commit): 사전적인 의미는 "저지르다"라는 뜻이지만, 여기서는 저장소에 변경사항을 전송하기 위한 모든 작업을 실행한다는 의미가 되겠다.

체크아웃(checkout): 저장소의 변경된 사항들을 원격의 서버의 저장소에 전송한다는 의미 인것 같다.

워킹디렉토리: 원격 서버에 있는 저장소를 복사한 로컬 디스크의 저장소.

2013년 6월 18일 화요일

박근혜의 선택

이전에는 물밑에서 잔잔하게 부정 선거에 대한 이야기가 나오곤 했는데

보이는 현상이 앞으로 박근혜를 당혹 시킬 만큼의 무게가 실릴 것으로 예측된다.

뭐 이미 저질러진 일들에 대해서 이렇다 저렇다 이야기 하는 것은 아무 문제 없지만

아무 말 없이 가만히 뭔가를 준비 하는 것 같은 느낌은 지울 수 없다.

부시가 석연찮은 선거로 대통령이 된 후

어처구니 없는 거짓말로 이라크 전쟁을 잃으켰듯.

한국에서도 비슷한 시나리오가 나오지 않기를 바란다.

2013년 6월 16일 일요일

안드로이드 개발 환경 설정

시스템은 데비안 리눅스 testing 배포판이고 기존에 eclipse 3.8 버전이 설치 되어 있다.

먼저, 새로운 android 번들 시스템이 있어서 이전 처럼 eclipse 플러그인과 android SDK를

따로 따로 설치해서 설정해야 하는 과정이 사라 진 것 같다.

우선 둘다 써보고 나중에 편한 것으로 선택해야 겠다.

번들 개발 환경의 설정은 쉬우니깐 eclipse와 android sdk, 그리고 eclipse plugin을 설치하는 방식을 기록해야 겠다.

우선 android sdk를 다운로드 하고 설치하자.

http://developer.android.com/sdk/index.html#ExistingIDE 에 가서


Download the SDK Tools for Linux를 클릭하여 android-sdk_r22.0.1-linux.tgz를 다운 로드하고,

적절한 위치에 압축 푼다. 나의 경우 /home/{username}/ 밑에 압축해제하였다.

그리고 /home/{username}/android-sdk-linux/tools 밑의 android라는 실행 파일을 실행시킨다.


최신 버전의 API와 기본적인  Tools을 선택하고 라이센스에 동의함을 선택한다.


선택한 패키지의 설치를 수행한다. 


설치가 마무리 되면 다음은 eclipse 설정이 필요하다. 

eclipse의 help->install new software를 선택한다.


Add 버튼을 클릭한다.



Android Development Tool을 가지고 있는 Eclipse plugin 주소를 추가한다.


해당 패키지 중 Developer Tools을 선택하고 Next> 버튼을 실행한다.



혹시 다른 패키지의 의존성 문제로 설치가 안되는 경우가 간혹 있다.

나의 경우가 그러한데 해결책은 eclipse를 지우고 다시 설치하는 방법이 가장 쉬운 방법인것 같다.

설치할 패키지는 다음과 같다. 아마도 eclipse-cdt만 설치하거나 한가지가 누락 되거나 한것 같다.

# apt-get install eclipse eclipse-cdt eclipse-jdt

위와 같은 과정을 거치고 eclipse를 다시 실행하면  android-sdk의 경로가 잘못되었다는 메시지와

함께 설정 다이어로그를 열 수 있게 해준다. 


자 기본적인 것들은 마무리 된 것 같다.