New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Embedded Rust Book #56

Closed
jamesmunns opened this Issue Feb 28, 2018 · 38 comments

Comments

Projects
None yet
@jamesmunns
Copy link
Member

jamesmunns commented Feb 28, 2018

This is a tracking issue for an official guide to using rustlang on microcontroller targets.

For now, these are the major steps:

  • Add a book/ folder to this repository (until a better home is found)
    • Populate the book folder with an MdBook project
  • Add some kind of CI to render the book
  • Determine where to host the book (possibly gh-pages of this repo for now?) -- https://book.rust-embedded.org/
  • Populate the book with some kind of content (see below)
  • Submit for official inclusion in The Rust Bookshelf

Audience

I think the first step is to decide the audience of this book. I think the major factors are:

  1. Do we expect that they already are relatively confident with microcontrollers?
  2. Do we expect that they already are relatively confident with Rust?

This gives us four possible target audiences. I will leave it up to discussion which of these four audiences we would like to initially target. We may extend the Book to cover all four eventually, but we may try and target some subset to get something going at first.

Content

Once we have decided who the (initial) audience is, it will be necessary to determine the content of the book.

Initially, I would suggest the following organization:

  1. The Rust Language itself, at least how developing microcontrollers differs from "regular" Rust applications
  2. The Rust Tooling and Ecosystem, particularly Cargo, Crates, and crates.io.
    1. This should include a full "getting started guide", getting to hello world/blinkenlights for at least one target
    2. We have to make this guide good, as it could be a big "falling off point" if people's first attempts fail
  3. Layers of developing embedded software in Rust:
    1. Writing/Integrating "Chip Support Crates" - i.e. register/peripheral level access and drivers
    2. Writing/Integrating "Board Support Crates" - i.e. constrained to a specific hardware configuration
    3. Writing/Integrating drivers for external components - i.e. sensors, radios, etc
    4. Writing/Integrating higher level applications
  4. Perhaps a more advanced guide, covering all the topics of 3 from start to finish, similar to the Guessing Game in the Rust Book
  5. Interoperability with existing C/C++ codebases
    1. Should consider "a little Rust with your C", and "a little C with your Rust" experiences
    2. May cover more advanced topics, like integrating with common RTOSs.

Concerns

We must decide how existing documentation, guides, and tooling falls into the following categories:

  1. Required steps - these guides/tools cover MUST DO. For example, using rustc/cargo to produce a #[no_std] elf/hex that can run on a given target. We should expect these items to be officially supported by the Rust organization proper
  2. Recommended steps - these guides/tools cover steps we expect MOST people to use. For example how to organize Chip/Board Support Crates, use of embedded-hal, etc. People should not expect these items to be officially supported or required. A parallel here would be nursery level crates like Futures, Tokio, Error Chain, etc.
  3. Example steps - these guides/tools cover things that are community driven, but widely used. i.e. Tock-OS, RTFM, svd2rust, etc. A parallel here would be crates like Serde, Hyper, etc.

I say these items are a concern, because we must be careful to avoid "blessing" parts of the ecosystem that are not officially maintained, as it will cause us to update our documentation if these components fall out of maintenance or fashion (or expose our users to a "broken" experience).

Additionally, we must discuss what embedded targets we will use for these guides. Chips from different architectures and manufacturers have an extremely wide variance in how they act, and if the guide is only written for an STM32, developers may struggle with an nRF5x or AVR based chip. I think initially, we should at least cover the officially supported thumb* architectures, and if the MSP, AVR and/or RISC-V branches are merged upstream, we should expect to update the guide to cover them around the same time as they become officially supported by Rustlang (We could also cover them beforehand, but I would say we MUST cover them when officially supported).

Reuse of existing material

There are a lot of existing blog posts, projects, etc. that can be used. Care must be taken to make sure anything we integrate into the official guide must be up to date and correct. Additionally it may require editing to fit the "style" of the book, to make sure developers have a consistent experience.

Maintainers

We will need to have maintainers for the book. (@jamesmunns) is willing to take this up initially, but will absolutely need help. Additionally, we should probably reach out to the Docs working group for guidance here (CC @carols10cents @steveklabnik).

