4

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

我的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 库中导入了一些东西。

有可能解决这个问题吗?

4

2 回答 2

5

据我所知,你没有。Tokio Reactor 0.1.1从标准库中导入了很多东西,没有一个是有条件的。

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

作为支持的 crate 示例no_std,请查看Futures 0.1.20。这有一个功能标志来选择需要标准库的功能。

如果您希望这样做,您需要为 Tokio 及其所有依赖项做出大量努力,以添加功能标志以选择加入需要标准库的所有功能。值得向维护者提出一个问题来协调这样的工作。

于 2018-04-19T17:43:35.347 回答
4

扩展 Shepmaster 已经说过的:你不想要tokio;它基于mio,这不太可能在内核中工作,尤其是在没有堆分配/标准的情况下。

那么如何Future在这样的环境中驱动任务(spawned s)(这是为futures0.1.x 系列编写的):

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

在 futures-0.2中NotifyHandle变成了Waker,然后UnsafeNotify变成了UnsafeWake;上下文消失了id: usize(只需使用包含您需要实现UnsafeWake的所有数据的结构)。Spawn<...>您需要为每个任务手动存储 a ,而不是为未来存储LocalMap,然后将其用于创建一个Contextwith Context::without_spawn,然后将其传递给Future::poll.

于 2018-04-25T21:18:11.507 回答