aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Emil Fresk <emil.fresk@gmail.com> 2023-01-23 20:05:47 +0100
committerGravatar Henrik Tjäder <henrik@tjaders.com> 2023-03-01 00:33:31 +0100
commit306aa47170fd59369b7a184924e287dc3706d64d (patch)
tree75a331a63a4021f078e330bf2ce4edb1228e2ecf
parentb8b881f446a226d6f3c4a7db7c9174590b47dbf6 (diff)
downloadrtic-306aa47170fd59369b7a184924e287dc3706d64d.tar.gz
rtic-306aa47170fd59369b7a184924e287dc3706d64d.tar.zst
rtic-306aa47170fd59369b7a184924e287dc3706d64d.zip
Add rtic-timer (timerqueue + monotonic) and rtic-monotonics (systick-monotonic)
-rw-r--r--ci/expected/cfg-monotonic.run0
-rw-r--r--examples/cfg-monotonic.rs121
-rw-r--r--macros/src/tests.rs4
-rw-r--r--macros/src/tests/single.rs40
-rw-r--r--rtic-monotonics/.gitignore6
-rw-r--r--rtic-monotonics/Cargo.toml12
-rw-r--r--rtic-monotonics/rust-toolchain.toml (renamed from rust-toolchain.toml)0
-rw-r--r--rtic-monotonics/src/lib.rs11
-rw-r--r--rtic-monotonics/src/systick_monotonic.rs1
-rw-r--r--rtic-timer/.gitignore6
-rw-r--r--rtic-timer/Cargo.toml7
-rw-r--r--rtic-timer/rust-toolchain.toml4
-rw-r--r--rtic-timer/src/lib.rs390
-rw-r--r--rtic-timer/src/linked_list.rs173
-rw-r--r--rtic-timer/src/monotonic.rs60
-rw-r--r--rtic-timer/src/sll.rs421
-rw-r--r--rtic/.cargo/config.toml (renamed from .cargo/config.toml)0
-rw-r--r--rtic/.gitignore6
-rw-r--r--rtic/CHANGELOG.md (renamed from CHANGELOG.md)0
-rw-r--r--rtic/Cargo.toml (renamed from Cargo.toml)0
-rw-r--r--rtic/build.rs (renamed from build.rs)0
-rw-r--r--rtic/ci/expected/async-delay.run (renamed from ci/expected/async-delay.run)0
-rw-r--r--rtic/ci/expected/async-infinite-loop.run (renamed from ci/expected/async-infinite-loop.run)0
-rw-r--r--rtic/ci/expected/async-task-multiple-prios.run (renamed from ci/expected/async-task-multiple-prios.run)0
-rw-r--r--rtic/ci/expected/async-task.run (renamed from ci/expected/async-task.run)0
-rw-r--r--rtic/ci/expected/async-timeout.run (renamed from ci/expected/async-timeout.run)0
-rw-r--r--rtic/ci/expected/big-struct-opt.run (renamed from ci/expected/big-struct-opt.run)0
-rw-r--r--rtic/ci/expected/binds.run (renamed from ci/expected/binds.run)0
-rw-r--r--rtic/ci/expected/cancel-reschedule.run (renamed from ci/expected/cancel-reschedule.run)0
-rw-r--r--rtic/ci/expected/capacity.run (renamed from ci/expected/capacity.run)0
-rw-r--r--rtic/ci/expected/cfg-whole-task.run (renamed from ci/expected/cfg-whole-task.run)0
-rw-r--r--rtic/ci/expected/common.run (renamed from ci/expected/common.run)0
-rw-r--r--rtic/ci/expected/complex.run (renamed from ci/expected/complex.run)0
-rw-r--r--rtic/ci/expected/declared_locals.run (renamed from ci/expected/declared_locals.run)0
-rw-r--r--rtic/ci/expected/destructure.run (renamed from ci/expected/destructure.run)0
-rw-r--r--rtic/ci/expected/extern_binds.run (renamed from ci/expected/extern_binds.run)0
-rw-r--r--rtic/ci/expected/extern_spawn.run (renamed from ci/expected/extern_spawn.run)0
-rw-r--r--rtic/ci/expected/generics.run (renamed from ci/expected/generics.run)0
-rw-r--r--rtic/ci/expected/hardware.run (renamed from ci/expected/hardware.run)0
-rw-r--r--rtic/ci/expected/idle-wfi.run (renamed from ci/expected/idle-wfi.run)0
-rw-r--r--rtic/ci/expected/idle.run (renamed from ci/expected/idle.run)0
-rw-r--r--rtic/ci/expected/init.run (renamed from ci/expected/init.run)0
-rw-r--r--rtic/ci/expected/locals.run (renamed from ci/expected/locals.run)0
-rw-r--r--rtic/ci/expected/lock-free.run (renamed from ci/expected/lock-free.run)0
-rw-r--r--rtic/ci/expected/lock.run (renamed from ci/expected/lock.run)0
-rw-r--r--rtic/ci/expected/message.run (renamed from ci/expected/message.run)0
-rw-r--r--rtic/ci/expected/message_passing.run (renamed from ci/expected/message_passing.run)0
-rw-r--r--rtic/ci/expected/multilock.run (renamed from ci/expected/multilock.run)0
-rw-r--r--rtic/ci/expected/not-sync.run (renamed from ci/expected/not-sync.run)0
-rw-r--r--rtic/ci/expected/only-shared-access.run (renamed from ci/expected/only-shared-access.run)0
-rw-r--r--rtic/ci/expected/periodic-at.run (renamed from ci/expected/periodic-at.run)0
-rw-r--r--rtic/ci/expected/periodic-at2.run (renamed from ci/expected/periodic-at2.run)0
-rw-r--r--rtic/ci/expected/periodic.run (renamed from ci/expected/periodic.run)0
-rw-r--r--rtic/ci/expected/peripherals-taken.run (renamed from ci/expected/peripherals-taken.run)0
-rw-r--r--rtic/ci/expected/pool.run (renamed from ci/expected/pool.run)0
-rw-r--r--rtic/ci/expected/preempt.run (renamed from ci/expected/preempt.run)0
-rw-r--r--rtic/ci/expected/ramfunc.run (renamed from ci/expected/ramfunc.run)0
-rw-r--r--rtic/ci/expected/ramfunc.run.grep.bar (renamed from ci/expected/ramfunc.run.grep.bar)0
-rw-r--r--rtic/ci/expected/ramfunc.run.grep.foo (renamed from ci/expected/ramfunc.run.grep.foo)0
-rw-r--r--rtic/ci/expected/resource-user-struct.run (renamed from ci/expected/resource-user-struct.run)0
-rw-r--r--rtic/ci/expected/schedule.run (renamed from ci/expected/schedule.run)0
-rw-r--r--rtic/ci/expected/shared.run (renamed from ci/expected/shared.run)0
-rw-r--r--rtic/ci/expected/smallest.run (renamed from ci/expected/smallest.run)0
-rw-r--r--rtic/ci/expected/spawn.run (renamed from ci/expected/spawn.run)0
-rw-r--r--rtic/ci/expected/static.run (renamed from ci/expected/static.run)0
-rw-r--r--rtic/ci/expected/t-binds.run (renamed from ci/expected/t-binds.run)0
-rw-r--r--rtic/ci/expected/t-cfg-resources.run (renamed from ci/expected/t-cfg-resources.run)0
-rw-r--r--rtic/ci/expected/t-htask-main.run (renamed from ci/expected/t-htask-main.run)0
-rw-r--r--rtic/ci/expected/t-idle-main.run (renamed from ci/expected/t-idle-main.run)0
-rw-r--r--rtic/ci/expected/t-late-not-send.run (renamed from ci/expected/t-late-not-send.run)0
-rw-r--r--rtic/ci/expected/t-schedule.run (renamed from ci/expected/t-schedule.run)0
-rw-r--r--rtic/ci/expected/t-spawn.run (renamed from ci/expected/t-spawn.run)0
-rw-r--r--rtic/ci/expected/task.run (renamed from ci/expected/task.run)0
-rw-r--r--rtic/ci/expected/zero-prio-task.run (renamed from ci/expected/zero-prio-task.run)0
-rw-r--r--rtic/examples/async-delay.no_rs (renamed from examples/async-delay.no_rs)0
-rw-r--r--rtic/examples/async-infinite-loop.no_rs (renamed from examples/async-infinite-loop.no_rs)0
-rw-r--r--rtic/examples/async-task-multiple-prios.rs (renamed from examples/async-task-multiple-prios.rs)0
-rw-r--r--rtic/examples/async-task.rs (renamed from examples/async-task.rs)0
-rw-r--r--rtic/examples/async-timeout.no_rs (renamed from examples/async-timeout.no_rs)0
-rw-r--r--rtic/examples/big-struct-opt.rs (renamed from examples/big-struct-opt.rs)0
-rw-r--r--rtic/examples/binds.rs (renamed from examples/binds.rs)0
-rw-r--r--rtic/examples/cancel-reschedule.no_rs (renamed from examples/cancel-reschedule.no_rs)0
-rw-r--r--rtic/examples/capacity.no_rs (renamed from examples/capacity.no_rs)0
-rw-r--r--rtic/examples/cfg-whole-task.no_rs (renamed from examples/cfg-whole-task.no_rs)0
-rw-r--r--rtic/examples/common.no_rs (renamed from examples/common.no_rs)0
-rw-r--r--rtic/examples/complex.rs (renamed from examples/complex.rs)0
-rw-r--r--rtic/examples/declared_locals.rs (renamed from examples/declared_locals.rs)0
-rw-r--r--rtic/examples/destructure.rs (renamed from examples/destructure.rs)0
-rw-r--r--rtic/examples/extern_binds.rs (renamed from examples/extern_binds.rs)0
-rw-r--r--rtic/examples/extern_spawn.rs (renamed from examples/extern_spawn.rs)0
-rw-r--r--rtic/examples/generics.rs (renamed from examples/generics.rs)0
-rw-r--r--rtic/examples/hardware.rs (renamed from examples/hardware.rs)0
-rw-r--r--rtic/examples/idle-wfi.rs (renamed from examples/idle-wfi.rs)0
-rw-r--r--rtic/examples/idle.rs (renamed from examples/idle.rs)0
-rw-r--r--rtic/examples/init.rs (renamed from examples/init.rs)0
-rw-r--r--rtic/examples/locals.rs (renamed from examples/locals.rs)0
-rw-r--r--rtic/examples/lock-free.no_rs (renamed from examples/lock-free.no_rs)0
-rw-r--r--rtic/examples/lock.rs (renamed from examples/lock.rs)0
-rw-r--r--rtic/examples/message.no_rs (renamed from examples/message.no_rs)0
-rw-r--r--rtic/examples/message_passing.no_rs (renamed from examples/message_passing.no_rs)0
-rw-r--r--rtic/examples/multilock.rs (renamed from examples/multilock.rs)0
-rw-r--r--rtic/examples/not-sync.rs (renamed from examples/not-sync.rs)0
-rw-r--r--rtic/examples/only-shared-access.rs (renamed from examples/only-shared-access.rs)0
-rw-r--r--rtic/examples/periodic-at.no_rs (renamed from examples/periodic-at.no_rs)0
-rw-r--r--rtic/examples/periodic-at2.no_rs (renamed from examples/periodic-at2.no_rs)0
-rw-r--r--rtic/examples/periodic.no_rs (renamed from examples/periodic.no_rs)0
-rw-r--r--rtic/examples/peripherals-taken.rs (renamed from examples/peripherals-taken.rs)0
-rw-r--r--rtic/examples/pool.no_rs (renamed from examples/pool.no_rs)0
-rw-r--r--rtic/examples/preempt.rs (renamed from examples/preempt.rs)0
-rw-r--r--rtic/examples/ramfunc.rs (renamed from examples/ramfunc.rs)0
-rw-r--r--rtic/examples/resource-user-struct.rs (renamed from examples/resource-user-struct.rs)0
-rw-r--r--rtic/examples/schedule.no_rs (renamed from examples/schedule.no_rs)0
-rw-r--r--rtic/examples/shared.rs (renamed from examples/shared.rs)0
-rw-r--r--rtic/examples/smallest.rs (renamed from examples/smallest.rs)0
-rw-r--r--rtic/examples/spawn.rs (renamed from examples/spawn.rs)0
-rw-r--r--rtic/examples/static.rs (renamed from examples/static.rs)0
-rw-r--r--rtic/examples/t-binds.rs (renamed from examples/t-binds.rs)0
-rw-r--r--rtic/examples/t-cfg-resources.rs (renamed from examples/t-cfg-resources.rs)0
-rw-r--r--rtic/examples/t-htask-main.rs (renamed from examples/t-htask-main.rs)0
-rw-r--r--rtic/examples/t-idle-main.rs (renamed from examples/t-idle-main.rs)0
-rw-r--r--rtic/examples/t-late-not-send.rs (renamed from examples/t-late-not-send.rs)0
-rw-r--r--rtic/examples/t-schedule.no_rs (renamed from examples/t-schedule.no_rs)0
-rw-r--r--rtic/examples/t-spawn.no_rs (renamed from examples/t-spawn.no_rs)0
-rw-r--r--rtic/examples/task.rs (renamed from examples/task.rs)0
-rw-r--r--rtic/examples/zero-prio-task.rs (renamed from examples/zero-prio-task.rs)0
-rw-r--r--rtic/macros/.gitignore (renamed from macros/.gitignore)0
-rw-r--r--rtic/macros/Cargo.toml (renamed from macros/Cargo.toml)2
-rw-r--r--rtic/macros/src/analyze.rs (renamed from macros/src/analyze.rs)0
-rw-r--r--rtic/macros/src/bindings.rs (renamed from macros/src/bindings.rs)0
-rw-r--r--rtic/macros/src/check.rs (renamed from macros/src/check.rs)0
-rw-r--r--rtic/macros/src/codegen.rs (renamed from macros/src/codegen.rs)0
-rw-r--r--rtic/macros/src/codegen/assertions.rs (renamed from macros/src/codegen/assertions.rs)0
-rw-r--r--rtic/macros/src/codegen/async_dispatchers.rs (renamed from macros/src/codegen/async_dispatchers.rs)0
-rw-r--r--rtic/macros/src/codegen/hardware_tasks.rs (renamed from macros/src/codegen/hardware_tasks.rs)0
-rw-r--r--rtic/macros/src/codegen/idle.rs (renamed from macros/src/codegen/idle.rs)0
-rw-r--r--rtic/macros/src/codegen/init.rs (renamed from macros/src/codegen/init.rs)0
-rw-r--r--rtic/macros/src/codegen/local_resources.rs (renamed from macros/src/codegen/local_resources.rs)0
-rw-r--r--rtic/macros/src/codegen/local_resources_struct.rs (renamed from macros/src/codegen/local_resources_struct.rs)0
-rw-r--r--rtic/macros/src/codegen/main.rs (renamed from macros/src/codegen/main.rs)0
-rw-r--r--rtic/macros/src/codegen/module.rs (renamed from macros/src/codegen/module.rs)0
-rw-r--r--rtic/macros/src/codegen/post_init.rs (renamed from macros/src/codegen/post_init.rs)0
-rw-r--r--rtic/macros/src/codegen/pre_init.rs (renamed from macros/src/codegen/pre_init.rs)0
-rw-r--r--rtic/macros/src/codegen/shared_resources.rs (renamed from macros/src/codegen/shared_resources.rs)0
-rw-r--r--rtic/macros/src/codegen/shared_resources_struct.rs (renamed from macros/src/codegen/shared_resources_struct.rs)0
-rw-r--r--rtic/macros/src/codegen/software_tasks.rs (renamed from macros/src/codegen/software_tasks.rs)0
-rw-r--r--rtic/macros/src/codegen/util.rs (renamed from macros/src/codegen/util.rs)0
-rw-r--r--rtic/macros/src/lib.rs (renamed from macros/src/lib.rs)0
-rw-r--r--rtic/macros/src/syntax.rs (renamed from macros/src/syntax.rs)0
-rw-r--r--rtic/macros/src/syntax/.github/bors.toml (renamed from macros/src/syntax/.github/bors.toml)0
-rw-r--r--rtic/macros/src/syntax/.github/workflows/build.yml (renamed from macros/src/syntax/.github/workflows/build.yml)0
-rw-r--r--rtic/macros/src/syntax/.github/workflows/changelog.yml (renamed from macros/src/syntax/.github/workflows/changelog.yml)0
-rw-r--r--rtic/macros/src/syntax/.github/workflows/properties/build.properties.json (renamed from macros/src/syntax/.github/workflows/properties/build.properties.json)0
-rw-r--r--rtic/macros/src/syntax/.gitignore (renamed from macros/src/syntax/.gitignore)0
-rw-r--r--rtic/macros/src/syntax/.travis.yml (renamed from macros/src/syntax/.travis.yml)0
-rw-r--r--rtic/macros/src/syntax/accessors.rs (renamed from macros/src/syntax/accessors.rs)0
-rw-r--r--rtic/macros/src/syntax/analyze.rs (renamed from macros/src/syntax/analyze.rs)0
-rw-r--r--rtic/macros/src/syntax/ast.rs (renamed from macros/src/syntax/ast.rs)0
-rw-r--r--rtic/macros/src/syntax/check.rs (renamed from macros/src/syntax/check.rs)0
-rw-r--r--rtic/macros/src/syntax/optimize.rs (renamed from macros/src/syntax/optimize.rs)0
-rw-r--r--rtic/macros/src/syntax/parse.rs (renamed from macros/src/syntax/parse.rs)0
-rw-r--r--rtic/macros/src/syntax/parse/app.rs (renamed from macros/src/syntax/parse/app.rs)0
-rw-r--r--rtic/macros/src/syntax/parse/hardware_task.rs (renamed from macros/src/syntax/parse/hardware_task.rs)0
-rw-r--r--rtic/macros/src/syntax/parse/idle.rs (renamed from macros/src/syntax/parse/idle.rs)0
-rw-r--r--rtic/macros/src/syntax/parse/init.rs (renamed from macros/src/syntax/parse/init.rs)0
-rw-r--r--rtic/macros/src/syntax/parse/resource.rs (renamed from macros/src/syntax/parse/resource.rs)0
-rw-r--r--rtic/macros/src/syntax/parse/software_task.rs (renamed from macros/src/syntax/parse/software_task.rs)0
-rw-r--r--rtic/macros/src/syntax/parse/util.rs (renamed from macros/src/syntax/parse/util.rs)0
-rw-r--r--rtic/macros/tests/ui.rs (renamed from macros/tests/ui.rs)0
-rw-r--r--rtic/macros/ui/extern-interrupt-used.rs (renamed from macros/ui/extern-interrupt-used.rs)0
-rw-r--r--rtic/macros/ui/extern-interrupt-used.stderr (renamed from macros/ui/extern-interrupt-used.stderr)0
-rw-r--r--rtic/macros/ui/idle-double-local.rs (renamed from macros/ui/idle-double-local.rs)0
-rw-r--r--rtic/macros/ui/idle-double-local.stderr (renamed from macros/ui/idle-double-local.stderr)0
-rw-r--r--rtic/macros/ui/idle-double-shared.rs (renamed from macros/ui/idle-double-shared.rs)0
-rw-r--r--rtic/macros/ui/idle-double-shared.stderr (renamed from macros/ui/idle-double-shared.stderr)0
-rw-r--r--rtic/macros/ui/idle-input.rs (renamed from macros/ui/idle-input.rs)0
-rw-r--r--rtic/macros/ui/idle-input.stderr (renamed from macros/ui/idle-input.stderr)0
-rw-r--r--rtic/macros/ui/idle-no-context.rs (renamed from macros/ui/idle-no-context.rs)0
-rw-r--r--rtic/macros/ui/idle-no-context.stderr (renamed from macros/ui/idle-no-context.stderr)0
-rw-r--r--rtic/macros/ui/idle-not-divergent.rs (renamed from macros/ui/idle-not-divergent.rs)0
-rw-r--r--rtic/macros/ui/idle-not-divergent.stderr (renamed from macros/ui/idle-not-divergent.stderr)0
-rw-r--r--rtic/macros/ui/idle-output.rs (renamed from macros/ui/idle-output.rs)0
-rw-r--r--rtic/macros/ui/idle-output.stderr (renamed from macros/ui/idle-output.stderr)0
-rw-r--r--rtic/macros/ui/idle-pub.rs (renamed from macros/ui/idle-pub.rs)0
-rw-r--r--rtic/macros/ui/idle-pub.stderr (renamed from macros/ui/idle-pub.stderr)0
-rw-r--r--rtic/macros/ui/idle-unsafe.rs (renamed from macros/ui/idle-unsafe.rs)0
-rw-r--r--rtic/macros/ui/idle-unsafe.stderr (renamed from macros/ui/idle-unsafe.stderr)0
-rw-r--r--rtic/macros/ui/init-divergent.rs (renamed from macros/ui/init-divergent.rs)0
-rw-r--r--rtic/macros/ui/init-divergent.stderr (renamed from macros/ui/init-divergent.stderr)0
-rw-r--r--rtic/macros/ui/init-double-local.rs (renamed from macros/ui/init-double-local.rs)0
-rw-r--r--rtic/macros/ui/init-double-local.stderr (renamed from macros/ui/init-double-local.stderr)0
-rw-r--r--rtic/macros/ui/init-double-shared.rs (renamed from macros/ui/init-double-shared.rs)0
-rw-r--r--rtic/macros/ui/init-double-shared.stderr (renamed from macros/ui/init-double-shared.stderr)0
-rw-r--r--rtic/macros/ui/init-input.rs (renamed from macros/ui/init-input.rs)0
-rw-r--r--rtic/macros/ui/init-input.stderr (renamed from macros/ui/init-input.stderr)0
-rw-r--r--rtic/macros/ui/init-no-context.rs (renamed from macros/ui/init-no-context.rs)0
-rw-r--r--rtic/macros/ui/init-no-context.stderr (renamed from macros/ui/init-no-context.stderr)0
-rw-r--r--rtic/macros/ui/init-output.rs (renamed from macros/ui/init-output.rs)0
-rw-r--r--rtic/macros/ui/init-output.stderr (renamed from macros/ui/init-output.stderr)0
-rw-r--r--rtic/macros/ui/init-pub.rs (renamed from macros/ui/init-pub.rs)0
-rw-r--r--rtic/macros/ui/init-pub.stderr (renamed from macros/ui/init-pub.stderr)0
-rw-r--r--rtic/macros/ui/init-unsafe.rs (renamed from macros/ui/init-unsafe.rs)0
-rw-r--r--rtic/macros/ui/init-unsafe.stderr (renamed from macros/ui/init-unsafe.stderr)0
-rw-r--r--rtic/macros/ui/interrupt-double.rs (renamed from macros/ui/interrupt-double.rs)0
-rw-r--r--rtic/macros/ui/interrupt-double.stderr (renamed from macros/ui/interrupt-double.stderr)0
-rw-r--r--rtic/macros/ui/local-collision-2.rs (renamed from macros/ui/local-collision-2.rs)0
-rw-r--r--rtic/macros/ui/local-collision-2.stderr (renamed from macros/ui/local-collision-2.stderr)0
-rw-r--r--rtic/macros/ui/local-collision.rs (renamed from macros/ui/local-collision.rs)0
-rw-r--r--rtic/macros/ui/local-collision.stderr (renamed from macros/ui/local-collision.stderr)0
-rw-r--r--rtic/macros/ui/local-malformed-1.rs (renamed from macros/ui/local-malformed-1.rs)0
-rw-r--r--rtic/macros/ui/local-malformed-1.stderr (renamed from macros/ui/local-malformed-1.stderr)0
-rw-r--r--rtic/macros/ui/local-malformed-2.rs (renamed from macros/ui/local-malformed-2.rs)0
-rw-r--r--rtic/macros/ui/local-malformed-2.stderr (renamed from macros/ui/local-malformed-2.stderr)0
-rw-r--r--rtic/macros/ui/local-malformed-3.rs (renamed from macros/ui/local-malformed-3.rs)0
-rw-r--r--rtic/macros/ui/local-malformed-3.stderr (renamed from macros/ui/local-malformed-3.stderr)0
-rw-r--r--rtic/macros/ui/local-malformed-4.rs (renamed from macros/ui/local-malformed-4.rs)0
-rw-r--r--rtic/macros/ui/local-malformed-4.stderr (renamed from macros/ui/local-malformed-4.stderr)0
-rw-r--r--rtic/macros/ui/local-not-declared.rs (renamed from macros/ui/local-not-declared.rs)0
-rw-r--r--rtic/macros/ui/local-not-declared.stderr (renamed from macros/ui/local-not-declared.stderr)0
-rw-r--r--rtic/macros/ui/local-pub.rs (renamed from macros/ui/local-pub.rs)0
-rw-r--r--rtic/macros/ui/local-pub.stderr (renamed from macros/ui/local-pub.stderr)0
-rw-r--r--rtic/macros/ui/local-shared-attribute.rs (renamed from macros/ui/local-shared-attribute.rs)0
-rw-r--r--rtic/macros/ui/local-shared-attribute.stderr (renamed from macros/ui/local-shared-attribute.stderr)0
-rw-r--r--rtic/macros/ui/local-shared.rs (renamed from macros/ui/local-shared.rs)0
-rw-r--r--rtic/macros/ui/local-shared.stderr (renamed from macros/ui/local-shared.stderr)0
-rw-r--r--rtic/macros/ui/shared-lock-free.rs (renamed from macros/ui/shared-lock-free.rs)0
-rw-r--r--rtic/macros/ui/shared-lock-free.stderr (renamed from macros/ui/shared-lock-free.stderr)0
-rw-r--r--rtic/macros/ui/shared-not-declared.rs (renamed from macros/ui/shared-not-declared.rs)0
-rw-r--r--rtic/macros/ui/shared-not-declared.stderr (renamed from macros/ui/shared-not-declared.stderr)0
-rw-r--r--rtic/macros/ui/shared-pub.rs (renamed from macros/ui/shared-pub.rs)0
-rw-r--r--rtic/macros/ui/shared-pub.stderr (renamed from macros/ui/shared-pub.stderr)0
-rw-r--r--rtic/macros/ui/task-divergent.rs (renamed from macros/ui/task-divergent.rs)0
-rw-r--r--rtic/macros/ui/task-divergent.stderr (renamed from macros/ui/task-divergent.stderr)0
-rw-r--r--rtic/macros/ui/task-double-local.rs (renamed from macros/ui/task-double-local.rs)0
-rw-r--r--rtic/macros/ui/task-double-local.stderr (renamed from macros/ui/task-double-local.stderr)0
-rw-r--r--rtic/macros/ui/task-double-priority.rs (renamed from macros/ui/task-double-priority.rs)0
-rw-r--r--rtic/macros/ui/task-double-priority.stderr (renamed from macros/ui/task-double-priority.stderr)0
-rw-r--r--rtic/macros/ui/task-double-shared.rs (renamed from macros/ui/task-double-shared.rs)0
-rw-r--r--rtic/macros/ui/task-double-shared.stderr (renamed from macros/ui/task-double-shared.stderr)0
-rw-r--r--rtic/macros/ui/task-idle.rs (renamed from macros/ui/task-idle.rs)0
-rw-r--r--rtic/macros/ui/task-idle.stderr (renamed from macros/ui/task-idle.stderr)0
-rw-r--r--rtic/macros/ui/task-init.rs (renamed from macros/ui/task-init.rs)0
-rw-r--r--rtic/macros/ui/task-init.stderr (renamed from macros/ui/task-init.stderr)0
-rw-r--r--rtic/macros/ui/task-interrupt.rs (renamed from macros/ui/task-interrupt.rs)0
-rw-r--r--rtic/macros/ui/task-interrupt.stderr (renamed from macros/ui/task-interrupt.stderr)0
-rw-r--r--rtic/macros/ui/task-no-context.rs (renamed from macros/ui/task-no-context.rs)0
-rw-r--r--rtic/macros/ui/task-no-context.stderr (renamed from macros/ui/task-no-context.stderr)0
-rw-r--r--rtic/macros/ui/task-priority-too-high.rs (renamed from macros/ui/task-priority-too-high.rs)0
-rw-r--r--rtic/macros/ui/task-priority-too-high.stderr (renamed from macros/ui/task-priority-too-high.stderr)0
-rw-r--r--rtic/macros/ui/task-priority-too-low.rs (renamed from macros/ui/task-priority-too-low.rs)0
-rw-r--r--rtic/macros/ui/task-priority-too-low.stderr (renamed from macros/ui/task-priority-too-low.stderr)0
-rw-r--r--rtic/macros/ui/task-pub.rs (renamed from macros/ui/task-pub.rs)0
-rw-r--r--rtic/macros/ui/task-pub.stderr (renamed from macros/ui/task-pub.stderr)0
-rw-r--r--rtic/macros/ui/task-unsafe.rs (renamed from macros/ui/task-unsafe.rs)0
-rw-r--r--rtic/macros/ui/task-unsafe.stderr (renamed from macros/ui/task-unsafe.stderr)0
-rw-r--r--rtic/macros/ui/task-zero-prio.rs (renamed from macros/ui/task-zero-prio.rs)0
-rw-r--r--rtic/macros/ui/task-zero-prio.stderr (renamed from macros/ui/task-zero-prio.stderr)0
-rw-r--r--rtic/rust-toolchain.toml4
-rw-r--r--rtic/src/export.rs (renamed from src/export.rs)0
-rw-r--r--rtic/src/export/executor.rs (renamed from src/export/executor.rs)0
-rw-r--r--rtic/src/lib.rs (renamed from src/lib.rs)0
-rw-r--r--rtic/tests/tests.rs (renamed from tests/tests.rs)0
-rw-r--r--rtic/ui/exception-invalid.rs (renamed from ui/exception-invalid.rs)0
-rw-r--r--rtic/ui/exception-invalid.stderr (renamed from ui/exception-invalid.stderr)0
-rw-r--r--rtic/ui/extern-interrupt-not-enough.rs (renamed from ui/extern-interrupt-not-enough.rs)0
-rw-r--r--rtic/ui/extern-interrupt-not-enough.stderr (renamed from ui/extern-interrupt-not-enough.stderr)0
-rw-r--r--rtic/ui/extern-interrupt-used.rs (renamed from ui/extern-interrupt-used.rs)0
-rw-r--r--rtic/ui/extern-interrupt-used.stderr (renamed from ui/extern-interrupt-used.stderr)0
-rw-r--r--rtic/ui/task-priority-too-high.rs (renamed from ui/task-priority-too-high.rs)0
-rw-r--r--rtic/ui/task-priority-too-high.stderr (renamed from ui/task-priority-too-high.stderr)0
-rw-r--r--rtic/ui/unknown-interrupt.rs (renamed from ui/unknown-interrupt.rs)0
-rw-r--r--rtic/ui/unknown-interrupt.stderr (renamed from ui/unknown-interrupt.stderr)0
-rw-r--r--rtic/ui/v6m-interrupt-not-enough.rs_no (renamed from ui/v6m-interrupt-not-enough.rs_no)0
-rw-r--r--rtic/xtask/Cargo.toml (renamed from xtask/Cargo.toml)0
-rw-r--r--rtic/xtask/src/build.rs (renamed from xtask/src/build.rs)0
-rw-r--r--rtic/xtask/src/command.rs (renamed from xtask/src/command.rs)0
-rw-r--r--rtic/xtask/src/main.rs (renamed from xtask/src/main.rs)0
276 files changed, 581 insertions, 687 deletions
diff --git a/ci/expected/cfg-monotonic.run b/ci/expected/cfg-monotonic.run
deleted file mode 100644
index e69de29b..00000000
--- a/ci/expected/cfg-monotonic.run
+++ /dev/null
diff --git a/examples/cfg-monotonic.rs b/examples/cfg-monotonic.rs
deleted file mode 100644
index 88c0d6f0..00000000
--- a/examples/cfg-monotonic.rs
+++ /dev/null
@@ -1,121 +0,0 @@
-//! examples/cfg-monotonic.rs
-
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![deny(missing_docs)]
-#![no_main]
-#![no_std]
-
-use panic_semihosting as _;
-
-#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
-mod app {
- use cortex_m_semihosting::{debug, hprintln};
- use systick_monotonic::*; // Implements the `Monotonic` trait
-
- // A monotonic timer to enable scheduling in RTIC
- #[cfg(feature = "killmono")]
- #[monotonic(binds = SysTick, default = true)]
- type MyMono = Systick<100>; // 100 Hz / 10 ms granularity
-
- // Not allowed by current rtic-syntax:
- // error: `#[monotonic(...)]` on a specific type must appear at most once
- // --> examples/cfg-monotonic.rs:23:10
- // |
- // 23 | type MyMono = Systick<100>; // 100 Hz / 10 ms granularity
- // | ^^^^^^
- // #[monotonic(binds = SysTick, default = true)]
- // type MyMono = Systick<100>; // 100 Hz / 10 ms granularity
-
- // Not allowed by current rtic-syntax:
- // error: this interrupt is already bound
- // --> examples/cfg-monotonic.rs:31:25
- // |
- // 31 | #[monotonic(binds = SysTick, default = true)]
- // | ^^^^^^^
- // #[monotonic(binds = SysTick, default = true)]
- // type MyMono2 = DwtSystick<100>; // 100 Hz / 10 ms granularity
-
- // Resources shared between tasks
- #[shared]
- struct Shared {
- s1: u32,
- s2: i32,
- }
-
- // Local resources to specific tasks (cannot be shared)
- #[local]
- struct Local {
- l1: u8,
- l2: i8,
- }
-
- #[init]
- fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
- let _systick = cx.core.SYST;
-
- // Initialize the monotonic (SysTick rate in QEMU is 12 MHz)
- #[cfg(feature = "killmono")]
- let mono = Systick::new(systick, 12_000_000);
-
- // Spawn the task `foo` directly after `init` finishes
- foo::spawn().unwrap();
-
- debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
-
- (
- // Initialization of shared resources
- Shared { s1: 0, s2: 1 },
- // Initialization of task local resources
- Local { l1: 2, l2: 3 },
- // Move the monotonic timer to the RTIC run-time, this enables
- // scheduling
- #[cfg(feature = "killmono")]
- init::Monotonics(mono),
- init::Monotonics(),
- )
- }
-
- // Background task, runs whenever no other tasks are running
- #[idle]
- fn idle(_: idle::Context) -> ! {
- loop {
- continue;
- }
- }
-
- // Software task, not bound to a hardware interrupt.
- // This task takes the task local resource `l1`
- // The resources `s1` and `s2` are shared between all other tasks.
- #[task(shared = [s1, s2], local = [l1])]
- fn foo(_: foo::Context) {
- // This task is only spawned once in `init`, hence this task will run
- // only once
-
- hprintln!("foo");
- }
-
- // Software task, also not bound to a hardware interrupt
- // This task takes the task local resource `l2`
- // The resources `s1` and `s2` are shared between all other tasks.
- #[task(shared = [s1, s2], local = [l2])]
- fn bar(_: bar::Context) {
- hprintln!("bar");
-
- // Run `bar` once per second
- // bar::spawn_after(1.secs()).unwrap();
- }
-
- // Hardware task, bound to a hardware interrupt
- // The resources `s1` and `s2` are shared between all other tasks.
- #[task(binds = UART0, priority = 3, shared = [s1, s2])]
- fn uart0_interrupt(_: uart0_interrupt::Context) {
- // This task is bound to the interrupt `UART0` and will run
- // whenever the interrupt fires
-
- // Note that RTIC does NOT clear the interrupt flag, this is up to the
- // user
-
- hprintln!("UART0 interrupt!");
- }
-}
diff --git a/macros/src/tests.rs b/macros/src/tests.rs
deleted file mode 100644
index e9e3326e..00000000
--- a/macros/src/tests.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-// NOTE these tests are specific to the Cortex-M port; `rtic-syntax` has a more extensive test suite
-// that tests functionality common to all the RTIC ports
-
-mod single;
diff --git a/macros/src/tests/single.rs b/macros/src/tests/single.rs
deleted file mode 100644
index f20c9ccb..00000000
--- a/macros/src/tests/single.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use quote::quote;
-use rtic_syntax::Settings;
-
-#[test]
-fn analyze() {
- let mut settings = Settings::default();
- settings.parse_extern_interrupt = true;
- let (app, analysis) = rtic_syntax::parse2(
- // First interrupt is assigned to the highest priority dispatcher
- quote!(device = pac, dispatchers = [B, A]),
- quote!(
- mod app {
- #[shared]
- struct Shared {}
-
- #[local]
- struct Local {}
-
- #[init]
- fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
- (Shared {}, Local {}, init::Monotonics())
- }
-
- #[task(priority = 1)]
- fn a(_: a::Context) {}
-
- #[task(priority = 2)]
- fn b(_: b::Context) {}
- }
- ),
- settings,
- )
- .unwrap();
-
- let analysis = crate::analyze::app(analysis, &app);
- let interrupts = &analysis.interrupts;
- assert_eq!(interrupts.len(), 2);
- assert_eq!(interrupts[&2].0.to_string(), "B");
- assert_eq!(interrupts[&1].0.to_string(), "A");
-}
diff --git a/rtic-monotonics/.gitignore b/rtic-monotonics/.gitignore
new file mode 100644
index 00000000..c4002562
--- /dev/null
+++ b/rtic-monotonics/.gitignore
@@ -0,0 +1,6 @@
+**/*.rs.bk
+.#*
+.gdb_history
+/target
+Cargo.lock
+*.hex
diff --git a/rtic-monotonics/Cargo.toml b/rtic-monotonics/Cargo.toml
new file mode 100644
index 00000000..24448fb2
--- /dev/null
+++ b/rtic-monotonics/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "rtic-timer"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+cortex-m = { version = "0.7.6" }
+embedded-hal-async = "0.2.0-alpha.0"
+fugit = { version = "0.3.6", features = ["defmt"] }
+rtic-timer = { version = "1.0.0", path = "../rtic-timer" }
diff --git a/rust-toolchain.toml b/rtic-monotonics/rust-toolchain.toml
index e28b55de..e28b55de 100644
--- a/rust-toolchain.toml
+++ b/rtic-monotonics/rust-toolchain.toml
diff --git a/rtic-monotonics/src/lib.rs b/rtic-monotonics/src/lib.rs
new file mode 100644
index 00000000..88398cad
--- /dev/null
+++ b/rtic-monotonics/src/lib.rs
@@ -0,0 +1,11 @@
+//! Crate
+
+#![no_std]
+#![no_main]
+#![deny(missing_docs)]
+#![allow(incomplete_features)]
+#![feature(async_fn_in_trait)]
+
+pub use rtic_timer::{Monotonic, TimeoutError, TimerQueue};
+
+pub mod systick_monotonic;
diff --git a/rtic-monotonics/src/systick_monotonic.rs b/rtic-monotonics/src/systick_monotonic.rs
new file mode 100644
index 00000000..491cf81c
--- /dev/null
+++ b/rtic-monotonics/src/systick_monotonic.rs
@@ -0,0 +1 @@
+//! ...
diff --git a/rtic-timer/.gitignore b/rtic-timer/.gitignore
new file mode 100644
index 00000000..c4002562
--- /dev/null
+++ b/rtic-timer/.gitignore
@@ -0,0 +1,6 @@
+**/*.rs.bk
+.#*
+.gdb_history
+/target
+Cargo.lock
+*.hex
diff --git a/rtic-timer/Cargo.toml b/rtic-timer/Cargo.toml
index 8e2e2ad6..b7b3a5fb 100644
--- a/rtic-timer/Cargo.toml
+++ b/rtic-timer/Cargo.toml
@@ -1,11 +1,10 @@
[package]
name = "rtic-timer"
-version = "0.1.0"
+version = "1.0.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-cortex-m = "0.7.6"
-rtic-monotonic = "1.0.0"
-fugit = "0.3.6" \ No newline at end of file
+critical-section = "1"
+futures-util = { version = "0.3.25", default-features = false }
diff --git a/rtic-timer/rust-toolchain.toml b/rtic-timer/rust-toolchain.toml
new file mode 100644
index 00000000..e28b55de
--- /dev/null
+++ b/rtic-timer/rust-toolchain.toml
@@ -0,0 +1,4 @@
+[toolchain]
+channel = "nightly"
+components = [ "rust-src", "rustfmt", "llvm-tools-preview" ]
+targets = [ "thumbv6m-none-eabi", "thumbv7m-none-eabi" ]
diff --git a/rtic-timer/src/lib.rs b/rtic-timer/src/lib.rs
index e7051d27..d7faa07f 100644
--- a/rtic-timer/src/lib.rs
+++ b/rtic-timer/src/lib.rs
@@ -1,138 +1,336 @@
+//! Crate
+
#![no_std]
+#![no_main]
+#![deny(missing_docs)]
+#![allow(incomplete_features)]
+#![feature(async_fn_in_trait)]
+
+pub mod monotonic;
+
+use core::future::{poll_fn, Future};
+use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
+use core::task::{Poll, Waker};
+use futures_util::{
+ future::{select, Either},
+ pin_mut,
+};
+pub use monotonic::Monotonic;
-use core::sync::atomic::{AtomicU32, Ordering};
-use core::{cmp::Ordering, task::Waker};
-use cortex_m::peripheral::{syst::SystClkSource, SYST};
-pub use fugit::{self, ExtU64};
-pub use rtic_monotonic::Monotonic;
+mod linked_list;
-mod sll;
-use sll::{IntrusiveSortedLinkedList, Min as IsslMin, Node as IntrusiveNode};
+use linked_list::{Link, LinkedList};
-pub struct Timer {
- cnt: AtomicU32,
- // queue: IntrusiveSortedLinkedList<'static, WakerNotReady<Mono>, IsslMin>,
+/// Holds a waker and at which time instant this waker shall be awoken.
+struct WaitingWaker<Mono: Monotonic> {
+ waker: Waker,
+ release_at: Mono::Instant,
+}
+
+impl<Mono: Monotonic> Clone for WaitingWaker<Mono> {
+ fn clone(&self) -> Self {
+ Self {
+ waker: self.waker.clone(),
+ release_at: self.release_at,
+ }
+ }
}
-#[allow(non_snake_case)]
-#[no_mangle]
-fn SysTick() {
- // ..
- let cnt = unsafe {
- static mut CNT: u32 = 0;
- &mut CNT
- };
+impl<Mono: Monotonic> PartialEq for WaitingWaker<Mono> {
+ fn eq(&self, other: &Self) -> bool {
+ self.release_at == other.release_at
+ }
+}
- *cnt = cnt.wrapping_add(1);
+impl<Mono: Monotonic> PartialOrd for WaitingWaker<Mono> {
+ fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
+ self.release_at.partial_cmp(&other.release_at)
+ }
}
-/// Systick implementing `rtic_monotonic::Monotonic` which runs at a
-/// settable rate using the `TIMER_HZ` parameter.
-pub struct Systick<const TIMER_HZ: u32> {
- systick: SYST,
- cnt: u64,
+/// A generic timer queue for async executors.
+///
+/// # Blocking
+///
+/// The internal priority queue uses global critical sections to manage access. This means that
+/// `await`ing a delay will cause a lock of the entire system for O(n) time. In practice the lock
+/// duration is ~10 clock cycles per element in the queue.
+///
+/// # Safety
+///
+/// This timer queue is based on an intrusive linked list, and by extension the links are strored
+/// on the async stacks of callers. The links are deallocated on `drop` or when the wait is
+/// complete.
+///
+/// Do not call `mem::forget` on an awaited future, or there will be dragons!
+pub struct TimerQueue<Mono: Monotonic> {
+ queue: LinkedList<WaitingWaker<Mono>>,
+ initialized: AtomicBool,
}
-impl<const TIMER_HZ: u32> Systick<TIMER_HZ> {
- /// Provide a new `Monotonic` based on SysTick.
+/// This indicates that there was a timeout.
+pub struct TimeoutError;
+
+impl<Mono: Monotonic> TimerQueue<Mono> {
+ /// Make a new queue.
+ pub const fn new() -> Self {
+ Self {
+ queue: LinkedList::new(),
+ initialized: AtomicBool::new(false),
+ }
+ }
+
+ /// Forwards the `Monotonic::now()` method.
+ #[inline(always)]
+ pub fn now(&self) -> Mono::Instant {
+ Mono::now()
+ }
+
+ /// Takes the initialized monotonic to initialize the TimerQueue.
+ pub fn initialize(&self, monotonic: Mono) {
+ self.initialized.store(true, Ordering::SeqCst);
+
+ // Don't run drop on `Mono`
+ core::mem::forget(monotonic);
+ }
+
+ /// Call this in the interrupt handler of the hardware timer supporting the `Monotonic`
///
- /// The `sysclk` parameter is the speed at which SysTick runs at. This value should come from
- /// the clock generation function of the used HAL.
+ /// # Safety
///
- /// Notice that the actual rate of the timer is a best approximation based on the given
- /// `sysclk` and `TIMER_HZ`.
- pub fn new(mut systick: SYST, sysclk: u32) -> Self {
- // + TIMER_HZ / 2 provides round to nearest instead of round to 0.
- // - 1 as the counter range is inclusive [0, reload]
- let reload = (sysclk + TIMER_HZ / 2) / TIMER_HZ - 1;
+ /// It's always safe to call, but it must only be called from the interrupt of the
+ /// monotonic timer for correct operation.
+ pub unsafe fn on_monotonic_interrupt(&self) {
+ Mono::clear_compare_flag();
+ Mono::on_interrupt();
- assert!(reload <= 0x00ff_ffff);
- assert!(reload > 0);
+ loop {
+ let mut release_at = None;
+ let head = self.queue.pop_if(|head| {
+ release_at = Some(head.release_at);
- systick.disable_counter();
- systick.set_clock_source(SystClkSource::Core);
- systick.set_reload(reload);
+ Mono::now() >= head.release_at
+ });
- Systick { systick, cnt: 0 }
- }
-}
+ match (head, release_at) {
+ (Some(link), _) => {
+ link.waker.wake();
+ }
+ (None, Some(instant)) => {
+ Mono::enable_timer();
+ Mono::set_compare(instant);
-impl<const TIMER_HZ: u32> Monotonic for Systick<TIMER_HZ> {
- const DISABLE_INTERRUPT_ON_EMPTY_QUEUE: bool = false;
+ if Mono::now() >= instant {
+ // The time for the next instant passed while handling it,
+ // continue dequeueing
+ continue;
+ }
- type Instant = fugit::TimerInstantU64<TIMER_HZ>;
- type Duration = fugit::TimerDurationU64<TIMER_HZ>;
+ break;
+ }
+ (None, None) => {
+ // Queue is empty
+ Mono::disable_timer();
- fn now(&mut self) -> Self::Instant {
- if self.systick.has_wrapped() {
- self.cnt = self.cnt.wrapping_add(1);
+ break;
+ }
+ }
}
-
- Self::Instant::from_ticks(self.cnt)
}
- unsafe fn reset(&mut self) {
- self.systick.clear_current();
- self.systick.enable_counter();
- }
+ /// Timeout at a specific time.
+ pub async fn timeout_at<F: Future>(
+ &self,
+ instant: Mono::Instant,
+ future: F,
+ ) -> Result<F::Output, TimeoutError> {
+ let delay = self.delay_until(instant);
- #[inline(always)]
- fn set_compare(&mut self, _val: Self::Instant) {
- // No need to do something here, we get interrupts anyway.
+ pin_mut!(future);
+ pin_mut!(delay);
+
+ match select(future, delay).await {
+ Either::Left((r, _)) => Ok(r),
+ Either::Right(_) => Err(TimeoutError),
+ }
}
- #[inline(always)]
- fn clear_compare_flag(&mut self) {
- // NOOP with SysTick interrupt
+ /// Timeout after a specific duration.
+ #[inline]
+ pub async fn timeout_after<F: Future>(
+ &self,
+ duration: Mono::Duration,
+ future: F,
+ ) -> Result<F::Output, TimeoutError> {
+ self.timeout_at(Mono::now() + duration, future).await
}
- #[inline(always)]
- fn zero() -> Self::Instant {
- Self::Instant::from_ticks(0)
+ /// Delay for some duration of time.
+ #[inline]
+ pub async fn delay(&self, duration: Mono::Duration) {
+ let now = Mono::now();
+
+ self.delay_until(now + duration).await;
}
- #[inline(always)]
- fn on_interrupt(&mut self) {
- if self.systick.has_wrapped() {
- self.cnt = self.cnt.wrapping_add(1);
+ /// Delay to some specific time instant.
+ pub async fn delay_until(&self, instant: Mono::Instant) {
+ if !self.initialized.load(Ordering::Relaxed) {
+ panic!(
+ "The timer queue is not initialized with a monotonic, you need to run `initialize`"
+ );
}
+
+ let mut first_run = true;
+ let queue = &self.queue;
+ let mut link = Link::new(WaitingWaker {
+ waker: poll_fn(|cx| Poll::Ready(cx.waker().clone())).await,
+ release_at: instant,
+ });
+
+ let marker = &AtomicUsize::new(0);
+
+ let dropper = OnDrop::new(|| {
+ queue.delete(marker.load(Ordering::Relaxed));
+ });
+
+ poll_fn(|_| {
+ if Mono::now() >= instant {
+ return Poll::Ready(());
+ }
+
+ if first_run {
+ first_run = false;
+ let (was_empty, addr) = queue.insert(&mut link);
+ marker.store(addr, Ordering::Relaxed);
+
+ if was_empty {
+ // Pend the monotonic handler if the queue was empty to setup the timer.
+ Mono::pend_interrupt();
+ }
+ }
+
+ Poll::Pending
+ })
+ .await;
+
+ // Make sure that our link is deleted from the list before we drop this stack
+ drop(dropper);
}
}
-struct WakerNotReady<Mono>
-where
- Mono: Monotonic,
-{
- pub waker: Waker,
- pub instant: Mono::Instant,
- pub marker: u32,
+struct OnDrop<F: FnOnce()> {
+ f: core::mem::MaybeUninit<F>,
}
-impl<Mono> Eq for WakerNotReady<Mono> where Mono: Monotonic {}
-
-impl<Mono> Ord for WakerNotReady<Mono>
-where
- Mono: Monotonic,
-{
- fn cmp(&self, other: &Self) -> Ordering {
- self.instant.cmp(&other.instant)
+impl<F: FnOnce()> OnDrop<F> {
+ pub fn new(f: F) -> Self {
+ Self {
+ f: core::mem::MaybeUninit::new(f),
+ }
}
-}
-impl<Mono> PartialEq for WakerNotReady<Mono>
-where
- Mono: Monotonic,
-{
- fn eq(&self, other: &Self) -> bool {
- self.instant == other.instant
+ #[allow(unused)]
+ pub fn defuse(self) {
+ core::mem::forget(self)
}
}
-impl<Mono> PartialOrd for WakerNotReady<Mono>
-where
- Mono: Monotonic,
-{
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
+impl<F: FnOnce()> Drop for OnDrop<F> {
+ fn drop(&mut self) {
+ unsafe { self.f.as_ptr().read()() }
}
}
+
+// -------- Test program ---------
+//
+//
+// use systick_monotonic::{Systick, TimerQueue};
+//
+// // same panicking *behavior* as `panic-probe` but doesn't print a panic message
+// // this prevents the panic message being printed *twice* when `defmt::panic` is invoked
+// #[defmt::panic_handler]
+// fn panic() -> ! {
+// cortex_m::asm::udf()
+// }
+//
+// /// Terminates the application and makes `probe-run` exit with exit-code = 0
+// pub fn exit() -> ! {
+// loop {
+// cortex_m::asm::bkpt();
+// }
+// }
+//
+// defmt::timestamp!("{=u64:us}", {
+// let time_us: fugit::MicrosDurationU32 = MONO.now().duration_since_epoch().convert();
+//
+// time_us.ticks() as u64
+// });
+//
+// make_systick_timer_queue!(MONO, Systick<1_000>);
+//
+// #[rtic::app(
+// device = nrf52832_hal::pac,
+// dispatchers = [SWI0_EGU0, SWI1_EGU1, SWI2_EGU2, SWI3_EGU3, SWI4_EGU4, SWI5_EGU5],
+// )]
+// mod app {
+// use super::{Systick, MONO};
+// use fugit::ExtU32;
+//
+// #[shared]
+// struct Shared {}
+//
+// #[local]
+// struct Local {}
+//
+// #[init]
+// fn init(cx: init::Context) -> (Shared, Local) {
+// defmt::println!("init");
+//
+// let systick = Systick::start(cx.core.SYST, 64_000_000);
+//
+// defmt::println!("initializing monotonic");
+//
+// MONO.initialize(systick);
+//
+// async_task::spawn().ok();
+// async_task2::spawn().ok();
+// async_task3::spawn().ok();
+//
+// (Shared {}, Local {})
+// }
+//
+// #[idle]
+// fn idle(_: idle::Context) -> ! {
+// defmt::println!("idle");
+//
+// loop {
+// core::hint::spin_loop();
+// }
+// }
+//
+// #[task]
+// async fn async_task(_: async_task::Context) {
+// loop {
+// defmt::println!("async task waiting for 1 second");
+// MONO.delay(1.secs()).await;
+// }
+// }
+//
+// #[task]
+// async fn async_task2(_: async_task2::Context) {
+// loop {
+// defmt::println!(" async task 2 waiting for 0.5 second");
+// MONO.delay(500.millis()).await;
+// }
+// }
+//
+// #[task]
+// async fn async_task3(_: async_task3::Context) {
+// loop {
+// defmt::println!(" async task 3 waiting for 0.2 second");
+// MONO.delay(200.millis()).await;
+// }
+// }
+// }
+//
diff --git a/rtic-timer/src/linked_list.rs b/rtic-timer/src/linked_list.rs
new file mode 100644
index 00000000..42ff8cb6
--- /dev/null
+++ b/rtic-timer/src/linked_list.rs
@@ -0,0 +1,173 @@
+//! ...
+
+use core::marker::PhantomPinned;
+use core::sync::atomic::{AtomicPtr, Ordering};
+use critical_section as cs;
+
+/// A sorted linked list for the timer queue.
+pub struct LinkedList<T> {
+ head: AtomicPtr<Link<T>>,
+}
+
+impl<T> LinkedList<T> {
+ /// Create a new linked list.
+ pub const fn new() -> Self {
+ Self {
+ head: AtomicPtr::new(core::ptr::null_mut()),
+ }
+ }
+}
+
+impl<T: PartialOrd + Clone> LinkedList<T> {
+ /// Pop the first element in the queue if the closure returns true.
+ pub fn pop_if<F: FnOnce(&T) -> bool>(&self, f: F) -> Option<T> {
+ cs::with(|_| {
+ // Make sure all previous writes are visible
+ core::sync::atomic::fence(Ordering::SeqCst);
+
+ let head = self.head.load(Ordering::Relaxed);
+
+ // SAFETY: `as_ref` is safe as `insert` requires a valid reference to a link
+ if let Some(head) = unsafe { head.as_ref() } {
+ if f(&head.val) {
+ // Move head to the next element
+ self.head
+ .store(head.next.load(Ordering::Relaxed), Ordering::Relaxed);
+
+ // We read the value at head
+ let head_val = head.val.clone();
+
+ return Some(head_val);
+ }
+ }
+ None
+ })
+ }
+
+ /// Delete a link at an address.
+ pub fn delete(&self, addr: usize) {
+ cs::with(|_| {
+ // Make sure all previous writes are visible
+ core::sync::atomic::fence(Ordering::SeqCst);
+
+ let head = self.head.load(Ordering::Relaxed);
+
+ // SAFETY: `as_ref` is safe as `insert` requires a valid reference to a link
+ let head_ref = if let Some(head_ref) = unsafe { head.as_ref() } {
+ head_ref
+ } else {
+ // 1. List is empty, do nothing
+ return;
+ };
+
+ if head as *const _ as usize == addr {
+ // 2. Replace head with head.next
+ self.head
+ .store(head_ref.next.load(Ordering::Relaxed), Ordering::Relaxed);
+
+ return;
+ }
+
+ // 3. search list for correct node
+ let mut curr = head_ref;
+ let mut next = head_ref.next.load(Ordering::Relaxed);
+
+ // SAFETY: `as_ref` is safe as `insert` requires a valid reference to a link
+ while let Some(next_link) = unsafe { next.as_ref() } {
+ // Next is not null
+
+ if next as *const _ as usize == addr {
+ curr.next
+ .store(next_link.next.load(Ordering::Relaxed), Ordering::Relaxed);
+
+ return;
+ }
+
+ // Continue searching
+ curr = next_link;
+ next = next_link.next.load(Ordering::Relaxed);
+ }
+ })
+ }
+
+ /// Insert a new link into the linked list.
+ /// The return is (was_empty, address), where the address of the link is for use with `delete`.
+ pub fn insert(&self, val: &mut Link<T>) -> (bool, usize) {
+ cs::with(|_| {
+ let addr = val as *const _ as usize;
+
+ // Make sure all previous writes are visible
+ core::sync::atomic::fence(Ordering::SeqCst);
+
+ let head = self.head.load(Ordering::Relaxed);
+
+ // 3 cases to handle
+
+ // 1. List is empty, write to head
+ // SAFETY: `as_ref` is safe as `insert` requires a valid reference to a link
+ let head_ref = if let Some(head_ref) = unsafe { head.as_ref() } {
+ head_ref
+ } else {
+ self.head.store(val, Ordering::Relaxed);
+ return (true, addr);
+ };
+
+ // 2. val needs to go in first
+ if val.val < head_ref.val {
+ // Set current head as next of `val`
+ val.next.store(head, Ordering::Relaxed);
+
+ // `val` is now first in the queue
+ self.head.store(val, Ordering::Relaxed);
+
+ return (false, addr);
+ }
+
+ // 3. search list for correct place
+ let mut curr = head_ref;
+ let mut next = head_ref.next.load(Ordering::Relaxed);
+
+ // SAFETY: `as_ref` is safe as `insert` requires a valid reference to a link
+ while let Some(next_link) = unsafe { next.as_ref() } {
+ // Next is not null
+
+ if val.val < next_link.val {
+ // Replace next with `val`
+ val.next.store(next, Ordering::Relaxed);
+
+ // Insert `val`
+ curr.next.store(val, Ordering::Relaxed);
+
+ return (false, addr);
+ }
+
+ // Continue searching
+ curr = next_link;
+ next = next_link.next.load(Ordering::Relaxed);
+ }
+
+ // No next, write link to last position in list
+ curr.next.store(val, Ordering::Relaxed);
+
+ (false, addr)
+ })
+ }
+}
+
+/// A link in the linked list.
+pub struct Link<T> {
+ val: T,
+ next: AtomicPtr<Link<T>>,
+ _up: PhantomPinned,
+}
+
+impl<T> Link<T> {
+ /// Create a new link.
+ pub const fn new(val: T) -> Self {
+ Self {
+ val,
+ next: AtomicPtr::new(core::ptr::null_mut()),
+ _up: PhantomPinned,
+ }
+ }
+}
diff --git a/rtic-timer/src/monotonic.rs b/rtic-timer/src/monotonic.rs
new file mode 100644
index 00000000..9b3742fa
--- /dev/null
+++ b/rtic-timer/src/monotonic.rs
@@ -0,0 +1,60 @@
+//! ...
+
+/// # A monotonic clock / counter definition.
+///
+/// ## Correctness
+///
+/// The trait enforces that proper time-math is implemented between `Instant` and `Duration`. This
+/// is a requirement on the time library that the user chooses to use.
+pub trait Monotonic {
+ /// The time at time zero.
+ const ZERO: Self::Instant;
+
+ /// The type for instant, defining an instant in time.
+ ///
+ /// **Note:** In all APIs in RTIC that use instants from this monotonic, this type will be used.
+ type Instant: Ord
+ + Copy
+ + core::ops::Add<Self::Duration, Output = Self::Instant>
+ + core::ops::Sub<Self::Duration, Output = Self::Instant>
+ + core::ops::Sub<Self::Instant, Output = Self::Duration>;
+
+ /// The type for duration, defining an duration of time.
+ ///
+ /// **Note:** In all APIs in RTIC that use duration from this monotonic, this type will be used.
+ type Duration;
+
+ /// Get the current time.
+ fn now() -> Self::Instant;
+
+ /// Set the compare value of the timer interrupt.
+ ///
+ /// **Note:** This method does not need to handle race conditions of the monotonic, the timer
+ /// queue in RTIC checks this.
+ fn set_compare(instant: Self::Instant);
+
+ /// Clear the compare interrupt flag.
+ fn clear_compare_flag();
+
+ /// Pend the timer's interrupt.
+ fn pend_interrupt();
+
+ /// Optional. Runs on interrupt before any timer queue handling.
+ fn on_interrupt() {}
+
+ /// Optional. This is used to save power, this is called when the timer queue is not empty.
+ ///
+ /// Enabling and disabling the monotonic needs to propagate to `now` so that an instant
+ /// based of `now()` is still valid.
+ ///
+ /// NOTE: This may be called more than once.
+ fn enable_timer() {}
+
+ /// Optional. This is used to save power, this is called when the timer queue is empty.
+ ///
+ /// Enabling and disabling the monotonic needs to propagate to `now` so that an instant
+ /// based of `now()` is still valid.
+ ///
+ /// NOTE: This may be called more than once.
+ fn disable_timer() {}
+}
diff --git a/rtic-timer/src/sll.rs b/rtic-timer/src/sll.rs
deleted file mode 100644
index 43b53c17..00000000
--- a/rtic-timer/src/sll.rs
+++ /dev/null
@@ -1,421 +0,0 @@
-//! An intrusive sorted priority linked list, designed for use in `Future`s in RTIC.
-use core::cmp::Ordering;
-use core::fmt;
-use core::marker::PhantomData;
-use core::ops::{Deref, DerefMut};
-use core::ptr::NonNull;
-
-/// Marker for Min sorted [`IntrusiveSortedLinkedList`].
-pub struct Min;
-
-/// Marker for Max sorted [`IntrusiveSortedLinkedList`].
-pub struct Max;
-
-/// The linked list kind: min-list or max-list
-pub trait Kind: private::Sealed {
- #[doc(hidden)]
- fn ordering() -> Ordering;
-}
-
-impl Kind for Min {
- fn ordering() -> Ordering {
- Ordering::Less
- }
-}
-
-impl Kind for Max {
- fn ordering() -> Ordering {
- Ordering::Greater
- }
-}
-
-/// Sealed traits
-mod private {
- pub trait Sealed {}
-}
-
-impl private::Sealed for Max {}
-impl private::Sealed for Min {}
-
-/// A node in the [`IntrusiveSortedLinkedList`].
-pub struct Node<T> {
- pub val: T,
- next: Option<NonNull<Node<T>>>,
-}
-
-impl<T> Node<T> {
- pub fn new(val: T) -> Self {
- Self { val, next: None }
- }
-}
-
-/// The linked list.
-pub struct IntrusiveSortedLinkedList<'a, T, K> {
- head: Option<NonNull<Node<T>>>,
- _kind: PhantomData<K>,
- _lt: PhantomData<&'a ()>,
-}
-
-impl<'a, T, K> fmt::Debug for IntrusiveSortedLinkedList<'a, T, K>
-where
- T: Ord + core::fmt::Debug,
- K: Kind,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut l = f.debug_list();
- let mut current = self.head;
-
- while let Some(head) = current {
- let head = unsafe { head.as_ref() };
- current = head.next;
-
- l.entry(&head.val);
- }
-
- l.finish()
- }
-}
-
-impl<'a, T, K> IntrusiveSortedLinkedList<'a, T, K>
-where
- T: Ord,
- K: Kind,
-{
- pub const fn new() -> Self {
- Self {
- head: None,
- _kind: PhantomData,
- _lt: PhantomData,
- }
- }
-
- // Push to the list.
- pub fn push(&mut self, new: &'a mut Node<T>) {
- unsafe {
- if let Some(head) = self.head {
- if head.as_ref().val.cmp(&new.val) != K::ordering() {
- // This is newer than head, replace head
- new.next = self.head;
- self.head = Some(NonNull::new_unchecked(new));
- } else {
- // It's not head, search the list for the correct placement
- let mut current = head;
-
- while let Some(next) = current.as_ref().next {
- if next.as_ref().val.cmp(&new.val) != K::ordering() {
- break;
- }
-
- current = next;
- }
-
- new.next = current.as_ref().next;
- current.as_mut().next = Some(NonNull::new_unchecked(new));
- }
- } else {
- // List is empty, place at head
- self.head = Some(NonNull::new_unchecked(new))
- }
- }
- }
-
- /// Get an iterator over the sorted list.
- pub fn iter(&self) -> Iter<'_, T, K> {
- Iter {
- _list: self,
- index: self.head,
- }
- }
-
- /// Find an element in the list that can be changed and resorted.
- pub fn find_mut<F>(&mut self, mut f: F) -> Option<FindMut<'_, 'a, T, K>>
- where
- F: FnMut(&T) -> bool,
- {
- let head = self.head?;
-
- // Special-case, first element
- if f(&unsafe { head.as_ref() }.val) {
- return Some(FindMut {
- is_head: true,
- prev_index: None,
- index: self.head,
- list: self,
- maybe_changed: false,
- });
- }
-
- let mut current = head;
-
- while let Some(next) = unsafe { current.as_ref() }.next {
- if f(&unsafe { next.as_ref() }.val) {
- return Some(FindMut {
- is_head: false,
- prev_index: Some(current),
- index: Some(next),
- list: self,
- maybe_changed: false,
- });
- }
-
- current = next;
- }
-
- None
- }
-
- /// Peek at the first element.
- pub fn peek(&self) -> Option<&T> {
- self.head.map(|head| unsafe { &head.as_ref().val })
- }
-
- /// Pops the first element in the list.
- ///
- /// Complexity is worst-case `O(1)`.
- pub fn pop(&mut self) -> Option<&'a Node<T>> {
- if let Some(head) = self.head {
- let v = unsafe { head.as_ref() };
- self.head = v.next;
- Some(v)
- } else {
- None
- }
- }
-
- /// Checks if the linked list is empty.
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.head.is_none()
- }
-}
-
-/// Iterator for the linked list.
-pub struct Iter<'a, T, K>
-where
- T: Ord,
- K: Kind,
-{
- _list: &'a IntrusiveSortedLinkedList<'a, T, K>,
- index: Option<NonNull<Node<T>>>,
-}
-
-impl<'a, T, K> Iterator for Iter<'a, T, K>
-where
- T: Ord,
- K: Kind,
-{
- type Item = &'a T;
-
- fn next(&mut self) -> Option<Self::Item> {
- let index = self.index?;
-
- let node = unsafe { index.as_ref() };
- self.index = node.next;
-
- Some(&node.val)
- }
-}
-
-/// Comes from [`IntrusiveSortedLinkedList::find_mut`].
-pub struct FindMut<'a, 'b, T, K>
-where
- T: Ord + 'b,
- K: Kind,
-{
- list: &'a mut IntrusiveSortedLinkedList<'b, T, K>,
- is_head: bool,
- prev_index: Option<NonNull<Node<T>>>,
- index: Option<NonNull<Node<T>>>,
- maybe_changed: bool,
-}
-
-impl<'a, 'b, T, K> FindMut<'a, 'b, T, K>
-where
- T: Ord,
- K: Kind,
-{
- unsafe fn pop_internal(&mut self) -> &'b mut Node<T> {
- if self.is_head {
- // If it is the head element, we can do a normal pop
- let mut head = self.list.head.unwrap_unchecked();
- let v = head.as_mut();
- self.list.head = v.next;
- v
- } else {
- // Somewhere in the list
- let mut prev = self.prev_index.unwrap_unchecked();
- let mut curr = self.index.unwrap_unchecked();
-
- // Re-point the previous index
- prev.as_mut().next = curr.as_ref().next;
-
- curr.as_mut()
- }
- }
-
- /// This will pop the element from the list.
- ///
- /// Complexity is worst-case `O(1)`.
- #[inline]
- pub fn pop(mut self) -> &'b mut Node<T> {
- unsafe { self.pop_internal() }
- }
-
- /// This will resort the element into the correct position in the list if needed. The resorting
- /// will only happen if the element has been accessed mutably.
- ///
- /// Same as calling `drop`.
- ///
- /// Complexity is worst-case `O(N)`.
- #[inline]
- pub fn finish(self) {
- drop(self)
- }
-}
-
-impl<'b, T, K> Drop for FindMut<'_, 'b, T, K>
-where
- T: Ord + 'b,
- K: Kind,
-{
- fn drop(&mut self) {
- // Only resort the list if the element has changed
- if self.maybe_changed {
- unsafe {
- let val = self.pop_internal();
- self.list.push(val);
- }
- }
- }
-}
-
-impl<T, K> Deref for FindMut<'_, '_, T, K>
-where
- T: Ord,
- K: Kind,
-{
- type Target = T;
-
- fn deref(&self) -> &Self::Target {
- unsafe { &self.index.unwrap_unchecked().as_ref().val }
- }
-}
-
-impl<T, K> DerefMut for FindMut<'_, '_, T, K>
-where
- T: Ord,
- K: Kind,
-{
- fn deref_mut(&mut self) -> &mut Self::Target {
- self.maybe_changed = true;
- unsafe { &mut self.index.unwrap_unchecked().as_mut().val }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn const_new() {
- static mut _V1: IntrusiveSortedLinkedList<u32, Max> = IntrusiveSortedLinkedList::new();
- }
-
- #[test]
- fn test_peek() {
- let mut ll: IntrusiveSortedLinkedList<u32, Max> = IntrusiveSortedLinkedList::new();
-
- let mut a = Node { val: 1, next: None };
- ll.push(&mut a);
- assert_eq!(ll.peek().unwrap(), &1);
-
- let mut a = Node { val: 2, next: None };
- ll.push(&mut a);
- assert_eq!(ll.peek().unwrap(), &2);
-
- let mut a = Node { val: 3, next: None };
- ll.push(&mut a);
- assert_eq!(ll.peek().unwrap(), &3);
-
- let mut ll: IntrusiveSortedLinkedList<u32, Min> = IntrusiveSortedLinkedList::new();
-
- let mut a = Node { val: 2, next: None };
- ll.push(&mut a);
- assert_eq!(ll.peek().unwrap(), &2);
-
- let mut a = Node { val: 1, next: None };
- ll.push(&mut a);
- assert_eq!(ll.peek().unwrap(), &1);
-
- let mut a = Node { val: 3, next: None };
- ll.push(&mut a);
- assert_eq!(ll.peek().unwrap(), &1);
- }
-
- #[test]
- fn test_empty() {
- let ll: IntrusiveSortedLinkedList<u32, Max> = IntrusiveSortedLinkedList::new();
-
- assert!(ll.is_empty())
- }
-
- #[test]
- fn test_updating() {
- let mut ll: IntrusiveSortedLinkedList<u32, Max> = IntrusiveSortedLinkedList::new();
-
- let mut a = Node { val: 1, next: None };
- ll.push(&mut a);
-
- let mut a = Node { val: 2, next: None };
- ll.push(&mut a);
-
- let mut a = Node { val: 3, next: None };
- ll.push(&mut a);
-
- let mut find = ll.find_mut(|v| *v == 2).unwrap();
-
- *find += 1000;
- find.finish();
-
- assert_eq!(ll.peek().unwrap(), &1002);
-
- let mut find = ll.find_mut(|v| *v == 3).unwrap();
-
- *find += 1000;
- find.finish();
-
- assert_eq!(ll.peek().unwrap(), &1003);
-
- // Remove largest element
- ll.find_mut(|v| *v == 1003).unwrap().pop();
-
- assert_eq!(ll.peek().unwrap(), &1002);
- }
-
- #[test]
- fn test_updating_1() {
- let mut ll: IntrusiveSortedLinkedList<u32, Max> = IntrusiveSortedLinkedList::new();
-
- let mut a = Node { val: 1, next: None };
- ll.push(&mut a);
-
- let v = ll.pop().unwrap();
-
- assert_eq!(v.val, 1);
- }
-
- #[test]
- fn test_updating_2() {
- let mut ll: IntrusiveSortedLinkedList<u32, Max> = IntrusiveSortedLinkedList::new();
-
- let mut a = Node { val: 1, next: None };
- ll.push(&mut a);
-
- let mut find = ll.find_mut(|v| *v == 1).unwrap();
-
- *find += 1000;
- find.finish();
-
- assert_eq!(ll.peek().unwrap(), &1001);
- }
-}
diff --git a/.cargo/config.toml b/rtic/.cargo/config.toml
index d70faef4..d70faef4 100644
--- a/.cargo/config.toml
+++ b/rtic/.cargo/config.toml
diff --git a/rtic/.gitignore b/rtic/.gitignore
new file mode 100644
index 00000000..c4002562
--- /dev/null
+++ b/rtic/.gitignore
@@ -0,0 +1,6 @@
+**/*.rs.bk
+.#*
+.gdb_history
+/target
+Cargo.lock
+*.hex
diff --git a/CHANGELOG.md b/rtic/CHANGELOG.md
index d1722781..d1722781 100644
--- a/CHANGELOG.md
+++ b/rtic/CHANGELOG.md
diff --git a/Cargo.toml b/rtic/Cargo.toml
index c22d0237..c22d0237 100644
--- a/Cargo.toml
+++ b/rtic/Cargo.toml
diff --git a/build.rs b/rtic/build.rs
index 35f8303f..35f8303f 100644
--- a/build.rs
+++ b/rtic/build.rs
diff --git a/ci/expected/async-delay.run b/rtic/ci/expected/async-delay.run
index 61852abf..61852abf 100644
--- a/ci/expected/async-delay.run
+++ b/rtic/ci/expected/async-delay.run
diff --git a/ci/expected/async-infinite-loop.run b/rtic/ci/expected/async-infinite-loop.run
index f9fd4e49..f9fd4e49 100644
--- a/ci/expected/async-infinite-loop.run
+++ b/rtic/ci/expected/async-infinite-loop.run
diff --git a/ci/expected/async-task-multiple-prios.run b/rtic/ci/expected/async-task-multiple-prios.run
index 0b42df0a..0b42df0a 100644
--- a/ci/expected/async-task-multiple-prios.run
+++ b/rtic/ci/expected/async-task-multiple-prios.run
diff --git a/ci/expected/async-task.run b/rtic/ci/expected/async-task.run
index 1f93a4c7..1f93a4c7 100644
--- a/ci/expected/async-task.run
+++ b/rtic/ci/expected/async-task.run
diff --git a/ci/expected/async-timeout.run b/rtic/ci/expected/async-timeout.run
index a8074230..a8074230 100644
--- a/ci/expected/async-timeout.run
+++ b/rtic/ci/expected/async-timeout.run
diff --git a/ci/expected/big-struct-opt.run b/rtic/ci/expected/big-struct-opt.run
index 7fdef35d..7fdef35d 100644
--- a/ci/expected/big-struct-opt.run
+++ b/rtic/ci/expected/big-struct-opt.run
diff --git a/ci/expected/binds.run b/rtic/ci/expected/binds.run
index f84cff01..f84cff01 100644
--- a/ci/expected/binds.run
+++ b/rtic/ci/expected/binds.run
diff --git a/ci/expected/cancel-reschedule.run b/rtic/ci/expected/cancel-reschedule.run
index 5a947526..5a947526 100644
--- a/ci/expected/cancel-reschedule.run
+++ b/rtic/ci/expected/cancel-reschedule.run
diff --git a/ci/expected/capacity.run b/rtic/ci/expected/capacity.run
index f96815de..f96815de 100644
--- a/ci/expected/capacity.run
+++ b/rtic/ci/expected/capacity.run
diff --git a/ci/expected/cfg-whole-task.run b/rtic/ci/expected/cfg-whole-task.run
index e69de29b..e69de29b 100644
--- a/ci/expected/cfg-whole-task.run
+++ b/rtic/ci/expected/cfg-whole-task.run
diff --git a/ci/expected/common.run b/rtic/ci/expected/common.run
index e69de29b..e69de29b 100644
--- a/ci/expected/common.run
+++ b/rtic/ci/expected/common.run
diff --git a/ci/expected/complex.run b/rtic/ci/expected/complex.run
index 5df884da..5df884da 100644
--- a/ci/expected/complex.run
+++ b/rtic/ci/expected/complex.run
diff --git a/ci/expected/declared_locals.run b/rtic/ci/expected/declared_locals.run
index e69de29b..e69de29b 100644
--- a/ci/expected/declared_locals.run
+++ b/rtic/ci/expected/declared_locals.run
diff --git a/ci/expected/destructure.run b/rtic/ci/expected/destructure.run
index 25a4b1bd..25a4b1bd 100644
--- a/ci/expected/destructure.run
+++ b/rtic/ci/expected/destructure.run
diff --git a/ci/expected/extern_binds.run b/rtic/ci/expected/extern_binds.run
index 9d925d52..9d925d52 100644
--- a/ci/expected/extern_binds.run
+++ b/rtic/ci/expected/extern_binds.run
diff --git a/ci/expected/extern_spawn.run b/rtic/ci/expected/extern_spawn.run
index 257cc564..257cc564 100644
--- a/ci/expected/extern_spawn.run
+++ b/rtic/ci/expected/extern_spawn.run
diff --git a/ci/expected/generics.run b/rtic/ci/expected/generics.run
index fb31731e..fb31731e 100644
--- a/ci/expected/generics.run
+++ b/rtic/ci/expected/generics.run
diff --git a/ci/expected/hardware.run b/rtic/ci/expected/hardware.run
index ef00864b..ef00864b 100644
--- a/ci/expected/hardware.run
+++ b/rtic/ci/expected/hardware.run
diff --git a/ci/expected/idle-wfi.run b/rtic/ci/expected/idle-wfi.run
index 43077763..43077763 100644
--- a/ci/expected/idle-wfi.run
+++ b/rtic/ci/expected/idle-wfi.run
diff --git a/ci/expected/idle.run b/rtic/ci/expected/idle.run
index 43077763..43077763 100644
--- a/ci/expected/idle.run
+++ b/rtic/ci/expected/idle.run
diff --git a/ci/expected/init.run b/rtic/ci/expected/init.run
index b1b71610..b1b71610 100644
--- a/ci/expected/init.run
+++ b/rtic/ci/expected/init.run
diff --git a/ci/expected/locals.run b/rtic/ci/expected/locals.run
index 4f1d3509..4f1d3509 100644
--- a/ci/expected/locals.run
+++ b/rtic/ci/expected/locals.run
diff --git a/ci/expected/lock-free.run b/rtic/ci/expected/lock-free.run
index 18de0eca..18de0eca 100644
--- a/ci/expected/lock-free.run
+++ b/rtic/ci/expected/lock-free.run
diff --git a/ci/expected/lock.run b/rtic/ci/expected/lock.run
index a987b372..a987b372 100644
--- a/ci/expected/lock.run
+++ b/rtic/ci/expected/lock.run
diff --git a/ci/expected/message.run b/rtic/ci/expected/message.run
index 11814db2..11814db2 100644
--- a/ci/expected/message.run
+++ b/rtic/ci/expected/message.run
diff --git a/ci/expected/message_passing.run b/rtic/ci/expected/message_passing.run
index a1448d8d..a1448d8d 100644
--- a/ci/expected/message_passing.run
+++ b/rtic/ci/expected/message_passing.run
diff --git a/ci/expected/multilock.run b/rtic/ci/expected/multilock.run
index dd8c1f29..dd8c1f29 100644
--- a/ci/expected/multilock.run
+++ b/rtic/ci/expected/multilock.run
diff --git a/ci/expected/not-sync.run b/rtic/ci/expected/not-sync.run
index cd91476a..cd91476a 100644
--- a/ci/expected/not-sync.run
+++ b/rtic/ci/expected/not-sync.run
diff --git a/ci/expected/only-shared-access.run b/rtic/ci/expected/only-shared-access.run
index dcc73e64..dcc73e64 100644
--- a/ci/expected/only-shared-access.run
+++ b/rtic/ci/expected/only-shared-access.run
diff --git a/ci/expected/periodic-at.run b/rtic/ci/expected/periodic-at.run
index bf5bb063..bf5bb063 100644
--- a/ci/expected/periodic-at.run
+++ b/rtic/ci/expected/periodic-at.run
diff --git a/ci/expected/periodic-at2.run b/rtic/ci/expected/periodic-at2.run
index 6e56421a..6e56421a 100644
--- a/ci/expected/periodic-at2.run
+++ b/rtic/ci/expected/periodic-at2.run
diff --git a/ci/expected/periodic.run b/rtic/ci/expected/periodic.run
index a1f89441..a1f89441 100644
--- a/ci/expected/periodic.run
+++ b/rtic/ci/expected/periodic.run
diff --git a/ci/expected/peripherals-taken.run b/rtic/ci/expected/peripherals-taken.run
index e69de29b..e69de29b 100644
--- a/ci/expected/peripherals-taken.run
+++ b/rtic/ci/expected/peripherals-taken.run
diff --git a/ci/expected/pool.run b/rtic/ci/expected/pool.run
index e69de29b..e69de29b 100644
--- a/ci/expected/pool.run
+++ b/rtic/ci/expected/pool.run
diff --git a/ci/expected/preempt.run b/rtic/ci/expected/preempt.run
index 932b2b32..932b2b32 100644
--- a/ci/expected/preempt.run
+++ b/rtic/ci/expected/preempt.run
diff --git a/ci/expected/ramfunc.run b/rtic/ci/expected/ramfunc.run
index 257cc564..257cc564 100644
--- a/ci/expected/ramfunc.run
+++ b/rtic/ci/expected/ramfunc.run
diff --git a/ci/expected/ramfunc.run.grep.bar b/rtic/ci/expected/ramfunc.run.grep.bar
index 33e002fe..33e002fe 100644
--- a/ci/expected/ramfunc.run.grep.bar
+++ b/rtic/ci/expected/ramfunc.run.grep.bar
diff --git a/ci/expected/ramfunc.run.grep.foo b/rtic/ci/expected/ramfunc.run.grep.foo
index 44e88226..44e88226 100644
--- a/ci/expected/ramfunc.run.grep.foo
+++ b/rtic/ci/expected/ramfunc.run.grep.foo
diff --git a/ci/expected/resource-user-struct.run b/rtic/ci/expected/resource-user-struct.run
index a587a942..a587a942 100644
--- a/ci/expected/resource-user-struct.run
+++ b/rtic/ci/expected/resource-user-struct.run
diff --git a/ci/expected/schedule.run b/rtic/ci/expected/schedule.run
index 1dbd445c..1dbd445c 100644
--- a/ci/expected/schedule.run
+++ b/rtic/ci/expected/schedule.run
diff --git a/ci/expected/shared.run b/rtic/ci/expected/shared.run
index 6d3d3e43..6d3d3e43 100644
--- a/ci/expected/shared.run
+++ b/rtic/ci/expected/shared.run
diff --git a/ci/expected/smallest.run b/rtic/ci/expected/smallest.run
index e69de29b..e69de29b 100644
--- a/ci/expected/smallest.run
+++ b/rtic/ci/expected/smallest.run
diff --git a/ci/expected/spawn.run b/rtic/ci/expected/spawn.run
index 240cd18f..240cd18f 100644
--- a/ci/expected/spawn.run
+++ b/rtic/ci/expected/spawn.run
diff --git a/ci/expected/static.run b/rtic/ci/expected/static.run
index 3d3f46f6..3d3f46f6 100644
--- a/ci/expected/static.run
+++ b/rtic/ci/expected/static.run
diff --git a/ci/expected/t-binds.run b/rtic/ci/expected/t-binds.run
index e69de29b..e69de29b 100644
--- a/ci/expected/t-binds.run
+++ b/rtic/ci/expected/t-binds.run
diff --git a/ci/expected/t-cfg-resources.run b/rtic/ci/expected/t-cfg-resources.run
index e69de29b..e69de29b 100644
--- a/ci/expected/t-cfg-resources.run
+++ b/rtic/ci/expected/t-cfg-resources.run
diff --git a/ci/expected/t-htask-main.run b/rtic/ci/expected/t-htask-main.run
index e69de29b..e69de29b 100644
--- a/ci/expected/t-htask-main.run
+++ b/rtic/ci/expected/t-htask-main.run
diff --git a/ci/expected/t-idle-main.run b/rtic/ci/expected/t-idle-main.run
index e69de29b..e69de29b 100644
--- a/ci/expected/t-idle-main.run
+++ b/rtic/ci/expected/t-idle-main.run
diff --git a/ci/expected/t-late-not-send.run b/rtic/ci/expected/t-late-not-send.run
index e69de29b..e69de29b 100644
--- a/ci/expected/t-late-not-send.run
+++ b/rtic/ci/expected/t-late-not-send.run
diff --git a/ci/expected/t-schedule.run b/rtic/ci/expected/t-schedule.run
index e69de29b..e69de29b 100644
--- a/ci/expected/t-schedule.run
+++ b/rtic/ci/expected/t-schedule.run
diff --git a/ci/expected/t-spawn.run b/rtic/ci/expected/t-spawn.run
index e69de29b..e69de29b 100644
--- a/ci/expected/t-spawn.run
+++ b/rtic/ci/expected/t-spawn.run
diff --git a/ci/expected/task.run b/rtic/ci/expected/task.run
index de45dce6..de45dce6 100644
--- a/ci/expected/task.run
+++ b/rtic/ci/expected/task.run
diff --git a/ci/expected/zero-prio-task.run b/rtic/ci/expected/zero-prio-task.run
index 123b0f26..123b0f26 100644
--- a/ci/expected/zero-prio-task.run
+++ b/rtic/ci/expected/zero-prio-task.run
diff --git a/examples/async-delay.no_rs b/rtic/examples/async-delay.no_rs
index fb478c3f..fb478c3f 100644
--- a/examples/async-delay.no_rs
+++ b/rtic/examples/async-delay.no_rs
diff --git a/examples/async-infinite-loop.no_rs b/rtic/examples/async-infinite-loop.no_rs
index a95f9986..a95f9986 100644
--- a/examples/async-infinite-loop.no_rs
+++ b/rtic/examples/async-infinite-loop.no_rs
diff --git a/examples/async-task-multiple-prios.rs b/rtic/examples/async-task-multiple-prios.rs
index 5c9674d7..5c9674d7 100644
--- a/examples/async-task-multiple-prios.rs
+++ b/rtic/examples/async-task-multiple-prios.rs
diff --git a/examples/async-task.rs b/rtic/examples/async-task.rs
index 7730c54d..7730c54d 100644
--- a/examples/async-task.rs
+++ b/rtic/examples/async-task.rs
diff --git a/examples/async-timeout.no_rs b/rtic/examples/async-timeout.no_rs
index 3f68df74..3f68df74 100644
--- a/examples/async-timeout.no_rs
+++ b/rtic/examples/async-timeout.no_rs
diff --git a/examples/big-struct-opt.rs b/rtic/examples/big-struct-opt.rs
index 408a2dec..408a2dec 100644
--- a/examples/big-struct-opt.rs
+++ b/rtic/examples/big-struct-opt.rs
diff --git a/examples/binds.rs b/rtic/examples/binds.rs
index cf078ffe..cf078ffe 100644
--- a/examples/binds.rs
+++ b/rtic/examples/binds.rs
diff --git a/examples/cancel-reschedule.no_rs b/rtic/examples/cancel-reschedule.no_rs
index a38a9c4e..a38a9c4e 100644
--- a/examples/cancel-reschedule.no_rs
+++ b/rtic/examples/cancel-reschedule.no_rs
diff --git a/examples/capacity.no_rs b/rtic/examples/capacity.no_rs
index a6172698..a6172698 100644
--- a/examples/capacity.no_rs
+++ b/rtic/examples/capacity.no_rs
diff --git a/examples/cfg-whole-task.no_rs b/rtic/examples/cfg-whole-task.no_rs
index f41866db..f41866db 100644
--- a/examples/cfg-whole-task.no_rs
+++ b/rtic/examples/cfg-whole-task.no_rs
diff --git a/examples/common.no_rs b/rtic/examples/common.no_rs
index 1fe671e6..1fe671e6 100644
--- a/examples/common.no_rs
+++ b/rtic/examples/common.no_rs
diff --git a/examples/complex.rs b/rtic/examples/complex.rs
index c1e9c6c6..c1e9c6c6 100644
--- a/examples/complex.rs
+++ b/rtic/examples/complex.rs
diff --git a/examples/declared_locals.rs b/rtic/examples/declared_locals.rs
index c8451910..c8451910 100644
--- a/examples/declared_locals.rs
+++ b/rtic/examples/declared_locals.rs
diff --git a/examples/destructure.rs b/rtic/examples/destructure.rs
index 81eff3b4..81eff3b4 100644
--- a/examples/destructure.rs
+++ b/rtic/examples/destructure.rs
diff --git a/examples/extern_binds.rs b/rtic/examples/extern_binds.rs
index 142a11d0..142a11d0 100644
--- a/examples/extern_binds.rs
+++ b/rtic/examples/extern_binds.rs
diff --git a/examples/extern_spawn.rs b/rtic/examples/extern_spawn.rs
index b2b95b9d..b2b95b9d 100644
--- a/examples/extern_spawn.rs
+++ b/rtic/examples/extern_spawn.rs
diff --git a/examples/generics.rs b/rtic/examples/generics.rs
index 2f23cce9..2f23cce9 100644
--- a/examples/generics.rs
+++ b/rtic/examples/generics.rs
diff --git a/examples/hardware.rs b/rtic/examples/hardware.rs
index 62ae0d66..62ae0d66 100644
--- a/examples/hardware.rs
+++ b/rtic/examples/hardware.rs
diff --git a/examples/idle-wfi.rs b/rtic/examples/idle-wfi.rs
index 8134ce3e..8134ce3e 100644
--- a/examples/idle-wfi.rs
+++ b/rtic/examples/idle-wfi.rs
diff --git a/examples/idle.rs b/rtic/examples/idle.rs
index 0c4bd044..0c4bd044 100644
--- a/examples/idle.rs
+++ b/rtic/examples/idle.rs
diff --git a/examples/init.rs b/rtic/examples/init.rs
index c3081bf8..c3081bf8 100644
--- a/examples/init.rs
+++ b/rtic/examples/init.rs
diff --git a/examples/locals.rs b/rtic/examples/locals.rs
index ec3d59d8..ec3d59d8 100644
--- a/examples/locals.rs
+++ b/rtic/examples/locals.rs
diff --git a/examples/lock-free.no_rs b/rtic/examples/lock-free.no_rs
index 053307c1..053307c1 100644
--- a/examples/lock-free.no_rs
+++ b/rtic/examples/lock-free.no_rs
diff --git a/examples/lock.rs b/rtic/examples/lock.rs
index 203ae6f4..203ae6f4 100644
--- a/examples/lock.rs
+++ b/rtic/examples/lock.rs
diff --git a/examples/message.no_rs b/rtic/examples/message.no_rs
index 76c5675a..76c5675a 100644
--- a/examples/message.no_rs
+++ b/rtic/examples/message.no_rs
diff --git a/examples/message_passing.no_rs b/rtic/examples/message_passing.no_rs
index ffa95371..ffa95371 100644
--- a/examples/message_passing.no_rs
+++ b/rtic/examples/message_passing.no_rs
diff --git a/examples/multilock.rs b/rtic/examples/multilock.rs
index 6208cacc..6208cacc 100644
--- a/examples/multilock.rs
+++ b/rtic/examples/multilock.rs
diff --git a/examples/not-sync.rs b/rtic/examples/not-sync.rs
index 6d1ddaea..6d1ddaea 100644
--- a/examples/not-sync.rs
+++ b/rtic/examples/not-sync.rs
diff --git a/examples/only-shared-access.rs b/rtic/examples/only-shared-access.rs
index 1d006e63..1d006e63 100644
--- a/examples/only-shared-access.rs
+++ b/rtic/examples/only-shared-access.rs
diff --git a/examples/periodic-at.no_rs b/rtic/examples/periodic-at.no_rs
index ca68ed5e..ca68ed5e 100644
--- a/examples/periodic-at.no_rs
+++ b/rtic/examples/periodic-at.no_rs
diff --git a/examples/periodic-at2.no_rs b/rtic/examples/periodic-at2.no_rs
index ec9adcc5..ec9adcc5 100644
--- a/examples/periodic-at2.no_rs
+++ b/rtic/examples/periodic-at2.no_rs
diff --git a/examples/periodic.no_rs b/rtic/examples/periodic.no_rs
index 2f9e8e6a..2f9e8e6a 100644
--- a/examples/periodic.no_rs
+++ b/rtic/examples/periodic.no_rs
diff --git a/examples/peripherals-taken.rs b/rtic/examples/peripherals-taken.rs
index 2f710e90..2f710e90 100644
--- a/examples/peripherals-taken.rs
+++ b/rtic/examples/peripherals-taken.rs
diff --git a/examples/pool.no_rs b/rtic/examples/pool.no_rs
index fb8589ad..fb8589ad 100644
--- a/examples/pool.no_rs
+++ b/rtic/examples/pool.no_rs
diff --git a/examples/preempt.rs b/rtic/examples/preempt.rs
index 4b11907c..4b11907c 100644
--- a/examples/preempt.rs
+++ b/rtic/examples/preempt.rs
diff --git a/examples/ramfunc.rs b/rtic/examples/ramfunc.rs
index e2e7f67b..e2e7f67b 100644
--- a/examples/ramfunc.rs
+++ b/rtic/examples/ramfunc.rs
diff --git a/examples/resource-user-struct.rs b/rtic/examples/resource-user-struct.rs
index fcbacaea..fcbacaea 100644
--- a/examples/resource-user-struct.rs
+++ b/rtic/examples/resource-user-struct.rs
diff --git a/examples/schedule.no_rs b/rtic/examples/schedule.no_rs
index 5bad5a30..5bad5a30 100644
--- a/examples/schedule.no_rs
+++ b/rtic/examples/schedule.no_rs
diff --git a/examples/shared.rs b/rtic/examples/shared.rs
index d0633fbd..d0633fbd 100644
--- a/examples/shared.rs
+++ b/rtic/examples/shared.rs
diff --git a/examples/smallest.rs b/rtic/examples/smallest.rs
index e54ae448..e54ae448 100644
--- a/examples/smallest.rs
+++ b/rtic/examples/smallest.rs
diff --git a/examples/spawn.rs b/rtic/examples/spawn.rs
index d30ecf1b..d30ecf1b 100644
--- a/examples/spawn.rs
+++ b/rtic/examples/spawn.rs
diff --git a/examples/static.rs b/rtic/examples/static.rs
index 7f656f45..7f656f45 100644
--- a/examples/static.rs
+++ b/rtic/examples/static.rs
diff --git a/examples/t-binds.rs b/rtic/examples/t-binds.rs
index bdeb3917..bdeb3917 100644
--- a/examples/t-binds.rs
+++ b/rtic/examples/t-binds.rs
diff --git a/examples/t-cfg-resources.rs b/rtic/examples/t-cfg-resources.rs
index 03287009..03287009 100644
--- a/examples/t-cfg-resources.rs
+++ b/rtic/examples/t-cfg-resources.rs
diff --git a/examples/t-htask-main.rs b/rtic/examples/t-htask-main.rs
index 8f885bc1..8f885bc1 100644
--- a/examples/t-htask-main.rs
+++ b/rtic/examples/t-htask-main.rs
diff --git a/examples/t-idle-main.rs b/rtic/examples/t-idle-main.rs
index 43215cf7..43215cf7 100644
--- a/examples/t-idle-main.rs
+++ b/rtic/examples/t-idle-main.rs
diff --git a/examples/t-late-not-send.rs b/rtic/examples/t-late-not-send.rs
index 44d1d855..44d1d855 100644
--- a/examples/t-late-not-send.rs
+++ b/rtic/examples/t-late-not-send.rs
diff --git a/examples/t-schedule.no_rs b/rtic/examples/t-schedule.no_rs
index 5ec42087..5ec42087 100644
--- a/examples/t-schedule.no_rs
+++ b/rtic/examples/t-schedule.no_rs
diff --git a/examples/t-spawn.no_rs b/rtic/examples/t-spawn.no_rs
index dad0c83a..dad0c83a 100644
--- a/examples/t-spawn.no_rs
+++ b/rtic/examples/t-spawn.no_rs
diff --git a/examples/task.rs b/rtic/examples/task.rs
index ab6a1e0e..ab6a1e0e 100644
--- a/examples/task.rs
+++ b/rtic/examples/task.rs
diff --git a/examples/zero-prio-task.rs b/rtic/examples/zero-prio-task.rs
index c810e8fa..c810e8fa 100644
--- a/examples/zero-prio-task.rs
+++ b/rtic/examples/zero-prio-task.rs
diff --git a/macros/.gitignore b/rtic/macros/.gitignore
index 4fffb2f8..4fffb2f8 100644
--- a/macros/.gitignore
+++ b/rtic/macros/.gitignore
diff --git a/macros/Cargo.toml b/rtic/macros/Cargo.toml
index 1cc95565..2041d37c 100644
--- a/macros/Cargo.toml
+++ b/rtic/macros/Cargo.toml
@@ -21,7 +21,7 @@ version = "2.0.0-alpha.0"
[lib]
proc-macro = true
-[feature]
+[features]
default = []
debugprint = []
# list of supported codegen backends
diff --git a/macros/src/analyze.rs b/rtic/macros/src/analyze.rs
index 65774f6c..65774f6c 100644
--- a/macros/src/analyze.rs
+++ b/rtic/macros/src/analyze.rs
diff --git a/macros/src/bindings.rs b/rtic/macros/src/bindings.rs
index 8b137891..8b137891 100644
--- a/macros/src/bindings.rs
+++ b/rtic/macros/src/bindings.rs
diff --git a/macros/src/check.rs b/rtic/macros/src/check.rs
index a05c82e8..a05c82e8 100644
--- a/macros/src/check.rs
+++ b/rtic/macros/src/check.rs
diff --git a/macros/src/codegen.rs b/rtic/macros/src/codegen.rs
index 24e98ce9..24e98ce9 100644
--- a/macros/src/codegen.rs
+++ b/rtic/macros/src/codegen.rs
diff --git a/macros/src/codegen/assertions.rs b/rtic/macros/src/codegen/assertions.rs
index dd94aa6d..dd94aa6d 100644
--- a/macros/src/codegen/assertions.rs
+++ b/rtic/macros/src/codegen/assertions.rs
diff --git a/macros/src/codegen/async_dispatchers.rs b/rtic/macros/src/codegen/async_dispatchers.rs
index a12ad325..a12ad325 100644
--- a/macros/src/codegen/async_dispatchers.rs
+++ b/rtic/macros/src/codegen/async_dispatchers.rs
diff --git a/macros/src/codegen/hardware_tasks.rs b/rtic/macros/src/codegen/hardware_tasks.rs
index 8a5a8f6c..8a5a8f6c 100644
--- a/macros/src/codegen/hardware_tasks.rs
+++ b/rtic/macros/src/codegen/hardware_tasks.rs
diff --git a/macros/src/codegen/idle.rs b/rtic/macros/src/codegen/idle.rs
index 0c833ef3..0c833ef3 100644
--- a/macros/src/codegen/idle.rs
+++ b/rtic/macros/src/codegen/idle.rs
diff --git a/macros/src/codegen/init.rs b/rtic/macros/src/codegen/init.rs
index 6e1059f7..6e1059f7 100644
--- a/macros/src/codegen/init.rs
+++ b/rtic/macros/src/codegen/init.rs
diff --git a/macros/src/codegen/local_resources.rs b/rtic/macros/src/codegen/local_resources.rs
index e6d15533..e6d15533 100644
--- a/macros/src/codegen/local_resources.rs
+++ b/rtic/macros/src/codegen/local_resources.rs
diff --git a/macros/src/codegen/local_resources_struct.rs b/rtic/macros/src/codegen/local_resources_struct.rs
index 100c3eb5..100c3eb5 100644
--- a/macros/src/codegen/local_resources_struct.rs
+++ b/rtic/macros/src/codegen/local_resources_struct.rs
diff --git a/macros/src/codegen/main.rs b/rtic/macros/src/codegen/main.rs
index 2775d259..2775d259 100644
--- a/macros/src/codegen/main.rs
+++ b/rtic/macros/src/codegen/main.rs
diff --git a/macros/src/codegen/module.rs b/rtic/macros/src/codegen/module.rs
index 4725b9a9..4725b9a9 100644
--- a/macros/src/codegen/module.rs
+++ b/rtic/macros/src/codegen/module.rs
diff --git a/macros/src/codegen/post_init.rs b/rtic/macros/src/codegen/post_init.rs
index c4e53837..c4e53837 100644
--- a/macros/src/codegen/post_init.rs
+++ b/rtic/macros/src/codegen/post_init.rs
diff --git a/macros/src/codegen/pre_init.rs b/rtic/macros/src/codegen/pre_init.rs
index 28ba29c0..28ba29c0 100644
--- a/macros/src/codegen/pre_init.rs
+++ b/rtic/macros/src/codegen/pre_init.rs
diff --git a/macros/src/codegen/shared_resources.rs b/rtic/macros/src/codegen/shared_resources.rs
index 19fd13fe..19fd13fe 100644
--- a/macros/src/codegen/shared_resources.rs
+++ b/rtic/macros/src/codegen/shared_resources.rs
diff --git a/macros/src/codegen/shared_resources_struct.rs b/rtic/macros/src/codegen/shared_resources_struct.rs
index fa6f0fcb..fa6f0fcb 100644
--- a/macros/src/codegen/shared_resources_struct.rs
+++ b/rtic/macros/src/codegen/shared_resources_struct.rs
diff --git a/macros/src/codegen/software_tasks.rs b/rtic/macros/src/codegen/software_tasks.rs
index 34fc851a..34fc851a 100644
--- a/macros/src/codegen/software_tasks.rs
+++ b/rtic/macros/src/codegen/software_tasks.rs
diff --git a/macros/src/codegen/util.rs b/rtic/macros/src/codegen/util.rs
index e121487c..e121487c 100644
--- a/macros/src/codegen/util.rs
+++ b/rtic/macros/src/codegen/util.rs
diff --git a/macros/src/lib.rs b/rtic/macros/src/lib.rs
index a8422d09..a8422d09 100644
--- a/macros/src/lib.rs
+++ b/rtic/macros/src/lib.rs
diff --git a/macros/src/syntax.rs b/rtic/macros/src/syntax.rs
index d6f5a476..d6f5a476 100644
--- a/macros/src/syntax.rs
+++ b/rtic/macros/src/syntax.rs
diff --git a/macros/src/syntax/.github/bors.toml b/rtic/macros/src/syntax/.github/bors.toml
index aee6042f..aee6042f 100644
--- a/macros/src/syntax/.github/bors.toml
+++ b/rtic/macros/src/syntax/.github/bors.toml
diff --git a/macros/src/syntax/.github/workflows/build.yml b/rtic/macros/src/syntax/.github/workflows/build.yml
index 29971b10..29971b10 100644
--- a/macros/src/syntax/.github/workflows/build.yml
+++ b/rtic/macros/src/syntax/.github/workflows/build.yml
diff --git a/macros/src/syntax/.github/workflows/changelog.yml b/rtic/macros/src/syntax/.github/workflows/changelog.yml
index ccf6eb91..ccf6eb91 100644
--- a/macros/src/syntax/.github/workflows/changelog.yml
+++ b/rtic/macros/src/syntax/.github/workflows/changelog.yml
diff --git a/macros/src/syntax/.github/workflows/properties/build.properties.json b/rtic/macros/src/syntax/.github/workflows/properties/build.properties.json
index fd3eed37..fd3eed37 100644
--- a/macros/src/syntax/.github/workflows/properties/build.properties.json
+++ b/rtic/macros/src/syntax/.github/workflows/properties/build.properties.json
diff --git a/macros/src/syntax/.gitignore b/rtic/macros/src/syntax/.gitignore
index f8d7c8b4..f8d7c8b4 100644
--- a/macros/src/syntax/.gitignore
+++ b/rtic/macros/src/syntax/.gitignore
diff --git a/macros/src/syntax/.travis.yml b/rtic/macros/src/syntax/.travis.yml
index 52d1ffdd..52d1ffdd 100644
--- a/macros/src/syntax/.travis.yml
+++ b/rtic/macros/src/syntax/.travis.yml
diff --git a/macros/src/syntax/accessors.rs b/rtic/macros/src/syntax/accessors.rs
index e75dde6c..e75dde6c 100644
--- a/macros/src/syntax/accessors.rs
+++ b/rtic/macros/src/syntax/accessors.rs
diff --git a/macros/src/syntax/analyze.rs b/rtic/macros/src/syntax/analyze.rs
index 3ed14877..3ed14877 100644
--- a/macros/src/syntax/analyze.rs
+++ b/rtic/macros/src/syntax/analyze.rs
diff --git a/macros/src/syntax/ast.rs b/rtic/macros/src/syntax/ast.rs
index 27e6773f..27e6773f 100644
--- a/macros/src/syntax/ast.rs
+++ b/rtic/macros/src/syntax/ast.rs
diff --git a/macros/src/syntax/check.rs b/rtic/macros/src/syntax/check.rs
index 989d4180..989d4180 100644
--- a/macros/src/syntax/check.rs
+++ b/rtic/macros/src/syntax/check.rs
diff --git a/macros/src/syntax/optimize.rs b/rtic/macros/src/syntax/optimize.rs
index e83ba31b..e83ba31b 100644
--- a/macros/src/syntax/optimize.rs
+++ b/rtic/macros/src/syntax/optimize.rs
diff --git a/macros/src/syntax/parse.rs b/rtic/macros/src/syntax/parse.rs
index c78453a4..c78453a4 100644
--- a/macros/src/syntax/parse.rs
+++ b/rtic/macros/src/syntax/parse.rs
diff --git a/macros/src/syntax/parse/app.rs b/rtic/macros/src/syntax/parse/app.rs
index e797f75e..e797f75e 100644
--- a/macros/src/syntax/parse/app.rs
+++ b/rtic/macros/src/syntax/parse/app.rs
diff --git a/macros/src/syntax/parse/hardware_task.rs b/rtic/macros/src/syntax/parse/hardware_task.rs
index 7f6dfbe4..7f6dfbe4 100644
--- a/macros/src/syntax/parse/hardware_task.rs
+++ b/rtic/macros/src/syntax/parse/hardware_task.rs
diff --git a/macros/src/syntax/parse/idle.rs b/rtic/macros/src/syntax/parse/idle.rs
index 124c1366..124c1366 100644
--- a/macros/src/syntax/parse/idle.rs
+++ b/rtic/macros/src/syntax/parse/idle.rs
diff --git a/macros/src/syntax/parse/init.rs b/rtic/macros/src/syntax/parse/init.rs
index 0aea20bd..0aea20bd 100644
--- a/macros/src/syntax/parse/init.rs
+++ b/rtic/macros/src/syntax/parse/init.rs
diff --git a/macros/src/syntax/parse/resource.rs b/rtic/macros/src/syntax/parse/resource.rs
index ff100576..ff100576 100644
--- a/macros/src/syntax/parse/resource.rs
+++ b/rtic/macros/src/syntax/parse/resource.rs
diff --git a/macros/src/syntax/parse/software_task.rs b/rtic/macros/src/syntax/parse/software_task.rs
index 769aa653..769aa653 100644
--- a/macros/src/syntax/parse/software_task.rs
+++ b/rtic/macros/src/syntax/parse/software_task.rs
diff --git a/macros/src/syntax/parse/util.rs b/rtic/macros/src/syntax/parse/util.rs
index 5a5e0c0e..5a5e0c0e 100644
--- a/macros/src/syntax/parse/util.rs
+++ b/rtic/macros/src/syntax/parse/util.rs
diff --git a/macros/tests/ui.rs b/rtic/macros/tests/ui.rs
index 9fb88a1b..9fb88a1b 100644
--- a/macros/tests/ui.rs
+++ b/rtic/macros/tests/ui.rs
diff --git a/macros/ui/extern-interrupt-used.rs b/rtic/macros/ui/extern-interrupt-used.rs
index 6346a7d7..6346a7d7 100644
--- a/macros/ui/extern-interrupt-used.rs
+++ b/rtic/macros/ui/extern-interrupt-used.rs
diff --git a/macros/ui/extern-interrupt-used.stderr b/rtic/macros/ui/extern-interrupt-used.stderr
index 970d39be..970d39be 100644
--- a/macros/ui/extern-interrupt-used.stderr
+++ b/rtic/macros/ui/extern-interrupt-used.stderr
diff --git a/macros/ui/idle-double-local.rs b/rtic/macros/ui/idle-double-local.rs
index 54e67d34..54e67d34 100644
--- a/macros/ui/idle-double-local.rs
+++ b/rtic/macros/ui/idle-double-local.rs
diff --git a/macros/ui/idle-double-local.stderr b/rtic/macros/ui/idle-double-local.stderr
index b558136a..b558136a 100644
--- a/macros/ui/idle-double-local.stderr
+++ b/rtic/macros/ui/idle-double-local.stderr
diff --git a/macros/ui/idle-double-shared.rs b/rtic/macros/ui/idle-double-shared.rs
index f66cb935..f66cb935 100644
--- a/macros/ui/idle-double-shared.rs
+++ b/rtic/macros/ui/idle-double-shared.rs
diff --git a/macros/ui/idle-double-shared.stderr b/rtic/macros/ui/idle-double-shared.stderr
index 6f62ad28..6f62ad28 100644
--- a/macros/ui/idle-double-shared.stderr
+++ b/rtic/macros/ui/idle-double-shared.stderr
diff --git a/macros/ui/idle-input.rs b/rtic/macros/ui/idle-input.rs
index c896b1ce..c896b1ce 100644
--- a/macros/ui/idle-input.rs
+++ b/rtic/macros/ui/idle-input.rs
diff --git a/macros/ui/idle-input.stderr b/rtic/macros/ui/idle-input.stderr
index 34c38fc0..34c38fc0 100644
--- a/macros/ui/idle-input.stderr
+++ b/rtic/macros/ui/idle-input.stderr
diff --git a/macros/ui/idle-no-context.rs b/rtic/macros/ui/idle-no-context.rs
index bab4680b..bab4680b 100644
--- a/macros/ui/idle-no-context.rs
+++ b/rtic/macros/ui/idle-no-context.rs
diff --git a/macros/ui/idle-no-context.stderr b/rtic/macros/ui/idle-no-context.stderr
index c9f4b3df..c9f4b3df 100644
--- a/macros/ui/idle-no-context.stderr
+++ b/rtic/macros/ui/idle-no-context.stderr
diff --git a/macros/ui/idle-not-divergent.rs b/rtic/macros/ui/idle-not-divergent.rs
index d1ae8b1d..d1ae8b1d 100644
--- a/macros/ui/idle-not-divergent.rs
+++ b/rtic/macros/ui/idle-not-divergent.rs
diff --git a/macros/ui/idle-not-divergent.stderr b/rtic/macros/ui/idle-not-divergent.stderr
index e318f58a..e318f58a 100644
--- a/macros/ui/idle-not-divergent.stderr
+++ b/rtic/macros/ui/idle-not-divergent.stderr
diff --git a/macros/ui/idle-output.rs b/rtic/macros/ui/idle-output.rs
index 16621572..16621572 100644
--- a/macros/ui/idle-output.rs
+++ b/rtic/macros/ui/idle-output.rs
diff --git a/macros/ui/idle-output.stderr b/rtic/macros/ui/idle-output.stderr
index 7070e25f..7070e25f 100644
--- a/macros/ui/idle-output.stderr
+++ b/rtic/macros/ui/idle-output.stderr
diff --git a/macros/ui/idle-pub.rs b/rtic/macros/ui/idle-pub.rs
index 0d8dd01a..0d8dd01a 100644
--- a/macros/ui/idle-pub.rs
+++ b/rtic/macros/ui/idle-pub.rs
diff --git a/macros/ui/idle-pub.stderr b/rtic/macros/ui/idle-pub.stderr
index aa46ac39..aa46ac39 100644
--- a/macros/ui/idle-pub.stderr
+++ b/rtic/macros/ui/idle-pub.stderr
diff --git a/macros/ui/idle-unsafe.rs b/rtic/macros/ui/idle-unsafe.rs
index 3422ef2c..3422ef2c 100644
--- a/macros/ui/idle-unsafe.rs
+++ b/rtic/macros/ui/idle-unsafe.rs
diff --git a/macros/ui/idle-unsafe.stderr b/rtic/macros/ui/idle-unsafe.stderr
index a416800f..a416800f 100644
--- a/macros/ui/idle-unsafe.stderr
+++ b/rtic/macros/ui/idle-unsafe.stderr
diff --git a/macros/ui/init-divergent.rs b/rtic/macros/ui/init-divergent.rs
index 5e4e96a3..5e4e96a3 100644
--- a/macros/ui/init-divergent.rs
+++ b/rtic/macros/ui/init-divergent.rs
diff --git a/macros/ui/init-divergent.stderr b/rtic/macros/ui/init-divergent.stderr
index 9f6acf67..9f6acf67 100644
--- a/macros/ui/init-divergent.stderr
+++ b/rtic/macros/ui/init-divergent.stderr
diff --git a/macros/ui/init-double-local.rs b/rtic/macros/ui/init-double-local.rs
index 5f6d7ac0..5f6d7ac0 100644
--- a/macros/ui/init-double-local.rs
+++ b/rtic/macros/ui/init-double-local.rs
diff --git a/macros/ui/init-double-local.stderr b/rtic/macros/ui/init-double-local.stderr
index 07c3b50e..07c3b50e 100644
--- a/macros/ui/init-double-local.stderr
+++ b/rtic/macros/ui/init-double-local.stderr
diff --git a/macros/ui/init-double-shared.rs b/rtic/macros/ui/init-double-shared.rs
index 4503c87e..4503c87e 100644
--- a/macros/ui/init-double-shared.rs
+++ b/rtic/macros/ui/init-double-shared.rs
diff --git a/macros/ui/init-double-shared.stderr b/rtic/macros/ui/init-double-shared.stderr
index af2a97bc..af2a97bc 100644
--- a/macros/ui/init-double-shared.stderr
+++ b/rtic/macros/ui/init-double-shared.stderr
diff --git a/macros/ui/init-input.rs b/rtic/macros/ui/init-input.rs
index d41a503f..d41a503f 100644
--- a/macros/ui/init-input.rs
+++ b/rtic/macros/ui/init-input.rs
diff --git a/macros/ui/init-input.stderr b/rtic/macros/ui/init-input.stderr
index e2360435..e2360435 100644
--- a/macros/ui/init-input.stderr
+++ b/rtic/macros/ui/init-input.stderr
diff --git a/macros/ui/init-no-context.rs b/rtic/macros/ui/init-no-context.rs
index cdce4c55..cdce4c55 100644
--- a/macros/ui/init-no-context.rs
+++ b/rtic/macros/ui/init-no-context.rs
diff --git a/macros/ui/init-no-context.stderr b/rtic/macros/ui/init-no-context.stderr
index 28e1fd4f..28e1fd4f 100644
--- a/macros/ui/init-no-context.stderr
+++ b/rtic/macros/ui/init-no-context.stderr
diff --git a/macros/ui/init-output.rs b/rtic/macros/ui/init-output.rs
index 7057c954..7057c954 100644
--- a/macros/ui/init-output.rs
+++ b/rtic/macros/ui/init-output.rs
diff --git a/macros/ui/init-output.stderr b/rtic/macros/ui/init-output.stderr
index 8bc3c830..8bc3c830 100644
--- a/macros/ui/init-output.stderr
+++ b/rtic/macros/ui/init-output.stderr
diff --git a/macros/ui/init-pub.rs b/rtic/macros/ui/init-pub.rs
index dd59aa19..dd59aa19 100644
--- a/macros/ui/init-pub.rs
+++ b/rtic/macros/ui/init-pub.rs
diff --git a/macros/ui/init-pub.stderr b/rtic/macros/ui/init-pub.stderr
index b1610ed7..b1610ed7 100644
--- a/macros/ui/init-pub.stderr
+++ b/rtic/macros/ui/init-pub.stderr
diff --git a/macros/ui/init-unsafe.rs b/rtic/macros/ui/init-unsafe.rs
index 4f89bafa..4f89bafa 100644
--- a/macros/ui/init-unsafe.rs
+++ b/rtic/macros/ui/init-unsafe.rs
diff --git a/macros/ui/init-unsafe.stderr b/rtic/macros/ui/init-unsafe.stderr
index fd0b8f36..fd0b8f36 100644
--- a/macros/ui/init-unsafe.stderr
+++ b/rtic/macros/ui/init-unsafe.stderr
diff --git a/macros/ui/interrupt-double.rs b/rtic/macros/ui/interrupt-double.rs
index e2addc7c..e2addc7c 100644
--- a/macros/ui/interrupt-double.rs
+++ b/rtic/macros/ui/interrupt-double.rs
diff --git a/macros/ui/interrupt-double.stderr b/rtic/macros/ui/interrupt-double.stderr
index 8db34e26..8db34e26 100644
--- a/macros/ui/interrupt-double.stderr
+++ b/rtic/macros/ui/interrupt-double.stderr
diff --git a/macros/ui/local-collision-2.rs b/rtic/macros/ui/local-collision-2.rs
index 08bc8e55..08bc8e55 100644
--- a/macros/ui/local-collision-2.rs
+++ b/rtic/macros/ui/local-collision-2.rs
diff --git a/macros/ui/local-collision-2.stderr b/rtic/macros/ui/local-collision-2.stderr
index 47dbbe33..47dbbe33 100644
--- a/macros/ui/local-collision-2.stderr
+++ b/rtic/macros/ui/local-collision-2.stderr
diff --git a/macros/ui/local-collision.rs b/rtic/macros/ui/local-collision.rs
index 0e4eef72..0e4eef72 100644
--- a/macros/ui/local-collision.rs
+++ b/rtic/macros/ui/local-collision.rs
diff --git a/macros/ui/local-collision.stderr b/rtic/macros/ui/local-collision.stderr
index 47fbb6ec..47fbb6ec 100644
--- a/macros/ui/local-collision.stderr
+++ b/rtic/macros/ui/local-collision.stderr
diff --git a/macros/ui/local-malformed-1.rs b/rtic/macros/ui/local-malformed-1.rs
index 219eef54..219eef54 100644
--- a/macros/ui/local-malformed-1.rs
+++ b/rtic/macros/ui/local-malformed-1.rs
diff --git a/macros/ui/local-malformed-1.stderr b/rtic/macros/ui/local-malformed-1.stderr
index d15c324b..d15c324b 100644
--- a/macros/ui/local-malformed-1.stderr
+++ b/rtic/macros/ui/local-malformed-1.stderr
diff --git a/macros/ui/local-malformed-2.rs b/rtic/macros/ui/local-malformed-2.rs
index d6914536..d6914536 100644
--- a/macros/ui/local-malformed-2.rs
+++ b/rtic/macros/ui/local-malformed-2.rs
diff --git a/macros/ui/local-malformed-2.stderr b/rtic/macros/ui/local-malformed-2.stderr
index 0b448f01..0b448f01 100644
--- a/macros/ui/local-malformed-2.stderr
+++ b/rtic/macros/ui/local-malformed-2.stderr
diff --git a/macros/ui/local-malformed-3.rs b/rtic/macros/ui/local-malformed-3.rs
index 7eddfa41..7eddfa41 100644
--- a/macros/ui/local-malformed-3.rs
+++ b/rtic/macros/ui/local-malformed-3.rs
diff --git a/macros/ui/local-malformed-3.stderr b/rtic/macros/ui/local-malformed-3.stderr
index 61af4f38..61af4f38 100644
--- a/macros/ui/local-malformed-3.stderr
+++ b/rtic/macros/ui/local-malformed-3.stderr
diff --git a/macros/ui/local-malformed-4.rs b/rtic/macros/ui/local-malformed-4.rs
index b9139476..b9139476 100644
--- a/macros/ui/local-malformed-4.rs
+++ b/rtic/macros/ui/local-malformed-4.rs
diff --git a/macros/ui/local-malformed-4.stderr b/rtic/macros/ui/local-malformed-4.stderr
index 0f7d9e72..0f7d9e72 100644
--- a/macros/ui/local-malformed-4.stderr
+++ b/rtic/macros/ui/local-malformed-4.stderr
diff --git a/macros/ui/local-not-declared.rs b/rtic/macros/ui/local-not-declared.rs
index 7c087e47..7c087e47 100644
--- a/macros/ui/local-not-declared.rs
+++ b/rtic/macros/ui/local-not-declared.rs
diff --git a/macros/ui/local-not-declared.stderr b/rtic/macros/ui/local-not-declared.stderr
index 10d4b04b..10d4b04b 100644
--- a/macros/ui/local-not-declared.stderr
+++ b/rtic/macros/ui/local-not-declared.stderr
diff --git a/macros/ui/local-pub.rs b/rtic/macros/ui/local-pub.rs
index 42da4f47..42da4f47 100644
--- a/macros/ui/local-pub.rs
+++ b/rtic/macros/ui/local-pub.rs
diff --git a/macros/ui/local-pub.stderr b/rtic/macros/ui/local-pub.stderr
index e4814ca0..e4814ca0 100644
--- a/macros/ui/local-pub.stderr
+++ b/rtic/macros/ui/local-pub.stderr
diff --git a/macros/ui/local-shared-attribute.rs b/rtic/macros/ui/local-shared-attribute.rs
index c594b5f6..c594b5f6 100644
--- a/macros/ui/local-shared-attribute.rs
+++ b/rtic/macros/ui/local-shared-attribute.rs
diff --git a/macros/ui/local-shared-attribute.stderr b/rtic/macros/ui/local-shared-attribute.stderr
index a8130e88..a8130e88 100644
--- a/macros/ui/local-shared-attribute.stderr
+++ b/rtic/macros/ui/local-shared-attribute.stderr
diff --git a/macros/ui/local-shared.rs b/rtic/macros/ui/local-shared.rs
index 4e8f9f48..4e8f9f48 100644
--- a/macros/ui/local-shared.rs
+++ b/rtic/macros/ui/local-shared.rs
diff --git a/macros/ui/local-shared.stderr b/rtic/macros/ui/local-shared.stderr
index fceb7630..fceb7630 100644
--- a/macros/ui/local-shared.stderr
+++ b/rtic/macros/ui/local-shared.stderr
diff --git a/macros/ui/shared-lock-free.rs b/rtic/macros/ui/shared-lock-free.rs
index b3a4b9c7..b3a4b9c7 100644
--- a/macros/ui/shared-lock-free.rs
+++ b/rtic/macros/ui/shared-lock-free.rs
diff --git a/macros/ui/shared-lock-free.stderr b/rtic/macros/ui/shared-lock-free.stderr
index 51e99a0c..51e99a0c 100644
--- a/macros/ui/shared-lock-free.stderr
+++ b/rtic/macros/ui/shared-lock-free.stderr
diff --git a/macros/ui/shared-not-declared.rs b/rtic/macros/ui/shared-not-declared.rs
index 5fef5347..5fef5347 100644
--- a/macros/ui/shared-not-declared.rs
+++ b/rtic/macros/ui/shared-not-declared.rs
diff --git a/macros/ui/shared-not-declared.stderr b/rtic/macros/ui/shared-not-declared.stderr
index 7c5fb32e..7c5fb32e 100644
--- a/macros/ui/shared-not-declared.stderr
+++ b/rtic/macros/ui/shared-not-declared.stderr
diff --git a/macros/ui/shared-pub.rs b/rtic/macros/ui/shared-pub.rs
index 10351fd5..10351fd5 100644
--- a/macros/ui/shared-pub.rs
+++ b/rtic/macros/ui/shared-pub.rs
diff --git a/macros/ui/shared-pub.stderr b/rtic/macros/ui/shared-pub.stderr
index 71488933..71488933 100644
--- a/macros/ui/shared-pub.stderr
+++ b/rtic/macros/ui/shared-pub.stderr
diff --git a/macros/ui/task-divergent.rs b/rtic/macros/ui/task-divergent.rs
index ffe2dc0f..ffe2dc0f 100644
--- a/macros/ui/task-divergent.rs
+++ b/rtic/macros/ui/task-divergent.rs
diff --git a/macros/ui/task-divergent.stderr b/rtic/macros/ui/task-divergent.stderr
index dd002080..dd002080 100644
--- a/macros/ui/task-divergent.stderr
+++ b/rtic/macros/ui/task-divergent.stderr
diff --git a/macros/ui/task-double-local.rs b/rtic/macros/ui/task-double-local.rs
index c5277e2b..c5277e2b 100644
--- a/macros/ui/task-double-local.rs
+++ b/rtic/macros/ui/task-double-local.rs
diff --git a/macros/ui/task-double-local.stderr b/rtic/macros/ui/task-double-local.stderr
index 91ed8446..91ed8446 100644
--- a/macros/ui/task-double-local.stderr
+++ b/rtic/macros/ui/task-double-local.stderr
diff --git a/macros/ui/task-double-priority.rs b/rtic/macros/ui/task-double-priority.rs
index 5c8bd5b1..5c8bd5b1 100644
--- a/macros/ui/task-double-priority.rs
+++ b/rtic/macros/ui/task-double-priority.rs
diff --git a/macros/ui/task-double-priority.stderr b/rtic/macros/ui/task-double-priority.stderr
index b3c814a9..b3c814a9 100644
--- a/macros/ui/task-double-priority.stderr
+++ b/rtic/macros/ui/task-double-priority.stderr
diff --git a/macros/ui/task-double-shared.rs b/rtic/macros/ui/task-double-shared.rs
index f9812d39..f9812d39 100644
--- a/macros/ui/task-double-shared.rs
+++ b/rtic/macros/ui/task-double-shared.rs
diff --git a/macros/ui/task-double-shared.stderr b/rtic/macros/ui/task-double-shared.stderr
index bb902126..bb902126 100644
--- a/macros/ui/task-double-shared.stderr
+++ b/rtic/macros/ui/task-double-shared.stderr
diff --git a/macros/ui/task-idle.rs b/rtic/macros/ui/task-idle.rs
index 353c7826..353c7826 100644
--- a/macros/ui/task-idle.rs
+++ b/rtic/macros/ui/task-idle.rs
diff --git a/macros/ui/task-idle.stderr b/rtic/macros/ui/task-idle.stderr
index 4ccc1135..4ccc1135 100644
--- a/macros/ui/task-idle.stderr
+++ b/rtic/macros/ui/task-idle.stderr
diff --git a/macros/ui/task-init.rs b/rtic/macros/ui/task-init.rs
index e58fdceb..e58fdceb 100644
--- a/macros/ui/task-init.rs
+++ b/rtic/macros/ui/task-init.rs
diff --git a/macros/ui/task-init.stderr b/rtic/macros/ui/task-init.stderr
index 161e1943..161e1943 100644
--- a/macros/ui/task-init.stderr
+++ b/rtic/macros/ui/task-init.stderr
diff --git a/macros/ui/task-interrupt.rs b/rtic/macros/ui/task-interrupt.rs
index 3d50bd83..3d50bd83 100644
--- a/macros/ui/task-interrupt.rs
+++ b/rtic/macros/ui/task-interrupt.rs
diff --git a/macros/ui/task-interrupt.stderr b/rtic/macros/ui/task-interrupt.stderr
index 087b6c6e..087b6c6e 100644
--- a/macros/ui/task-interrupt.stderr
+++ b/rtic/macros/ui/task-interrupt.stderr
diff --git a/macros/ui/task-no-context.rs b/rtic/macros/ui/task-no-context.rs
index 55e8c3b4..55e8c3b4 100644
--- a/macros/ui/task-no-context.rs
+++ b/rtic/macros/ui/task-no-context.rs
diff --git a/macros/ui/task-no-context.stderr b/rtic/macros/ui/task-no-context.stderr
index 62147aab..62147aab 100644
--- a/macros/ui/task-no-context.stderr
+++ b/rtic/macros/ui/task-no-context.stderr
diff --git a/macros/ui/task-priority-too-high.rs b/rtic/macros/ui/task-priority-too-high.rs
index f33ba569..f33ba569 100644
--- a/macros/ui/task-priority-too-high.rs
+++ b/rtic/macros/ui/task-priority-too-high.rs
diff --git a/macros/ui/task-priority-too-high.stderr b/rtic/macros/ui/task-priority-too-high.stderr
index 5790c883..5790c883 100644
--- a/macros/ui/task-priority-too-high.stderr
+++ b/rtic/macros/ui/task-priority-too-high.stderr
diff --git a/macros/ui/task-priority-too-low.rs b/rtic/macros/ui/task-priority-too-low.rs
index 16e05577..16e05577 100644
--- a/macros/ui/task-priority-too-low.rs
+++ b/rtic/macros/ui/task-priority-too-low.rs
diff --git a/macros/ui/task-priority-too-low.stderr b/rtic/macros/ui/task-priority-too-low.stderr
index 85c86604..85c86604 100644
--- a/macros/ui/task-priority-too-low.stderr
+++ b/rtic/macros/ui/task-priority-too-low.stderr
diff --git a/macros/ui/task-pub.rs b/rtic/macros/ui/task-pub.rs
index 1ae533f6..1ae533f6 100644
--- a/macros/ui/task-pub.rs
+++ b/rtic/macros/ui/task-pub.rs
diff --git a/macros/ui/task-pub.stderr b/rtic/macros/ui/task-pub.stderr
index 7b9813d8..7b9813d8 100644
--- a/macros/ui/task-pub.stderr
+++ b/rtic/macros/ui/task-pub.stderr
diff --git a/macros/ui/task-unsafe.rs b/rtic/macros/ui/task-unsafe.rs
index a8383ef4..a8383ef4 100644
--- a/macros/ui/task-unsafe.rs
+++ b/rtic/macros/ui/task-unsafe.rs
diff --git a/macros/ui/task-unsafe.stderr b/rtic/macros/ui/task-unsafe.stderr
index 90ac76fe..90ac76fe 100644
--- a/macros/ui/task-unsafe.stderr
+++ b/rtic/macros/ui/task-unsafe.stderr
diff --git a/macros/ui/task-zero-prio.rs b/rtic/macros/ui/task-zero-prio.rs
index de3c86fc..de3c86fc 100644
--- a/macros/ui/task-zero-prio.rs
+++ b/rtic/macros/ui/task-zero-prio.rs
diff --git a/macros/ui/task-zero-prio.stderr b/rtic/macros/ui/task-zero-prio.stderr
index 1ab9aab6..1ab9aab6 100644
--- a/macros/ui/task-zero-prio.stderr
+++ b/rtic/macros/ui/task-zero-prio.stderr
diff --git a/rtic/rust-toolchain.toml b/rtic/rust-toolchain.toml
new file mode 100644
index 00000000..e28b55de
--- /dev/null
+++ b/rtic/rust-toolchain.toml
@@ -0,0 +1,4 @@
+[toolchain]
+channel = "nightly"
+components = [ "rust-src", "rustfmt", "llvm-tools-preview" ]
+targets = [ "thumbv6m-none-eabi", "thumbv7m-none-eabi" ]
diff --git a/src/export.rs b/rtic/src/export.rs
index cdca9727..cdca9727 100644
--- a/src/export.rs
+++ b/rtic/src/export.rs
diff --git a/src/export/executor.rs b/rtic/src/export/executor.rs
index e64cc43e..e64cc43e 100644
--- a/src/export/executor.rs
+++ b/rtic/src/export/executor.rs
diff --git a/src/lib.rs b/rtic/src/lib.rs
index e8b8140a..e8b8140a 100644
--- a/src/lib.rs
+++ b/rtic/src/lib.rs
diff --git a/tests/tests.rs b/rtic/tests/tests.rs
index 9fb88a1b..9fb88a1b 100644
--- a/tests/tests.rs
+++ b/rtic/tests/tests.rs
diff --git a/ui/exception-invalid.rs b/rtic/ui/exception-invalid.rs
index 4f8e943e..4f8e943e 100644
--- a/ui/exception-invalid.rs
+++ b/rtic/ui/exception-invalid.rs
diff --git a/ui/exception-invalid.stderr b/rtic/ui/exception-invalid.stderr
index 32123680..32123680 100644
--- a/ui/exception-invalid.stderr
+++ b/rtic/ui/exception-invalid.stderr
diff --git a/ui/extern-interrupt-not-enough.rs b/rtic/ui/extern-interrupt-not-enough.rs
index 94c8ee11..94c8ee11 100644
--- a/ui/extern-interrupt-not-enough.rs
+++ b/rtic/ui/extern-interrupt-not-enough.rs
diff --git a/ui/extern-interrupt-not-enough.stderr b/rtic/ui/extern-interrupt-not-enough.stderr
index e6c01b99..e6c01b99 100644
--- a/ui/extern-interrupt-not-enough.stderr
+++ b/rtic/ui/extern-interrupt-not-enough.stderr
diff --git a/ui/extern-interrupt-used.rs b/rtic/ui/extern-interrupt-used.rs
index 42de4c08..42de4c08 100644
--- a/ui/extern-interrupt-used.rs
+++ b/rtic/ui/extern-interrupt-used.rs
diff --git a/ui/extern-interrupt-used.stderr b/rtic/ui/extern-interrupt-used.stderr
index 75657399..75657399 100644
--- a/ui/extern-interrupt-used.stderr
+++ b/rtic/ui/extern-interrupt-used.stderr
diff --git a/ui/task-priority-too-high.rs b/rtic/ui/task-priority-too-high.rs
index 44e4a25d..44e4a25d 100644
--- a/ui/task-priority-too-high.rs
+++ b/rtic/ui/task-priority-too-high.rs
diff --git a/ui/task-priority-too-high.stderr b/rtic/ui/task-priority-too-high.stderr
index 12563777..12563777 100644
--- a/ui/task-priority-too-high.stderr
+++ b/rtic/ui/task-priority-too-high.stderr
diff --git a/ui/unknown-interrupt.rs b/rtic/ui/unknown-interrupt.rs
index 3c6c69f8..3c6c69f8 100644
--- a/ui/unknown-interrupt.rs
+++ b/rtic/ui/unknown-interrupt.rs
diff --git a/ui/unknown-interrupt.stderr b/rtic/ui/unknown-interrupt.stderr
index c7d32699..c7d32699 100644
--- a/ui/unknown-interrupt.stderr
+++ b/rtic/ui/unknown-interrupt.stderr
diff --git a/ui/v6m-interrupt-not-enough.rs_no b/rtic/ui/v6m-interrupt-not-enough.rs_no
index 3fbf3cf7..3fbf3cf7 100644
--- a/ui/v6m-interrupt-not-enough.rs_no
+++ b/rtic/ui/v6m-interrupt-not-enough.rs_no
diff --git a/xtask/Cargo.toml b/rtic/xtask/Cargo.toml
index f1c468ed..f1c468ed 100644
--- a/xtask/Cargo.toml
+++ b/rtic/xtask/Cargo.toml
diff --git a/xtask/src/build.rs b/rtic/xtask/src/build.rs
index 148a9fde..148a9fde 100644
--- a/xtask/src/build.rs
+++ b/rtic/xtask/src/build.rs
diff --git a/xtask/src/command.rs b/rtic/xtask/src/command.rs
index 4e903691..4e903691 100644
--- a/xtask/src/command.rs
+++ b/rtic/xtask/src/command.rs
diff --git a/xtask/src/main.rs b/rtic/xtask/src/main.rs
index 7eada917..7eada917 100644
--- a/xtask/src/main.rs
+++ b/rtic/xtask/src/main.rs