狠狠撸

狠狠撸Share a Scribd company logo
/15
MikanOSと自作CPUを
USBで接続する
2022年7月23日
自作OSもくもく会
@uchan_nos
1
/15
もくじ
?発表のコンセプト:
自作CPUのアーキテクチャ、MikanOSとの接続部分、CDCドライ
バの詳細を、ソフト?ハード両面から伝える
?自作CPUをMikanOSにつなげたい!
?自作CPUのアーキテクチャ
?自作CPUに機械語を送る
?USB CDCクラスドライバを作る
?CDC ACMのボーレート設定
?今後MikanOSに搭載したい機能
2
/15
自作CPUをMikanOSにつなげたい!
?「自作CPU」
?ComProc(Compiler+Processor自作)プロジェクトで
作ってるCPU
?独自の命令体系、アーキテクチャを持つ
?UART(シリアル通信)にて機械語プログラムを受信し
て実行できる
?MikanOS
?「ゼロからのOS自作入門」で作るOS
?USBマウスとキーボードのドライバを搭載
?USBシリアル変換で両者を接続できるのでは?!
3
/15
自作CPUのアーキテクチャ
コール
スタック
メインメモリ
(FPGA内蔵BRAM)
0x000
0x200
0x3ff
機械語
プログラム
PC
ALU
FP
アドレス
insn[15:0]
0
1
…
15
演算用スタック
(16ビット幅)
読み出しデータ
BP
書き込みデータ
CPUコア
UART
送受信
RX
TX
機械語
書き込み
4
/15
命令体系
1+2;
C言語
PUSH 1
PUSH 2
ADD
アセンブラ
0001
0002
B002
機械語
機械語パターン 命令
0iii iiii iiii iiii imm15のPUSH
1011 0000 iiii iiii 2項演算命令、imm8はALU機能選択
x
x
x
x
1
x
x
x
2
1
x
x
3
x
x
x
演算用スタックの変化
PUSH 1 PUSH 2 ADD
5
/15
命令デコードと信号線
PUSH imm15
ADD
LD imm8
ST imm8
STA
JMP imm8
ニーモニック
xxxx
B002
90xx
94xx
9500
A0xx
機械語 機械語上位8ビットのデコード後信号
1_10_00_01_00_0_00_00
0_10_00_10_00_0_00_00
1_11_10_01_00_0_00_00
1_01_01_10_00_0_00_00
0_00_01_10_00_0_00_00
1_00_00_00_01_0_00_00
Imm 1=即値命令
Load 0=stack[0] 1=stack[1]、
2=ALU出力 3=メモリ
R 1=メモリ読込
W 1=メモリ書込
Pop 1=演算用スタックからポップ
Push 1=演算用スタックにプッシュ
Jmp 0=ジャンプしない、1=無条件
addr
data
a
b
addr
a
b
x
Load=0 & Pop=1
6
/15
自作CPUに機械語を送る
?自作CPUはUARTで機械語を受け取る
?自分のパソコンにはシリアル端子が無い
?→USBシリアル変換をかませよう
?MikanOSにはUSBバスドライバが搭載済み
?USBシリアル変換機器用のCDC ACMクラスドラ
イバを作ればOK
パソコン
USBホスト
自作CPU
UART端末
USBシリアル
変換機器
xHCIドライバ
USBバスドライバ
クラスドライバ
PCIバスドライバ PCIバスの制御を担当
ホストコントローラの初期化や駆動
USB仕様に則ったAPIを上位側に提供
機器固有の処理を担当
7
/15
接続対象のUSBシリアル変換機器
?AE-PIC18F14K50
?USB機能が搭載されたPICマイコンボード
?ここにUSBシリアル変換プログラムを書き
込んで使う
?TX端子電圧=5V
?FT231XS搭載USBシリアル変換アダプタ
?USBシリアル変換の専用機器
?TX端子電圧=3.3V
5V
0V
0xA2
Start Stop
3.3V
0V
0xA2
Start Stop
8
/15
ちょっと脱線:レベル変換
?AE-PIC18F14K50のTX端子電圧=5V
?Tang Nano 9KのIO端子(Bank 1,2)の入力
電圧範囲は-0.3V~3.6V
?直接繋ぐとTang Nano 9Kが壊れる
?→レベル変換回路を間に挟む
自作CPU
UART端末
TX端子の出力電圧=5V
RX端子の許容電圧=3.6V
Nch MOSFETを用いた
双方向レベル変換回路
AE-PIC18F14K50
9
/15
USB CDCクラスドライバを作る
?CDC: Communication Device Class
?電話回線やイーサネットなどでの通信を行うデバイ
スを包括するクラス
?ACM: Abstract Control Model subclass
?ATコマンド(電話をかけたり切ったりするコマン
ド)で制御できる機器
xHCIドライバ
USBバスドライバ
クラスドライバ
PCIバスドライバ
USB
ホスト
USB
デバイス
Endpoint 0
Endpoint x
Endpoint y
Communication Class interface: 機器の管理と発信(call)の管理
Data Class interface: データの送受信
10
/15
CDCドライバの実装(簡易版)
Error CDCDriver::SendSerial(const void* buf, int len) {
uint8_t* buf_out = new uint8_t[len];
memcpy(buf_out, buf, len);
ParentDevice()->NormalOut(ep_bulk_out_, buf_out, len);
uint8_t* buf_in = new uint8_t[8];
ParentDevice()->NormalIn(ep_bulk_in_, buf_in, 8);
return MAKE_ERROR(Error::kSuccess);
}
int CDCDriver::ReceiveSerial(void* buf, int len) {
const auto recv_len =
std::min(len, static_cast<int>(receive_buf_.size()));
auto buf8 = reinterpret_cast<uint8_t*>(buf);
for (int i = 0; i < recv_len; ++i) {
buf8[i] = receive_buf_.front();
receive_buf_.pop_front();
}
return recv_len;
}
Out方向のエンドポイント
でデータを送信する
In方向のエンドポイント
に対し受信をかけておく
デバイスからデータが
受信されていれば
receive_buf_に
データが書かれている
11
/15
クラスドライバの動作の様子
?2つのインターフェースが認識されている
?Communication/Data Class interface
?Data Class interface用に2つのエンドポイント
?ep_idの最下位ビットは入出力の向きを表す
?0がOut(Host→Device)、1がIn(Device→Host)
QEMU on WSL2
でMikanOSを起動
QEMUにCDC ACM
機器を接続してある
12
/15
CDC ACMのボーレート設定
?自作CPUは機械語プログラムを115.2kbpsで受信する
?Linuxが勝手にCDC ACM機器を9600bpsに設定してしまう
?QEMU起動前に sudo stty -F /dev/ttyACM0 115200 すれば解決
?CDC ACM機器のボーレートを変更するのはSetLineCoding要求
オフセット フィールド バイト数 説明
0 dwDTERate 4 ボーレート
4 bCharFormat 1 ストップビット数 0→1 bit, 1→1.5 bits, 2→2 bits
5 bParityType 1 パリティ設定 0→None, 1→Odd, 2→Even
6 bDataBits 1 データ幅 5, 6, 7, 8, 16
LineCoding構造体
13
/15
setbaudコマンド
ボーレートをsetbaud
(動画中撮影時はsetcdc)
によって設定してから
comprocコマンドで
機械語を送信し、
結果を受け取っている
14
/15
今後MikanOSに搭載したい機能
?hex2bin: 16進数テキストをバイナリデータに変換するコマンド
?ハンドアセンブルでの実験用
?ucc, uasm: ComProc用コンパイラ、アセンブラ
?echo/catと組み合わせて自作CPUのプログラミングが可能
?FTDIドライバ
?市販のUSBシリアル変換はFTDIチップを使っていることが多い
?FTDIはCDC ACM仕様ではない、独自仕様
?複数のUSBシリアル変換機器の識別と選択機能
?現状、1つのデバイスしか使えない
15

More Related Content

惭颈办补苍翱厂と自作颁笔鲍を鲍厂叠で接続する