Last Update : 2009/Dec/22
Mac による
ARM 開発
動機
動作環境
ツールチェーン
FTDI 2232 ボード
openocd
Eclipse
参考URL と謝辞
<<戻る

     iPhone の普及や OSX, Intel CPU の採用による Windows の実行環境(BootCamp, 各種VM)の整備によりMacの普及が目覚ましい。インストールベースでは Windows が圧倒的に多いので各種の開発環境は Windows-PC で構築されることが多いが、折角Macにスイッチしたのだから Mac で開発を出来ないだろうか?と考えるのは人情だ。ここでは Mac での ARM 開発環境の構築方法を解説する。


  • 動機

     拙著、「Eclipse/ARMプロセッサによる組込み開発」の発刊から2年が経ち、内容的にも古くなってしまった。当時はそれほどMacに拘泥するような環境でもなかったが自分自身が Mac にスイッチしたのだから、この際すべてを最初から組み上げてみようと思い立った。また、先達が切り開いてくれた様々なインストール情報は貴重だ。ただ分散しているし Mac 用としてまとまっているものも少ないのでまとめてみようと考えた。


  • 動作環境

     ここでは以下の環境での動作を確認しているが、必ずしも動作を保証するものではない。各自の責任で構築して欲しい。  

       
    • ホスト  
          
      • MacBookPro 15inch (Late 2008)   
      • Snow Leopard 10.6  
       
    • ターゲット  
          
      • FT2232D インターフェイスボードを用いた自作 jtag デバッガ   
      • EZ-SERVO  オプティマイズから販売されているサーボモータコントロールボード  
       
    • Snow Leopard

       既に標記内容は Web で散見されるが、Snow Leopard での動作実績に言及してあるものはあまり多くない。64bit 化を推し進めた Snow Leopard では思いもかけずにトラブルになることがよくある。ここでは最近の環境 (2009/Dec/10 時点) での動作実績を目指すことにし、開発に必須のツールからインストールしていく。少なくとも openocd までの動作を実現しないと作成したソフトのリフラッシュが出来ないためボードの開発は出来ない。


  • ツールチェーン

       
    • arm-elf-gcc  

      マイコン開発にコンパイラは必須なので最初に試すのは GNU のツールチェーンである arm-elf-gcc とその周辺のソフトウェアだ。arm-elf-gcc を Mac にインストールするにはいくつかの方法が紹介されている。  

        
          
      • macports   

        OSX からは UNIX なので UNIX のツールを簡単に Mac に導入するための手段である。当初は macports からの arm-elf-gcc のインストールを試みたが途中でエラーが出てしまう。不具合の回避策が無いかと、しばしネットを徘徊したが有用な情報は見つけられなかった。macports への不具合報告のチケットもオープンになったままだった。   

             
      • YAGARTO   

        ARM のツールチェーンとしては老舗である。Mac の他に Windows, Linux などの各種環境用にコンパイル済みのツールを提供している。こちらを導入して無事に arm-elf-gcc が使えるようになった。

           

             
        • インストール方法    
                 
          1. サイトからダウンロード      
          2. dmg パッケージからファイルをとり出し、任意の場所にコピーする。(今回は ?/yagarto を作成し、そこにコピー。)      
          3. その場に展開する      
          4. パスを通す。以下をホームディレクトリの .bash_profile に記述して、source .bash_profile を行うか再起動する。
            export PATH="$PATH:$HOME/yagarto/yagarto-4.4.2/bin"
            export PATH="$PATH:$HOME/yagarto/yagarto-4.4.2/tools"
            
               
                    
        • 動作確認    

          以上の設定が完了したら、実際に arm-elf-gcc が動作するか確認する。コマンドラインから、以下のように打ち込む    

          $arm-elf-gcc [return]
          arm-elf-gcc: no input files
          

          と応答が返ってくれば、インストールは無事に終了している。

          次に実際にビルドが出来るかどうかを確認する。今回は RoboShell を使う。適当なディレクトリに展開後、移動して

          $make [return]
          

          RoboShell.elf が作成出来れば成功である。


    • FTDI 2232 ボード

      FTDI 2232 のチップを利用した jtag デバッガは各社からリリースされている。他のデバッガに比べて比較的安価であるので時間のない場合やハードの組立を行いたくない場合はこれらを購入してもよいだろう。筆者はコスト最優先なのとシリアルも同じコネクタに搭載したいので、FT2232D のボードを改造してデバッガを製作することにした。

      • 各社のボード

        国内では下記から購入可能である。機能は同じであるが秋月電子の方がかなり安い。基板のカタチが違うので、気に入ったほうを買えばよいと思う。

      • デバッグ用ハードの製作

        買ってきたそのままではターゲットに接続出来ないので接続用のジグを製作する。このジグのミソは市販されている同機能の他に jtag とシリアルの両方を使ってターゲットに接続することにある。ターゲットがシリアルで PC と接続する場合は非常にすっきりする。

        • ジグの様子
          • 秋月電子の FTDI2232 ボード

          • ツール工房の FTDI2232 ボード

        • 接続

          FTDI Target
          ADBUS0 TCK
          ADBUS1 TDI
          ADBUS2 TDO
          ADBUS3 TMS
          ACBUS0 tRST
          BDBUS0 RxD
          BDBUS1 TxD

          Note: nRst をモーメンタリSW を介して GND へ接続

      • ドライバのインストール

        ダウンロードしたドライバをインストール後、以下の操作を行う。
        $cp libftd2xx.0.1.6.dylib /usr/local/lib [return]
        $cd /usr/local/lib [return]
        $ln -sf libftd2xx.0.1.6.dylib libftd2xx.dylib [return]
        


    • openocd

      openocd は頻繁に更新されているのでノウハウの陳腐化が早いが、ツボを押さえておくことにより更新後の導入も比較的スムーズに行えると思う。

      • インストール

        macports からの導入をおこなう $sudo ports install openocd

      • 起動方法

        openocd はどのデバイスで jtag を実現するかあるいは接続するターゲットにより設定が変わる。

        • 注意点

          FTDI のドライバをインストールし、Mac に接続した時点で VCP (Virtual Com Port) がアクティブになる。このためリソースの競合が起こり openocd がエラーを返してしまい起動出来ない。これを防ぐためには再起動の度に下記のコマンドを投入し VCP をアンロードする。
          $sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext
          
          FTDI の VCP を金輪際、使わないのであれば上記の kext (カーネルエクステンション)を移動するなり、削除してもよい。

               
        • TIPS

          ちょっとした工夫でシリアルと jtag を共存させることも出来る。ここらあたりの情報を参考に筆者が試したところをうまくいったので紹介したい。今回利用する jtag アダプタは EEPROM の搭載されていないので FTDI の VenderID, ProductID を利用するものである。これの記述が Info.plist (プロパティリスト)に記述されている。具体的には下記のファイルである     
          /System/Library/Extensions/FTDIUSBSerialDriver.kext/Contents/Info.plist
          

          今回の jtag アダプタは Port A に jtag, Port B にシリアルを割り当てているので、Port A にシリアルが割り当てられないようにすれば良いわけである。そのために Info.plist の中の Port A に関する部分の記述を削除する。
          <key>FT2232C_A</key>
            <dict>
               <key>CFBundleIdentifier</key>
               <string>com.FTDI.driver.FTDIUSBSerialDriver</string>
               <key>IOClass</key>
               <string>FTDIUSBSerialDriver</string>
               <key>IOProviderClass</key>
               <string>IOUSBInterface</string>
               <key>bConfigurationValue</key>
               <integer>1</integer>
               <key>bInterfaceNumber</key>
               <integer>0</integer>
               <key>idProduct</key>
               <integer>24592</integer>
               <key>idVendor</key>
               <integer>1027</integer>
            </dict>
          

               

          ファイルの加工が終わったら、下記のコマンドを実行する     
          $sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext
          $sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext
          

          /dev ディレクトリを確認して、tty.usbserial* のファイルが一つだけあることを確認する。筆者の環境だと、
          $ ls /dev/tty.usb*
          /dev/tty.usbserial-00002006B
          
          が確認出来た。これにより Port A は VCP が設定されていないことがわかる。         

        • コンフィグレーションファイル

          今回利用したコンフィグファイルは以下のとおり、
          #daemon configuration
          telnet_port 4444
          gdb_port 3333
          
          #interface
          interface ft2232
          
          # You have to comment out ft2232_device_desc in Windows environment
          #ft2232_device_desc "RoboShell debugger"
          
          ft2232_layout jtagkey
          ft2232_vid_pid 0x0403 0x6010
          jtag_khz 500
          
          jtag_nsrst_delay 100
          jtag_ntrst_delay 100
          #use combined on interfaces or targets that can't set TRST/SRST separately
          #reset_config trst_and_srst srst_pulls_trst
          reset_config trst_and_srst
          
          #jtag scan chain
          #format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)
          jtag_device 4 0x1 0xf 0xe
          
          #target arm7tdmi    
          target create target0 arm7tdmi -endian little -chain-position 0 -variant arm7tdmi-s_r4
          [new_target_name] configure -work-area-virt 0 -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0
          
          #flash configuration
          flash bank lpc2000 0x0 0x7D000 0 0 0 lpc2000_v2 14765 calc_checksum
          
          # For more information about the configuration files, take a look at:
          # http://openfacts.berlios.de/index-en.phtml?title=Open+On-Chip+Debugger
          
          init
          

        • ターゲットとの接続

          接続図

          1. ホストとターゲットの接続後、ターゲットの電源投入
          2. jtag アダプタボードのマニュアルリセットスイッチを押下
          3. コマンド投入

            $openocd -f ./RoboShell.cfg
            
            RoboShell.cfg は RoboShellCore のコードに同梱してある。

              
            Open On-Chip Debugger 0.3.1 (2009-12-07-14:46)
            $URL$
            For bug reports, read
            	http://openocd.berlios.de/doc/doxygen/bugs.html
            500 kHz
            trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain
            OLD SYNTAX: DEPRECATED - translating to new syntax
            jtag newtap CHIP TAP -irlen 4 -ircapture 0x1 -irvalue 0xf
            Example: STM32 has 2 taps, the cortexM3(len4) + boundaryscan(len5)
            jtag newtap stm32 cortexm3 ....., thus creating the tap: "stm32.cortexm3"
            jtag newtap stm32 boundary ....., and the tap: "stm32.boundary"
            And then refer to the taps by the dotted name.
            NEW COMMAND:
            Warn : Specify TAP 'chip0.tap0' by name, not number 0
            Warn : don't use numbers as target identifiers; use names
            Warn : use 'target0' as target identifier, not '0'
            Info : clock speed 500 kHz
            Info : JTAG tap: chip0.tap0 tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
            Warn : JTAG tap: chip0.tap0       UNEXPECTED: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
            Error: Trying to use configured scan chain anyway...
            Warn : Bypassing JTAG setup events due to errors
            Info : Embedded ICE version 4
            
            現在のところ、上記のようなメッセージを出力して動作を開始する。

        • 動作確認

          べつのコンソールを開き、telnet を起動する。
          $ telnet 127.0.0.1 4444 [return]
          

          下記のメッセージが出力され動作を開始する
          Trying 127.0.0.1...
          Connected to localhost.
          Escape character is '^]'.
          Open On-Chip Debugger
          > 
          
          これで各種のコマンドを受け付けることが出来るようになった。help と入力することで、利用するコマンドの一覧を取得出来る。

        • リフラッシュ

          ビルドで生成したファイルは下記のコマンドでリフラッシュする
          > arm7_9 dcc_downloads enable [return]
          > halt [return]
          > poll [return]
          > flash probe 0 [return]
          >flash info 0 [return] ← セクタ数の確認
          > flash write_image erase ./RoboShell.elf 0x0                         
          auto erase enabled
          Padding image section 0 with 0 bytes
          Verification will fail since checksum in image (0xb8a06f58) to be written to flash is different from calculated vector checksum (0xb9205f80).
          To remove this warning modify build tools on developer PC to inject correct LPC vector checksum.
          wrote 27356 byte from file ./RoboShell.elf in 2.577914s (10.362969 kb/s)
          > 
          


    • Eclipse

      Eclipse の導入/運用が出来れば各種ツールを有機的に組み合わせ、高次元の操作が可能になり市販のツールと遜色ない環境を構築出来る。

      • インストール

        C/C++ CDT をインストールする。筆者は cocoa - 32bit version をインストールした。

      • ビルド
        • プロジェクトの作成

          Eclipse の環境に認識させるために展開したファイルの導入方法を解説する

          1. File -> Import...

            Existing Projects into Workspace を選択し、"Next"

          2. プロジェクトの選択

            • "Browse..." ボタンをから、該当プロジェクトを含んだフォルダを選択する。
            • そのプロジェクトが Projects: に選択されていることを確認する
            • "Finish" を押す

        • makefile の修正

          今回のプロジェクトは makefile に基づいてビルドされる。makefile 中に arm-elf-gcc 関連ツールのパスを設定しておく。

        • ターゲットの設定

          1. Project -> Property
            ビルド時のオプション設定をおこなう。

          2. Project -> Build All
            このメニューは上記 Property の図中が反映される。デフォルトだと all が設定されているので適宜変更する。

          3. Project -> clean
            makefile の clean オプションの実行

          4. その他のビルドオプション
            makefile に記述されているオプションを必要に応じて設定する。
            Project -> Make Target -> Create

      • デバッグ

        デバッグで使うツールは openocd なので、openocd がメニューの選択で起動出来るように設定する。

        • ツールの設定

          Run -> External Tools -> External Tools Configuration...

          • Location:
            Browse File System... により openocd が格納されているディレクトリを指定。

          • Working Directory:
            Browse File System... により 現在のプロジェクトの実ディレクトリ。

          • Arguments:
            -f ./RoboShell.cfg ← Working Directory はプロジェクトの箇所であり、openocd のプロジェクト用のコンフィグファイルは同じ場所にあるため

                
        • openocd の起動

      • ZylinCDT

        ZylinCDT は ノルウェーの Zylin 社がリリースしている組み込み用のデバッガのプラグインツールである。

        • インストール
          Help -> Install New Software ... から
          Work with: に 以下を入力する

                
          http://opensource.zylin.com/zylincdt
          
          後は通常の plug in と同様にインストールする。

            
        • 設定

          Run -> Debug Configuration...

          • Main:

          • Debugger:

          • Commands:

            target remote localhost:3333
            mon reset
            mon halt
            monitor debug_level 2
            load RoboShell.elf
            compare-sections
            monitor soft_reset_halt
            set mem inaccessible-by-default off
            monitor debug_level 0
            thbreak main
            

          • Source:

          • Common:

        • オペレーション

          • DSDP(Device Software Development Platform)

            Eclipse で組込みソフト開発を行う時に役立つのが DSDP だ。今回の RoboShell もそうだが組込み開発では シリアルを多用する。また、OpenOCD の制御では telnet のクライアントが必要になる。これらのシリアルや telnet, ssh の機能を拡張する TM-terminal のプラグインを用いる。

            • インストール

              TM-Terminal を使用するには Java でシリアルをハンドリングするドライバをインストールする必要がある。

              • TM-Terminal

                ダウンロード後、解凍すると features, plugin の2つのフォルダが出来る。その中身を eclipse のフォルダ中にあるそれぞれのフォルダに全てコピーする。

              • rxtx

                rxtx は Java からシリアル/パラレルをハンドリングするためのドライバ群である。Windows, Linux, Mac などの各プラットフォーム別に提供されている。解凍して取り出したファイル、RXTXcomm.jar と librxtxSerial.jnilib を /Library/Java/Extensions にコピーする。


      • 参考URL と謝辞

        このページを作成するにあたり、下記サイトを参考にさせていただきました。先達の努力と探求心に感謝します。


頁の先頭
織田裕一へメール


Copyright (C) 1998 - 2009 TeamKNOx