Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1e392cca648c
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 55b253547799
Choose a head ref
  • 4 commits
  • 13 files changed
  • 1 contributor

Commits on Sep 29, 2016

  1. Rust: add support for artiq_coreconfig.

    whitequark committed Sep 29, 2016
    Copy the full SHA
    83940ae View commit details
  2. Rust: port clock, rtio_crg routines.

    whitequark committed Sep 29, 2016
    Copy the full SHA
    9c18f1b View commit details
  3. Rust: move a few things around (NFC).

    whitequark committed Sep 29, 2016
    Copy the full SHA
    9d00023 View commit details
  4. Rust: print git commit during startup.

    whitequark committed Sep 29, 2016
    Copy the full SHA
    55b2535 View commit details
33 changes: 33 additions & 0 deletions artiq/runtime.rs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions artiq/runtime.rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -2,6 +2,10 @@
authors = ["The ARTIQ Project Developers"]
name = "runtime"
version = "0.0.0"
build = "build.rs"

[build-dependencies]
walkdir = "0.1"

[lib]
name = "artiq_rust"
42 changes: 42 additions & 0 deletions artiq/runtime.rs/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
extern crate walkdir;

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::process::Command;

use walkdir::WalkDir;

fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("git_info.rs");
let mut f = File::create(&dest_path).unwrap();

writeln!(f, "const GIT_COMMIT: &'static str = {:?};",
git_describe().unwrap()).unwrap();

println!("cargo:rerun-if-changed=../../.git/HEAD");
for entry in WalkDir::new("../../.git/refs") {
let entry = entry.unwrap();
println!("cargo:rerun-if-changed={}", entry.path().display());
}
}

// Returns `None` if git is not available.
fn git_describe() -> Option<String> {
Command::new("git")
.arg("describe")
.arg("--tags")
.arg("--dirty")
.arg("--always")
.arg("--long")
.output()
.ok()
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|mut s| {
let len = s.trim_right().len();
s.truncate(len);
s
})
}
77 changes: 77 additions & 0 deletions artiq/runtime.rs/src/clock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use board::csr::timer0;

const INIT: u64 = ::core::i64::MAX as u64;
const FREQ: u64 = ::board::csr::CONFIG_CLOCK_FREQUENCY as u64;

pub fn init() {
unsafe {
timer0::en_write(0);
timer0::load_write(INIT);
timer0::reload_write(INIT);
timer0::en_write(1);
}
}

pub fn get_ms() -> u64 {
unsafe {
timer0::update_value_write(1);
(INIT - timer0::value_read()) / (FREQ / 1_000)
}
}

pub fn spin_us(interval: u64) {
unsafe {
timer0::update_value_write(1);
let threshold = timer0::value_read() - interval * (FREQ / 1_000_000);
while timer0::value_read() > threshold {
timer0::update_value_write(1)
}
}
}

#[derive(Debug, Clone, Copy)]
struct Watchdog {
active: bool,
threshold: u64
}

pub const MAX_WATCHDOGS: usize = 16;

#[derive(Debug)]
pub struct WatchdogSet {
watchdogs: [Watchdog; MAX_WATCHDOGS]
}

impl WatchdogSet {
pub fn new() -> WatchdogSet {
WatchdogSet {
watchdogs: [Watchdog { active: false, threshold: 0 }; MAX_WATCHDOGS]
}
}

pub fn set_ms(&mut self, interval: u64) -> Result<usize, ()> {
for (index, watchdog) in self.watchdogs.iter_mut().enumerate() {
if !watchdog.active {
watchdog.active = true;
watchdog.threshold = get_ms() + interval;
return Ok(index)
}
}

warn!("cannot add watchdog; all {} watchdogs used", MAX_WATCHDOGS);
Err(())
}

pub fn clear(&mut self, index: usize) {
if index < MAX_WATCHDOGS {
self.watchdogs[index].active = false
}
}

pub fn expired(&self) -> bool {
self.watchdogs.iter()
.filter(|wd| wd.active)
.min_by_key(|wd| wd.threshold)
.map_or(false, |wd| get_ms() > wd.threshold)
}
}
63 changes: 63 additions & 0 deletions artiq/runtime.rs/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use std::cmp;
use std::vec::Vec;
use libc::{c_void, c_char, c_int, c_uint};

extern {
fn fs_remove(key: *const c_char);
fn fs_erase();
fn fs_write(key: *const c_char, buffer: *const c_void, buflen: c_uint) -> c_int;
fn fs_read(key: *const c_char, buffer: *mut c_void, buflen: c_uint,
remain: *mut c_uint) -> c_uint;
}

