Как использовать Tokio Reactor в среде # [no_std]?

Я пытаюсь реализовать фьючерсы на встроенной операционной системе Tock OS. Я пытаюсь использовать Tokio в #[no_std] среда.

Мой Cargo.toml файл выглядит так:

[package]
name = "nrf52dk"
version = "0.1.0"
authors = ["Tock Project Developers <[email protected]>"]
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.

Можно ли обойти эту проблему?


person EmbeddedOS    schedule 19.04.2018    source источник


Ответы (2)


Насколько я могу судить, вы не делаете. Tokio Reactor 0.1.1 импортирует многие вещи из стандартной библиотеки, ни один из них не является условным.

Большую часть импорта, вероятно, можно было бы переключить на libcore альтернативы, но Arc требует выделения памяти, которая находится в alloc корзине.

В качестве примера ящика, поддерживающего no_std, ознакомьтесь с Фьючерс 0.1.20. У этого есть флаг функции для включения функций, требующих стандартной библиотеки.

Если вы хотите сделать это, вам нужно будет приложить значительные усилия для Tokio и всех его зависимостей, чтобы добавить флаги функций для включения всех функций, требующих стандартной библиотеки. Было бы целесообразно обсудить вопрос с сопровождающими, чтобы они скоординировали такие усилия.

person Shepmaster    schedule 19.04.2018
comment
futures также пропустит множество функций (например, _ 2_) в no_std, и mio тоже будет сложным. Наверное, проще написать своего исполнителя для собственных нужд. - person Stefan; 21.04.2018

Расширяя то, что уже сказал Шепмастер: вы не хотите tokio; он основан на mio, который вряд ли когда-либо будет работать в ядре, особенно без выделения кучи / std.

Итак, как управлять задачами (порожденными Futures) в такой среде (это написано для серии futures 0.1.x):

  • ваш "исполнитель" ("основной цикл") захочет отслеживать какое-то состояние для каждой задачи, например нужно ли вам его опросить, возможно, какой-то связанный список, чтобы найти тех, которые нужно опросить.
  • вам нужно место для этого состояния; вам также необходимо хранить Futures, завернутые в Spawn<...> . Для этого должна быть возможность использовать «статическое» выделенное хранилище.
  • вам потребуется реализовать UnsafeNotify (и базовый признак Notify), вероятно, для необработанного указателя / &'static ссылки на задачу (включая состояние); notify должна иметь возможность ставить задачи в очередь, чтобы их опрашивали потокобезопасным способом. Функции {clone,drop}_{raw,id} могут быть пустыми, поскольку вы в любом случае будете использовать статические выделения. notify также необходимо запланировать основной цикл, если он спит. Самой очереди также потребуется какое-то глобальное состояние («заголовок списка + хвост»); если вам нужны разные очереди, вы также можете сохранить ссылку на них в NotifyHandle (например, в параметре id: usize).
  • вы даже можете попробовать запустить несколько циклов в одной и той же «очереди опроса», удачи в обеспечении потоковой безопасности :) The future-0.2 _ 15_ может дать некоторые идеи, как это сделать (или _ 16_ ящик).
  • вам, вероятно, потребуется добавить некоторую обработку «таймера» в цикл событий; таймер должен сохранять NotifyHandle для задачи, которая должна пробуждаться по таймауту, некоторое состояние, чтобы отслеживать, был ли достигнут тайм-аут, а циклу событий нужен список активных (указателей на) таймеров, чтобы определить, сколько времени ждать. (ящик tokio-timer может дать вам несколько идей, как это реализовать)
  • некоторая аналогичная обработка для асинхронного ввода-вывода; в пользовательском пространстве вы должны использовать select с тайм-аутом (или его оптимизированную версию для конкретной платформы), в ядре вам, вероятно, придется искать другие способы :) (В мире tokio это обеспечивается Reactor, который основан на mio)
  • для выполнения задачи вы захотите использовать poll_future_notify

В Futures-0.2 NotifyHandle стал Waker и UnsafeNotify стал UnsafeWake; контекст id: usize пропал (просто используйте структуру со всеми данными, которые нужно реализовать UnsafeWake). Вместо того, чтобы сохранять Spawn<...> на будущее, вам нужно вручную сохранить LocalMap для каждой задачи, которая затем используется для создания Context с _ 33_, который затем передается в _ 34_.

person Stefan    schedule 25.04.2018