1 of 139

ウェッブエンジニアの

ローレベル

プログラミング

cho45

2 of 139

自己紹介

www.lowreal.net 仕事はウェブ(Perl, JavaScriptなど)

3 of 139

今回の内容

  1. ARM assembly のススメ
  2. ハードウェアプログラミング
  3. さらにローレベルへ

どんどこ掘っていく感じで

4 of 139

ウェッブアプリ

5 of 139

JavaScript

Perl / Ruby

HTML, CSS

6 of 139

生まれたときから

7 of 139

Lightweight

Language

は自然にあった

8 of 139

参考:

Perl : 1987年生(12月)

cho45: 1987年生(1月)

9 of 139

C言語

言語バインディング用

にしか書かない

10 of 139

一方で

11 of 139

某スーパークリエイター

「なんかドライバなかったから

書いた」

12 of 139

すごい人は下から上まで全部できる

13 of 139

こんな経験はありませんか?

  • アセンブラ読めないし目をそむける
  • レジスタって何
  • 教科書の「こんぴゅーた の しくみ」�と現実のコンピュータとが一致しない
  • リンカって実際何するの?

14 of 139

ARM/Linux 用のアセンブリのススメ

なぜ ARM/Linux か?

  1. x86 と比べて命令数がだいぶ少ない
  2. スマフォはだいたいARM Linux / Raspberry Pi も
  3. レジスタ名が大変わかりやすい�r0〜r15 32bit レジスタ
  4. Linux 上で動かせばデバッグしやすい

15 of 139

参考:ARM 実機がない場合

ARM Linux EABI / QEMU http://lowreal.net/2014/03/15/2

実機なしでも QEMU で簡単に環境をつくれます

16 of 139

ARM のアーキテクチャ

  1. 基本 32bit 固定命令長 (16bitのモードもある)
  2. 演算は常にレジスタ対象�ロード/ストアアーキテクチャ�メモリを操作する命令は ldr/str のみ
  3. 殆ど全ての命令に条件を設定できる�cmp (比較命令) → 条件付の任意の命令(加算とかジャンプとか)�ARM の特徴的な仕様
  4. 命令一覧はググったら出てくる�結局、命令セットさえ簡単に検索できればコードは読める

17 of 139

Linux ABI

ABI とはバイナリレベルでのOSとアプリ間の規則のこと

  • スタックはどうつむか?
  • システムコールはどう呼ぶか?

などを定めている。

18 of 139

ARM Linux ABI

  • ARM OABI (Old ABI)
  • ARM EABI (Embed ABI)

の2つがある。

システムコールの呼びかたとかが普通に違ってる

EABI だけに言及します。

19 of 139

exit するだけのプログラム

20 of 139

obj-dump

21 of 139

gdb でアセンブリもデバッグ可能

  1. as --gstabs+ foo.s でコンパイル
  2. gdb foo で起動
  3. info registers でレジスタの値が見れる

22 of 139

簡単!!

23 of 139

しかし何か作る目標がないと

学習のやる気がでない

24 of 139

アセンブリで何を書くか?

25 of 139

ウェブエンジニアなら

26 of 139

ブログツール

27 of 139

簡易 blosxom

ディレクトリを走査し、�テンプレートに従ってHTMLで表示するだけの CGI

アセンブリで書いたものが�ブラウザ上に出てくるのがおもしろい

28 of 139

みちのり

29 of 139

getenv

CGI 書きたいなら必須

Linux におけるメモリ上のプロセスイメージを知らないと書けない

getenv というシステムコールはない

ref. http://lowreal.net/2014/03/15/1

30 of 139

プロセスイメージ

← こういうの

←←←←←← 環境変数はココ!!

31 of 139

getdents

簡易 ls を書く

open/close など含めファイル関係になじむ

低レベルなディレクトリ構造体をいじる

ref. http://lowreal.net/2014/03/16/1

32 of 139

sbrk/mmap

動的なメモリ確保

メモリにより親しむ

malloc の実装の違いを意識するように

おもしろい

ref. http://lowreal.net/2014/03/17/2

