C is a terrible language for building things in the modern world. Not including the progress over the last 4 decades in your new language is a mistake.
C is a terrible language for building things in the modern world. Not including the progress over the last 4 decades in your new language is a mistake.
No allocation = no leaks, no use after free, no dangling pointers.
No multi core = no atomics or concurrency to worry about.
Ring buffers solve 99% of my interrupt data sharing = no need to worry about synchronization.
Bounds/safety checks? Need to run and test release builds most of the time because of space/memory constraints.
For example, your i2c controller only supports two specific pins and they have to be in a specific mode? That can be a compile error if you make a mistake.
But C has no problems abstracting away peripherals, just hide the register bits in a private TU and expose i2c_init(), i2c_write(), etc.
That's not a zero cost abstraction, unless these "functions" are actually provided in an include file. Embedded programming is often performance sensitive, so this can matter.
- The package management is a nice. Install a generic ring buffer or a board support package for the hardware you are using.
- Async-await can be really nice for dealing with hardware peripherals.
- Don't interrupts constitute concurrency?
- Reduced UB and footguns compared to C
Often you don't allocate because it's not a necessity and a PITA due to C, but with rust I see no point in not using a tiny allocator if one has a few 100 KiB of RAM - totally depends on the project and target platform.
> No multi core = no atomics or concurrency to worry about.
There are interrupts though and those just need the same mechanisms than multicore and can be a PITA to manage in C. Besides that, there are quite a few cheap multicore embedded CPUs available now.
You can encode safety checks like pull-down/up clashes and the like nicely via the rust type system, that alone makes it a major benefit over C.
For example, from the rust embedded book:
One can also statically check that operations, like setting a pin low,
can only be performed on correctly configured peripherals.
For example, trying to change the output state of a pin configured in
floating input mode would raise a compile error.
-- https://docs.rust-embedded.org/book/static-guarantees/index....And this is where Hare is meant to be used, is it not?