Of course if you're bare-metal programming, it might be nice to have a lightweight mechanism for this.
Of course if you're bare-metal programming, it might be nice to have a lightweight mechanism for this.
1: I think you still need xargo/cargo-xbuild for no-std embedded sysroots, but there may have been some upstream development on that front since I last played in this sandbox.
Cargo's build-std flag is the bespoke way now. Unstable, but working it's way to stable. AFAIK cargo/build aren't getting any more development in lieu of build-std.
Can one use Rust's embedded_hal from a different programming language?
That api you write can be exposed via C abi so you can link C or languages that have an FFI to C to the rust code. https://docs.rust-embedded.org/book/interoperability/rust-wi...
Now if Cargo had a way of producing multiple variants of the same project (e.g. different --targets with pre-set features) just with `cargo build` then things would be a lot better.
As of now, a Makefile is still needed to bring it all together.
I don't use it in my firmwares because:
- All of the embedded-HAL libs I've found (eg drivers) have had notable limitations or ergonomics problems.
- It appears unsuitable for use with DMA, which I use for all runtime IO
- The APIs tend to be a mess due to heavy use of typestatesThe `embedded-hal-async` traits can be implemented with DMA, the Embassy HALs do so. This is a problem with the `nb` traits only.
> The APIs tend to be a mess due to heavy use of typestates
This is an issue of some HAL crates implementing the traits, not with the `embedded-hal` traits themselves. I also dislike the heavy use of typestates/generics, Embassy tries to implement the traits while keeping typestates at a minimum.
(disclaimer: Embassy maintainer here)
For parallelism, you also usually want a userspace task scheduler because simply spawning threads in kernelspace is much slower. Cilk and Go provide this built into their language runtime.
correct me if i'm wrong, but i think that even with an almost standard abi it's five instructions and 27 cortex-m3 clock cycles; here we reserve r10 for the current task pointer (with the bonus that you can use it for a tls base register) and round-robin among the tasks in a circularly linked list:
yield: push {r4-r9, r11, lr} @ save all callee-saved regs except r10
str sp, [r10], #4 @ save stack pointer in current task
ldr r10, [r10] @ load pointer to next task
ldr sp, [r10] @ switch to next task's stack
pop {r4-r9, r11, pc} @ return into yielded context there
i think in gcc that's more or less -mpic-register=r10 -msingle-pic-base, though that isn't what those options are meant forif you're willing and able to deform the abi a little by having less callee-saved registers, something you might want to do anyway for efficiency, you can cut r4-r9 down to r4-r5 and shave that down to i think 19 clocks? if you're willing to eliminate callee-saved registers entirely you can get to 15, but that seems like a heavy price to pay
if you have to use the standard abi it's i think 37 clocks on a cortex-m3 or better:
yield: push {r4-r12, lr}
ldr r9, =current_task_pointer
ldr r10, [r9]
str sp, [r10], #4
ldr r10, [r10]
str r10, [r9]
ldr sp, [r10]
pop {r4-r12, pc}
i feel like something in the range of 20-40 clocks is really not that expensive? i mean an ldr or str is 3 or 4 clocks if it's not accessing tcm, right? and on cortex-m0 every taken branch is 3 clocks because you don't have branch prediction?i mean it's not going to compete with barrel processors on context switch time, but if it's really the cost of accessing seven fields of structs on the heap, it hardly seems like it's "a hell of a lot more expensive" than even zero
if we're talking about preemptive context switching, that's a different ball of wax; you have to save all the registers that you use at all, not just callee-saved registers, and depending on your application maybe vfp registers as well as integer registers
Protothreads are classic now: https://dunkels.com/adam/pt/index.html
Contiki OS is also a piece of embedded development classic: https://en.wikipedia.org/wiki/Contiki
In general, it's more about syntax than semantics. Semantics is generally difficult and rarely changes.