エンジニアの備忘録

仕事や趣味でのトラブルシューティングの備忘録

Tera Termでバイナリ通信

通常、Tera Termはテキストデータ通信

マイコンWindows PCとの通信ではTera Termを使わせてもらっている. 通常Tera Termが入出力するデータはテキストデータとなっている.

具体的には、Tera Termを立ち上げて、キーボードのaを押すと、Windows PCからマイコンへは0x61が送信される.

参考:http://e-words.jp/p/r-ascii.html

Tera Termでバイナリ通信したい

時々、Tera Termでマイコンへバイナリデータを送りたい時や、マイコンから送信されたバイナリデータをTera Termで受信してPCモニターに表示させたい時がある.

例えば、モータを制御するマイコンがあって、"マイコンに0xAF, 0x03, 0x02と送るとモータが動き出し、正常にモータが動くとマイコンから0xAF, 0x22と応答がある"ような仕様の場合、Tera Termでテキストデータ通信していると困ってしまう.

バイナリデータ送信

マクロを使って任意のバイナリデータを送る.

まず、Tera Termの<設定>--><端末> --> <漢字-送信>をSJISに設定する.

"マイコンに0xAF, 0x03, 0x02と送る"場合、マクロは以下のように書く.

send $AF$03$02

受信したバイナリデータの表示

受信バイナリデータをそのまま表示するのにも設定が必要.

まず、Tera Termの<設定>--><端末> --> <漢字-受信>をSJISに設定する.

Tera Termのバイナリデータ表示はdebug modeで行うので、設定ファイル(TERATERM.INI)の編集してdebug modeを有効にしておく. TERATERM.INIの中でdebug modeの部分を以下のように書き換える.(自分の場合、462行目にあった.)

; Display all characters (debug mode)
Debug=on

書き換えたら、Tera Termを再起動するか、Tera Termの<設定>--><設定の読み込み>でTERATERM.INIを読み込む. 表示はSHIFT+ESCで切替できる. マイコンからバイナリデータを受信しているときに、何回かSHIFT+ESCを押していき、バイナリデータ表示されれば完了.

参考:http://shuzo-kino.hateblo.jp/entry/20111027/1319682490

Windows8での.emacsの場所

こんなところにありました

C:\Users\username\AppData\Roaming

git diffでカラー表示

git diffはカラー表示じゃないと

raspberry piでgitを使ってみたら、git diffでカラー表示されなかった. 今までそんな経験がなかった. git diffをカラー表示なしで使ってみたが、やっぱり不便. カラー表示する方法を調べたら、すぐ見つかった.

git config --global color.ui true

これで、git diffでカラー表示された. 参考 : http://rochefort.hatenablog.com/entry/20110811/p1

Walkthrough: API Gateway and Lambda Functionsでつまづいたところ

aws documentationを読む

初めてAWSを使うことになった. Amazon API Gatewayを使って、サーバー不要で、AWS Lambdaで作成したfunctionを実行することにした. awsのドキュメントのWalkthrough: API Gateway and Lambda Functionsの通りやれば、だいたい試したいことはできた。 http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/getting-started.html

Lambdaの画面でつまづいた

上記のドキュメント(Walkthrough: API Gateway and Lambda Functions)は古いためか、最新のLambdaの画面と対応していないようで、所々、どこをクリックすればいいかわからなかった.

まず、To create the GetHelloWorld Lambda functionに

12. In the pop-up window, choose Edit or test function.

13. For Sample event, replace any code that appears with the following code:

と記載されているが、私のLambdaの画面にはEditやtest functionがなかった. どうやら、Action --> Configure sample eventとやるようだ. f:id:AngusYoung:20150801192350p:plain

また、

14. Choose Invoke. Execution result shows {"Hello": "World"}, which is also written to the CloudWatch logs.

と記載されているが、Invoke は私のLambdaの画面にはなかった. こちらは、InvokeではなくTestを選択する. すると画面下部にresultが表示される. f:id:AngusYoung:20150801192508p:plain

Ethernetインターフェースを指定してソケットを作成する (Raspberry Pi)

Ethernetのソケット作成

