Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Lisp Meet Up #25, 8-bit PIC マイコン用ネイティブコンパイラの作成

2,951 views

Published on

Introducing a native compiler for 8-bit PIC micro controllers written in Common Lisp.

Published in: Technology
  • Be the first to comment

Lisp Meet Up #25, 8-bit PIC マイコン用ネイティブコンパイラの作成

  1. 1. 8-bit PIC マイコン用ネイティブコンパイラの作成 2015.2.25 Masayuki Takagi Lisp Meet Up presented by Shibuya.lisp #25
  2. 2. © 2015 Masayuki Takagi -2- 自己紹介 高木 雅之 cl-cuda : a library to use NVIDIA CUDA in Common Lisp Common Lisp から CUDA を使うライブラリ。半年ほどまえに、ここで紹介しました。 仕事は? 先月に会社を設立。売上はまだないです >_< Common Lisp
  3. 3. © 2015 Masayuki Takagi -3- 8-bit PICマイコン向けネイティブコンパイラ:動機 これまで、まともにアセンブラを書いたことがなかったのです。 1月下旬:はじめての PIC マイコン 2月上旬:はじめてのアセンブラ PIC マイコンをはじめて触りました。 PIC で何作ろう?PIC用のコンパイラ作ろう。 2月中旬:PIC 用のコンパイラ
  4. 4. © 2015 Masayuki Takagi -4- 今日の話の流れ そのあと、今回作った、PIC マイコン用のコンパイラについて説明します。 PIC マイコンについて PIC マイコン用コンパイラについて 最初に、PIC マイコン自体について説明します。
  5. 5. © 2015 Masayuki Takagi -5- PIC マイコンとは? いまだと Arduino とかありますが、PIC はそれより昔からよく使われています。 マイクロコントローラ マイクロチップ・テクノロジー社 演算器、メモリ、発振回路、割り込み、タイマ、リセット、スリープなど 各種回路が1チップに。 今回使ったのは、一番小さな 8 ビット PIC。PIC12F683 や PIC16F630。 8ビット、16ビット、32ビット
  6. 6. © 2015 Masayuki Takagi -6- ピン PIC12F683(8ピン) PIC16F630(14ピン) VDD  上2本(VDD, VSS)を電源に接続  残り6本を IO に使用可能(HI/LOW)  ただし、4番ピンは入力のみ GP5 GP4 GP3 VSS GP0 GP1 GP2 VDD VSS RA5 RA4 RA3 RC5 RC4 RC3 RA0 RA1 RA2 RC0 RC1 RC2  上2本(VDD, VSS)を電源に接続  残り12本を IO に使用可能(HI/LOW)  ただし、4番ピンは入力のみ
  7. 7. © 2015 Masayuki Takagi -7- PIC12F683  プログラムメモリは、2K ワード  SRAM は、128 バイト  DDPROM は、256 バイト
  8. 8. © 2015 Masayuki Takagi -8- PIC12F683 デバイス概観  ALU  乗算器、FPU、16ビット演算器はない  プログラムメモリとデータメモリ  ハードウェアスタック
  9. 9. © 2015 Masayuki Takagi -9- メモリアーキテクチャ  プログラムメモリとデータメモリが分離(ハーバード・アークテクチャ)  プログラムメモリには、専用の機器でプログラムを書き込む  プログラムからプログラムメモリを操作することはできない データメモリプログラムメモリ
  10. 10. © 2015 Masayuki Takagi -10- プログラムメモリ  プログラムメモリは 2048 ワード(000h-07FFh)  プログラムは 0 番地から始まる  4 番地は割り込み発生時にここにジャンプ  ハードウェアスタックを持つ  CALL 命令などで、戻り値アドレスが積まれる
  11. 11. © 2015 Masayuki Takagi -11- データメモリ  データメモリは、SFR と GPR からなる  SFR は、Special Function Registers  GPR は、General Purpose Registers  SFR は、CPU やその他機能の制御に使う  残念なことに、番地により「バンク」を切り替え なければならない SFR 汎用 レジスタ SFR 汎用 レジスタ バンク0 バンク1 00h 20h 80h A0h BFh 7Fh
  12. 12. © 2015 Masayuki Takagi -12- スペシャル・ファンクション・レジスタ  SFR は、CPU やその他機能の制御に使う  STATUS は、バンク切替(RP0)、ゼロビット(Z)、キャリー ビット(DC,C)など  GPIOは、ピンの状態(High/Low)  TRISIOは、ピンの入出力モード  PCL と PCLATH は、プログラムカウンタ  INTCON と IOC は、割り込みの有効/無効
  13. 13. © 2015 Masayuki Takagi -13- W レジスタ  ALU は、W レジスタとデータメモリから 入力を受け付ける  通常の CPU の「レジスタ」に相当  ただし、1つしかない W レジスタ レジスタ データメモリ メモリ EEPROM ストレージ PIC マイコン 通常のCPU 記憶装置の対応
  14. 14. © 2015 Masayuki Takagi -14- 内蔵発振回路  発振回路を内蔵  デフォルトの周波数は、4MHz ±1%  1命令サイクル = 4クロック = 1μsec
  15. 15. © 2015 Masayuki Takagi -15- 命令セット ADDWF ANDWF CLRF CLRW COMF DECF DECFSZ INCF INCFSZ IORWF MOVF MOVWF NOP RLF RRF SUBWF SWAPF XORWF BCF BSF BTFSC BTFSS ADDLW ANDLW CALL CLRWDT GOTO IORLW MOVLW RETFIE RETLW RETURN SLEEP SUBLW XORLW  命令は35種類のみ。非常に簡単  要する命令サイクルは、1サイクル(=1μsec@4MHz)  ただし、CALLや条件分岐などは、2サイクル
  16. 16. © 2015 Masayuki Takagi -16- ちょっと面倒  何をするにも、単一の W レジスタを要するので、ちょっと面倒  データのムーブ(R0番地からR1番地へデータをコピー) MOVF R0,W MOVWF R1 END  整数の加算(R0番地に 42 を加算) MOVLW 42 ADDWF R0,F END
  17. 17. © 2015 Masayuki Takagi -17- コンパイラの概要  ホスト言語は、ML 系言語の本当に小さなサブセット  ターゲット言語は、8-bit PIC マイコンのアセンブリ  コンパイラ言語は、Common Lisp  コンパイラの設計は、MinCaml を参考にした(MinCaml ですみません…)
  18. 18. © 2015 Masayuki Takagi -18- MinCaml とは?  http://esumii.github.io/min-caml/
  19. 19. © 2015 Masayuki Takagi -19- 構文 今回のコンパイラ MinCaml 定数 プリミティブ演算(+,-,*,/ など) 条件分岐 if e1 then e2 else e3 変数定義 let 変数の読み出し x 再帰関数定義 let rec 関数呼び出し e e1, …, en 組の作成 (e1, …, en) 配列の作成 Array.create e1 e2 組の読み出し let 配列の読み出し e1.(e2) 配列への書き込み e1.(e2) ← e3 定数 プリミティブ演算 条件分岐 変数定義 変数の読み出し 再帰関数定義(クロージャ不採用) 関数呼び出し 組は不採用 配列は不採用 SFRへの書き込み setreg
  20. 20. © 2015 Masayuki Takagi -20- コンパイルステージ 今回のコンパイラ MinCaml 字句解析 構文解析 型推論 K正規化 α変換 β簡約 ネストした let の簡約 インライン展開 不要定義削除 定数畳み込み クロージャ変換 仮想マシンコード生成 即値最適化 レジスタ割当て アセンブリ生成 (CommonLisp のリーダを使用) (型は 8 ビット整数のみ) K正規化 α変換 β簡約 ネストした let の簡約 (最適化はあとで) クロージャ変換 仮想マシンコード生成 レジスタ割当て アセンブリ生成 (最適化はあとで)
  21. 21. © 2015 Masayuki Takagi -21- 呼び出し規約  当初、ソフトウェアスタックに積んで渡していた  間接アドレッシングが煩雑なため、方針変更  入力用疑似レジスタ(I0-I7)、ローカル用疑似レジスタ(L0-L7)  引数は、入力用レジスタに格納して、呼び出される関数に渡す  関数は、ローカル用レジスタを自由に使える  戻り値は、W レジスタに格納して返す  関数呼び出し時に、「生きているレジスタ」をスタックに退避する
  22. 22. © 2015 Masayuki Takagi -22- クロージャを不採用とした理由  クロージャには、間接アドレスへのジャンプが必要  CALL 命令は、オペランドに即値のみ受け付ける  間接アドレスへのジャンプは、プログラムカウンタへの書き込みで可能  しかし、いろいろ面倒  PCL と PCLATH  戻りアドレスの計算  戻りアドレスの管理(ハードウェアスタックを使えない)  PCL の桁上がりの考慮
  23. 23. © 2015 Masayuki Takagi -23- API  defpic  defpicmacro  pic-compile  pic-disassemble
  24. 24. © 2015 Masayuki Takagi -24- サンプル - LED (defpic init () (progn (setreg :gpio #x0) (setreg :cmcon0 #b00000111) (setbank1) (setreg :trisio #b00001000) (setreg :ansel #x0) (setreg :ioc #x0) (setbank0) (setreg :intcon #b00000000))) (defpic main () (progn (setreg :gpio #b00100000) (mdelay 50) (setreg :gpio #b00000000) (mdelay 950) (main))) (defpic mdelay1 () (loop 52 0)) (defpicmacro mdelay (n) (unless (<= 0 n 65535) (error "The value ~S is invalid." n)) (multiple-value-bind (q r) (truncate n 256) (if (= q 0) `(loop ,r (mdelay1)) `(loop ,q (loop ,r (mdelay1))))))

×