Author Topic: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)  (Read 32152 times)

0 Members and 1 Guest are viewing this topic.

Offline ve7xen

  • Super Contributor
  • ***
  • Posts: 1192
  • Country: ca
    • VE7XEN Blog
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #325 on: March 29, 2023, 12:55:52 am »
I see. So, the ownership is static and never changes. You can access any periphery from only a single IRQL, and there's no way to circumvent this. I've never, not once, had a problem with accesses to certain periphery, and I do access the same periphery from different IRQLs for various reasons. May be there are people who routinely have those problems, but I really doubt so. Thus this ownership feature solves the problem which doesn't exist. On the other hand, it imposes restrictions on what you can do. So, such feature is both useless and harmful.

No, you don't see. Ownership can change, but it must be possible for the compiler to analyze it statically and it must satisfy some constraints. In other words the compiler needs to be able to infer a chain of (mutable) ownership. That is not possible when you introduce arbitrary concurrency, such as interrupts or (usually) threads/tasks. It's no problem to pass around a peripheral reference to wherever it's needed in your code within the same thread, either returning it implicitly (borrowing), even from a shared static, or with explicit ownership transfers. The problem here is trying to transfer it across thread boundaries.

Your view on what is 'harmless' seems...confused. It is definitely not harmless to let you do whatever you want in a concurrent context, there are countless ways this can go wrong. Concurrency is pretty difficult to get right in all but the most trivial of cases. In fact, it is usually difficult to show you aren't doing something stupid. It might 'work', but I think in a great many cases these things 'work' almost by accident and ignore many edge cases, for example the common read-modify-write semantics of GPIOs. What is useful about how Rust handles concurrency and ownership is that you can trust that if it compiles, you aren't doing something broken with concurrency, which is far more than most languages that can target microcontrollers can say about safe concurrency.

If you really want you can just stuff the peripheral in a UnsafeCell and wrap your access in unsafe {} but this is kind of defeating the purpose of the conversation. It might be necessary and safe sometimes, but it's not really what we're talking about here, and if you're littering your code with this, you're holding it wrong and should rethink your design.

Quote
Your vision of a CPU is very strange.  You say: "monitor the action inside the task", "set a flag that you monitor for this condition in another task". But how can you monitor flags or actions? CPU consecutively executing instructions from memory. To notice the change of a flag, the CPU needs to encounter an instruction that polls for that flag. If CPU executes a different task which doesn't want to yield, such task must be pre-empted first. This is done through a timer interrupt (which is typically 1ms in RTOSes). 1 ms is a very long time by MCU standards. And then the scheduler may give execution to a different task which it thinks needs execution faster. Here goes another 1 ms, and another, and another ...
Whether that task is the main loop, a green thread being run in an async exectuor, or a full-fledged RTOS task isn't really relevant, the point is that you safely 'send a message' out of interrupt context to where you can handle it more appropriately rather than try to do it in interrupt context itself. If you want to access it in the interrupt anyway, you can do so fairly easily with the pattern I showed above, which will be generally included in the processor support package, or use the built-in support in rtic or similar embedded runtime for this.