33 of 139

← この部分

メモリ確保せずにアクセスすると

いわゆる SEGV する

34 of 139

その他細かいこと

ファイル読みこみ

文字列置換

数値文字列化

割り算の実装

(ARM にはかなり新しくないと割り算命令がない)

35 of 139

36 of 139

得られたこと

  • アセンブリへの親しみ
  • レジスタへの親しみ
  • CPUへの親しみ
  • メモリへの親しみ
  • Linux カーネルへの親しみ
  • gdb への親しみ
  • リンカへの親しみ

37 of 139

コンピュータへの親しみ!!!

38 of 139

ARM アセンブリオススメです!!

39 of 139

結局書いてみないとわからない

40 of 139

ARM の情報源

41 of 139

第1部

42 of 139

第2部

ハードウェアプログラミング

43 of 139

昨今のコンピュータは

外部インターフェイスが RS-232C やプリンタポートから

USB や Thunderbolt などに移り変わり

気軽に使えるとはいいがたいものになった。

我々は長らく、ソフトウェアから気軽に�ハードウェアへアクセスする手段を奪われていた。

44 of 139

 Raspberry Pi 

45 of 139

スペックの低いパソコン�安い (4000円ぐらい)

46 of 139

そこが重要ではない

47 of 139

GPIO

48 of 139

General Purpose

Input Output

49 of 139

GPIO ↓↓

50 of 139

奪われていた

Input / Output

51 of 139

GPIO ↓↓

52 of 139

GPIO ↓↓

53 of 139

echo “high” > /sys/class/gpio/gpio23/direction

54 of 139

55 of 139

とりもどした

56 of 139

ファイルシステム経由で

GPIO ピンの論理を変更できる

0V ←→ 3.3V

57 of 139

ただし余り電流を流せないので、

電子回路の知識が必要

“トランジスタ スイッチング” とか

“FET スイッチング” とかでググる

Raspberry Pi は 3.3V

1ピン最大16mA / トータルで最大50mA

参考: 赤LED1つで10〜20mA程度

58 of 139

もっと簡単に楽しむには

周辺機器とのハードウェアプロトコルを知る

59 of 139

I2C

60 of 139

61 of 139

I2C

2線式プロトコル

1つのバスを複数のデバイスで共有できる

バス上の全デバイスがマスターとなれる

いろんなモジュールが出ているので便利

繋ぐだけなので電子回路の知識は殆どいらない

(電圧だけ注意)

62 of 139

I2C デバイスの例

温度計・湿度計・気圧計・モータードライバ

キャラクタ液晶ディスプレイ

ジャイロ・時計(RTC)・デジタルコンパス

など

63 of 139

I2C 使いかた

Linux にドライバを組込めば

ファイルシステムからアクセス可能

LL で簡単にアクセス可能

どんなプロトコルか? は仕様を読む

http://www.i2c-bus.org/

機器ごとにアクセス方法が違うので

データシートを読む

64 of 139

使いかたの例: ファイルシステム (i2c-dev)

open / ioctl / read / write / close あたりを使う

簡単な書きこみ例

65 of 139

使いかたの例: ruby-i2c-devices

https://github.com/cho45/ruby-i2c-devices

i2c-dev または sysfs gpio による bit banging のラッパー

一部デバイスについては簡単に使える

  • MPL115A2 (気圧計)
  • よくある 16x2 の液晶 (だいたいプロトコルが共通)

66 of 139

ruby-i2c-devices + MPL115A2

気圧計

工場校正値を取得して、ちょっと計算する必要がある

ライブラリで隠蔽してるので

すぐ hPa (ヘクトパスカル) とれる

67 of 139

I2C と GPIO

を使えれば楽にいろいろできる

その他のキーワード: SPI, Serial (RS-232C)

68 of 139

ところで

最近は Arduino というのもきく

69 of 139

Raspberry Pi と Arduino の違い

Raspberry Pi

CPU: 32bit ARM 700MHz

メモリ: 512MB

OS: Linux

スペック低いパソコン

Arduino

CPU: 8bit AVR 16MHz