LinuxEthernetインターフェースを使ってソケット通信する場合、以下のようなコードを書くことでソケット通信の準備ができる.

    deststr = IP_ADDRESS; //接続先のIPアドレス #define IP_ADRESS ("192.168.0.12")
     /* ソケットを生成 */
     if((*sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
     {
          printf("fail to create socket\n");
          return -1;
     }

     /* 接続先サーバのアドレス構造体の作成 */
     memset(&server, 0, sizeof(server));
     server.sin_family = PF_INET;
     server.sin_addr.s_addr = inet_addr(deststr);
     server.sin_port = htons(PORT);

     /* 接続処理 */
     if(connect (*sock, (struct sockaddr *)&server, sizeof(server)) < 0)
     {
          printf("fail to connect\n");
          return -1;
     }

ただ、このコードだと、複数Ethernetインターフェースある場合、自動で1つのEthernetインターフェースが使われることになる.例えば、"eth0", "eth1"と二つのEthernetインターフェースがあったとき、自動で"eth0"のインターフェースを使ったsokcetが作成される.

"eth1"のsokectを作成したい

ここで、"eth1"のインターフェースを使ったsokcet通信がしたい場合は、setsockopt関数でインターフェースを指定してやればいい.setsockopt()はソケットの生成socket()と接続処理connect()の間で呼び出す.

    deststr = IP_ADDRESS; //Set IP address
     /* ソケットを生成 */
     if((*sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
     {
          printf("fail to create socket\n");
          return -1;
     }

     /** For usb-ehternet converter **/
     char *opt;
     opt = "eth1";
     setsockopt(*sock, SOL_SOCKET, SO_BINDTODEVICE, opt, 4);

     /* 接続先サーバのアドレス構造体の作成 */
     memset(&server, 0, sizeof(server));
     server.sin_family = PF_INET;
     server.sin_addr.s_addr = inet_addr(deststr);
     server.sin_port = htons(PORT);

     /* 接続処理 */
     if(connect (*sock, (struct sockaddr *)&server, sizeof(server)) < 0)
     {
          printf("fail to connect\n");
          return -1;
     }

参考 : http://stackoverflow.com/questions/3998569/how-to-bind-raw-socket-to-specific-interface

ルートで実行しないとダメ

しかし、上記のコードでも"eth1"のインターフェースで通信できなかった. 参考に挙げたぺーたをよくよく読んでみると、

SO_BINDTODEVICE only works if you run as root, right? (on Linux at least) –  sep332 Nov 27 '12 at 21:29

とコメントされている. つまりroot権限で実行しないといけないようだ. sudoで実行することで、無事に"eth1"のインターフェースで通信できるようになった.

mbedでシリアル通信のstop bitを2bitにする方法

UARTのstop bitを2にしたい

開発しているマイコンの通信確認相手にmbedを使うことがあります. すぐに通信を記述できて、結果を簡単にPCに表示できるので便利です.今回、シリアル通信の仕様でstop bitが2bitの場合に、mbedのプログラムどう記述すればいいかメモします.

name.format(bits, parity, stop_bits) で OK

記述は簡単でした.name.format(bits, parity, stop_bits)のstop_bitを2にするだけでした. "1回の通信が8bit / パリティビットなし / stop bitが2bit"のUARTの場合は以下のようになります.

#include "mbed.h"        
Serial uart(p28, p27);

int main() {    
    //serial setting
    uart.baud(19200); 
    uart.format(8, Serial::None, 2);

参考 : https://developer.mbed.org/users/okini3939/notebook/Serial_jp/

Raspberry PiでMicro SDカードが壊れたときの対処方法

Kernel panic発生

Raspberry Pi2 Model Bで開発していると、シャットダウン --> USB電源抜く --> USB電源入れる --> Kernel panic になってしまうことが発生. kernel panic (Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,2)) すごく悲しいこの事態への対処方法ををメモします.

fsck.fatで修復

対処の手順としては

  1. VMwareを立ち上げる
  2. Micro SDをVMwareに認識させる
  3. fsck.fatコマンドで修復

まずWindowsでは修復できないようのなで、Linuxで修復します.おそらくWindowsではデフォルトで見えない領域を修復しないといけないからだと思います.

VMwareを立ち上げます. 自分が使っているLinuxディストリビューションはXubuntu14.04. VAIO Pro 13ではMicro SDをSDカードアダプタに入れて、VAIO Pro 13のSDカードスロットに入れてもVMwareでMicro SDカードを認識することができませんでした. なので、ELECOMのUSBマルチメディアリーダーをVAIO Pro 13のUSBに接続し、メディアリーダーにSDカードを接続することでMicro SDをVMwareに認識させることができました. まず、Micro SDがどのdevに割り当てられているか確認します.

hogehoge@ubuntu:~$ dmesg | tail
[ 8002.324262] sd 34:0:0:1: Attached scsi generic sg4 type 0
[ 8002.327772] sd 34:0:0:0: [sdb] Attached SCSI removable disk
[ 8002.392444] sd 34:0:0:1: [sdc] Attached SCSI removable disk
[ 8203.563956] sd 34:0:0:1: [sdc] 15759360 512-byte logical blocks: (8.06 GB/7.51 GiB)
[ 8203.572055] sd 34:0:0:1: [sdc] No Caching mode page found
[ 8203.572060] sd 34:0:0:1: [sdc] Assuming drive cache: write through
[ 8203.592378] sd 34:0:0:1: [sdc] No Caching mode page found
[ 8203.592383] sd 34:0:0:1: [sdc] Assuming drive cache: write through
[ 8203.595436]  sdc: sdc1 sdc2
[ 8208.144829] EXT4-fs (sdc2): mounted filesystem with ordered data mode. Opts: (null)

/dev/sdcに割り当てられていることがわかります. Ubuntu系ではSDカードなどのメディアを認識すると、自動でmountします. これをumountしておきます.

hogehoge@ubuntu:~$ sudo umount /dev/sdc*
umount: /dev/sdc: not mounted

そしてfsck.fatで修復.自分の場合は毎回/dev/sdc1が壊れるので、/dev/sdc1を修復します. 場合によっては/dev/sdc2を修復しないといけないこともあるかもしれません.

hogehoge@ubuntu:/media/hogehoge$ sudo fsck.fat -V /dev/sdc1
fsck.fat 3.0.26 (2014-03-07)
0x25: Dirty bit is set. Fs was not properly unmounted and some data may be corrupt.
1) Remove dirty bit
2) No action
? 1
Starting check/repair pass.
Starting verification pass.
Perform changes ? (y/n) y
/dev/sdc1: 54 files, 2428/7161 clusters

最後にもう一度fsck.fatして、corruptの警告がでなかればOKです.

hogehoge@ubuntu:/media/hogehoge$ sudo fsck.fat -V /dev/sdc1
fsck.fat 3.0.26 (2014-03-07)
Starting check/repair pass.
Starting verification pass.
/dev/sdc1: 54 files, 2428/7161 clusters

メモ

  • ググると、「fsckで修復」というのがすぐに見つかったが、なぜか自分はfsckではダメで、fsck.fatだとうまく修復できた.
  • raspberry piを終了するときはsudo shutdown -h nowで終了しているのだが、次回起動でkernel panicになることがある.