@jamesmunns

This comment has been minimized.

Copy link
Member Author

jamesmunns commented Feb 28, 2018

Related issues:
#54 - IDE Development Guide
#49 - Material for the revamped website
#22 - Tools you need/want
#12 - Tools you frequently use
#15 - provide real content at rust-embedded domains

@ah-

This comment has been minimized.

Copy link

ah- commented Feb 28, 2018

Oh fantastic! I've been thinking about how to document an embedded pet project of mine and it will be super useful to have an up to date book to point to for how to get started with microcontrollers and Rust.

Regarding the audience, I could see many people coming from a traditional embedded background being interested, without them having much prior Rust experience.

@ratkins

This comment has been minimized.

Copy link

ratkins commented Feb 28, 2018

If you mean to take an audience survey, I'm in the "confident with µCs, new to Rust" quadrant. I think a significant "market" for embedded Rust is people who like Arduino but have the hump with C++.

I think your points 1, 2 are a fantastic start, and I would consume them voraciously. One of the problems I've faced (and I've seen others mention) is that there are a number of "blink an LED with Rust!" blog posts/tutorials out there, but they all target different µCs, take different (from-scratch) approaches, and were written up to years apart, and therefore start with a different set of variously outdated assumptions. A canonical "this is how you get a functional embedded Rust environment" reference would be 💯.

Of particular note for section 2 ii) is how to install the correct dependencies on macOS, Windows and Linux. On macOS particularly, anything trickier than brew install ... is going to lose a lot of people.

Regarding section 3, I would first focus on a reference section for the existing, supported chip, feature and board support crates (or if this already exists, links to them). A how-to for writing new ones is a second-order consideration, I guess?

Under "Concerns" point 2, is it really necessary to write a guide for people who are not going to use embedded-hal? I would figure that to be an advanced topic for people who had already hit a limit to the embedded-hal approach.

Thanks for leading this up! I'm watching with interest and keen to help out where I can.

@andre-richter

This comment has been minimized.

Copy link
Member

andre-richter commented Feb 28, 2018

One of the problems I've faced (and I've seen others mention) is that there are a number of "blink an LED with Rust!" blog posts/tutorials out there, but they all target different µCs, take different (from-scratch) approaches, and were written up to years apart, and therefore start with a different set of variously outdated assumptions.

You are mentioning two points that came to my mind instantly.

  1. Choice of target. Shall the book cover one target it mainly focuses on, or shall it cover multiple targets?
    1. There a lots of good books on programming that take the approach of a constantly evolving project throughout the book. For example, focusing mainly on a Raspberry Pi and guide the reader on a journey from booting up until writing device drivers for various peripherals on it. Stanford's CS140e does that, which is ridiculously good material (https://web.stanford.edu/class/cs140e/).
    2. Another approach could be to stay more generic and trying to cover a broader range of controllers.

For 1.1, I can see the advantage that a reader stays interested due to the one big project on which he can work. Here, focus could be on which language constructs of Rust fit for driving different kinds of peripherals and components.

For 1.2, focus could be more on abstraction and frameworks like embedded-hal, and how to stay generic on top of different targets.

Maybe also a hybrid approach is possible. Covering the part of booting a very basic system on multiple targets, but move on with more sophisticated content only with one target, e.g. one that is easily accessible like Raspberry Pi.

  1. Second aspect is how to stay up to date. Rust and its embedded environment is a moving target, and a ridiculously fast one because it just gets started. How shall the book cover the moving ecosystem. For example, Xargo will be part of Cargo in the future, and many more. Shall the book be updated on the go, or freeze the current dev environment of a certain point in time, and only be updated in big revisions once in a while?
@ratkins

This comment has been minimized.

Copy link

ratkins commented Feb 28, 2018

Shall the book be updated on the go, or freeze the current dev environment of a certain point in time, and only be updated in big revisions once in a while?

If it's all in Git it can be tagged periodically, with the current-at-the-time versions of Rust/Cargo/etc noted. Should be pretty simple to default the user to the latest version but allow them to select a previous tag relevant to their environment.

