3个不稳定版本
使用旧的Rust 2015
0.2.1 | 2017年11月16日 |
---|---|
0.1.1 | 2017年11月12日 |
0.1.0 | 2017年11月11日 |
#1535 in 嵌入式开发
95KB
2K SLoC
Tockloader协议
实现了Tockloader协议。
TockOS应用程序通过tockloader
加载。它使用特定协议与TockOS引导加载程序通信。此crate实现了该协议,以便您可以使用Rust编写兼容未来的tockloader
引导加载程序!
用法
在您的嵌入式引导加载程序中,您需要一个类似于以下内容的循环
use tockloader_proto::{ResponseEncoder, CommandDecoder};
#[no_mangle]
pub extern "C" fn main() {
let mut uart = uart::Uart::new(uart::UartId::Uart0, 115200, uart::NewlineMode::Binary);
let mut decoder = CommandDecoder::new();
loop {
if let Ok(Some(ch)) = uart.getc_try() {
let mut need_reset = false;
let response = match decoder.receive(ch) {
Ok(None) => None,
Ok(Some(tockloader_proto::Command::Ping)) => Some(tockloader_proto::Response::Pong),
Ok(Some(tockloader_proto::Command::Reset)) => {
need_reset = true;
None
},
Ok(Some(_)) => Some(tockloader_proto::Response::Unknown),
Err(_) => Some(tockloader_proto::Response::InternalError),
};
if need_reset {
decoder.reset();
}
if let Some(response) = response {
let mut encoder = ResponseEncoder::new(&response).unwrap();
while let Some(byte) = encoder.next() {
uart.putc(byte);
}
}
}
}
}
在CLI闪存工具(如tockloader)中使用此库是一个练习留给读者(提示:您想要ResponseDecoder
和CommandEncoder
)。
有线协议
这些都是从TockOS文档中抄来的。
所有消息都是通过UART发送的,并由客户端发起,由引导加载程序响应。
帧格式
命令
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Message (arbitrary length) | Escape Char | Command |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Message
:由各个命令指定的命令包。通过将所有0xFC
替换为两个连续的0xFC
进行转义。Escape Character
:0xFC
。Command
:命令字节。
响应
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Escape Char | Response | Message (arbitrary length)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Escape Character
:0xFC
。Response
:响应字节。Message
:由各个命令指定的响应包。通过将所有0xFC
替换为两个连续的0xFC
进行转义。
命令
PING
向引导加载程序发送ping。如果一切正常,它将响应pong。
命令
Command
:0x01
。Message
:None
。
响应
Response
:0x11
。Message
:None
。
INFO
从引导加载程序检索信息字符串。
命令
Command
:0x03
。Message
:None
。
响应
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length | String...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
192 bytes |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Response
:0x25
Length
:信息字符串的长度。String
: 信息字符串的Length
字节和192长度的零。
重置
在引导加载程序中重置内部缓冲区指针。这通常在每次命令之前调用。
命令
命令
:0x05
。Message
:None
。
响应
无。
擦除页面
擦除内部闪存的页面。
命令
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
命令
:0x06
。地址
: 要擦除的页面的地址。小端。
响应
响应
:0x15
。Message
:None
。
写入页面
写入内部闪存的页面。
命令
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
(512 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
命令
:0x07
。地址
: 要写入的页面的地址。小端。数据
: 写入页面的512个数据字节。
响应
响应
:0x15
。Message
:None
。
读取范围
读取内部闪存的任意范围。
命令
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
命令
:0x06
。地址
: 要擦除的页面的地址。小端。长度
: 要读取的字节数。
响应
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
(arbitrary length) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
响应
:0x20
。数据
: 从闪存读取的字节。
设置属性
在内部闪存的指定索引处设置一个属性。
命令
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Index | Key
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length | Value
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
(arbitrary length) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
命令
:0x13
。索引
: 要设置的属性索引。0-15。密钥
: 八字节密钥,零填充。长度
: 值的长度。1-55。值
: 存储在属性中的Length
字节值。
响应
响应
:0x15
。Message
:None
。
获取属性
从内部闪存获取指定索引的属性。
命令
0
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
| Index |
+-+-+-+-+-+-+-+-+
命令
:0x13
。索引
: 要获取的属性索引。0-15。
响应
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Key
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length | Value
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
(55 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
响应
:0x22
。密钥
: 八字节密钥,零填充。长度
: 值的长度。1-55。值
: 55字节的可能值。
内部闪存CRC
获取内部闪存范围的CRC。
命令
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
命令
:0x13
。地址
: 开始CRC计算的地址。小端。长度
: 计算CRC的范围长度。
响应
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| CRC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
响应
:0x23
。CRC
: 计算的CRC。
更改波特率
为引导加载程序设置新的波特率。
命令
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SubCmd | Baud Rate
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+
命令
:0x21
。子命令
: 子命令。使用0x01
来设置新的波特率。当发送子命令0x01
时,响应将以旧波特率发送,但引导加载程序将在发送响应后切换到新波特率。为了确认一切正常,引导加载程序期望再次收到CHANGE_BAUD_RATE
命令,这次使用子命令0x02
。不要在这两个CHANGE_BAUD_RATE
命令之间发送RESET
命令。确保两个消息中发送相同的波特率。波特率
: 要使用的新波特率。小端。
响应
响应
:0x15
。Message
:None
。
依赖关系
~115KB