FLOSS-878
Jonathan Bennett: This week I'm talking with Jonathan Pallant about Rust and primarily in the embedded world, the Raspberry Pi Pico, the Nordic, Espressif, all of your favorite little MCUs. You can run Rust there and partially due to efforts by people like Jonathan. This is Floss Weekly, episode 878, recorded Tuesday, August the 4th.
A tool with opinions Hey, folks. It's time for FOSS Weekly. That's the show about free, libre, and open source software. I am your host, Jonathan Bennett, and today, once again, we're gonna get rusty. Whereas last time though, when we talked to someone with Ferrous Systems, we were talking about Rust on the Linux desktop, in user space, Rust on general purpose computers, and today we're talking about Rust somewhere a little different.
I've got Jonathan Palant with us today. He is also from Ferrous Systems. In fact, I think his day job is teaching Rust there, and I think also doing some programming work. But let's get him on and ask about all of the places where Rust runs that you may not have thought about. Hey, Jonathan.
Welcome to the show.
Jonathan Pallant: Great to be here. Thanks for having me.
Jonathan Bennett: Yeah, it's good to have you back. Or no, you for the first time. Good to have Ferrous Systems back. The second interview with one of you guys in a couple of months now. All right, so this, this magical thing called Rust it runs on the desktop, it runs on the server, it also runs on the Raspberry Pi Pico?
Jonathan Pallant: Yeah. It- So joys of having a systems programming language, right? You get a compiler, source code goes in, machine code comes out, right? So anything that runs the machine code should be able to run it. So yeah, Rust is really interesting in being able to scale from the very, very large. It is the language that powers Amazon Web Services, and Cloudflare, and Google, and a whole bunch of other stuff.
But it scales down to, as you talked last time, desktop applications- ... things like Sudo written in Rust. But also scales down to the small, very small. How small is always an interesting question, but-
Jonathan Bennett: Yes, it is.
Jonathan Pallant: I have run Rust on ST Micro, Microcontroller, Arm Cortex-M4 32K flash, 4K RAM.
As modern things go, that's pretty small.
I'm not sure I'd be happy squeezing Rust-generated code onto like a Z80 or a 6502. That may be a bit too small, but certainly tens of K of flash, a few K of RAM, I think- ... is quite workable.
Jonathan Bennett: I happen to have here the Seeed Studio Xiao board actually their next generation Xiao board.
It is a Nordic nRF54. The word Xiao in Chinese means tiny, and it is an appropriate name, as you can see. T- Can we do Rust on a nRF as well, on, on Nordic?
Jonathan Pallant: Yeah. So Nordic semi generally use Cortex-M4 M0 in the nRF51, M4 in the nRF52. I did a lot of work with their cellular modules. Don't know if you've ever used a 9160?
Jonathan Bennett: I've not,
Jonathan Pallant: but- the very small device that does LTE Cat M- ... so the, the IoT version of 4G, and that comes with a Cortex M33 that you get to play with, and then a secret second processor that runs the modem firmware- ... that you are absolutely not allowed to play with because cellular.
Jonathan Bennett: Yeah.
Okay. So the ... Boy, the, the embedded world is an interesting world. There's a large there's quite the gamut of different things that count as embedded, and sometimes the lines get a little blurred, right? Because you can take the Linux kernel and run it on an ESP32-S3. Now, it's not a fun experience, but you can do it.
It'll boot. It can be made to, it can be made to happen. And so i- it's interesting to me that Rust goes all the way down to some of those very, very small targets. How does that work? Is there an operating system that a, a Rust binary is then running on top of? Is there some kind of real time operate OS?
Do you guys run on Zephyr, or is, are you literally just writing Rust that runs on the bare metal?
Jonathan Pallant: Yeah the output of the, the Rust compiler, it works like a C compiler. Source code goes in, machine code comes out. So the compiler doesn't really care whether- ... you have an operating system or not.
You could absolutely be the first code that boots when the system comes out of reset.
Jonathan Bennett: But I mean- Where- ... there's like the question of am I making system calls to a kernel? Am I telling the kernel to do, the, the multitasking stuff, or am I just always, is the binary always running on the
Jonathan Pallant: CPU?
And where that comes in is less in the, the language, but more in Rust's choice of standard library. People say, "Ah, the standard library," as if it's one thing. But as with all good things, it's actually three things in a trench coat. The, the top part of the standard library in Rust is the thing that knows about files and threads and networking, and that's the thing that's gonna be operating system specific.
And it's basically the Rust equivalent of hash defines that say, "Hey, if you're on Windows, we're gonna call this Windows function, but if you're on POSIX, we're gonna call, open read and write." Sure. And that's what lib std is doing. It's this operating system abstraction layer. As I said, file system, networking, threading.
Below that you've got the heap allocator and all of the heap allocated collections. They actually live in their own separate library. If you're a Windows, Mac, or Linux user, you may not be aware of that because it's hidden, and everything heap-related is all exposed at the top level anyway. But there is this lib alloc, so if you want a heap allocator, it lives there.
And then you've got these fundamental Rust types, these things that no Rust program can live without, and that don't actually care about what operating system. If you've used Rust, you'll be familiar with the result and the option types. They're enums, they are generic, they need to be defined in a library somewhere.
And things like that go into a library called lib core. So when people write bare metal Rust, so Rust running on a Cortex-M4 or a RISC-V processor with no operating system these people say, "Oh, I'm using Rust as no std." And what they mean is I'm using the Rust standard library, but I've basically switched off the top half and I'm only using lib core.
So I'm only using the parts that are operating system agnostic. No file system, no threading, no networking, but you do get Unicode string handling, as I say, result and option types, sort of fundamental properties of integers and floats and things like that.
Jonathan Bennett: It, does this work hand-in-hand with a like an SDK the published stuff that the vendor puts out?
So like we, we mentioned the Nordic. Obviously Nordic writes... I mean they, they've written Zephyr support. They've also got their oh, I forget what they call it, their little shim libraries, almost like an OS. SoftDevice I think they call it. And so when we're in Arduino land with C and C++, we do a lot with SoftDevice on the Nordic devices.
Do, do... When you write Rust, do you use that stuff on this, this sort of a device, or are you f- blaze your own path?
Jonathan Pallant: People come at this from different places. I went to a trade show in London recently, and I went round and surveyed all the people there who had the booths down at the show in London, said how do you write embedded firmware?"
And honestly, I was surprised at how often Zephyr comes up. A lot of people seem to be really into Zephyr. And if you wanna use Zephyr, absolutely, you can put Rust on top, build your little Rust applications, link them into the Zephyr kernel, and that's all gonna work great. I wouldn't describe myself as a purist-
but I'm in this to push what Rust can do. A great analogy came up the other day about about, about AI usage, and it was like sometimes there are heavy things that need to be lifted, and sometimes this is your job, and you should use whatever machine you've got to lift the heavy things.
And sometimes it's 'cause you're at the gym- ... and if you bring a forklift truck to the gym, you are defeating the point. You're cheating. When I write Rust, I'm at the gym, and I wanna do it the hard way because I wanna practice my Rust, but also I wanna show what Rust can do- ... and find if there are any corners where Rust doesn't work.
'Cause I wanna know about those- ... and maybe I can go to the Rust project and get them fixed, or, I can educate my customers about areas where Rust doesn't work. So- Yeah ... for me, going bare metal is always more interesting. Jamming random integers into random memory addresses, that's where I'm most comfortable.
But if people wanna use like a FreeRTOS or a ThreadX or any number of real-time operating systems that are written in Rust- If that gets the job done, that's great.
Jonathan Bennett: Yeah. I think that's actually a really good segue to ask the question of what do- what is your day job? You're not... Are you writing production code, or are you doing the the education thing there at Ferrous?
Jonathan Pallant: So my I asked for the words senior embeddage engineer to be written on my business card- Okay ... because it covers a multitude of sins. Technically what I'm doing mostly is teaching. So I teach Rust. I am the lead trainer. I'm responsible for all of our training materials, which are all open source.
Anyone listening can just go and find Ferrous Systems Rust training, read all my slides, do all my exercises. It's all creative commons. You can help yourself. But I can't only teach, one, because my head would melt. I did a day of teaching today. I've been teaching eight hours already, so I may- ... yeah, just dribble a little bit.
But also, yeah, you need breaks. But also, if I only taught Rust I don't think I would get better at Rust. There is an a need to sharpen the knives and practice the tools. So in between trainings, I'm, like, picking random dev kits and going, "Great, let's do some Rust on this. Let's write some training material about it.
Let's pick an entirely new platform nobody's ever written Rust before." I have in my hands a lovely NXP developer kit.
S32Z2 for the people who don't have video. This is get this right, eight Cortex-R52 with 20 megs of RAM.
Jonathan Bennett: Oh, wow.
Jonathan Pallant: As microcontrollers go- It's huge ... this thing is cooking.
But it can't run Linux because none of these processors have an MMU. These are all- ... Arm's real-time platform.
So a couple years ago I was like, "Can you even do this in Rust?" Probably, but I don't find anyone online who's done it in Rust.
So we called in a favor from NXP. We got the board.
I would not personally wanna buy one of these out of my own pocket money. It's a little out of my fun budget. Yeah, and we got Rust running on it bare metal, dual-core lop step. We can run asynchronous Rust. We got the interrupt controller going. But I do that because it's interesting and because it ends up useful for customers and useful as training material, yeah, embedded systems engineer, as I said, covers a multitude of sins.
Jonathan Bennett: Rust and embed- the embedded world as a whole is really a moving target as places like NXP and STMicro and Microchip, Nordic, and all the rest of Espressif, everybody, they're constantly pushing the envelope, releasing new things, g- gluing new weird chips together that we didn't think we would ever see, and then suddenly- you see it at a trade show or a talk. But it's a moving target, and if all you're doing was education, then, you're, you would get stale, right? So I think it's incredibly useful to stay hands-on with the technology.
Jonathan Pallant: No, absolutely, and I try to make it out to Embedded World every year to run the booth, but also just to walk the floor and- go and see what's new and get a sense of how things are training changing. You go to Embedded World three or four years ago- most of the floor didn't know what Rust was. "Do you do Rust?" "No." "What's Rust? Tell me about Rust." And this, they'd never heard of it. And now they're like, "Yeah, no, we've heard of it.
It feels like a thing we should be doing."
But certainly I think these big silicon vendors are thinking about, "What is my next step? How would I introduce this without alienating all of my existing customers who like the CSDK? Is there a migration path? How... do these things feel the same or do they feel different?"
Espressif, I gotta give shout-out to them for being far ahead here. They basically hired all the open source hobbyists who were doing Rust on their chips. Gave them a job and they have their own Rust team. We've seen Rust news out of Infineon as well. Yeah, and I hope we see more out of the other silicon vendors as well because if they don't do it, who will?
I mean me, but my time is somewhat limited and there's only so many dev kits I can buy. And it's the open source community. It's random hobbyists who go, "Oh, I've got a random dev kit I got off Adafruit or whatever. Got a chip. Does this have Rust support? I don't know, let's write something.
Let's put something together." And we have all this sort of flourishing ecosystem around STMicro, around Nordic, around Raspberry Pi. I personally did the Rust support for the 2350. That was fun 'cause they gave me pre-production chips, so we had Rust support ready to go on launch day. But these are all independent ecosystems with their own thing going on.
Which is great if you just wanna get into Rust and have some fun. But if you are- on the hook to design the firmware for a product where you wanna make a million a month, I can see why you may not just want to pick up random packages online, and you may wanna talk to the silicon vendor or someone else-
and get a bit more professional support.
Jonathan Bennett: Because the way where madness lies, and I know because we've done this ourselves, is you end up coming along and forking about 100 different packages, that you've got your own version of the library because you have some fix, and the upstream library is dead, or you can't get ahold of the maintainer, or this or that.
Yeah. Been there, done that. That's my life these days. How similar is it? We've thrown out a lot of different embedded architectures. So again, compare, like, Nordic to the Raspberry Pi Pico. Can you write one Rust program and get it to run on both places? Is there cross-platform driver support?
So say I've got a an I2C-connected temperature probe. Can I write one Rust driver for that and run the same code on the Pico and the the, the Nordic?
Jonathan Pallant: You can, and this is thanks to the work of a great bunch of people called the Rust Embedded Devices Working Group. So take you back to 2017.
I'm just starting to get into Rust. I'm using a random TI Stellaris dev kit that I happened to have lying around, and I'm doing my own thing, and some other people are doing their own thing, and we find each other. And we're like, "We're C developers. We've written a lot of C code." "Rust looks fun, but we're very aware of how-" I describe the C embedded ecosystem as like islands.
And these islands are all really quite far apart. Yeah. And if you live in Nordic island, and I don't know, you happen to run out of chips 'cause there's a chip shortage, and you wanna get over to-
Jonathan Bennett: That would
Jonathan Pallant: never happen ... ST Island, to get over to ST Island, those islands are quite far apart, and it's pretty difficult to write, say, a cross-platform driver that, that works across that.
And we looked at that and we said, "What could we do in this fledging fledgling Rust embedded ecosystem to try to, for that not to happen?"
And the Rust language mechanism that it offers for that is a thing called a trait. And if you're a C programmer, you can think of it like struct full of function pointers.
That's how the Linux kernel does it. That's how the Linux kernel thinks one disk controller looks like another. They both, drivers, provide a struct with a function point of open and a function point of a close, and read block and write block. In Rust we call that a trait. So the Rust embedded working group published some traits, and there's a trait for I2C, and there's a trait for SPI, and a couple of other sort of common peripherals, GPIO- razor pin high or low. And then what someone needs to do is come along and say, "Oh, I would like Rust to be usable on i- my particular chip." NRF 52 for example. So you would write some Rust code, and you would implement the trait. So here's my I2C driver- Yep ... represents this peripheral, and it implements the trait.
When I flip to the other side, someone's got- a CO2 sensor. Little I2C device, measure the air quality. I've got- And they just need an
Jonathan Bennett: I squared- I've got one of those on the desk behind me waiting for me to either find or write a driver for it.
Jonathan Pallant: Fantastic. And you just need an I2C bus to put it on.
And what do I2C devices need to do? The driver needs to do a read maybe do a, a write and then a read. There's a couple of fairly basic operations. 7-bit addresses, 10-bit addresses, and that's all encoded in the trait. So if I wanna write a Rust driver for my little CO2 sensor, I am generic over some type T, where I don't care what type T is as long as it implements embedded hal colon I2C- some trait. And then a third person comes along, and they're like, "I may be the first person in the universe to use that CO2 sensor with that microcontroller."
And they can compose it together. Yep. And in general, it should just work. You will... There's ef- efficiencies that you will lose because it's a g- sort of a very generic API- that's not very- ... chip specific. But the trade-off is, yeah, here's my random Adafruit LCD screen, here's my CO2 sensor. Plop them all on a board. Here's a, a, what we call a, a HAL implementation someone's written for this chip, and it should all just work together, and generally it does.
Jonathan Bennett: Yeah, that's very cool.
It's actually similar to the way the the Adafruit excuse me, the Arduino ecosystem has evolved. You've got kind of that, that same idea in mostly C code, some C++, but it's that same idea. We've got an abstraction of here's what a wire bus is going to look like. It's usually what you see it called.
And then somebody else can come along and write a driver for it. Was that part of the inspiration?
Jonathan Pallant: Yeah, I think we'd the people who formed the Embedded Work Group, we'd obviously used Arduino before, but we'd also used these kind of very vendor-specific SDKs. But you also get the, the classic embedded commercial vendors.
They all have their own stacks and their, probably their own in-house operating system. It seems every embedded company's got their own operating system they've had since the '90s- Of course ... and that kind of stuff. So we've seen all of that. And what would a, like a utopian future look like? I'd love anybody to be able to pick up any MCU-
and any device and just plug them together.
Jonathan Bennett: Do you see vendors actually starting to write the the, that bottom half, that support layer for you guys?
Jonathan Pallant: So we have seen Espressif do that. So they publish all of the, the, the drivers you need for their chips. For most of the other vendors, I think we've seen something from Infineon.
But for most of the other vendors it's wait and see. Maybe throw the hobbyists a bone, some free hardware occasionally. But that's all mainly hobbyist-driven. I will shout out STMicro, who have done the other side. Surprised me. But if you've got your little STMicro sensors, 'cause obviously they don't just make MCUs- I believe
they have all these sensing modules as well. They will give you Rust drivers for the sensors.
Jonathan Bennett: Cool.
Jonathan Pallant: Which you can just get from STMicro's GitHub and use, and then use those drivers with your other Rust code.
Jonathan Bennett: I've been really impressed with STMicro's open source support. They were off my radar for the longest time.
And then I started working with some of their hardware, and it's like, you ... 'Cause I'm from the Meshtastic project. That's my day job these days. As all of our listeners know, because I mention it at least, take a shot, if you're playing the drinking game. But so I got ahold of some STMicro hardware, and it's I wonder what it would be like to
'Cause, because it was gonna be able ... Get Ar- get the Arduino working on this, and then run our platform IO build on it, and then finally make Meshtastic work. And I was ready to strap in for the long haul, and it's oh, no, just go download it off of their GitHub and pick the board and it'll compile.
It was easy. It was like a day's worth of work to make everything start working. It really surprised me how good their support was.
Jonathan Pallant: Nice. I will shout out their tools. So I do use CubeMX quite a lot. Their MCUs have very complicated clock trees, so having a little graphical tool where I can just feed in the crystal frequency and go- Oh
"Oh, I want a, like a times two," and configure the PLL. I don't need the C code that gets auto-generated out the back end, but it's very useful visually doing the clock tree. I also love the pin planner. Nordic don't need one, right? 'Cause you could put any peripheral on any pin. But ST you generally can't.
On STM32 each pin has a set of three random functions. And you're like, "Great, I need UART5." I guess I can have it over there and over here, but oh, not here because I need th- that pin to be like a, an input interrupt, so I'll put it on this pin. And doing that with a pen and paper or a spreadsheet's horrible, so I do love the CubeMX pin planner-
where I'm just like, "I need these peripherals. Just lay it all out on the, the 80 pin package, and I'll design the board around that." And then again, I throw away all the C code, and then I teach, I program Rust to f- to follow the kind of the, the pin map that we've got out the tool.
Jonathan Bennett: Yeah. It's almost like a, a traveling salesman-esque problem.
It's like it, it seems very simple, but then when you try to do it, it gets really complicated really fast.
Jonathan Pallant: One, one of, one of those puzzles where there's one hole left- ... and one piece left. And this piece doesn't fit in that hole, and you're like, "Oh, I'm gonna have to take this all apart and redo this-" Yep
"before, before this fits."
Jonathan Bennett: Yep. Exactly. That's fun. So what what other interesting hardware have you run Rust on? We talked about a bunch of them, but what's your favorite, what's your favorite device to write Rust for?
Jonathan Pallant: Ah, that's a really good question. I do love these kind of big real-time microcontrollers.
But just 'cause they're so outside, like, where I'm normally using microcontrollers. Eight R52s is just an outrageous amount of power. So these are fun. Running the dual core lockstep actually turns out to be really easy. 'Cause the thing about having two cores locked together that do the same thing for safety purposes, so- Oh, okay
if one of the cores gets hit with an electron and crashes, the other core does something different, and the hardware goes, "Oh, these cores do not agree. Let's reboot the system." I thought that was gonna be really tricky to program. But the thing is both cores do the same thing.
So you program one core and the other one does exactly the same thing, but one clock cycle later.
So you can effectively ignore it until then a bad event happens and they diverge, and the hardware goes, "Oh, oops, upset. You need to reset the system." So playing with this safety critical rated hardware- Interesting ... has been fun.
Jonathan Bennett: Yeah.
Jonathan Pallant: I also... I- I'm from Cambridge originally. Cambridge was the city I was born in.
I've been hanging around with the Raspberry Pi people since 2012- ... with the original launch of the very first Raspberry Pi. I had one I ordered day one. I've got it signed by the team. Nice. So I have a soft spot for the Raspberry Pi stuff. I did enjoy doing the Rust port for the 2350. I think having RISC-V and Arm on the same silicon is just really fun.
It's w- my first opportunity to write Rust for RISC-V. N- maybe the first Rust program that actually had to compile for both architectures, 'cause that's not normally a thing for bare metal. Indeed. You are either building an Arm program or a RISC-V program. So to suddenly end up where you want one program, talks to the UR, talks to the I2C, but it compiles for either architecture-
With all the peripherals at the same memory addresses. I don't know, that was fun and unique. I'd never had to solve that one before.
Jonathan Bennett: Yeah. Yeah, interesting. I, I have... Speaking of Raspberry Pi and their unique peripherals, I can't help but think about- ... the RP1, and I still, I want the little RP1 chip on a PCI Express board that I can slap into my desktop or put into a laptop.
Yeah ... that's my dream. I asked the guys at I, I think it was Embedded World, actually. I, 'cause I was there this year. I don't think I ta- I don't think I bumped into you. I don't remember for sure when they- We
Jonathan Pallant: did, 'cause that's how this podcast happened.
Jonathan Bennett: Oh, that's right.
Jonathan Pallant: Okay. 'Cause you came by and I said, "Yeah, I'd love to do that."
And then Florian was like, "Oh, is that the guy from Floss Weekly?" "Yeah, we should give you his number. We should do that."
Jonathan Bennett: Okay. Yeah, that makes sense. And so I've got your business card somewhere on my desk here underneath all of the DEF CON prep- ... that's just piled up. Anyway, I went to the Raspberry Pi guys, and I'm like, "Hey, you guys really need to make the RP1 available."
And they're like, "We don't wanna make it available because we know our competitors will buy them and start putting them on their boards too." Good
Jonathan Pallant: point. So you know they've got dual Cortex-M3s In the RP1
Jonathan Bennett: I don't know a whole lot about what's actually inside the
Jonathan Pallant: RP1 Yeah, so it is actually a lot...
have you ever clocked the numbering? So the, the RP2040, if you look at the chip, silk screened onto the chip, it simply says RP2.
Jonathan Bennett: So- So I know that was the second board that they start- the second chip, excuse me, that they started designing in-house.
Jonathan Pallant: Yeah. And
Jonathan Bennett: The RP- See, so the
Jonathan Pallant: RP1 was first- The RP1
and the RP2 was-
Jonathan Bennett: And then there's the
Jonathan Pallant: RP3 as well Do you remember what the RP3 was?
Jonathan Bennett: Wasn't it the power supply?
Jonathan Pallant: It is. If I remember right, it is the custom version of the Broadcom SOC that has SDRAM stacked on top So the Raspberry Pi Zero I think it's the 01, maybe the 02. Someone's gonna correct me.
That's fine. One of the Raspberry Pi Zeros has the RAM sitting on top of the processor- ... a package on package, and that was the RP3.
Jonathan Bennett: Oh, okay.
Jonathan Pallant: Which according to the numbering, they started third, but was the one they managed to ship the first.
RP2 came out in the middle, and then finally RP1 came out.
But as I understand it, there are some Cortex M3s in the RP1, and we're like, "Can we program them?" And they're like, "Nope, absolutely not. You- ... that is not designed for general use." I can imagine they would not wanna deal with random people like me asking, "Why does it do this when I poke this register?"
And he's like- ... "Don't poke that register. Just leave it alone." That's- ... that's
Jonathan Bennett: not the kind of errata we want to write for this.
Jonathan Pallant: No. That- I think that is a chip that they have enjoyed using. I hope to see it again on, on some other boards, but who knows what RP4's gonna be, right? Yeah.
It's interesting to see what comes next.
Jonathan Bennett: I just love the idea that you can have PCI Express and then GPIO and SPI and I2C, and I want that on a desktop. Do you know how- Yeah ... how amazing it would be to be able to do development and debugging work on hardware if I could have an accessible SPI bus on a desktop?
Would be amazing.
Jonathan Pallant: Yeah, without a s- without a stack of USB dongles all hanging off some- Ah ... crummy $10 USB hub that likes to reset. Yeah.
Jonathan Bennett: Yep. Absolutely. But there, there are some chips out there that'll let you get SPI and GPIO. I2C, I think too. There's a Chinese chip called the CH341, which I've used a lot here recently.
In, in fact, I met I met Nirav... Oh, I can't remember his last name, but Nirav, the CEO of Framework, and I gave him one of these guys. It's a Framework module, and it's got a CH341 in it that lets us talk to LoRa chips from on a desktop, which is a lot of fun. Very cool. No, no Rust- Do you have- No Rust code on, running on that yet, but maybe one of these days.
Jonathan Pallant: Do you have a, like a box of boards you've bought and you thought, "That's gonna be fun one day"? So I ha- I have my guilty box. It's things like, "Ooh, that looks fun." There's a CH chip that has USB 3. And I'm like, "Microcontroller with SuperSpeed USB, that sounds great. I want some of that."
So I bought one. It's on the pile with about 19 other boards- ... and maybe one day I'll get round to pulling it out and giving it a go.
Jonathan Bennett: Yeah. So you note that when we started the show, I was able to just reach onto my desk and pull up a Seeed Xiao board, right? And that's not the only one that's there.
That was just the one that was on top.
Jonathan Pallant: Yeah. I just, yeah, there, there's a reason I just have random $800 no- NXP dev kits just kicking around. Yeah.
Jonathan Bennett: Yes, absolutely. Yeah. I've got a, I've got a couple of FPGAs around here too. It's something I've really I've not been able to get into it yet, not with a ver- fervor at least, but the FPGAs with fully open source tool chains is really fascinating to me.
Is that a realm that Rust gets to play in too? Can we write FPGA code in Rust, or?
Jonathan Pallant: So I know there are people who like to do SoC design, and I think there's some that are built on Python where you write Python and out comes full FPGA SoC with core and bus and- and peripherals and so on. I don't know of anyone doing that in Rust, but it would not surprise me.
Jonathan Bennett: Yeah.
Jonathan Pallant: You can- I would love to get into the open source F- FPGA stuff. What I did do, shout out to Matt Venn on the Tiny ASIC thing, 'cause I did that a few years ago. And made... That I do have which I forget which run we were on, but I have the run that doesn't work unless you get the voltage precisely right.
So technic- technically I have some ASICs with my code my designs in that will do a thing. I don't think I'm ever gonna get them to work, but it's cool. I can go, "Yeah my design is in that ASIC." Yeah. That was a lot of fun.
Jonathan Bennett: Yeah. That's cool. A- and I guess you can quite easily take that a step to the side and put an SoC on an FPGA and then run Rust code on the
Jonathan Pallant: SoC.
Absolutely. That, that is one of the great things about RISC-V is you can just grab a core without paying- ... a license fees, drop it on. Rust has great support for RISC-V- ... 32 and 64-bit, so yeah that's a great way to get started, and that Tiny ASIC chip has a RISC-V core on it. Yeah, I should have given that a go.
I should get some Rust code running on that. That definitely seems possible. I have also done Rust on PowerPC.
I have a bunch of '90s Unix machines for fun because, I... you need a hobby, right? So my hobby- ... is Unix System Admin '98, which is the worst simulator game you've ever played.
I- It's like installing H- HPUX Nine on some broken old PA-RISC machine is quite fun ... I've,
Jonathan Bennett: I've played that game once. I, ... I had a customer that had an old SCO Unix server, and they're like, "The hardware is dying. We need to resurrect this because it's got our old legacy system." And so my, my solution was to get a copy of the hard drive and host SCO Unix inside a virtual machine on a Linux box.
And I was pretty proud of that- Like- ... when that finally came up and worked.
Jonathan Pallant: You're lucky it was x86, 'cause I have a PowerPC Macintosh, an UltraSPARC, and a HyperSPARC. I have a MIPS Silicon Graphics. That has run Rust code. I ha- was able to compile a Rust binary- Nice ... for MIPS, but the Rust the LLVM linker just makes ELF files, and it turns out IRIX- Just uses ELF files.
Oh. So I just copied all the object code over to the SGI machine, used the SGI linker, and that works. Yeah, I've done Rust on SPARC as well. I know the European Space Agency, still rather fond of their SPARC processors- ... because they have the, the LEON3. SPARC was famously an open architecture.
Anyone could make SPARC chips.
And so the European Space Agency did, and there is an open source processor the LEON3 you can find online. It's a SPARC V8 32-bit. And so I did Rust, again, just as a fun thing to talk about. I have Rust code running on bare metal SPARC, and that means I ended up as the target maintainer.
So Rust has these, these targets, these sort of operating system architecture pairs- ... or bare metal and architecture, and everyone technically needs a maintainer. Some of them don't. And I'm like, "Yeah, this would be funny if Rust could run on bare metal SPARC." They're like, "Yeah, okay, cool you can submit that as a pull request, but you're gonna have to put your name on it as the maintainer.
And I'm like okay, that seems fine. I can't imagine anyone's gonna use this." And then I get messages from people going, "Yeah, we've taken your work, and we're now running Rust on RTEMS on Spark Leon3, and it's working great." Huh. By the way, we've observed this, so w- what do you think we can fix this?"
And I'm like, "Cool. I didn't know anyone was gonna do this, but great." I'm glad to have, made that exist. It's a lot of fun.
Jonathan Bennett: Yeah. Yeah. Y- you also mentioned MIPS in passing, and I've done- ... I've done some MIPS stuff mainly because in a previous life I did some OpenWrt stuff, and a lot of those routers surprisingly are running on MIPS.
Yeah. And you would think, oh MIPS, we've left MIPS in the past now. All of this stuff is running on ARM, or they've gone to RISC-V. There's the Chinese Loongson, which is a MIPS-based architecture too. There's still some life left in MIPS and it might be interesting to run Rust there.
Jonathan Pallant: Yeah, no, absolutely. I know MIPS, yeah, long and storied history. I think the latest version of the, the Loongson architecture has diverged away enough from MIPS that it now has the target string begins with a Loongson or whatever the name is rather than- ... mIPS. That makes sense. But there are still some MIPS targets in there.
Yeah, it's fascinating to dive back and ap- apologies if this is gonna upset any old hands. I'm just gonna say branch delay slots. If you know what that is, you're quivering on the floor, but if you don't, it's fine. Don't worry about it. Never look up what a branch delay slot is. You won't enjoy it.
Jonathan Bennett: I'm going to ignore your advice and look up what that is- ... because that's the sort of thing that I lose hours- Oh ... of time reading about.
Jonathan Pallant: Yeah, so i- yeah, imagine a pipelined processor that is busy fetching, executing decoding and executing instructions. And if you hit a branch, you've already fetched the next instruction.
So why don't you just execute it anyway and then do the branch?
Jonathan Bennett: Oh,
Jonathan Pallant: branch- So a branch delay slot means you always execute the instruction after the branch before you branch.
Jonathan Bennett: That's what x86-64 processors do all the time, and they never ran into any problems from that. Never caused anybody problems.
Yeah. No, that was a great idea.
Jonathan Pallant: Just having, when you're handwriting assembly, just remembering that, yeah, you're gonna get one extra free instruction before the branch.
Jonathan Bennett: Yeah that's fun. Okay. I understand now. I get it. We've talked about the very, very tiny embedded side of things. What about the, the big iron, like System 360 and some of those IBM which I guess a lot of those are just PowerPC, aren't they?
Jonathan Pallant: Ah, so System 360 I guess originally starts in the 1960s.
And it's really funny 'cause it's like a, a big technology project that ended up being massively over budget and massively late. You think that's a modern concept, no. People have been late delivering tech- Of course ... since the very first kind of computers. And I got into that kind of stuff Because I wanted to build my own computer.
So I'm like, "Yeah, what is a computer? And can I turn a microcontroller into a computer?" And so you go back and go, "All right, traditionally, what was a computer?" You think of the movie The Italian Job. There's a, the big mainframe in the background- ... with all the spinny tapes. You look at it and go, "Yeah, '60s computer, spinny tapes, stuff is happening.
Yeah, looks, looks fun." So I'm like what is it? What does it do? How does it work?" And computers really haven't changed much. They need some sort of terminal- ... where input can go in and output come out. They need some RAM as like some scratch space to store the stuff they're working on.
They need a processor that can execute instructions, and they probably need some non-volatile storage to remember the things they've worked on, be that a spinning drum, a paper tape, a magnetic tape, or whatever. And actually, like a Raspberry Pi Pico, where, what do you got? Pico one, two Cortex M0s at 150 MHz.
That absolutely wipes the floor with a Commodore Amiga- ... Atari ST. You'll absolutely spank something like, the Saturn, the PlayStation 1. It's probably not far off my Silicon Graphics O2. Peak 1996 desktop workstation. Obviously has a lot more RAM, but two 32-bit ARM cores at 150 MHz is pretty cooking.
So why can't it be a computer? The answer is, A, it doesn't have enough RAM. So I wrote a little MS-DOS style operating system. It boots to a terminal. You can load programs off disk. You can run them. There's a graphical display that's all rendered in real time. The Raspberry Pi Pico's great at doing that.
It's nice having a whole second core to run the video so the main core is uninterrupted. And so yeah, just distilling a machine down into what is the kind of smallest kind of computer. And yeah, those basic concepts, terminals with input and output. Your dev TTY- ... is named that because it was connected to a teletype, literally a typewriter on the end of a serial cable- where you could type and it would h- fire the hammers and print on the paper. Can you imagine that, running LS minus R on a machine where everything's printed on paper? Just the amount of paper you would get through. Obviously you can't use Vim. You don't have a screen. You're in Ed.
You've got line based editing at that point. But- That is the fundamentals of a computer, and that is the same whether it's gonna be, you're doing a little operating system on a microcontroller or you're on a, a, a modern, big Linux system. I know there's good Rust support for Z Series, current IBM mainframes, PowerPC.
We can still do SPARC64. And it's got a big iron systems. They're the same kind of concepts we had in the '60s, which is fun.
Jonathan Bennett: One of the, one of the things we haven't touched on yet that I think we, we can't do a Rust show without talking about is the memory safety aspect of Rust.
And I always used to say that I was a little unimpressed by the idea of let's say Rust in the kernel because The memory safety aspect of Rust just doesn't jive very well with writing device drivers, right? Because a device driver, by definition you're writing into uninitialized memory locations, and Rust won't let you
Jonathan Pallant: do that.
Random integer and random memory addresses.
Jonathan Bennett: And so- That's
Jonathan Pallant: how the machine works ...
Jonathan Bennett: yeah, and the dr- the driver is just all gonna be unsafe Rust code, right? I I'm curious your take on that. I don't nec- I don't necessarily take that approach the, quite the same, but e- educate past me as to why there's still some some value in writing bare metal Rust when it's all unsafe anyways.
Jonathan Pallant: Yeah, so I think that, I think there's kind of two, two aspects of that. One, actually the, the kernel's the very low layer part of the s- the system, and the bit that actually has to get a right to the memory, put the random number at the random memory location, is the very bottom of this stack of code.
And everything above it doesn't have to do that because it's got the device driver to do it for you. Yeah. So if the device driver itself has the unsafe code in it, we can check that and validate that and manually review it and go, "Yes, this looks good. That's what the data sheet says we should do."
And then above that, we can build a bunch of safe abstractions. A serial port driver. Is it okay to send some bytes over the serial port? Yeah, provided you've enabled it and configured the board rate generator. I can do all that in safe code. I can design an API that means it's impossible to send data on the UART until the board rate has been configured, 'cause I've got a type system that lets me do that and take ownership, and this is an unconfigured UART, and this is a configured one.
And this one lets you send text, and this one only lets you set the board rate, and you're gonna have to do one before the other. So all those kinds of problems, I don't need to access random memory to do that because I'm building on top of this kind of low level that does. But I was also pointed to things that kernel maintainers have said.
I think it was Greg KH at a recent Rust conference in the Netherlands. He said that introducing Rust into the Linux kernel has made the Linux kernel better, which was not a thing that he was expecting.
But it's being forced to think about those Rust terms. I've got a value, and I'm giving you ownership of it.
I'm calling a function, and I'm getting ownership of the thing back, and now it is mine. Or I'm calling a function, and I'm only letting you temporarily borrow it. Maybe you have a shared borrow, and you need to be aware that other people may be borrowing. Maybe you have an exclusive borrow. You can assume that nobody else is using this object right now, 'cause although you don't own it, you do have exclusive access to it.
Those concepts exist in C The problem is the C language doesn't have the syntax and the terminology to describe them, so it goes into the comments.
When you call this function, you get given a pointer to foo. You must call free on pointer to foo later because I've heap allocated it and it belongs to you.
Or you must pass the pointer to foo into the foo destroy function later- ... and then you must not use the pointer again after you've done it. But it's all in the comments, not in the code, which means the kernel the, the compiler can't check it.
Jonathan Bennett: The compiler-
Jonathan Pallant: So the thing I
Jonathan Bennett: think they- Yeah, the compiler will let you break all of those contracts- '
Jonathan Pallant: Cause it can't read it
because it doesn't know about
Jonathan Bennett: them. Yeah.
Jonathan Pallant: It can't read the comments. It has no idea whether you're supposed to use this foo pointer and where you're not. Whereas in Rust you can. So when the kernel was forced to adapt their C APIs to make them usable to a driver written in Rust, the Rust people went do I own this?
Is it mine? How do I destroy it? Where do I have to give it when I'm done? Are you just giving me a thing I gave you earlier, or is this a new unique thing you have created for me?"
And I think that kind of understanding those concepts and going, "Oh, yeah, actually we could probably make this C API better in exporting the features you need for the Rust code," actually this becomes a better C API for all the C drivers as well- because these things are expressed better and it's kind of understanding of this kind of moving and ownership and borrowing. I, yeah it's fundamental to how computers work, but it's nice to have a language that lets you express it yeah, natively and not just in the comments.
Jonathan Bennett: Yeah. One of the w- the early, early, this is a long time ago actually, but one of the criticisms I saw about all the different efforts to make Rust and C work together was that it was essentially making Rust under the hood in its memory management actually speak the C, sort of the C memory management language, and that I think s- I can't remember who it was that was writing about this, was really critical of that idea, and it's like we're taking Rust and we're making it almost C in order to make it work together.
I've not heard anybody make that point in a long time though, so m- maybe that was just a a red herring a, a false road to chase down. But-
Jonathan Pallant: I think it's, I think it's a fair observation because, yeah, if you want a Rust program to interface with a C library, or vice versa, a C program to interface with a Rust library Raw pointers and C compatible types are going to be involved.
But the thing is for the Rust thing, whether it's the program or whether it's the library, that that C-ness only infects the edges, and you can wall it off and go, "95% this is Rust." We've got our unit tests, we've got our code coverage, we've got our Clippy tool giving us opinions.
All of that is gonna work across almost all of this code base. But right at the edge, I'm like, "Okay, here is my heap allocated, my boxed type."
I'm gonna convert it to a raw pointer and give it to the C library, and then later the C library's gonna give me the pointer back, and I'm gonna look at it and go, "Did you give me null?
Did you give me a non-aligned pointer?" Does this actually look like a thing? And like, all right, it seems validly aligned. It's not zero. Let's assume it actually is the original Rust heap allocated thing that we had before, and you can convert back having done those checks. So most of your code is still very Rust, but there is this kind of C thing at the edge, which is only needed if you need to interact with it from C.
If you're gonna interact with it from a Rust library, we just bypass that. Yeah. Just go straight into the Rust APIs. And I would say that one of the disadvantages of using the C compatible types There's a great feature in the Rust compiler. If you have a structure with three fields- you may assume the first field appears at the lowest memory address, appears first in memory. In Rust, that is not true. The order of structure fields is not defined. The compiler can change it between- ... compiler versions, and it allows it to remove padding because it can go, "Oh, you've got small thing, big thing, small thing.
Let me put big thing first, two small things after-" "... and now I've made your structure smaller," which is great when it's Rust code calling Rust code. C compilers don't love that. They do rather assume the structure is laid out in the order you wrote it. So you just go, "Hey, Rust. This is a C-compatible structure.
Don't do any shenanigans. Just put it in the order I put it." And then it's C-compatible, and Rust and C can just share the same memory and ha- have the same view of the same data. The reason you don't do that by default is it gives you padding, where previously, a Rust-native version might not.
So it's a little bit of a price to pay with that, but it's generally not too bad, and I think it's worth it. Yeah. And we know there's a lot of great success cases, Firefox, Android, and so on- ... introducing bits of Rust into their code base and generally the trade-offs kind of work out.
Jonathan Bennett: Yeah.
Just a second ago you, you mentioned a Clippy tool, and I couldn't help but think of starting up Microsoft Word back in the day and little Clippy popping up. "It looks like you're writing a let," so do... Is there a Rust tool, "It looks like you're writing a system driver. Here, let me help you with it."
Jonathan Pallant: Yeah, and that's literally why it's called Clippy.
The Rust compiler-
Jonathan Bennett: Oh ...
Jonathan Pallant: will tell you when your code is wrong, right? There's errors and warnings, where a warning is, "This is probably wrong, but I'm not 100% sure." So it's about whether your code is correct.
Clippy is merely a tool with opinions. And it's a great tool, and any kind of static analysis of a Rust program is probably gonna be built around Clippy.
I can give you an example. You've got some kind of array, and you would like to iterate through all the items in the array. So you write for i in 0 to array.len. I'm doing my array indexing, I've got my integer, it goes from zero to len minus one, that's how the loop works, and I'm gonna index my array with my variable i.
And that is not wrong, and the compiler will give you no warnings- ... 'cause that is all very valid Rust. If you give it to Clippy, it says, "It looks like you're trying to index through an array. Why don't you write for item in array instead of for i in 0 to len?"
That's an opinion. The code you have is not wrong, but actually Clippy's opinions are generally pretty good, and you probably should have said for item in array instead, because it's probably gonna be faster, you can maybe skip a bounds check, you're not gonna accidentally go off the end, all that kind of good stuff.
Jonathan Bennett: It's an opinionated style linter.
Jonathan Pallant: Yeah, and highly configurable. So it has a default set of lints. But I know a lot of commercial customers have their own in-house rule set. You're probably familiar with the idea of a coding standard. Yes. Every company's got a C coding standard, so many different ways to write C.
They're starting to get Rust coding standards, and they're usually expressed in the form of a set of Clippy lints- ... that you should have turned on. Would you believe the Society of Automotive Engineers, the SAE, have published a document which is basically a guide for writing Rust for high integrity systems?
I think the document is JA 1020, 1020, and it's a document that you have to buy it. It's a commercial thing. But it includes a list of Clippy lints, but also rationale for why every single one of them should be turned on. It's al- almost like a sort of MISRA for Rust, which doesn't yet exist. But it's quite nice if you're writing Rust code to be able to have this thing and go, "Okay they've clearly thought about it a lot harder than I have, so I'm just gonna turn on their default set of rules," which is probably more than Clippy has on out of the box.
And a lot of them are great, like every unsafe block should have a comment above it that begins with the word safety and then a colon. Like you should explain why you're telling the compiler, "Trust me, bro, I know what I'm doing." Because you may not know what you're doing. You do. So bit- Clippy can check that.
Clippy can go, "Oh, here's an unsafe block without a safety comment above it." You should fix that. And turning on those kind of rules is a great idea.
Jonathan Bennett: Yeah. Yeah. That's really good. All right boy, I think we're, I think we've been going at this close to an hour. I gotta ask, would you recommend somebody either just getting started in the programming world or even an old hand to go out and learn Rust and add that to their resume?
Jonathan Pallant: I think it's really useful because I remember when I was learning Rust, I was a C developer. I've been doing this for gosh, I left university in 2004. Do not tell me how many years that is. I do not wanna think about it. But I spent my professional life writing C code- ... building all these kind of embedded products.
And as I learnt Rust, I became a better C developer. And I write Rust 'cause I think it's a great tool to solve the kind of problems I have, but even if you don't actually want to write Rust full time, it's still fascinating to learn those concepts about ownership and borrowing, and it will make you rethink those C functions that return a pointer.
And you're like, "Do I own it? Is it mine? Am I borrowing it? Is it a pointer I gave you earlier?" And having that new language to describe that, I think is- ... is super useful. I don't know, it's just super exciting. There's loads of new, fun stuff going on, loads of research in academia. That seem- they really seem to have taken Rust to heart.
So yeah, it's it's a fun and exciting thing to get into, and even if you wanna remain a, a grizzly old C developer as I was, I still think it's a useful thing to dig into.
Jonathan Bennett: Yeah, interesting. Very good. It- where should somebody go to, you mentioned that there's a, a lot of education material from Ferrous that's available.
Where should somebody go to look for that?
Jonathan Pallant: Yeah, so you can just find our website, ferrous-systems.com. You can also look at our GitHub, github.com/ferrous-systems. And you will find my training material and my exercises. They're all free of charge. Yeah, you can check them out and enjoy them.
Jonathan Bennett: Yeah, very cool.
And then before I let you go, I gotta ask a f- couple of final questions, and that is, what is your personal favorite text editor and scripting language?
Jonathan Pallant: Ooh, that is a great question. I- I love Sublime Text. V- Codium, VS Codium seems to be the one that is mostly open on my computer, but you just cannot get past the speed of Sublime Text.
And it introduced me to the world of multi-cursors, pressing Command+D to select multiple things at the same time. Which is still witchcraft as far as I'm concerned. And when you s- you just see it happen in front of you, that's amazing. I edited 39 things simultaneously in this file. So yep I love love Sublime Text.
For scripting languages I've done a lot. I've done Perl and PHP and Python. So let's go with one that doesn't begin with P. Let's just say Tcl, 'cause I'm feeling obtuse.
Jonathan Bennett: I'll
Jonathan Pallant: have to go- Everything's a string. Why not?
Jonathan Bennett: I'll have to go, I'll have to go look that up. I don't know what Tcl scripting is.
Jonathan Pallant: Oh, yeah. Oh you're gonna have so much fun.
Jonathan Bennett: Another rabbit hole for me to dive down after the show.
Jonathan Pallant: Absolutely.
Jonathan Bennett: Absolutely fun. All right. Thank you, Jonathan, for being here. It has been an absolute blast to talk with you.
Jonathan Pallant: Yeah, it's been great. Thank you so much.
Jonathan Bennett: All right. That is Jonathan Palant of Ferrous Systems talking about Rust on the other end of the spectrum.
And so we do not have a guest yet for next week, I don't think, unless one is scheduled in the time that we've had the show. So if you want to be on the show or know a project that should be, you can drop us an email. You can get us at floss@hackaday.com. Let us know who we should be talking to.
I will be at DEF CON later this week, and so if anybody is there, make sure to stop by and find me. I don't have a booth that I'm running this time. I'm just on the run, but find me and we can say hi, and we can chat for a bit. But yeah, we appreciate everybody that's here. Whether you watch or whether you listen, whether you get us live or on the download, thank you so much for being here, and we will be back on Floss Weekly.
All right, cool. We had a bunch of fun show titles that got suggested too. Oh, Tickle TCL, I have heard of that.
I'm not super familiar with it, but I... Yes. Some- someone linked it in Discord, and it's like, okay I know what TCL is. Three Things in a Trench Coat was a lot of fun. Source Code In, Machine Code Out.
Sometimes There Are Heavy Things To Be Lifted, that one's long. A Tool With Opinions. I think I like either A Tool With Opinions or Three Things in a Trench Coat.
Jonathan Pallant: I think if I was gonna pitch you an alternative, I'd say Don't Bring a Forklift To The Gym.
Jonathan Bennett: Don't Bring a Forklift To The Gym.
That one's pretty good too. Yeah. It's a little long.
Jonathan Pallant: It is, yeah.
Jonathan Bennett: See, I really like both Three Things in a Trench Coat and A Tool With Opinions. I think we'll probably go with A Tool With Opinions because it's also, it's a great snapshot of what Rust itself is, I think.
Jonathan Pallant: It is, and the British people in your audience will assume it may be a description of your guest.
Jonathan Bennett: Yes. That's great. That's brilliant. All right, we'll go with that one then.
Jonathan Pallant: I'll live with that. That's fine.
Jonathan Bennett: I may reference that pun somewhere in the show description too. That's great. Thank, thank you, sir, for being here. It's been a lot of fun. It's really been a blast.
Jonathan Pallant: Yeah, my pleasure.
It's been great.
Jonathan Bennett: All right. See you next time. Let me get a title and tease recorded here. 878. Bye.
878, a tool with opinions. Yes, I had not thought about the the, the British-ism baked into that, but that's really good. All right.
This week I talk with Jonathan Palant about Ferris systems and Rust in the embedded world. It's a lot of fun. You don't wanna miss it. This is Floss Weekly, episode 878, recorded Tuesday, August the 4th. A tool with opinions
One of those should do it. Thank you everybody for being here, and thank you again, Jonathan. We'll see everybody next week. Bye.
Jonathan Pallant: My pleasure. Bye.
Avsnitt sparat!
Du hittar sparade avsnitt på Mina sidor.
Kunde inte spara avsnitt
Något gick fel. Försök igen.