hackndev / zinc

The bare metal stack for rust
zinc.rs
Apache License 2.0
1k stars 100 forks source link

Using uart from outside of "run". #239

Closed chrisdew closed 9 years ago

chrisdew commented 9 years ago

First, apologies for not using a mailing list - I've searched (in-page) for "mail" in https://github.com/hackndev/zinc and http://zinc.rs/ but found nothing.

I'm trying to use the uart (and other run_args) from outside the run function.

Adding just a small quantity of code:

+ fn func(args: &pt::run_args) {
+   args.uart.puts("Hello, world, from func.\n"); // this isn't allowed
+ }

fn run(args: &pt::run_args) {
  ...
  args.uart.puts("Hello, world\n"); // no error here, this is allowed
+ func(args);

to the app_uart.rs causes it to fail to compile with:

/home/chris/ecryptfs/rust/zinc/apps/app_uart.rs:61:13: 61:47 error: type `&zinc::hal::lpc17xx::uart::UART` does not implement any method in scope named `puts`
/home/chris/ecryptfs/rust/zinc/apps/app_uart.rs:61   args.uart.puts("Hello, world, from func.\n");
                                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

P.S. It all compiles and runs perfectly until I try to use the uart from a function other than run. P.P.S. Full source:

#![feature(phase)]
#![crate_type="staticlib"]
#![no_std]

extern crate core;
extern crate zinc;
#[phase(plugin)] extern crate macro_platformtree;

platformtree!(
  lpc17xx@mcu {
    clock {
      source = "main-oscillator";
      source_frequency = 12_000_000;
      pll {
        m = 50;
        n = 3;
        divisor = 4;
      }
    }

    timer {
      timer@1 {
        counter = 25;
        divisor = 4;
      }
    }

    uart {
      uart@0 {
        baud_rate = 115200;
        mode = "8N1";
        tx = &uart_tx;
        rx = &uart_rx;
      }
    }

    gpio {
      0 {
        uart_tx@2;
        uart_rx@3;
      }
      1 {
        led4@23 { direction = "out"; }
      }
    }
  }

  os {
    single_task {
      loop = "run";
      args {
        timer = &timer;
        txled = &led4;
        uart = &uart;
      }
    }
  }
)

fn func(args: &pt::run_args) {
  args.uart.puts("Hello, world, from func.\n");
}

fn run(args: &pt::run_args) {
  use zinc::drivers::chario::CharIO;
  use zinc::hal::timer::Timer;
  use zinc::hal::pin::Gpio;

  args.uart.puts("Hello, world\n");
  func(args);

  let mut i = 0;
  loop {
    args.txled.set_high();
    args.uart.puts("Waiting for ");
    args.uart.puti(i);
    args.uart.puts(" seconds...\n");

    i += 1;
    args.txled.set_low();

    args.timer.wait(1);
  }
}
farcaller commented 9 years ago

This is rust issue: use zinc::drivers::chario::CharIO;

You need to use it in the correct scope of func, or globally for the whole file.

farcaller commented 9 years ago

Also mind that pt::run_args is opaque type which might contain implicit trait typization further expanded by #[zinc_task], so in general case it's not safe to pass it down.

chrisdew commented 9 years ago

Thanks for explaining that.

Is there a better way to output debug to the serial port, from random places in a program?

(I do understand that Zinc is experimental, so 'no' is an understandable answer.)

bharrisau commented 9 years ago

Is there a logging framework for Rust that is small enough to use?

On 18 November 2014 17:01, Chris Dew notifications@github.com wrote:

Thanks for explaining that.

Is there a better way to output debug to the serial port, from random places, all over a program?

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/issues/239#issuecomment-63439997.

farcaller commented 9 years ago

There is os::debug for generic debug case. It's not exactly safe, but it's globally available if you pass it an UART during initialisation.

chrisdew commented 9 years ago

Thanks, I'll try os::debug.