rtt feature 之后,您还可以往它的下行通道写入,于是一个 cargo test 就能驱动一个交互式控制台。
有两条路径,它们的行为并不相同。
请优先使用交互式会话。单向流产出的是原始的 HTTP 分块传输帧,而不是干净的负载 —— 见下面的警告。
交互式会话
启用该 feature
rtt feature 隐含启用 blocking。它没有异步版本。
打开一个会话
RttOptions
channel 同时决定两个方向上的通道。chunk_size 只对交互式会话有效;单向的 HTTP 流会忽略它。
方法
方法参考
read(timeout: Duration) -> Result<Vec<u8>>
在 timeout 时间内到达的上行通道字节,有多少给多少。
目标空闲时,
read() 会把整个超时时间等满。在轮询循环里请改用 try_read(),否则每一轮迭代都要花掉整个超时时长。try_read() -> Result<Vec<u8>>
已经收到的字节,不等待。没有缓冲内容时返回空 vector。
wait_for(needle: &[u8], timeout: Duration) -> Result<Vec<u8>>
不断累积输出,直到出现 needle。
返回: 直到该标记为止、并且包含该标记的全部内容。标记之后的字节会继续留在缓冲区里,供下一次读取。空标记会立即返回;没找到则是 Error::Timeout。
write(data: &[u8]) -> Result<()> 和 write_str(s: &str) -> Result<()>
写入目标的 RTT 下行通道。
stop() -> Result<()>
干净地停止。它会消耗掉该会话。把会话 drop 掉同样会停止它,但 stop() 会把错误暴露出来,而不是吞掉。
单向流
debug.rtt() 和 debug.rtt_with(&RttOptions) 返回一个 RttStream,它实现了 std::io::Read。它不需要任何 cargo feature,也不需要 Socket.IO。
示例
驱动固件控制台并对回复做断言
在目标空闲时收集启动输出而不被阻塞
说明
- Box 的 RTT telnet 端口只接受一个客户端。 在同一个探针和同一个通道上开第二个会话,会被以
Error::Stream和RTT port 9090 is already in use by another session拒绝。同一个探针上的两个不同通道属于不同端口,可以同时运行。 - 字节是原始的。
defmt输出是压缩的二进制,必须经defmt-print -e <elf>管道处理;wait_for只在纯文本控制台上才帮得上忙。 - 连接确认的超时是 30 秒,比 UART 的 15 秒更宽。多出来的时间用于在 RAM 中搜索 RTT 控制块,以及在 gdbserver 稳定下来的过程中重试 telnet 挂接。
- 会话会在 Socket.IO 握手时带上网关 bearer 令牌,因此受网关保护的 Box 无需额外配置即可使用。
- 需要 Box 软件 0.35.0 或更高版本。更旧的 Box 会给出
Error::UnsupportedByBox。

