Since then, I have seen a few posts utilizing my fork to run Rust on the ESP32 (see this great write-up by citron, if you haven't already), most of which are building on top of esprit which is written in C. In this post I'll be discussing the steps I took to generate valid binaries for the tens architecture with rust and then write some no_std code to build a blink program for the ESP32 only using Rust ! In March 2019, Espresso released their first run at a LLVM fork to support the tens architecture.
The LLVM fork in its current state cannot perform object generation, so we must use an external assembler. The tens_lx6_rt crate does most of the heavy lifting in this respect, we simply need to define an entry point and the panic handler.
To control a peripheral we simply need to write values to the right addresses in memory, with respect to the reference manual supplied by the chip manufacturer. Firstly, it's simply a case of setting a bit in the GPO output enable register.
The problem with this approach is that depending on of the optimization level, the number of clock cycles each iteration of the loop changes. The default clock speed on most ESP boards is 40mhz, hence waiting for 40 million cycles equates to a one-second delay.
Now I know what most of you are thinking at this point, it's not very Rusty; it contains bundles of unsafe and there are no real abstractions here, and you are right; but it's something to get the ball rolling. I opened an issue to document my findings in the hopes it can be sorted in the next iteration of the LLVM fork.
Espresso has started the upstream process, the first ten patches are now in review, there should be an update coming to their fork moving from the older llvm6 to llvm8 (and hopefully some other additions and fixes too! API features to be included in the next svd2rust release can be generated by cloning the svd2rust repository, checking out the above commit, and running cargo doc --open.
This should connect to the Modbus TCP port of a Sensor. For this purpose, I would like to use the Modbus Rust implementation, which already exists.
If you’re really desperate to use Rust, you could, in theory, use the LLVM C Backend, which converts LLVM IR C, then use the tool chain provided by Espresso to compile to ESP32 machine code. You will find it a lot easier to bite the bullet and use C in this case, which is a shame, because Rust is a great language, but its embedded support is not as good as C’s at the moment.
There’s a very similar chip, the RTL8710, that is recommended for use in situations where you’d use an ESP32, but want to use Rust. This should connect to the Modbus TCP port of a Sensor.
If you're really desperate to use Rust, you could, in theory, use the LLVM C Backend, which converts LLVM IR C, then use the tool chain provided by Espresso to compile to ESP32 machine code. You will find it a lot easier to bite the bullet and use C in this case, which is a shame, because Rust is a great language, but its embedded support is not as good as C's at the moment.
You could also take a look at the Zephyr or Nutty projects who have roughly that same level of functionality at the moment (i.e. run from Iraq only, but basics are in place). Thanks for the detailed response this should be plenty to get me started. I think using the IDF bootloader as a makeshift runtime for Rust is a great idea, and something that can easily swapped out later if we wanted it to be written in pure Rust.