Quote
For example, you want to drive a pin high, then start a timer, get an interrupt from this timer 100 us later and, in the ISR, drive the pin low. Thus you hope to produce a 100 us pulse. Although this is not a good mechanism for producing pulses, this is a good example to demonstrate the time scale. If you relay the processing of the interrupt to the task-switching mechanism (because the ownership doesn't let you use the same pin from the ISR directly), the length of the pulse will be very far from 100 us. May be several ms instead. That's not you want.

No it's not, you should improve the design :).

Quote
Then you need to get creative and think how do you circumvent the static ownership. For example, you may give the ownership of the pin to the interrupt code, then immediately invoke the interrupt (say with 100 ns timer) to drive the pin high and then start the real timer to drive it low. See what happened: the language forced you to change things a bit to satisfy its internal hunger, but didn't provide any benefits in return. You spent time fighting the language instead of concentrating on your direct tasks. Does that make you more productive. I doubt so.

More productive? Once you embrace and learn how to use it, I don't think these concepts make you *less* productive. But they certainly provide far stronger guarantees about the correctness of what you are doing, which is, at least to me, of a lot of value and removes one huge source of both errors and 'problem solving' for lack of a better word. The learning curve is pretty steep though, and I am coming to this opinion from my experience using it for traditional programming. I haven't explored it much in embedded space yet, but I absolutely see the benefits.

Quote
Or, am I misunderstanding the mechanism of the ownership?
There are actually two concepts at play here. Ownership / borrow checker is one of them, the other is Sync/Send and concurrency. If peripherals were Sync+Send ('thread safe' basically), then they could be borrowed in interrupt context, but they aren't, so they need to somehow be wrapped in something that *is* Sync+Send. This is not difficult.
« Last Edit: March 29, 2023, 01:02:15 am by ve7xen »
73 de VE7XEN
He/Him
 

Online JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #326 on: March 29, 2023, 05:27:00 am »
For example, you want to drive a pin high, then start a timer, get an interrupt from this timer 100 us later and, in the ISR, drive the pin low. Thus you hope to produce a 100 us pulse. Although this is not a good mechanism for producing pulses, this is a good example to demonstrate the time scale. If you relay the processing of the interrupt to the task-switching mechanism (because the ownership doesn't let you use the same pin from the ISR directly), the length of the pulse will be very far from 100 us. May be several ms instead. That's not you want.

If your system is multitasking, and the scheduler has enough resolution, use a delay in the task/raise the task priority/make it a critical section and wait.. there are always alternatives. When i'm using freestanding C i'm taking all the liberties i want, i have to do all the choices after all. Instead in a freeRTOS project, for example, i try to use whatever the OS gives me for the best, even if i have to start again with a new approach at some point. Your case would be an exception because i would reserve a peripheral to do the work, or write a tiny, tiny section of firmware that live outside of he framework. It is an exception.

I always try not to share peripehrals between processes, but have a peripheral controlled by one process, then everything is between processes so the problem of sharing hardware never arises in the first place
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 8167
  • Country: fi
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #327 on: March 29, 2023, 05:47:17 am »
I see. So, the ownership is static and never changes. You can access any periphery from only a single IRQL, and there's no way to circumvent this. I've never, not once, had a problem with accesses to certain periphery, and I do access the same periphery from different IRQLs for various reasons. May be there are people who routinely have those problems, but I really doubt so. Thus this ownership feature solves the problem which doesn't exist. On the other hand, it imposes restrictions on what you can do. So, such feature is both useless and harmful.

No, you don't see. Ownership can change, but it must be possible for the compiler to analyze it statically and it must satisfy some constraints. In other words the compiler needs to be able to infer a chain of (mutable) ownership. That is not possible when you introduce arbitrary concurrency, such as interrupts or (usually) threads/tasks. It's no problem to pass around a peripheral reference to wherever it's needed in your code within the same thread, either returning it implicitly (borrowing), even from a shared static, or with explicit ownership transfers. The problem here is trying to transfer it across thread boundaries.

OK, I think I have seen enough. As a summary, Rust is completely unusable for most microcontroller projects because the whole paradigm is designed around problems that are not relevant at all, and the solutions to these nonexistent problems limits what you can do with it greatly; clearly the importance of interrupt-driven programming was not considered during language design, but instead OS-type scheduling multitasking.

There probably are workarounds that basically bypass the whole ownership system, but then the question is, is it sensible to use Rust, then?

I can see Rust being used in a general computing type, non-realtime system which does not need the event-response type programming written on top of the peripherals and their interrupt requests.

I still want to see a "better C" which fixes actual problems, those that cause real-life issues, which are possible to deal with language level; return addresses in stack, stack corruption, zero terminated strings, type system which is nearly OK but a bit too lacking resulting people to cast void* pointers.

But this whole ownership system seems like a total disaster of complexity. If the issue is atomic access to peripheral registers, it can be dealt with much easier.
« Last Edit: March 29, 2023, 05:49:44 am by Siwastaja »
 
The following users thanked this post: neil555, SiliconWizard

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 8167
  • Country: fi
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #328 on: March 29, 2023, 07:14:35 am »
Could you possibly confirm/deny that you've ever used Rust locally (hello world is sufficient) to dispel/cement the concern some posters have

How would Hello World help me dispel the concerns I have about the Rust's ownership system being useful in interrupt-driven real-time microcontroller development:palm:

Quote
that you're simply biased against new tools?  This post in particular simply shouts "fear" to me.

Your post in particular simply shouts absolute non-technical stupidness to me.

But now it's clear. This thread is polluted with the classical fanboyism, as always. Thanks for the "discussion".
 

Offline uliano

  • Regular Contributor
  • *
  • Posts: 172
  • Country: it
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #329 on: March 29, 2023, 07:34:48 am »
the concerns I have about the Rust's ownership system being useful in interrupt-driven real-time microcontroller development:palm:

I found a feasible answer in rtic with the caveat that it is immature (API is changing fast) and that it is just a solution for distributing ownership across interrupt tasks which is kinda an artificial problem introduced by rust, therefore you need to be already curious/motivated to check out rust.

Quote
But now it's clear. This thread is polluted with the classical fanboyism, as always. Thanks for the "discussion".

As always, it is everybody's choice to contribute to the content or to the noise...
« Last Edit: March 29, 2023, 07:38:42 am by uliano »
 
The following users thanked this post: gmb42

Offline wek

  • Frequent Contributor
  • **
  • Posts: 494
  • Country: sk
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #330 on: March 29, 2023, 08:02:27 am »
OK, I think I have seen enough. As a summary, Rust is completely unusable for most microcontroller projects because the whole paradigm is designed around problems that are not relevant at all, and the solutions to these nonexistent problems limits what you can do with it greatly; clearly the importance of interrupt-driven programming was not considered during language design, but instead OS-type scheduling multitasking.

There probably are workarounds that basically bypass the whole ownership system, but then the question is, is it sensible to use Rust, then?

I can see Rust being used in a general computing type, non-realtime system which does not need the event-response type programming written on top of the peripherals and their interrupt requests.

I still want to see a "better C" which fixes actual problems, those that cause real-life issues, which are possible to deal with language level; return addresses in stack, stack corruption, zero terminated strings, type system which is nearly OK but a bit too lacking resulting people to cast void* pointers.
The touted ownership feature may solve a problem which we don't have, and maybe there's no real solution in Rust for the real atomicity/concurrency/whaeveryoucallit problem; but that problem is hard, may have no good solution generally, and the language as such still may solve other problems which we do have (you've listed quite a couple of them above).

So, it still may be the "better C", although not for the reasons its proponents put forth; and it may drag unwanted baggage in, but which language doesn't.

JW
« Last Edit: March 29, 2023, 08:07:00 am by wek »
 
The following users thanked this post: Siwastaja, SiliconWizard

Offline Marco

  • Super Contributor
  • ***
  • Posts: 6716
  • Country: nl
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #331 on: March 29, 2023, 08:44:17 am »
You can use unsafe global variables to your c programmer hearts content, objecting to rust for not having an idiomatic way to do it better is a bit silly. Finding the best way to do it better is an open problem, but doing it just as bad is always an option (with a slightly more headache inducing syntax).

https://github.com/rust-embedded/not-yet-awesome-embedded-rust#sharing-data-with-interrupts
 

Offline wek

  • Frequent Contributor
  • **
  • Posts: 494
  • Country: sk
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #332 on: March 29, 2023, 09:09:14 am »
> objecting to rust for not having an idiomatic way to do it better is a bit silly

Rust is touted as the ultimate "safe" language, and the most pressing problem in mcu programming is atomicity/concurrency/whatevrryoucallit of variables/registers in main/interrupts. So, without knowing up front what exactly is meant by "safety", IMO it's a reasonable expectation that it encompasses this characteristic problem.

Turns out, it doesn't. Let's move on.

JW
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19465
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #333 on: March 29, 2023, 09:56:04 am »
I'll highlight a few comments I think important. The full context in ve7xen's post justifies them.

...

Your view on what is 'harmless' seems...confused. It is definitely not harmless to let you do whatever you want in a concurrent context, there are countless ways this can go wrong. Concurrency is pretty difficult to get right in all but the most trivial of cases. In fact, it is usually difficult to show you aren't doing something stupid. It might 'work', but I think in a great many cases these things 'work' almost by accident and ignore many edge cases, for example the common read-modify-write semantics of GPIOs.

...the point is that you safely 'send a message' out of interrupt context to where you can handle it more appropriately rather than try to do it in interrupt context itself ...

...
No it's not, you should improve the design :)

...

Once you embrace and learn how to use it, I don't think these concepts make you *less* productive. But they certainly provide far stronger guarantees about the correctness of what you are doing, which is, at least to me, of a lot of value and removes one huge source of both errors and 'problem solving' for lack of a better word. The learning curve is pretty steep though, and I am coming to this opinion from my experience using it for traditional programming. I haven't explored it much in embedded space yet, but I absolutely see the benefits.

...

Having noted those, if your market is such that getting to market fast is more important and having unreproduceable failures is less important, then I can understand that the existing tools may be preferable.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26883
  • Country: nl
    • NCT Developments
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #334 on: March 29, 2023, 10:08:08 am »
OK, I think I have seen enough. As a summary, Rust is completely unusable for most microcontroller projects because the whole paradigm is designed around problems that are not relevant at all, and the solutions to these nonexistent problems limits what you can do with it greatly; [....]

But this whole ownership system seems like a total disaster of complexity. If the issue is atomic access to peripheral registers, it can be dealt with much easier.

Could you possibly confirm/deny that you've ever used Rust locally (hello world is sufficient) to dispel/cement the concern some posters have that you're simply biased against new tools?

This post in particular simply shouts "fear" to me.
More like lack of understanding which is also where I am at. I'm thankfull for the insights that people who actually use Rust provide in this thread  :-+. IMHO it takes a far deeper study to understand how to use Rust effectively on embedded targets like microcontrollers while leveraging the advantages Rust is supposed to give. I assume that will be completely different compared to C and shoehorning the 'C way' into Rust will just result in pain & poor code.

One particular example of shoehorning one language into another is how VHDL and Verilog examples are typically put side to side where Verilog is translated into VHDL 1:1. In many cases VHDL provides a much better way of implementing the example due to the more extensive language constructs but the creator of the examples didn't know or didn't care.
« Last Edit: March 29, 2023, 01:23:57 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline baldurn

  • Regular Contributor
  • *
  • Posts: 187
  • Country: dk
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #335 on: March 29, 2023, 01:19:44 pm »
This is enough to solve the problem in C, but not in Rust.

I feel there is a big misunderstanding here. Nothing prevents you from writing an unsafe {} block in rust, casting a pointer to the GPIO block and just write to the damn IO pin. Bypassing the ownership model and everyting. Anything you can do in C you can also do in Rust in the exact same way, more or less. It is just unsafe code.

In doing so you are _probably_ shooting yourself in the foot, but if you really think it is warranted, you just do it.

In fact many fuctions in the Rust standard library are using unsafe blocks to implement stuff that can not be implemented in "pure" Rust. There are things where unsafe is the solution. If you isolate that to a few places and make sure that part of the program is well analyzed and understood, there is no problem. You can still use the safety of the language in the rest of the program.
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 8167
  • Country: fi
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #336 on: March 29, 2023, 03:29:28 pm »
I feel there is a big misunderstanding here. Nothing prevents you from writing an unsafe {} block in rust, casting a pointer to the GPIO block and just write to the damn IO pin. Bypassing the ownership model and everyting. Anything you can do in C you can also do in Rust in the exact same way, more or less. It is just unsafe code.

In doing so you are _probably_ shooting yourself in the foot, but if you really think it is warranted, you just do it.

I don't think there is any misunderstanding. Obviously you can bypass the "safety".

How is that different from casting and storing typed pointers into void* in C, then back into typed pointers, something nctnico brings up? It's the same thing, language has the more "safe" feature available which is the recommended way to work with, but because it is possible to circumvent, people do exactly that - and then others complain that it's the language problem.

What I realistically see is Rust programmer writing peripheral access functions (abstractions) and just wrap the implementation of said functions into unsafe{}, with parameter checking. It's exactly what I would do. But how is that different from the usual C counterpart, writing similar access functions and again doing parameter checks? Such C function is safe to call, too. The only difference I can see is the C's arrays decaying into pointers and not coupled with size; an error-prone process. Which is why I concentrate on that array bounds checking thing being a truly useful feature, but the ownership thing not so much.
« Last Edit: March 29, 2023, 03:34:14 pm by Siwastaja »
 

Offline baldurn

  • Regular Contributor
  • *
  • Posts: 187
  • Country: dk
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #337 on: March 29, 2023, 04:00:03 pm »
What I realistically see is Rust programmer writing peripheral access functions (abstractions) and just wrap the implementation of said functions into unsafe{}, with parameter checking. It's exactly what I would do. But how is that different from the usual C counterpart, writing similar access functions and again doing parameter checks? Such C function is safe to call, too. The only difference I can see is the C's arrays decaying into pointers and not coupled with size; an error-prone process. Which is why I concentrate on that array bounds checking thing being a truly useful feature, but the ownership thing not so much.

I would suggest that most people will use the premade PACs where available. But you can of course easily make your own version and you could make your PACs more C-like than Rust-like if that is to your likening. Having not done so much Rust code myself yet, I can not be sure, but I believe that Rust-style is actually not so bad to work with as some here thinks.

For simple programs I might agree that mixing up access to simple GPIO pins is probably not a huge deal. The available Rust PACs just implement pin ownership because they can and it is easy. It is better, at least in theory. And very easy to escape from if you find it a problem. You just put the "pin" into one of the available shareable container classes made for this purpose. Now it is the container that owns the pin and this container can be used from both your interrupt handler and main loop. You can choose a container that is a Mutex, or one that checks that there is no conflict at runtime or even one that is just "unsafe". No problem at all.

But even if you chose unsafe IO there is still a lot to be gained from memory safety and concurrency safety etc. It has been claimed by big players such as Microsoft and Google that 70% of all security bugs are memory related. Why not use the language if it fixes just that one thing?

 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3138
  • Country: ca
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #338 on: March 29, 2023, 04:04:36 pm »
This is enough to solve the problem in C, but not in Rust.

I feel there is a big misunderstanding here. Nothing prevents you from writing an unsafe {} block in rust, casting a pointer to the GPIO block and just write to the damn IO pin. Bypassing the ownership model and everyting. Anything you can do in C you can also do in Rust in the exact same way, more or less.

But I was thinking of a plan
To dye one's whiskers green,
And always use so large a fan
That it could not be seen.
 
The following users thanked this post: SiliconWizard

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3138
  • Country: ca
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #339 on: March 29, 2023, 04:29:34 pm »
Your view on what is 'harmless' seems...confused. It is definitely not harmless to let you do whatever you want in a concurrent context, there are countless ways this can go wrong.

This about explains everything.

You adopted the philosophy of a servant. In your mind, there must be a master who guides you through everything. And you have chosen Rust to be your master. You perceive "not being allowed" as a good thing. This gives you a feeling of safety. You're told that there many problems.  You have chosen to be afraid of them. You have chosen to trust your master to guide you around them in the safest way possible, whatever that means.

I however, adopted the philosophy of a free man. In my design, I can do whatever I want, nobody needs to allow me to do things. I perceive "not being allowed" as an assault to my freedom. I realize that there are problems out there. I have chosen not to be afraid of them. I have chosen to understand them and I I have chosen to learn to deal with them. As time goes by, I understand things better and better, and I will continue to learn until my brain stops working.

So, happy rusting :)
 

Offline ve7xen

  • Super Contributor
  • ***
  • Posts: 1192
  • Country: ca
    • VE7XEN Blog
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #340 on: March 29, 2023, 05:13:19 pm »
This discussion has focused on how Rust is not C, and doing things differently is bad.

Let's shift the focus to some things that are useful and convenient, and not just about safety guarantees that like anything safety-related are often less 'convenient', just like using your fall protection when working at height is less 'convenient' and a lot of people will be opposed to it, despite it saving many lives.

1. 'Enum Types' (aka. algebraic data types, sum types, tagged unions) and the match operator:

Code: [Select]
enum Message {
    One(u32),
    Two(String)
}

fn main() {
   let foo: Message = Message::One(10);
   let num = match foo {
       Message::One(uint) => uint,
       Message::Two(s) => s.len() as u32,
   };
}

There is no equivalent of this in C or C++, and it is so useful and ergonomic. Match is also much more powerful than suggested here, it can include predicate conditions in addition to the demonstrated type matching, and of course classic 'switch/case' type conditions, etc. This is also used throughout core and std, for example the useful Result (returns an Ok type that wraps a result, or an Err type that wraps an error result) and Option patterns (return a wrapped type or None). Since this leverages the static type system, there is no storage cost.

2. 'Traits' (aka. interfaces, mixins)

Code: [Select]
// Adding to the above
impl ToString for Message {
    fn to_string(&self) -> String {
        match self {
            Message::One(uint) => uint.to_string(),
            Message::Two(s) => s.to_owned(),
        }
    }
}

// Then we can pass anything that implements ToString as a parameter as a virtual call:
fn stringable(foo: &impl ToString) {
    println!("{}", foo.to_string());
}

// Or statically (generate new code for each T)
fn stringable2<T: ToString> (foo: T) {
  println!("{}", foo.to_string());
}

There are a host of standard traits in the library, and they can be used for things like automatically parsing strings to other types, converting/coercing between types, operator overrides, comparisons, and many other common tasks.

You can do this in C++ with multiple inheritance, but it's a lot less clean and avoiding dynamic calls is a lot more difficult (maybe impossible? not a template expert).

3. First-class closures and good iterators/functional primitives

Code: [Select]
let pred = |x: &&u32| x < &&10; // Yes this looks a bit ugly, it's not as silly for non-primitive types
let data: [u32; 5] = [1,11,2,12,15];
let sum: u32 = data.iter().filter(pred).sum();
println!("{}", sum);

3

C++11 has closures, but they aren't as ergonomic and it's lacking a lot of functional methods. C++20 can do the above (I think), but it's not nearly as clean.

4. The 'question mark operator' / error handling

Code: [Select]
fn foo() -> Result<u32, MyError> {
  let number = something_that_returns_a_result()?;
}

This is shorthand to unwrap the result if it's Ok, otherwise coerce to the error type of our result and return that. When you actually need to handle the error, you can use `match` or the similar `if let`. Not exceptions, and far more ergonmic than constantly wrapping calls in if() and returning sentinel values or whatever. C and C++ both suck at this and most programmers seem to prefer to not do any error handling at all.

And general observations: Type inference is awesome, and I haven't tried a language that is better than Rust at it (though I haven't ever ventured into things like Haskell). Rust's compiler errors are the most useful I have ever seen. The language seems to minimize boilerplate, while not generally feeling like it's constraining my style or forcing a particular approach. Learning how to contend with the borrow checker and lifetimes is challenging, but once you grok it, it doesn't really get in the way.

Quote
You adopted the philosophy of a servant. In your mind, there must be a master who guides you through everything. And you have chosen Rust to be your master. You perceive "not being allowed" as a good thing. This gives you a feeling of safety. You're told that there many problems.  You have chosen to be afraid of them. You have chosen to trust your master to guide you around them in the safest way possible, whatever that means.

Wow, just...wow. What an absurd take. Rather, it is the opposite. I have taken the view that I'd rather let my tools do the hard work of figuring out if what I'm doing makes sense. I'm going to stop wasting my time responding to you.
« Last Edit: March 29, 2023, 05:34:03 pm by ve7xen »
73 de VE7XEN
He/Him
 
The following users thanked this post: nctnico, alexanderbrevig, baldurn, karpouzi9

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26883
  • Country: nl
    • NCT Developments
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #341 on: March 29, 2023, 05:24:37 pm »
I have to say I find the syntax of Rust very cryptic. The meaning of the examples above is not clear at all to me. I get that the creators of Rust wanted to avoid getting slapped for creating a too verbose language like Ada/Pascal/VHDL but IMHO they went a bit overboard. It makes it hard to do a code review unless you are really intimate with the language.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline baldurn

  • Regular Contributor
  • *
  • Posts: 187
  • Country: dk
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #342 on: March 29, 2023, 05:43:56 pm »
I have to say I find the syntax of Rust very cryptic. The meaning of the examples above is not clear at all to me. I get that the creators of Rust wanted to avoid getting slapped for creating a too verbose language like Ada/Pascal/VHDL but IMHO they went a bit overboard. It makes it hard to do a code review unless you are really intimate with the language.

I come from a background in computer science. I know Haskel and several other functional languages. I have worked a fair amount Scala (a functional language on the JVM / alternative to Java). I have worked with libraries that do a lot of type system magic. Many of the concepts in Rust translate very well. I do however fear the learning curve is going to be steep for someone who has only done C or has not previously been exposed to much functional programming paradigm.

In the Scala community they have the same problem. So they made "levels" that represent reduced set of the language. The idea that the beginner is guided to learn the most useful parts of the language before getting confused by advanced concepts.

For me the problem with Rust has been mostly the documentation and specifically the auto generated API documentation. Nothing wrong with generating documentation from source code, but even the standard library seems to have a lot of methods that have just one line, actually only a shortened sentence, as a description. You are apparently supposed to recognize what this is about just from the name of the function and the function signature. This part is really subpar :-( The thing is for a learner you don't know how things fit together, plus parsing the signatures can be very hard. Double so if you are not used to read signatures with a lot of type variance, which might be concepts you do not really understand that well.

 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19465
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #343 on: March 29, 2023, 06:15:38 pm »
Your view on what is 'harmless' seems...confused. It is definitely not harmless to let you do whatever you want in a concurrent context, there are countless ways this can go wrong.

This about explains everything.

You adopted the philosophy of a servant. In your mind, there must be a master who guides you through everything. And you have chosen Rust to be your master. You perceive "not being allowed" as a good thing. This gives you a feeling of safety. You're told that there many problems.  You have chosen to be afraid of them. You have chosen to trust your master to guide you around them in the safest way possible, whatever that means.

I however, adopted the philosophy of a free man. In my design, I can do whatever I want, nobody needs to allow me to do things. I perceive "not being allowed" as an assault to my freedom. I realize that there are problems out there. I have chosen not to be afraid of them. I have chosen to understand them and I I have chosen to learn to deal with them. As time goes by, I understand things better and better, and I will continue to learn until my brain stops working.

Now you are just being a twat.

Yes, that is an ad hominem attact, one that is justified IMNHSO.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26883
  • Country: nl
    • NCT Developments
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #344 on: March 29, 2023, 06:34:42 pm »
I have to say I find the syntax of Rust very cryptic. The meaning of the examples above is not clear at all to me. I get that the creators of Rust wanted to avoid getting slapped for creating a too verbose language like Ada/Pascal/VHDL but IMHO they went a bit overboard. It makes it hard to do a code review unless you are really intimate with the language.

I come from a background in computer science. I know Haskel and several other functional languages. I have worked a fair amount Scala (a functional language on the JVM / alternative to Java). I have worked with libraries that do a lot of type system magic. Many of the concepts in Rust translate very well. I do however fear the learning curve is going to be steep for someone who has only done C or has not previously been exposed to much functional programming paradigm.

In the Scala community they have the same problem. So they made "levels" that represent reduced set of the language. The idea that the beginner is guided to learn the most useful parts of the language before getting confused by advanced concepts.
Not sure whether the spoon fed approach is a good one. Many will stick with the simple concepts and never be willing to use more efficient constructs. When I started with VHDL I always looked how I could get the most done with as little code as possible. It is not very productive in the beginning but it pays back later.

Quote
For me the problem with Rust has been mostly the documentation and specifically the auto generated API documentation. Nothing wrong with generating documentation from source code, but even the standard library seems to have a lot of methods that have just one line, actually only a shortened sentence, as a description. You are apparently supposed to recognize what this is about just from the name of the function and the function signature. This part is really subpar :-( The thing is for a learner you don't know how things fit together, plus parsing the signatures can be very hard. Double so if you are not used to read signatures with a lot of type variance, which might be concepts you do not really understand that well.
That is a big fail. Automatically generated documentation is outright useless because the coherency between the parts gets lost. How the parts fit together and how they are to be used is the most important information a user for a library needs. Someone should add ChatGPT to Doxygen as a code analysis tool and produce documentation. It will be an improvement for sure... But maybe (hopefully) there is a book about it.
« Last Edit: March 29, 2023, 06:54:36 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 
The following users thanked this post: Siwastaja

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 8167
  • Country: fi
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #345 on: March 29, 2023, 06:40:21 pm »
Now you are just being a twat.

That's true - but after all the snake oil selling and the utter "you are not just open to new things" bullshit* that comment made me chuckle out loud.

*) it's weird how some people always assume asking for data, and showing that something is not suitable for a specified task, based on data, is some kind of irrational "not liking change" reaction. Maybe, just maybe, we are not old bitter greybeards, but engineers who would not buy a capacitor if it has no voltage rating listed, and once found out that the voltage rating is 50V and our DC bus is 80V, then not buy the capacitor. But this is actually totally unsurprising - people project their own values into others. If one chooses to be interested in a programming language out of pure interest, then it's logical to assume others who don't reach the same conclusion do that out of disinterest. This is not necessarily the case. For example, I have commented multiple times which features I find useful (array bounds, more powerful type system) and which are the pain points (difficult to understand ownership system that does not seem to actually solve concurrency in interrupt-driven microcontroller designs at all). Yet, any of this does not matter - I'm being labeled a greybeard who is not open to the new things. So let it be that way, then; thumbs-up to NorthGuy's comment.
 
The following users thanked this post: neil555

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19465
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #346 on: March 29, 2023, 07:43:11 pm »
We have all seen new mousetraps[1] that are merely incremental variations on existing mousetraps. Boring.

I am always looking for a better mousetrap, where "better" "different" and "worse" all need to be specfied. TINSTAAFL.

Rust appears on the surface to be significantly better in some ways, but I do not yet understand the significant "different" and "worse" aspects. They will be more widely understood when many people have kicked the tyres.

And that's why I've stayed in this thread.

[1] or nutcrackers or, judging by the number and variety of Victorian patents, Apple corers.
« Last Edit: March 29, 2023, 09:02:00 pm by tggzzz »
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14440
  • Country: fr
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #347 on: March 29, 2023, 08:50:40 pm »
This discussion has focused on how Rust is not C,

That's not what most of the posts I've read or written here are about. If that's what you read, read again. IMHO.

and doing things differently is bad.

That's not at all what most posts here are about either.
I have actually not seen any real comparison of Rust with C in this thread, but more general considerations about programming languages and how Rust may not be as useful as it's hyped to be, at least for embedded software. It's more about how Rust *may* not actually address the issues that are mainly encountered for embedded dev rather than about how C would be better. You keep mentioning C, while very few other people have actually mentioned it except to reply to bluntly false assertions.

But maybe trying to make it all look like a Rust vs. C battle, you are cornering Rust proponents into some victim position, shutting down all discussion after that.

Actually most people here have said that C was ridden with its own issues and that something "better" would be nice, but have argued that Rust may not be the answer.
If you don't like that idea, sorry to hear that.

I have appreciated that the OP has posted links to actual projects in Rust that we can all have a look at. That's better than blind promotion.
Unfortunately, we are failing to see any real-world metric that would prove it yields undoubtedly "safer" products while keeping productivity at a reasonable level, so it's often a lot of talk and some whining as soon as some people dare question its benefits.

 
The following users thanked this post: Siwastaja

Offline coppice

  • Super Contributor
  • ***
  • Posts: 8636
  • Country: gb
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #348 on: March 29, 2023, 09:48:40 pm »
We have all seen new mousetraps[1] that are merely incremental variations on existing mousetraps. Boring.

I am always looking for a better mousetrap, where "better" "different" and "worse" all need to be specfied. TINSTAAFL.

Rust appears on the surface to be significantly better in some ways, but I do not yet understand the significant "different" and "worse" aspects. They will be more widely understood when many people have kicked the tyres.

And that's why I've stayed in this thread.

[1] or nutcrackers or, judging by the number and variety of Victorian patents, Apple corers.
Well we all know its a waste of time creating a new Nutcracker, when people love the Tchaikovsky one so much.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19465
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Embedded Rust on microcontrollers (Cortex M, Cortex A, Softcores etc.)
« Reply #349 on: March 29, 2023, 11:26:22 pm »
We have all seen new mousetraps[1] that are merely incremental variations on existing mousetraps. Boring.

I am always looking for a better mousetrap, where "better" "different" and "worse" all need to be specfied. TINSTAAFL.

Rust appears on the surface to be significantly better in some ways, but I do not yet understand the significant "different" and "worse" aspects. They will be more widely understood when many people have kicked the tyres.

And that's why I've stayed in this thread.

[1] or nutcrackers or, judging by the number and variety of Victorian patents, Apple corers.
Well we all know its a waste of time creating a new Nutcracker, when people love the Tchaikovsky one so much.

I dislike Tchaikovsky with a vengence. Put me off classical music for years.

I have found exactly one nutcracker that I like using; I've been using it for more than half a century. Even so, it isn't wonderful with brazil "nuts". Memo to self: find a tool that is better for that use case.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf