USB-シリアル変換ケーブルでPICとPCを接続した

PL2303HX USB変換ケーブルには以下の説明が記されていました。

黒いケーブル----- GND
グリーンケーブル---- TXD
白いケーブル---- RXD
レッドケーブル----- VCC(5V)

念のためテスターで電圧を測ってみると、 グリーンケーブルは3.5V付近で安定、白いケーブルは1.5V~2.0V辺りをふらふら、という状態で上の説明に間違いは無さそうでした。

そこで、グリーンケーブルをPICのRX(18pin)、白いケーブルをTX(17pin)に接続して、PIC側は受信データに+1した値を送信するというプログラムでPIC-PC間のループバック・テストを行い、無事完了しました。(パチパチパチ~)

 

いよいよ、PIC-PC(Raspi)間で送受するコマンドおよび応答のフォーマットを設計して、組み込みます。

 

PIC16F1938でPIC側の開発を始めた

PIC16F1769にするか?それともPIC16F1778にするか?
PICデバイスの選定で迷っています。秋月電子が取り扱うPIC16F1769は入手性に優れますが、残念なことに20pinでメモリもPIC16F1778の半分です。

 

最終的な選定は基板設計まであと送りにして、取り敢えず手持ちのPIC16F1938でPIC側の開発を進めることにしました。

MCC(Microchip Code Configurator)のお陰で、Projectの立ち上げは至ってスムーズです。最終的に別のデバイスに置き換える際の修正もMCCが自動的に行ってくれるものと期待しています。

f:id:RASPI-PIC-CLUB:20170730155239p:plain

EUARTとMEMORYをProject Resourcesに登録して、Generateボタンをクリックするだけで、Raspi_Picに必要な機能の大半が組み込まれました。

このプログラムで確認するのは以下の三項目です。

(1)PC(およびRaspi)とPIC間のUART通信

(2)FLASHメモリのRead/Write

 (3)FLASHメモリに書き込んだプログラムの実行

 

Projectの立ち上げと同じくらいサラッと進んでくれると良いな~

 

USB-シリアル変換ケーブルを試してみた

Raspi-Picのプログラム(JAVA)はPCで開発し、Raspiで動作確認するという方法を採用しています。I2Cの時はbcmlib_for_java(↓これです)がRaspiでないと動かないので、PC上の開発に大きな制限がありました。

GitHub - Denshikobo-Life/bcmlib_for_java: Interface between Java app. and bcm2835 library(written by C)


PCとRaspiにインストールしたUARTライブラリのVersionが異なっていたらしく、RXTXcomm.jarを切り替えなくてはならないのですが、(大きな支障では無いので)そのまま作業を続けることにしました。

f:id:RASPI-PIC-CLUB:20170729132910j:plain

Amazonで手に入れたUSB-シリアル変換ケーブル(↑こんな奴 ¥200で売られているのは非正規品かも・・・)をPC(Windows10)に接続してみました。するとドライバでエラー(コード10)を起こして動いてくれません。orz
以下のページに記された修正方法(最後の修正プログラムを適用)で認識してくれるようになりました。

ehbtj.com

尚、RaspiではこのUSB-シリアル変換ケーブルは問題なく認識されます。(/dev/ttyUSB0)

 

Commクラスに二つのThread(送信用と受信用)を設けて、PCとRaspiでループバックテストO.Kの確認がとれました。(パチパチパチ~)

 

(↓こんな感じです)

