3个版本 (重大变更)
使用旧的Rust 2015
0.5.0 | 2017年2月1日 |
---|---|
0.4.0 | 2017年1月29日 |
0.3.0 | 2016年11月19日 |
#44 in #uart
在 2 crate 中使用
26KB
208 行
嵌入式串行特性
简介
此crate包含适合嵌入式开发的特性。这允许开发者创建依赖于通用UART功能的crate(例如,AT命令接口),使得应用程序开发者可以将crate与板上的特定UART结合起来。
它类似于C语言中使用函数 getc
和 putc
来解耦IO设备与库的思想,但以一种更加Rust的风格。
特性有接收和发送、阻塞、带超时阻塞和非阻塞的变体。
未解答的问题
- 如果不同的特性使用相同的函数名会更好吗?
lib.rs
:
嵌入式串行特性
描述串行端口(UART)功能的特性。
在这里,串行端口是指一次可以顺序发送和/或接收一个八位字节的数据的设备。八位字节使用 u8
类型表示。我们在这里只谈论八位字节,而不是字符(尽管如果您使用ASCII或UTF-8对字符串进行编码,它们将成为一个八位字节的序列)。
此crate包含适合嵌入式开发的特性。这允许开发者创建依赖于通用UART功能的crate(例如,AT命令接口),使得应用程序开发者可以将crate与板上的特定UART结合起来。
它类似于C语言中使用函数 getc
和 putc
来解耦IO设备与库的思想,但以一种更加Rust的风格。
以下是 MutBlockingTx
特性的示例。
use embedded_serial::MutBlockingTx;
struct SomeStruct<T> { uart: T };
impl<T> SomeStruct<T> where T: MutBlockingTx {
fn new(uart: T) -> SomeStruct<T> {
SomeStruct { uart: uart }
}
fn write_data(&mut self) -> Result<(), <T as MutBlockingTx>::Error> {
self.uart.puts(b"AT\n").map_err(|e| e.1)?;
Ok(())
}
}
以下是 MutBlockingTxWithTimeout
特性的示例。
struct SomeStruct<T> { uart: T };
use embedded_serial::MutBlockingTxWithTimeout;
impl<T> SomeStruct<T> where T: MutBlockingTxWithTimeout {
fn new(uart: T) -> SomeStruct<T> {
SomeStruct { uart: uart }
}
fn write_data(&mut self, timeout: &<T as MutBlockingTxWithTimeout>::Timeout) -> Result<bool, <T as MutBlockingTxWithTimeout>::Error> {
let len = self.uart.puts_wait(b"AT\n", timeout).map_err(|e| e.1)?;
Ok(len == 3)
}
}
以下是 MutNonBlockingTx
特性的示例。您将调用 write_data
函数,直到它返回 Ok(true)
。
use embedded_serial::MutNonBlockingTx;
struct SomeStruct<T> {
sent: Option<usize>,
uart: T
};
impl<T> SomeStruct<T> where T: MutNonBlockingTx {
fn new(uart: T) -> SomeStruct<T> {
SomeStruct { uart: uart, sent: Some(0) }
}
fn write_data(&mut self) -> Result<bool, <T as MutNonBlockingTx>::Error> {
let data = b"AT\n";
if let Some(len) = self.sent {
match self.uart.puts_try(&data[len..]) {
// Sent some or more of the data
Ok(sent) => {
let total = len + sent;
self.sent = if total == data.len() {
None
} else {
Some(total)
};
Ok(false)
}
// Sent some of the data but errored out
Err((sent, e)) => {
let total = len + sent;
self.sent = if total == data.len() {
None
} else {
Some(total)
};
Err(e)
}
}
} else {
Ok(true)
}
}
}
在这个示例中,我们从阻塞串行端口读取了三个八位字节。
use embedded_serial::MutBlockingRx;
pub struct SomeStruct<T> { uart: T }
impl<T> SomeStruct<T> where T: MutBlockingRx {
pub fn new(uart: T) -> SomeStruct<T> {
SomeStruct { uart: uart }
}
pub fn read_response(&mut self) -> Result<(), <T as MutBlockingRx>::Error> {
let mut buffer = [0u8; 3];
// If we got an error, we don't care any many we actually received.
self.uart.gets(&mut buffer).map_err(|e| e.1)?;
// process data in buffer here
Ok(())
}
}
在这个示例中,我们带超时从阻塞串行端口读取了三个八位字节。
use embedded_serial::MutBlockingRxWithTimeout;
pub struct SomeStruct<T> { uart: T }
impl<T> SomeStruct<T> where T: MutBlockingRxWithTimeout {
pub fn new(uart: T) -> SomeStruct<T> {
SomeStruct { uart: uart }
}
pub fn read_response(&mut self, timeout: &<T as MutBlockingRxWithTimeout>::Timeout) -> Result<bool, <T as MutBlockingRxWithTimeout>::Error> {
let mut buffer = [0u8; 3];
// If we got an error, we don't care any many we actually received.
let len = self.uart.gets_wait(&mut buffer, timeout).map_err(|e| e.1)?;
// process data in buffer here
Ok(len == buffer.len())
}
}
在这个示例中,我们从非阻塞串行端口读取了16个八位字节到一个向量中,该向量的大小正好等于我们迄今为止读取的量。您将调用 read_data
函数,直到它返回 Ok(true)
。这与其他示例的不同之处在于,我们有一个对UART的不可变引用,而不是拥有它。
use embedded_serial::ImmutNonBlockingRx;
struct SomeStruct<'a, T> where T: 'a {
buffer: Vec<u8>,
uart: &'a T
};
const CHUNK_SIZE: usize = 4;
const WANTED: usize = 16;
impl<'a, T> SomeStruct<'a, T> where T: ImmutNonBlockingRx {
fn new(uart: &T) -> SomeStruct<T> {
SomeStruct { uart: uart, buffer: Vec::new() }
}
fn read_data(&mut self) -> Result<bool, <T as ImmutNonBlockingRx>::Error> {
let mut buffer = [0u8; CHUNK_SIZE];
if self.buffer.len() < WANTED {
let needed = WANTED - self.buffer.len();
let this_time = if needed < CHUNK_SIZE { needed } else { CHUNK_SIZE };
match self.uart.gets_try(&mut buffer[0..needed]) {
// Read some or more of the data
Ok(read) => {
self.buffer.extend(&buffer[0..read]);
Ok(self.buffer.len() == WANTED)
}
// Sent some of the data but errored out
Err((read, e)) => {
self.buffer.extend(&buffer[0..read]);
Err(e)
}
}
} else {
Ok(true)
}
}
}