2019/04/27

[raspi]yoctoで動かしてみたい (1)

なんとなく、手持ちのRaspberry Pi ZeroWにyoctoで作ったLinuxを載せたくなった。
使わない機能を減らして動作が軽くなってくれないだろうか、という期待をしているのだが、はてさて。


といったものの、yocto自体ほとんど使ったことが無いので、こちらを参考にした。

Yocto で Raspberry Pi 用 Linux を作る - Qiita
https://qiita.com/propella/items/042b7bb361ad71f9bd7e

1年半ほど前だからか、多少違いがあった。
まあ、ログを見ればすぐ分かる程度なのだが。


mkdir yocto
cd yocto

git clone git://git.yoctoproject.org/poky
git clone git://git.openembedded.org/meta-openembedded
git clone https://github.com/agherzan/meta-raspberrypi.git

source poky/oe-init-build-env rpi-build


これでrpi-buildの中にconfディレクトリができるので、Qiitaの人と同じようにlocal.confを書き換え。
私は、

MACHINE = "raspberrypi0-wifi"

だけ変更。


bblayers.confも同じようにやるのだが、meta-openembeddedの中にlayerがあるので、そっちを追加する。
BBLAYERSだけ、こうした。本家に4つ書いてあるから、4つ追加すればいいんだろう。

BBLAYERS ?= " \
  /home/xxx/yocto/poky/meta \
  /home/xxx/yocto/poky/meta-poky \
  /home/xxx/yocto/poky/meta-yocto-bsp \
  /home/xxx/yocto/meta-openembedded/meta-oe \
  /home/xxx/yocto/meta-openembedded/meta-multimedia \
  /home/xxx/yocto/meta-openembedded/meta-networking \
  /home/xxx/yocto/meta-openembedded/meta-python \
  /home/xxx/yocto/meta-raspberrypi \
"


そして、bitbake

bitbake core-image-base



私はVirtualBox上でやっているのだが、非常にマシンが重たくなる。


rpi-build/tmp/deploy/images/raspberrypi0-wifi/rpi-basic-image-raspberrypi0-wifi-20190427023702.rootfs.rpi-sdimg

サイズは130,023,424byte。124MBらしい。

ddすればいいそうだが、よくわからんのでQiitaの人をまねした。


そして、UARTをつないで起動させたのだが、何も出ない・・・。
今日は力尽きたので、ここまで。

2019/04/21

[c/c++]きっちり3文字だけ入力したことを確認する

C/C++を使って長いものの、標準出力とか標準入力には、疎い。
特に、標準入力は使う機会がほとんどなかったので、あまり理解していない。


さて、今、Linuxで標準入力から文字を入力させ、その内容をチェックして処理を進める、ということをやろうとしている。
"YES"と入力した場合だけ進める、ということにしよう。


まずはシンプルに。

01: #include <stdio.h>
02: #include <string.h>
03: 
04: int main(void)
05: {
06:     char prompt[20];
07:     scanf("%s", prompt);
08:     if (strcmp(prompt, "YES") == 0) {
09:         printf("YES !\n");
10:     } else {
11:         printf("no\n");
12:     }
13:     return 0;
14: }

問題点は、大きく2つ。

  • スペースが入ると、その前までしか評価されない
  • バッファサイズよりも大きい文字列が入力できてしまう


前者は、たとえば"YES ?"のように半角スペースを間に挟むと、その手前までしか評価されないということだ。
これはどちらかというと、bashとかそういう環境に依存しているんじゃなかろうか。

後者は、"YESSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"なんて入力すると、バッファが20しかないので死んでしまう、というやつだ。
%sの方でしばることもできるが、何にせよ前者の方が対処できない。


調べてみると、fgets()で標準入力を取り込む作戦がよく出てきた。

ただ、このfgets()、改行コードもそのまま取り込むようだ。
strlen()で\0の前に改行コードがあるはず、という前提にしようかと思ったが、それなら改行コード込みでmemcmp()でもいいんじゃなかろうか。

01: #include <stdio.h>
02: #include <string.h>
03: 
04: int main(void)
05: {
06:     char prompt[5];
07:     fgets(prompt, sizeof(prompt), stdin);
08:     if (memcmp(prompt, "YES\n", 4) == 0) {
09:         printf("YES !\n");
10:     } else {
11:         printf("no\n");
12:     }
13:     return 0;
14: }

まあ、4を直接書くのは嫌だから、YESの文字列をマクロにしてsizoef()-1するとかか。

2019/04/20

[python3]文字列の%dみたいなやつは{}になった

最近、テストコードをpython3で書いている。
python3だ、とわざわざ言わないと、以前のようにpython2の期限が近づいていることを忘れてしまうかもしれない。
なるべく「python3」と明記するようにしよう。


それはともかく、私がやっていることはそんなに難しいことではない。
JSON-RPCのインターフェースがあって、python3のAPIが準備されているので、それを呼び出すだけだ。


私の近況はともかく、APIを実行したら、何か結果を出したい。
そして今回は、単に標準出力に出せば良い。
となると、print()だ。
python2であれば制御命令みたいな使い方をされていたが、python3では関数っぽい使い方になった。
まあ、C言語を使っている身としては、そちらの方が自然な気がする。


で、今のところ結果を出力するのに、

print('result=' + val)

だったり、

print(('result: val1=' + val1 + ', ' val2=' + str(val2))

みたいな書き方をしている。

問題は無いのだが・・・リプレースメントというか、C言語のprintf()で言うところの%dや%sみたいな代替文字を使って出力手段があったことは覚えている。

今が、それを使うときだ!


https://docs.python.org/ja/3.6/library/string.html#format-string-syntax
print()特有というよりは、文字列操作の一環なのだろう。
str.format()というのがそれっぽい気がするのだが・・・複雑すぎやしないかい?


あまり難しく考えなければ、arg_nameに数字を使って、波括弧の中にarg_nameを書いて、その順番に並べればいいんじゃなかろうか。

01: hello = 'hello'
02: world = 'world'
03: 
04: print('{0} {1}'.format(hello, world))

hello world

おお、動いた。


これはこれでいいとして、python2のときは%とか使ってた気がする。
あれは、python3では使わなくなったのだろうか?

https://docs.python.org/ja/3/library/string.html#format-examples

「従来の%-書式」とか「古い%-書式」とか書いてあるので、python3だけ覚えておきたいなら気にしなくてよいんだろう。


昔は、このリプレースメントみたいな引数の順番を出力側のフォーマットで入れ替えできる意味が分かってなかったのだけど、多言語化でどうしても語順が入れ替わる場合なんかに有用なのだということに気付いてから、真面目に理解すべきだと考えるようになった。

まあ、いつもログ出力とか、ちょっとした計算結果とかでしか使わないから、+で文字列をつなぐだけのことが多いのだけどね。。。