private class ReceiveThread extends Thread {
         public void run() {
            int receive = 0;
            System.out.println("Receive run");
            while (true) {
                if( receive_ringbuff.full )
                {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Comm.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                else
                {
                    try {
                        receive = in.read();
                    } catch (IOException ex) {
                        Logger.getLogger(Comm.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    receive_ringbuff.write((byte)receive);
                }
            }
         }
     }

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

追伸

リング・バッファはThread Safeなのでこういうときには重宝します。

 

 

Raspi-Picの操作が少しずつ形になってきた

色々、試行錯誤しながらRaspi-Picの開発を進めています。
デザイン的にウィンドウ・フレームが邪魔だったので消してみました。
その技がこれ(↓)です。

setUndecorated( true );

 

f:id:RASPI-PIC-CLUB:20170726120456p:plain

本当は角を丸く落としたいのですが、方法が未だ分からないので当分はこのままです。

そろそろPICとの通信を始めようとしているのですが、そこに大きな課題が浮かんできました。

RaspiとPIC間の通信をI2Cでやるか、UARTでやるかという問題です。

PICの新しいデバイス(PIC32MKシリーズ)にはI2Cの回路が組み込まれておらず、ソフトウェアで処理するようなのです。400kHzで連続通信したときのCPU負荷が50%だとか・・・orz

一方、UARTは通信速度が向上して(数十MHzに達して)いて、アドレス指定で通信対象を選択できるので、I2Cよりも高機能になっている(N対Nの通信が出来る)のです。

MicrochipがI2CからUARTにシフトしようとしているのは明らかです。

 

一方Raspiは、二つあるUARTの一つはBluetoothで使っていて、残りの一つ(miniUART)はVPUのコアクロックを固定しないと使えない(baud rateが変化してしまう)らしいのです。ここ(↓)に色々書いてあります。

The Raspberry Pi UARTs - Raspberry Pi Documentation

 

何だかとっても使いにくい感じです。

方策その1

当面はI2Cで行って、RaspiのUART事情が変わったらUARTに乗り換える。

方策その2

I2CとUARTどちらも使えるようにしておく。

方策その3

さっさとUARTに乗り換える。

 

開発側にとって楽なのは方策その1ですが、乗り換え時にユーザの混乱を招くのではないかという懸念があります。

 

ユーザにとって、もっとも望ましいのは方策その2?、それとも方策その3?

 

開発側にとっての負担は?

ふむ・・・、UARTを使う環境を構築する手順を確立すること!

 UARTでやってみて、その結果を見て方策を決定することにします。

 

DEBUG_INFOの解析が走り出した

readelf --debug-dumpの出力を解析して、ユーザ・プログラムに出てくる変数や関数の情報を取り出すプログラムを開発しています。

例えば、こんな二行を解析して・・・
 8ad 1 10 3 int 2 5-(signed)
 8b4 1 20 6 xt_int 1 69 <0x8ad> 1 3-byte-block:-3-53-0-(DW_OP_addr:-53)

 こんな情報を取り出します。

 xt_int 53 2 base_type 2  int 2

変数名はxt_int、アドレスは0x53で2バイトのint型変数という結果です。

base_tytpeの変数なので情報も取り出し易いのですが・・・

 

構造体変数に関する入力行はこんな感じで・・・

 91e 2 9 5 tstr 1 74 <0x95b> 3-byte-block:-3-4a-0-(DW_OP_addr:-4a)
 95b 1 21 5 <0x98f> test_struct 3 1 72
 970 2 6 3 test_c <0x844> 2-byte-block:-23-0-(DW_OP_plus_uconst:-0)
 97f 2 6 3 test_i <0x8ad> 2-byte-block:-23-1-(DW_OP_plus_uconst:-1)

出力はこうなります。
 tstr 4a 3 structure_type 6  1 test_c <test_c|null|1|base_type|unsigned-char|1> 2 test_i <test_i|null|2|base_type|int|2>

少し複雑ですが、変数名tstr、アドレスは0x4a、サイズは3バイトの構造体で、unsigned char型のtest_cと、int型のtest_iをメンバーに持つことが読み取れます。

 

<>で挟んだ文字列は構造体メンバのTYPE属性で、複雑な構造を持つ変数のTYPE属性の解析に必要な情報を記します。この例では、メンバ変数がbase_typeなので簡単な記述に留まっていますが、メンバ変数が構造体だったり、構造体配列へのポインタだったりすると、<>の中の記述がどんどん複雑になっていきます。

 

利用するときに苦労しそうですが、面倒な心配は先送り!(<==開発の基本スタンス)

 先ずは変数名からアドレスとそのサイズを調べてPICから読み出し、バイト列で表示するところから始めます。(<==構造体メンバもバイト列で表現する)

構造体メンバーの変数表示とか、配列の型変換表示とか・・・機能拡張(<==面倒だけど多分出来る)は追々考えていきたいと思います。
 

DWARFDUMPを諦めた

DWARFDUMPの出力がやけに短いと思ったら、解析が途中で止まっていました。orz

出力はこんな感じです。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

.debug_info

COMPILE_UNIT<header overall offset = 0x00000000>:
< 0><0x0000000b>  DW_TAG_compile_unit
                    DW_AT_stmt_list             0x00000000
                    DW_AT_producer              Microchip MPLAB XC8 Compiler v1.42
                    DW_AT_language              DW_LANG_C89
                    DW_AT_name                  C:\common\developement\Raspi-Pic\RaspiPic-1938.X\mcc_generated_files/pin_manager.c
                    DW_AT_low_pc                0x00000452
                    DW_AT_high_pc               0x0000046f

途中省略

< 1><0x00000344>    DW_TAG_subprogram
                      DW_AT_sibling               <0x00000377>
                      DW_AT_name                  i2c_put_into_ring_buff
                      DW_AT_external              yes(1)
                      DW_AT_decl_file             0x00000001
                      DW_AT_decl_line             0x00000049
                      DW_AT_low_pc                0x000005cd
                      DW_AT_high_pc               0x000005d6
                      DW_AT_inline                DW_INL_not_inlined
< 2><0x00000368>      DW_TAG_variable
                        DW_AT_name                  d
                        DW_AT_decl_file             0x00000001 C:\common\developement/Raspi-Pic/SRC/i2c_comm.c
                        DW_AT_decl_line             0x00000049
                        DW_AT_type                  <0x00000129>
                        
dwarfdump ERROR:  dwarf_get_loclist_c:  <==ここでエラーになったらしい  DW_DLE_DEBUG_LOC_SECTION_SHORT(194)

CU Name = C:\common\developement\Raspi-Pic/SRC/i2c_comm.c
CU Producer = Microchip MPLAB XC8 Compiler v1.42
DIE OFF = 0x00000368 GOFF = 0x00000415, Low PC = 0x000005bb, High PC = 0x000005c4

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

xc32-readelf --debug-dumpなら最後まで解析できたので、インストールしたDWARFDUMPの利用は諦めることにします。

DWARFDUMPをインストールした

Maker Faire Tokyoの選考に落ちてしまいました。orz

しょげていても始まらないので、Maestronの開発は一先ず置いて、以前からやりたいと思っていた『Raspi-Pic』の開発に取り組むことにしました。

『Raspi-Pic』は、Raspberry piとPICデバイスを組み合わせた、新しい『PIC電子工作の学習、開発、アプリケーション実行環境』になる予定です。構想(<==妄想?)があれこれ膨らみ、その実現方法を思案しながら開発を進めています。


PICコンパイラが出力したELFファイルから、デバッグ情報を取り出す方法がわからず、あれこれ調べてDWARFDUMPというプログラムに行き着きました。

これ(↓)です。

www.prevanders.net

これをRaspiにインストールしたので、その手順を以下に記します。
(1) sudo apt-get install libelf-dev
(2) wget https://www.prevanders.net/libdwarf-20170416.tar.gz
(3) tar --extract -f libdwarf-20170416.tar.gz
(4) cd dwarf-20170416
(5) ./configure
(6) make
(7) sudo cp dwarfdump/dwarfdump /usr/local/bin
(8) dwarfdump -V


これを使ってelfファイルを解析するとこんな感じにデバッグ情報を取り出すことが出来ました。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
.debug_info

COMPILE_UNIT<header overall offset = 0x00000000>:
< 0><0x0000000b>  DW_TAG_compile_unit
                    DW_AT_stmt_list             0x00000000
                    DW_AT_producer              Microchip MPLAB XC8 Compiler v1.42
                    DW_AT_language              DW_LANG_C89
                    DW_AT_name                  C:\common\developement\Raspi-Pic\RaspiPic-user.X\mcc_generated_files/interrupt_manager.c
                    DW_AT_low_pc                0x00000004
                    DW_AT_high_pc               0x00000032

LOCAL_SYMBOLS:
< 1><0x00000092>    DW_TAG_subprogram
                      DW_AT_name                  INTERRUPT_InterruptManager
                      DW_AT_type                  <0x000000ba>
                      DW_AT_external              yes(1)
                      DW_AT_decl_file             0x00000001
                      DW_AT_decl_line             0x00000033
                      DW_AT_low_pc                0x00000004
                      DW_AT_high_pc               0x00000032
                      DW_AT_inline                DW_INL_not_inlined
< 1><0x000000ba>    DW_TAG_subroutine_type
以下省略
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
この出力を解析するプログラムが次の課題です。
(先はまだまだ長いなぁ~)

 

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
補足
”version 20120410-2”なら、以下のコマンドで簡単にインストールできるようです。
sudo apt-get install dwarfdump