9 ms·
Question - How does one write microcontroller code (or other memory-mapped I/O code) using a memory-safe language?
by jmole 7y ago
Question - How does one write microcontroller code (or other memory-mapped I/O code) using a memory-safe language?
- tedunangst 7y agoBy calling unsafe code. :) The semantics and guarantees offered by the interface vary, but that's the short version.
- Nelson69 7y agoI have over 10 years of professional C++ and helped teach a course on it in college. One of my observations, and I may be off, is that a fair number of C++ users tend to take on a kind of macho attitude about it: it's a hammer for every nail, if you make certain mistakes you shouldn't use it or maybe be programming at all, garbage collection and other safety apparatus are kind of like training wheels while the "big boys" don't need that sort of thing. I'm being a little snarky here, but if you are truly a macho developer, then crapping out that unsafe code in optimized assembly or C or something is a really really easy time to show off and shouldn't be such a big deal for such a seasoned developer. Instead, the question is always raised in this more insecure way: for that tiny percentage of the time you have to do some bit-banging (and it's usually pretty small and encapsulated on most embedded projects) you had might as well do the whole thing in C or C++.
- hermitdev 7y agoI've over 15 years professional experience in C++, around 16 years in C#, and around 14 in Python, all overlapping. For me, it's about using the right tool for the job. It's not being a macho developer, but sometimes you need the hammer that C++ is, and you'll probably hit your thumb a few times using it.
- User23 7y agoOften that unsafe code is assembly language.
- AnimalMuppet 7y agoBeen there, done that. We were using Pascal (standard Pascal, no Turbo extensions) on a machine with memory mapped I/O. This means that we had to drop into assembly to write to the I/O registers. And that meant that we lost all type checking for those functions. We couldn't even check the number of parameters! Unsurprisingly, that led to a crash. That is: The extreme safety of Pascal led to a crash (when we had to do something that Pascal, in its wisdom, said we weren't allowed to do).
- snaky 7y agoPresuming it's not formally verified assembly code https://blogs.ncl.ac.uk/andreymokhov/spacecraft-control/ https://blogs.ncl.ac.uk/andreymokhov/spacecraft-control/
- clouddrover 7y agoLike this: https://rust-embedded.github.io/book/ https://rust-embedded.github.io/book/
- hu3 7y agoThat's not memory safe as the book itself states: > Now, the volatile accesses are performed automatically through the read and write methods. It's still unsafe to perform writes, but to be fair, hardware is a bunch of mutable state and there's no way for the compiler to know whether these writes are actually safe, so this is a good default position. https://github.com/rust-embedded/book/blob/9c05a419fc2ad231c204087dc073677026ba9488/src/peripherals/a-first-attempt.md#volatile-accesses https://github.com/rust-embedded/book/blob/9c05a419fc2ad231c...
- clouddrover 7y agoI think you need to read on a bit further. The very next section after the sentence you quoted is: "We need to wrap this struct up into a higher-layer API that is safe for our users to call. As the driver author, we manually verify the unsafe code is correct, and then present a safe API for our users so they don't have to worry about it (provided they trust us to get it right!)." Rust lets you write clearly defined unsafe code blocks. It's not a bug, it's a feature: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html https://doc.rust-lang.org/nomicon/index.html https://doc.rust-lang.org/nomicon/index.html It's worth reading through the whole Embedded Rust book even if you won't be implementing such software. It's interesting.
- hu3 7y agoDon't assume I haven't read it. I read the book. Wrapping unsafe code behind an API doesn't make it go away. It's still unsafe and needs manual checking. Also wrapping code with hints and annotations of some sort is a thing in numerous PL. It's a given, not a feature and certainly not a bug as you wrongly implied I stated. TLDR: it's still unsafe as the book and others pointed out.
- blihp 7y agoHistorically speaking, you didn't. It is only relatively recently that microcontrollers have become powerful and spacious enough for that to be an option.
- jbarham 7y agoUse MicroPython (http://micropython.org/ http://micropython.org/)
- shakna 7y agoTradeoffs. Ada has a history on microcontrollers, and is old enough we can answer with some certainty. You may end up having to bypass bottlenecks caused by runtime checks... And that means unsafe code in a critical location. Performance or safety. At different parts of your code you may find yourself choosing.
- 0xDEEPFAC 7y agoNot really, once you are sure of your Ada code you may choose to disable all checks or selectively disable checks for your production code. Meaning you essentially have no penalty if you choose to go the performance route after significant testing
- ajxs 7y agoI feel this is quite a nuanced question, I can answer one aspect of it though. When I think of what 'memory-safety' means in this context I think mainly of buffer overflows, dangling pointers, etc, things that have nothing really to do with memory mapped IO. I can't speak for Rust, but I've recently been doing quite a bit of embedded development in Ada ( Disclaimer: Not an expert ) and it supports mapping variables onto a arbitrary memory addresses through a variety of means that don't forgo static typing and compile-time checking. You can use access-types which are the closest thing to C's pointers, they allow for direct memory access while still preventing a good deal of the issues arising from misuse of pointers. I'd say it's well worth checking out for yourself.
- snaky 7y agoUsing ATS https://www.youtube.com/watch?v=eY1e3MLoYqg https://www.youtube.com/watch?v=eY1e3MLoYqg
- scoutt 7y agoYou can't, at least safely. If you can write arbitrarily to any position in RAM then it's not a memory-safe language. You can hide accesses behind some kind of abstraction (unsafe blocks, libraries or whatever). But that's not a memory-safe language, it's the developer making a contract with himself agreeing to not allowing direct, straight accesses (like those caveats we C/C++ developers do to not make "memory bugs"). Some microcontrollers can protect certain memory areas and raise access faults, but those are the same faults for a program written in C, C++, assembler, etc., and not related to the language. One make the safest RTOS in trendy-safe-lang for some small microcontroller, but the end-user (developers) would still be able to write some unsafe code and blow a fuse. A different thing is for MCUs with MMU and/or an OS that handles virtual memory per process/thread, but that wasn't your question.