如何在#[no_std]环境中使用Tokio Reactor?

时间:2018-04-19 13:58:39

标签: rust future rust-cargo rust-tokio

我正在尝试在Tock OS嵌入式操作系统上实现期货。我试图在#[no_std]环境中使用Tokio

我的Cargo.toml文件如下所示:

[package]
name = "nrf52dk"
version = "0.1.0"
authors = ["Tock Project Developers <tock-dev@googlegroups.com>"]
build = "build.rs"

[profile.dev]
panic = "abort"
lto = true
opt-level = "z"
debug = true

[profile.release]
panic = "abort"
lto = true
opt-level = "z"
debug = true

[dependencies]
cortexm4 = { path = "../../arch/cortex-m4" }
capsules = { path = "../../capsules" }
kernel = { path = "../../kernel" }
nrf52 = { path = "../../chips/nrf52" }
nrf5x = { path = "../../chips/nrf5x" }
futures = {version = "0.2.0", default-features = false }

这样编译时没有错误,但是当我添加tokio-reactor = "0.1.1"时,我收到错误:error[E0463]: can't find crate for std。我理解这是因为Tokio从std库中导入了一些东西。

是否有可能解决这个问题?

2 个答案:

答案 0 :(得分:2)

据我所知,你。 Tokio Reactor 0.1.1 imports many things from the standard library,其中没有一个是有条件的。

大多数导入可能会切换到libcore替代品,但Arc需要内存分配,它位于alloc箱中。

作为支持no_std的套餐的示例,请查看Futures 0.1.20。这有一个功能标志,可以选择加入需要标准库的功能。

如果您希望这样做,您需要为Tokio及其所有依赖项贡献大量精力,以添加功能标记以选择加入需要标准库的所有功能。值得与维护人员讨论协调此类工作的问题。

答案 1 :(得分:2)

扩展Shepmaster已经说过的内容:你不想要tokio;它基于mio,它不太可能在内核中工作,特别是没有堆分配/ std。

那么如何在这样的环境中驱动任务(产生Future)(这是为futures 0.1.x系列编写的):

  • 你的&#34;执行官&#34; (&#34;主循环&#34;)将希望跟踪每个任务的某些状态,例如是否需要轮询它,也许是一些链表来查找需要轮询的列表。
  • 你需要一个适合那个州的地方;您还需要存储Spawn<...>中包含的Future。应该可以使用&#34;静态&#34;为此分配了存储空间。
  • 您需要实现UnsafeNotify(和基本特征Notify),可能是对任务的原始指针/ &'static引用(包括状态); notify需要能够以线程安全的方式对任务进行排队以进行轮询。 {clone,drop}_{raw,id}函数可以为空,因为您无论如何都要使用静态分配。如果主循环正在休眠,notify还需要安排主循环。队列本身也需要一些全局状态(&#34; list head + tail&#34;);如果您需要不同的队列,您也可以在NotifyHandle中存储对它的引用(例如在id: usize参数中)。
  • 你甚至可以尝试在相同的&#34;轮询队列中运行多个循环&#34;,祝你好运线程安全:)未来-0.2 ThreadPool可能会提供一些想法如何做到(或tokio-threadpool箱子。
  • 你可能需要添加一些&#34;计时器&#34;处理事件循环;一个计时器应该存储一个NotifyHandle到它应该在超时时唤醒的任务,一些状态来跟踪超时是否被命中,并且事件循环需要一个活动(指针)计时器列表来确定多长时间等待。 (tokio-timer包可能会给你一些如何实现这个的想法)
  • async IO的一些类似处理;在用户空间中,您使用select超时(或特定于平台的优化版本),在内核中您可能需要找到其他方式:)(在tokio中世界由Reactor提供,基于mio
  • 推动您要使用poll_future_notify
  • 的任务

在期货-0.2 NotifyHandle成为WakerUnsafeNotify成为UnsafeWake; id: usize上下文消失了(只需使用包含实现UnsafeWake所需的所有数据的结构)。您不必为将来存储Spawn<...>,而是需要为每项任务手动存储LocalMap,然后将其用于创建Context Context::without_spawn,然后传递到Future::poll