@anxiousmodernman

This comment has been minimized.

Copy link

anxiousmodernman commented Mar 1, 2018

Bounced here from Reddit. To quote a comment from there:

You probably want to target two of the possible audiences: Controller experience but new to Rust; and Rust programmers but new to controllers.

Speaking as someone who is the latter, I think what this ecosystem really needs right now are contributions from the former: experienced hardware developers who want to try Rust.

In practical terms, that probably means lingering at the lower levels, and teaching good patterns for safe abstractions over unsafe code. You really want that foundation to be in Rust. Once it is, all the other embedded-curious Rustaceans like me will have a way easier time.


As a side note, you might want to regularly check in with the portability initiative, because it seems like what they're doing is relevant to building on embedded platforms.

@enricostano

This comment has been minimized.

Copy link

enricostano commented Mar 1, 2018

I would love some content for "new to µCs, new to Rust" quadrant 😬

@IGBC

This comment has been minimized.

Copy link

IGBC commented Mar 3, 2018

I think initially targeting the new to rust new to µC's is probably the best option. It includes everyone and readers can skip over paragraphs explaining concepts they are familiar with.

@therealprof

This comment has been minimized.

Copy link
Contributor

therealprof commented Mar 3, 2018

@IGBC I agree, especially since a developed Rust ecosystem is far easier to use than a generic C/C++ ecosystem and specialised/vendor ecosystems may look great and easy at first glance but quite restrictive both in terms of moving to a different vendor and getting things one once you (inevitably) run into the restrictions of the particular choice. Establishing Rust as the choice for embedded programming would mean plenty of new Rust users, I even see potential for it to become something like a second "Arduino"...

@nastevens

This comment has been minimized.

Copy link
Member

nastevens commented Mar 7, 2018

@jamesmunns As this moves forward, please let me know if you want to do anything with the rust-embedded.com, rust-embedded.org, and/or areweembeddedyet.com domains. I parked these a while ago and would love to see them actually get use. If someone wants to share responsibility for the DNS records themselves I'd be game as well - it'd be good to reduce the bus-factor.

@jamesmunns

This comment has been minimized.

Copy link
Member Author

jamesmunns commented Mar 7, 2018

@nastevens that sounds great! I'll keep it in mind. Feel free to shoot me an email regarding the DNS records (its in my profile)

@cldershem

This comment has been minimized.

Copy link

cldershem commented Mar 8, 2018

As far as targets audiences go, I think we could take a look at how Rust itself has moved. There is The RPL book (intro/overview of the language), Rustonomicon (advanced/easier to shoot yourself in the foot), and soon to be the Rust Compiler Book (advanced). I'm not suggesting we start out with the idea to write 3 books, but that we think of it in the same fashion.

We've already got Discovery which is a pretty darn good intro and with a few tweaks could be a perfect overview of the Rust Embedded Story (RES to the RPL). The HAL/driver initiative has already started off with some fantastic blog posts that could be compiled into a Rustonomicon, Rust By Example style, closer to the metal, "if you already know what you're doing", book. The compiler book part could be the the other side of things, writing an LLVM backend, svd2rust, writing an RTOS.

When you break it apart like that it sounds like a lot more work, but I think it could make things a little more simple in the the near and far term (especially if we reuse some of resources already out there). Instead of trying to figure out how to write one chapter that can address those new to Rust and those new to embedded, you can focus on one, knowing that the other will be addressed in a separate section. I also believe, just from this thread alone where we've got enough people from both sides, that more people can contribute this way.

@kfihihc

This comment has been minimized.

Copy link

kfihihc commented Mar 9, 2018

We've already got Discovery which is a pretty darn good intro and with a few tweaks could be a perfect overview of the Rust Embedded Story (RES to the RPL). The HAL/driver initiative has already started off with some fantastic blog posts that could be compiled into a Rustonomicon, Rust By Example style, closer to the metal, "if you already know what you're doing", book. The compiler book part could be the the other side of things, writing an LLVM backend, svd2rust, writing an RTOS.

For RTOS, I recommend TockOS.

@steveklabnik