macro_rules! c_str {
($s:ident) => {
{
let mut c = [0; 64 + 1];
let len = cmp::min($s.len(), c.len() - 1);
c[..len].copy_from_slice($s.as_bytes());
c
}
}
}

pub fn read(key: &str, buf: &mut [u8]) -> Result<usize, usize> {
let key_c = c_str!(key);
let mut remain: c_uint = 0;
let result = unsafe {
fs_read(key_c.as_ptr() as *const c_char,
buf.as_mut_ptr() as *mut c_void, buf.len() as c_uint, &mut remain)
};
if remain == 0 { Ok(result as usize) } else { Err(remain as usize) }
}

pub fn read_to_end(key: &str) -> Vec<u8> {
let mut value = Vec::new();
match read(key, &mut []) {
Ok(0) => (),
Ok(_) => unreachable!(),
Err(size) => {
value.resize(size, 0);
read(key, &mut value).unwrap();
}
}
value
}

pub fn write(key: &str, buf: &[u8]) -> Result<(), ()> {
let key_c = c_str!(key);
let result = unsafe {
fs_write(key_c.as_ptr() as *const c_char,
buf.as_ptr() as *mut c_void, buf.len() as c_uint)
};
if result == 1 { Ok(()) } else { Err(()) }
}

pub fn remove(key: &str) {
let key_c = c_str!(key);
unsafe { fs_remove(key_c.as_ptr() as *const c_char) }
}

pub fn erase() {
unsafe { fs_erase() }
}
29 changes: 20 additions & 9 deletions artiq/runtime.rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,46 @@
#![no_std]
#![feature(const_fn)]
#![feature(libc)]

#[macro_use]
extern crate std_artiq as std;
extern crate libc;
#[macro_use]
extern crate log;
extern crate log_buffer;
extern crate byteorder;

use std::prelude::v1::*;
use buffer_logger::BufferLogger;
use logger::BufferLogger;

pub mod board;
pub mod io;
pub mod buffer_logger;
pub mod session;
mod board;
mod sched;
mod config;
mod clock;
mod rtio_crg;

mod logger;

mod session_proto;
mod session;

extern {
fn network_init();
fn lwip_service();
}

include!(concat!(env!("OUT_DIR"), "/git_info.rs"));

#[no_mangle]
pub unsafe extern fn rust_main() {
static mut log_buffer: [u8; 4096] = [0; 4096];
BufferLogger::new(&mut log_buffer[..])
.register(move |logger| {
info!("Accepting network sessions in Rust.");
info!("booting ARTIQ runtime ({})", GIT_COMMIT);

clock::init();
rtio_crg::init();
network_init();

let mut scheduler = io::Scheduler::new();
let mut scheduler = sched::Scheduler::new();
scheduler.spawn(4096, move |waiter| {
session::handler(waiter, logger)
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use core::mem;
use core::cell::RefCell;
use log::{self, Log, LogMetadata, LogRecord, LogLevelFilter};
use log_buffer::LogBuffer;
@@ -41,7 +40,7 @@ impl BufferLogger {
}

impl Log for BufferLogger {
fn enabled(&self, _metadata: &log::LogMetadata) -> bool {
fn enabled(&self, _metadata: &LogMetadata) -> bool {
true
}

47 changes: 47 additions & 0 deletions artiq/runtime.rs/src/rtio_crg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use board::csr;
use {clock, config};

pub fn init() {
unsafe { csr::rtio_crg::pll_reset_write(0) }

let mut opt = [b'i'];
let clk;
match config::read("startup_clock", &mut opt) {
Ok(0) | Ok(1) if &opt == b"i" => {
info!("startup RTIO clock: internal");
clk = 0
}
Ok(1) if &opt == b"e" => {
info!("startup RTIO clock: external");
clk = 1
}
_ => {
error!("unrecognized startup_clock configuration entry");
clk = 0
}
};

if !switch_clock(clk) {
error!("startup RTIO clock failed");
warn!("this may cause the system initialization to fail");
warn!("fix clocking and reset the device");
}
}

pub fn check() -> bool {
unsafe { csr::rtio_crg::pll_locked_read() != 0 }
}

pub fn switch_clock(clk: u8) -> bool {
unsafe {
let cur_clk = csr::rtio_crg::clock_sel_read();
if clk != cur_clk {
csr::rtio_crg::pll_reset_write(1);
csr::rtio_crg::clock_sel_write(clk);
csr::rtio_crg::pll_reset_write(0);
}
}

clock::spin_us(150);
return check()
}
File renamed without changes.
Loading