メモリ: 2kB (ATmega328)

OS: なし

使いやすいマイコン

70 of 139

マイコン

→ マイクロコントローラ

組み込み機器で使われる小さなコンピュータ

ファームウェアを書きこむと、基本単独で動作する

できることは少ないが、パソコンとは用途が違う

(消費電力・CPUクロック同期など)

71 of 139

Arduino は実情的には

いい感じマイコンボード + 開発環境 (IDE) + エコシステム

といえる

72 of 139

Arudino スケッチ

IDE + C like な独自文法

73 of 139

シールドと呼ばれる

外部連携ボードがいろいろ出てる

74 of 139

Arduino は

入門にはいいが、ちょっと高すぎる

1台 2000円〜3000円

謎言語みたいなの嫌い

75 of 139

なので Arduino の話は

しない

76 of 139

ところで

77 of 139

Raspberry Pi と Arduino の違い

Raspberry Pi

CPU: ARM 700MHz

メモリ: 512MB

OS: Linux

スペック低いパソコン

Arduino

CPU: AVR 16MHz

メモリ: 2kB (ATmega328)

OS: なし

使いやすいマイコン

78 of 139

Raspberry Pi と Arduino の違い

Raspberry Pi

CPU: ARM 700MHz

メモリ: 512MB

OS: Linux

スペック低いパソコン

Arduino

CPU: AVR 16MHz

メモリ: 2kB (ATmega328)

OS: なし

使いやすいマイコン

79 of 139

Raspberry Pi に

OS は必要か?

80 of 139

bare metal

81 of 139

やってみた

https://github.com/cho45/raspberrypi-bare-metal

OSレスでボード上のACT LED を点滅させる

82 of 139

こんなかんじ (Lチカ)

83 of 139

やってみた2

https://github.com/cho45/raspberrypi-mruby-bare-metal

mruby を OS レスで直接動かし、

GPIO を操作

→ LL が直接ボードで動いている

84 of 139

こんな感じ

GPIO オブジェクトは

自作ライブラリ

このコードは直接Raspi上で

インタプリトされる

(mrubyのバイトコードで)

mruby 拡張書きやすくて最高

85 of 139

実際に動かしてみるとおもしろい

ARM アセンブリの知識が生きます

86 of 139

ただ、開発が大変…

キーワード: (JTAG, オンチップデバッグ)

87 of 139

得られたこと

  • Linux カーネルへの親しみ
  • OS ブートプロセスへの親しみ
  • リンカへの親しみ
  • ナマで自分のコードが動く喜び

88 of 139

第2部まとめ

  • Raspberry Pi はおもしろい
  • I2C なモジュールとの組合せは超簡単
  • ハードウェア入門に最適
  • OS レスで動かすのもワクワク体験

89 of 139

第2部

90 of 139

第3部

91 of 139

もっとローレベルへ

92 of 139

Raspberry Pi

I/O を解放した

93 of 139

しかし

94 of 139

我々は

まだ

囚われている

95 of 139

第3部

〜ホストコンピュータからの《解放》〜

96 of 139

Arduino は単体でも動く

97 of 139

中身は AVR というワンチップマイコン

電源があれば単体で完全に動く

98 of 139

AVR

  • ハーバードアーキチェクチャ�プログラムとデータはわかれている�データを実行することはできない
  • SRAM (メインメモリ)
  • EEPROM (不揮発性外部記憶)
  • クロックも組み込み (128kHz/1MHz/8MHz)�外付け水晶発振子で20MHzぐらいまで
  • クロック単位で同期したりするのが得意�(Raspi とかとは用途が違う)

99 of 139

Arduino なんか捨てろ!!!

100 of 139

ATmega328P 250円

ATmega168P 200円

ATTiny2313 150円

ATTiny13A 50円

101 of 139

いろいろあって楽しい

102 of 139

ただし初期費用としてライターに金がかかる

(3200円ほど)

チップ側と指定通り結線し、�USB経由で書きこむためのインターフェイス

もっと安くあがる方法もあるが

無難にこれぐらい買っといたほうがいい