This comment has been minimized.

Copy link

steveklabnik commented Mar 12, 2018

Sorry for taking a while here, @jamesmunns <3

I think the first step is to decide the audience of this book. I think the major factors are:

So, I basically agree with what has been said above: the big concerns are "knows Rust vs not" and "knows embedded vs not". I think the two important audience are "knows Rust but not embedded" and "knows embedded but not Rust."

What I would recommend is that you make your primary audience "knows embedded and Rust", with some small caveats. I think up-front you should talk about your audience. For example, in the book we say:

This book is written for a reader who already knows how to program in at least one programming language. After reading this book, you should be comfortable writing Rust programs. We’ll be learning Rust through small, focused examples that build on each other to demonstrate how to use various features of Rust as well as how they work behind the scenes.

I think you should state up front that this book isn't for teaching Rust, but references material along the way. You should suggest that your readers read chapter 2, 3, and 4 of the Rust book as a pre-requisite, and go from there. 2 as a quick overview, 3 for common syntax, and 4 for the core of ownership. From there, when you come across a more advanced Rust concept, you should do a small aside giving a few sentence overview and cross-link to the relevant part of the book.

@cyplo

This comment has been minimized.

Copy link

cyplo commented Mar 12, 2018

I would love to help editing and proof-reading or trying to follow examples, if needed. I have some prior experience (AOSA books)

@jjmilburn

This comment has been minimized.

Copy link

jjmilburn commented Mar 19, 2018

STM32 development is primarily my bread-and-butter, but I've followed the Rust project with interest for a while. I'm excited about this project.

One section that might be of interest is understanding how Rust fits in vs. Ada/SPARK and Frama-C, understanding the differences between provable code and embedded Rust, etc.

@japaric japaric added this to the 2018 edition milestone Mar 26, 2018

@japaric

This comment has been minimized.

Copy link
Member

japaric commented Mar 26, 2018

