tomoyuki-nakabayashi / Rustemu86

Apache License 2.0
5 stars 0 forks source link

uart16550っぽい何かを作る #11

Closed tomoyuki-nakabayashi closed 6 years ago

tomoyuki-nakabayashi commented 6 years ago

文字列出力&インテグレーションテスト用。 出力先を標準出力か、バッファかを、DIできるようにすると、テストで使える。

tomoyuki-nakabayashi commented 6 years ago

VecDequeがFIFOに適しているらしい。

tomoyuki-nakabayashi commented 6 years ago

https://doc.rust-lang.org/nightly/core/fmt/trait.Write.html

Write traitを実装するもの、をTxにすればうまくできる気がする。

tomoyuki-nakabayashi commented 6 years ago

テンプレートとLifetimeを両方書くとややこしいな。ただ、Lifetimeもtraitと思えばまぁ?

struct Uart16550<'a, T: 'a> {
  tx_buffer: &'a mut T,
}

impl<'a, T: 'a + Write> Uart16550<'a, T> {
  fn new(buffer: &'a mut T) -> Uart16550<T> {
    Uart16550 {
      tx_buffer: buffer,
    }
  }

  fn write(&mut self, c: char) {
    write!(self.tx_buffer, "{}", c).expect("Printing to serial failed")
  }
}
tomoyuki-nakabayashi commented 6 years ago

メモリマップドにせねばならぬ。

tomoyuki-nakabayashi commented 6 years ago

一旦、メモリマッピング固定のinterconnectを作って、それをCPUが持つ形にするか。

tomoyuki-nakabayashi commented 6 years ago

UART、テスト時は、TXバッファを読み込みできるようにするか。 エミュレーション時は、読み込みするとErr返せば良い気がする。

tomoyuki-nakabayashi commented 6 years ago

ダメですな。 テスト時はファイルに書き込んで、テスト終了時に再オープンして中身を確かめるか。

tomoyuki-nakabayashi commented 6 years ago

UART自体は完成した。Interconnectにつないで、CPUから使えるようにしょう。

tomoyuki-nakabayashi commented 6 years ago

うあ、インテグレーションテストだと、プロダクトコードはtest設定じゃないのか。これはうっかり。

tomoyuki-nakabayashi commented 6 years ago
$ cargo run -- tests/asms/hello
    Finished dev [unoptimized + debuginfo] target(s) in 0.14s
     Running `target/debug/rustemu86 tests/asms/hello`
Program load... 53 bytes.
Hello
Finish emulation. 13 instructions executed.

それはともかく、力づくHelloが動いたのを喜ぶか。

tomoyuki-nakabayashi commented 6 years ago

UartWriteを知っていていいのは、Interconnectまでだよなぁ。 そうなると、Interconnectはジェネリックにできない。

tomoyuki-nakabayashi commented 6 years ago

http://keens.github.io/blog/2017/05/06/rustkazenidezainpata_n23tane/

Factoryパターンでtrait objectを返そう。

tomoyuki-nakabayashi commented 6 years ago

この方がシンプルだ。

pub fn uart_factory(target: Target) -> Uart16550 {
  match target {
    Target::Stdout => Uart16550 { tx_writer: Box::new(StdoutWriter::new()) },
    Target::File => Uart16550 { tx_writer: Box::new(FileWriter::new()) },
  }
}