Mac で問題なく開発可能です

103 of 139

普通にCで開発可能

gcc

ただしコードサイズやメモリはそこそこ厳しい

gcc

普通のエディタで開発

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc gcc

104 of 139

コンパイル

書きこむ

動かす

をループして開発

105 of 139

Raspberry Pi と違い

1ピン 40mA まで出力できる

ATmega 系なら I2C 装備

106 of 139

こんな感じのコード (Lチカ)

107 of 139

Raspberry Pi ではできないことも…

  • ADC (Analog Digital Converter)�AVR にはだいたいついている�アナログ信号をサンプリングしてデジタル化する回路�(電圧計)

アナログセンサーを読みたいときには必須

ただ、使いこなすにはアナログ回路の知識が必要

108 of 139

初期につくってみたもの

エレキー (for Ham Radio)

モールス符号を正確に打ちだすための

補助装置

1:3 の符号を正確に出力する

出力がただのon/offなので習作に最適

109 of 139

こういうの

https://www.youtube.com/watch?v=rqAvbTJpZzs

(これの最初の方、右手で操作しているのがパドル、パドルの操作に応じて符号が自動で出力される)

110 of 139

いくつか作った

  • オーソドックスなもの
  • 低消費電力にこだわったもの
  • 小さくボタン電池で動くようにしたもの

このぐらいの回路だと全部品の挙動を理解しながら作れる

111 of 139

112 of 139

113 of 139

コード書いた結果が

直で消費電力に直結する

プログラミング

114 of 139

電流計る

コード変える

電流変わる

ウケる

115 of 139

基本CPUを使いきることしか考えてない

いかにCPUを使わないかという新鮮さ

116 of 139

プログラマなら

マイコン使いこなすのも簡単

世界が広がっておすすめです

117 of 139

自由を手にし身軽になった身体で

再びホストコンピュータと出会う

118 of 139

I2C を使えば Raspberry Pi とは簡単

119 of 139

しかし Raspberry Pi からも解放されたい

120 of 139

AVR で USB デバイス

121 of 139

USB 対応の AVR もあるが

V-USB (GPL) で安いAVRを

USB 対応にできる

122 of 139

作ってみた: 振動するだけのマウス

接続するとポインタが震えるだけ

V-USB のサンプルをちょっといじっただけ

一瞬でできる

123 of 139

こういうの

124 of 139

V-USB 用のスケルトン

125 of 139

周辺機器も自由に作れるようになり

完全に解放…

126 of 139

しかし

127 of 139

まともな周辺機器を作るには

電子工学の知識が必須

128 of 139

必要な知識

  • オームの法則 (V=IR)
  • 半導体 (ダイオード・トランジスタ・FET)

デジタル回路中心なら覚えることは少ない

129 of 139

プログラムの考えかたを活かす

  • データシート(仕様書)読む
  • 問題の切り分け
  • モジュール化
  • 信頼性設計

→ ほとんどプログラム書くのと変わらない

ルールが物理ベースになっただけ

130 of 139

勉強中

131 of 139

完全解放までの道程は遠い

132 of 139

つづく…

133 of 139

まとめ

  • ARM アセンブリおすすめ
  • Raspberry Pi があるといろいろできる
  • AVR も覚えると夢が広がる
  • USB デバイスが作れるようになると夢が広がる
  • 回路設計もできると夢が広がる

134 of 139

電子回路も

プログラムと同じように

学べば学ぶほど実になる分野

135 of 139

最近は個人でハード設計もしやすい

基板外注

3Dプリンタ

など

136 of 139

プログラミング初めたころのように

「毎日できることが増える!」という体験を

もう一度したいならオススメです

137 of 139

外注自作基板に部品のせたところ

138 of 139

まずは…

RaspberryPi + I2C モジュール

次に

Arduino または AVR

欲を出して

回路・基板設計

139 of 139

広告

電子工学学ぶついでに、

アマチュア無線を初めました

(コールサイン JH1UMV)

twitter: @JH1UMV

モールスの練習をしておりますので

よろしくお願いします