(adding to the 2018 edition milestone as per last week's meeting)

@jamesmunns

This comment has been minimized.

Copy link
Member Author

jamesmunns commented Mar 29, 2018

For anyone watching this issue, I have an initial skeleton PR, #74, of what I see as the initial version of the embedded rust book. Feedback is welcome, and once that is merged, contributions are very welcome!

@AJAnderson

This comment has been minimized.

Copy link

AJAnderson commented Jun 23, 2018

@jamesmunns I would like to help as I have to go through this process anyway, one question, how does this project differ from the embedonomicon?

Also, as a newbie coming in who doesn't have the particular board the book is based around, it would be good if the book gave indications of the supporting rust libs which make the f3 attractive, and which might be missing for other boards.

@japaric

This comment has been minimized.

Copy link
Member

japaric commented Jul 3, 2018

A reminder from the last WG meeting:

To get more feedback on the UI of cargo-binutils (cf. #51) we'll start using cargo-binutils, instead of GNU binutils, in the embedded Rust book. I'll also update the Discovery book to do the same.


@AJAnderson

I would like to help as I have to go through this process anyway, one question, how does this project differ from the embedonomicon?

  • The embedded Rust book is for people that want to learn embedded Rust but only know (some) embedded (C / Python / lua / node / etc.) and (some) Rust.

  • The Discovery book is for people that know some Rust but know nothing about embedded development and want to learn embedded development.

  • The embedonomicon documents how to build a no-std program for an embedded target from scratch. This is useful if you intend to bootstrap Rust support for a currently unsupported architecture (e.g. RISCV). You can also read it if want to know how cortex-m-rt works and why it looks the way it looks.

The three documents will contain this information and cross reference each other.

@AJAnderson

This comment has been minimized.

Copy link

AJAnderson commented Jul 3, 2018

@japaric japaric referenced this issue Jul 3, 2018

Closed

The embeddonomicon #59

1 of 4 tasks complete
@korken89

This comment has been minimized.

Copy link

korken89 commented Jul 4, 2018

Hi, I had a look at the proposed content in "Running and Debugging", do you want help to add for the Black Magic Probe debugger, to have some diversity rather than just OpenOCD?
We use it in production rather than OpenOCD due to it having the GDB server built in and does not requite any extra installs more than GDB.

Link to Git and Wiki: https://github.com/blacksphere/blackmagic

Tell me if you want some input there, I can help write that part if you'd like.

@therealprof

This comment has been minimized.

Copy link
Contributor

therealprof commented Jul 4, 2018

@korken89 The BMP is by far not as versatile as OpenOCD and it exclusively works with GDB, not lldb (and possibly never will). If we add that content there probably should be a big caveat in there so people don't treat such content as recommendation to go out and buy one only to figure out that it doesn't work for their setup.

@AJAnderson

This comment has been minimized.

Copy link

AJAnderson commented Jul 4, 2018

@korken89

This comment has been minimized.

Copy link

korken89 commented Jul 4, 2018

@therealprof I would argue the it might not be as versatile in some corner cases (MCU support) but much less hassle than OpenOCD based systems to use, hence why we use it. However I am not here to discuss features nor debugger vs debugger, there are countless threads already doing this.
I simply argue that one should not base it all on one system and give the reader a broader view of what is available and where to find more information. As on the topic of debuggers, it's all spread over blog-posts and other incoherent sources of information which is not easy for beginners to parse and make decisions on, where we can give this broader view.

If lldb does not support the extended remote protocol, it will be a profound roadblock and not only for BMP, but other internal GDB server based platforms.
Is this something that has been taken under consideration when pushing for lldb? I have never used lldb so I can't say much here.

@AJAnderson I think this would be fine as well, though I think that it still should be given a proper write up.

@therealprof

This comment has been minimized.

Copy link
Contributor

therealprof commented Jul 4, 2018

@korken89

I would argue the it might not be as versatile in some corner cases (MCU support) but much less hassle than OpenOCD based systems to use

I disagree but of course if it works for you that's great.

I simply argue that one should not base it all on one system and give the reader a broader view of what is available and where to find more information.

I agree. Just saying that if it is brought up there should be a disclaimer. There's a very good reason pretty much any other project is actively pushing OpenOCD or PyOCD support.

If lldb does not support the extended remote protocol, it will be a profound roadblock and not only for BMP, but other internal GDB server based platforms.

Err, the GDB protocol is notoriously under documented so implementations (including lldb) will differ. The BMP maintainer stated several times that the authoritative implementation of the gdb server protocol is GDB and he's not interested in making an effort to improve compatibility with anything else. So that is that.

@korken89

This comment has been minimized.

Copy link

korken89 commented Jul 4, 2018

@therealprof

I disagree but of course if it works for you that's great.

We can't agree on everything :)

Just saying that if it is brought up there should be a disclaimer.

Then I would say we are on the same page, just as OpenOCD should have one. It's all about educating the reader and then letting them make their own decision.

Err, the GDB protocol is notoriously under documented so implementations (including lldb) will differ.
...

Indeed, and this is true. I just want to point out that parts of industry today is built on this foundation, and the more people we can pull to Rust the better. And to pull people the path has to have low resistance as most people want it to "just work" from what they are used to.

But I think we have discussed this enough here, I don't want to start another "debugger vs debugger" :)


If there is interest to add a part on different debuggers, wherever it might be placed in the end, I can help write that part.

@ryankurte

This comment has been minimized.

Copy link
Contributor

ryankurte commented Jul 4, 2018

I'm in favour of documenting a few different debuggers, so people can use whatever they have on hand / are familiar with / is on their dev board / works.
I'd suggest OpenOCD, BMP, JLink, and STLink would be a good start, and I'm happy to contribute towards the JLink / BMP parts. The documentation is probably a good first step towards some kind of unified programmer/debugger.

@therealprof

This comment has been minimized.

Copy link
Contributor

therealprof commented Jul 4, 2018

@ryankurte We need to be careful about mixing things here. Are we talking about software, protocols and/or hardware? BMP is a bit of an oddball here because it is hardware and software in one and provides a gdb-server protocol specific for GDB use; it's the only hardware I know which can not be used with OpenOCD, which is purely software speaking a number of protocols with different hardware. JLink can either refer to hardware and or the protocol but a firmware talking the JLink protocol can not only be flashed to JLink hardware but is also supported on various debuggers from vendors like STM and NXP. Similarly STLink is both hardware and protocol. And then there're also open (and proprietary) solutions around the CMSIS-DAP/DAPlink protocol standard and of course completely proprietary solutions... 😉

@AJAnderson

This comment has been minimized.

Copy link

AJAnderson commented Jul 4, 2018

@ryankurte

This comment has been minimized.

Copy link
Contributor

ryankurte commented Jul 4, 2018

@therealprof fair point, for the purposes of the documentation I mean "how do I use this physical debugger in front of me to make the lights flash", whether that be JLink hw/sw, STLink hw/sw, BMP+GDB or any hw+OpenOCD, and GDB or LLDB as appropriate. I have never successfully got OpenOCD working, so I don't know how much it /could/ replace, but ime there are justifications for each of em.

@therealprof

This comment has been minimized.

Copy link
Contributor

therealprof commented Jul 4, 2018

@ryankurte OpenOCD is a jack of all trades, unfortunately it is also not quite user friendly and might required some deep technical understanding, especially if you're looking for an exotic configuration or combination of interface and hardware. Many projects provide useful configuration and helper tools to simplify its use a lot. It would be great to have something like that in the Rust world, too.

If you're curious how to use OpenOCD, you could check out my https://github.com/therealprof/microbit, https://github.com/therealprof/nucleo-f042k6 or even my (kind of orphaned) https://github.com/therealprof/atsamd20e15a repositories which all provide working configuration and a helper script to flash binaries via OpenOCD.

@kjetilkjeka

This comment has been minimized.

Copy link

kjetilkjeka commented Jul 4, 2018

@ryankurte @therealprof Are you aware of Bobbin-cli? It brings the awesomeness of cargo to programming/debugging microcontrollers. It's my clear first choice when doing embedded development in Rust. It provides a consistent interface similar to cargo for the most common debugging tool. I've used it with STLink (insert STLink is superior to all other debuggers rant), and it also supports tools with OpenOCD back-ends plus some other common debuggers. Perhaps you have something to add @jcsoo ?

I think recommending this tool makes way more sense than documenting how to use a handful different debuggers with rust.

@therealprof

This comment has been minimized.

Copy link
Contributor

therealprof commented Jul 4, 2018

@kjetilkjeka I do know bobbin-cli and agree it's a great tool. To me it certainly makes sense to focus on documenting its use, however it does not completely address the points I raised, since it cannot handle every situation automagically. Since I revisited it just now after a few months of abstinence I think we can even use it as a foundation to develop and document best practices to follow so people don't have to reinvent the wheel all the time when it comes to flashing and debugging.

@ryankurte

This comment has been minimized.

Copy link
Contributor

ryankurte commented Jul 4, 2018

@therealprof thanks for the resources, tbqh I have a JLink workflow that works and is reproducible across different OSs and I'd rather worry about making things than shaving more yaks in debugger setups.

@kjetilkjeka bobbin-cli looks neat, maybe that's a good default. I agree with @therealprof that it doesn't however handle all situations. Also, as not open-source as it is, $job almost exclusively use JLink because they're the only devices that work reliably with the cores we use.

Shall we create another issue for working on the flashing/debugging components?

@therealprof

This comment has been minimized.

Copy link
Contributor

therealprof commented Jul 4, 2018

@ryankurte Sounds like a plan.

@korken89

This comment has been minimized.

Copy link

korken89 commented Jul 5, 2018

@ryankurte / @therealprof Please include me in this issue, I am very much interested in looking to unify and simplify the flashing/debugging step for users.

@japaric

This comment has been minimized.

Copy link
Member

japaric commented Aug 3, 2018

This is superseded by the issues with the "book" label so I'm going to close this.

@japaric japaric closed this Aug 3, 2018

@japaric japaric referenced this issue Aug 10, 2018

Closed

The book - Running and Debugging section #10

0 of 15 tasks complete

@japaric japaric referenced this issue Sep 4, 2018

Open

Programming, Running and Debugging Book #1

0 of 15 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment