wg icon indicating copy to clipboard operation
wg copied to clipboard

Rust embedded pic32mz

Open RevoluPowered opened this issue 6 years ago • 25 comments

I'd like to request potentially making a port for PIC32MZ chips.

I've got a device which we designed but I'm sick of the tool-chain (MPLAB + XC32) we use.

I'd like to potentially make a PIC32MZ port for the PIC32MZ1024EFK144 with a BSP, etc but would need some help as I'm new to rust but it is definitely a good option. Rather than trying to get GCC to work with PIC32MZ properly.

My proposal would add support for the PIC32MZ1024EFK144, but if someone else requires another PIC32 board to function they should easily be able to extend this functionality.

Thoughts, I'm open to discussing this further as I want to know potential pros and cons?

RevoluPowered avatar Feb 07 '19 16:02 RevoluPowered

@nagisa looked into Rust on pic32 some time ago. iirc, they found out that llvm does support the (variant of the) mips architecture of this microcontroller family but didn't pursue further due to problems with the microchip toolchain (?).

In general, the Rust team is OK with adding new targets (e.g. the riscv bare metal target) provided that the llvm backend is stable (i.e. the backend can compile libcore).

The first thing to do here is to figure out what needs to be written in the target specification. I would suggest using Xargo and a custom target specification (.json) file to compile a #![no_core] crate to pic32 machine code; that should let you figure out what needs to be written in the .json file.

Once you have figured out the target specification I would suggest adding the target to the compiler (see third commit in rust-lang/rust#52787) and then try to compile libcore using bootstrap (see x.py in rust-lang/rust and https://rust-lang.github.io/rustc-guide/how-to-build-and-run.html).

Once you have that you can try to build something like cortex-m-rt (see the embedonomicon, which is required to compile a flashable binary.

If you have questions about bringing up a new target you can ask them here.

japaric avatar Feb 07 '19 17:02 japaric

Yes, the microchip toolchain is nightmarish to work with.

I will read through these reference notes from this repository on LLVM configuration with pic32. https://github.com/dwelch67/pic32_samples

Appreciate some info, I'll do more research myself and see where I get, Thanks!

I'll fork this and do as you suggest and update this as I progress.

RevoluPowered avatar Feb 07 '19 19:02 RevoluPowered

PIC32 is a based on MIPS architecture for which there should be mature support already since it is supported under Linux. Someone build an SDK for the Playstation 2 which has a custom MIPS processor which was probably quite a bit tricker: https://github.com/ZirconiumX/prussia . You can check that approach and adapt for the PIC32.

therealprof avatar Feb 07 '19 21:02 therealprof

Found out why original support was dropped for the llvm pic32 backend.

"it was written violating almost every LLVM programmer's guidelines and, even more, the authors refused to address review comments."

http://lists.llvm.org/pipermail/llvm-dev/2015-June/086284.html

RevoluPowered avatar Feb 11 '19 18:02 RevoluPowered

"it was written violating almost every LLVM programmer's guidelines and, even more, the authors refused to address review comments."

That’s the PIC8/16 backend, not PIC32 one. The MIPS backend should be able to serve the PIC32 needs just fine.

nagisa avatar Feb 11 '19 18:02 nagisa

didn't pursue further due to problems with the microchip toolchain (?).

I decided bothering with this architecture is not worth it given the Microchip’s extremely hostile behaviour towards the third-parties. It didn’t help that my goodwill budget towards Microchip specifically was in a non-ideal place to begin with.

nagisa avatar Feb 11 '19 18:02 nagisa

That’s the PIC8/16 backend, not PIC32 one. The MIPS backend should be able to serve the PIC32 needs just fine.

I will try out a few different things, I appreciate you clearing up that it's okay to just use the MIPS arch from LLVM compiler.

I decided bothering with this architecture is not worth it given the Microchip’s extremely hostile behaviour towards the third-parties. It didn’t help that my goodwill budget towards Microchip specifically was in a non-ideal place to begin with.

Ah, yeah my goodwill budget is very restrained with them after harmony 1.x.x to 2.x.x porting, and being forced to use MPLab X.

RevoluPowered avatar Feb 11 '19 18:02 RevoluPowered

I'm first going to port an existing small 'hello world' uart application to the clang c compiler, and work on getting compatible PIC32MZ binaries which match the format required by the pic32 and upload to one of my development boards.

If this works then I know llvm mips asm is compatible and perhaps, I can work on a proper backend which could be 'production ready' but right now I'm not holding my breath about being production ready.

More notes: Initial research also suggests that the GCC( XC32 ) lib files are cross compiler compatible with LLVM as GCC uses the normal 'ld' linker. XC32 uses this too.

So my hope is that if I get this working I can link the existing PIC32MZ1024EFK.lib and use the existing compiler headers to allow us to port away from the XC32 system.

Thoughts? Advice welcome.

RevoluPowered avatar Feb 15 '19 19:02 RevoluPowered

No way of knowing right now if the hex file will even function, when I get it to generate it, this will probably be the most painful part

RevoluPowered avatar Feb 15 '19 20:02 RevoluPowered

Got a hex file, will be testing on a dev kit tomorrow night

used open source - objcopy to generate an ihex file which is what MPLab instructs 'pic32_objcopy' to execute.

got harmony to compile too and a basic project configured and building with LLVM / Clang.

Then i will figure out how to do a 'generic' port for Rust.

RevoluPowered avatar Feb 18 '19 12:02 RevoluPowered

I created a Rust example for the PIC32MX470 (on github). Maybe, it could be helpful for your project. Should be possible to adapt it to the PIC32MZ.

It uses the ChipKIT toolchain to process some assembly files. Interrupt handlers are called via an assembly wrapper without relying on compiler features. It's quite experimental.

kiffie avatar Mar 10 '19 23:03 kiffie

@RevoluPowered Any updates are where you got with this? I am currently using the PIC32MM and the desire to get away from Microchip cannot be overstated.

skrapi avatar Apr 30 '20 16:04 skrapi

Unfortunately, the company I worked for went bankrupt when working on the embedded device.

The IP itself has been sold on, so will need to see if I will be re-activated for this project in the future.

I do still think rust on the pic32 would be an amazing enhancement, additionally a support for TI's 8051 processors like the CC1101 (harder to support) and CC1350 (this one is easier) would be very very beneficial as they all have painful toolchains.

They have very locked down and set way of doing things, which doesn't work for unit testing or has some obscure errata workarounds required.

I hope we can sort more embedded support here for the mainstream stuff like PIC,TI and ATMEL.

Cruft is everywhere and this is the best chance IMO of making the cruft less painful.

RevoluPowered avatar May 01 '20 13:05 RevoluPowered

Ahh too bad, funnily enough the board I am working on also uses the CC1101.

skrapi avatar May 01 '20 21:05 skrapi

yeah its tiny and quite powerful, i enjoyed working on them

RevoluPowered avatar May 01 '20 22:05 RevoluPowered

@kiffie Thank you! I confirm, it works! 👍 @japaric please, take a look at it.

0x433 avatar Sep 06 '20 13:09 0x433

Seems like this target spec just needs to be upstreamed: https://github.com/kiffie/pic32-rs-oled-demo/blob/master/mipsel-none.json

This would give us a generic bare-metal MIPS target, which we do not have at the moment. We do have a slightly more specific target, mipsel-sony-psp, for PSP homebrew, so you can take inspiration from that.

I'd be happy to review a PR for this, but I don't have any PIC32 hardware to test this with.

jonas-schievink avatar Oct 06 '20 19:10 jonas-schievink

Hi @jonas-schievink,

I created PR #78676 for an embedded MIPS target. I would be happy if you could have a look at it. It tried it on a stage1 rustc with one of my projects and it worked.

kiffie avatar Nov 02 '20 18:11 kiffie

Great job, @kiffie ! Thank you!

0x433 avatar Nov 02 '20 19:11 0x433

Link to the (now merged) pull request: https://github.com/rust-lang/rust/pull/78676

What would be the next step here? I'm looking for a low-power MCU that I can program in Rust, so that's how I landed here. However, while the bare-metal MIPS target has been merged in Rust, this issue is still open, and I saw no mention of PIC32 as a supported target in the embedded docs I read. What's missing to get Rust there?

chrish42 avatar Jul 04 '21 05:07 chrish42

The main things you'd want to get similar support to cortex-m and riscv is something like an architecture crate (e.g. cortex-m) which provides asm intrinsics and perhaps drivers for the core peripherals (though in the pic32 maybe all the peripherals are 'core'), a runtime crate (e.g. cortex-m-rt) that sorts the initial boot (like crt0, loads .data and clears .bss and jumps to main) and sorts out a linker script and vector tables and registering interrupt handlers, and some kind of crate to support your particular device (e.g. a register map, like the svd2rust-generated PACs).

A lot of that could be shortcut to just get something going quickly, by just sticking everything in one crate and doing the least work to at least get something like an LED blinking. You'd need to handle most of the specific things I mentioned above, especially writing a reset handler that sets up RAM and jumps to main and a linker script of some kind, and perhaps just some plain structs that you map to the right address for the MMIO.

There's some introduction to bare-metal from scratch in this blog and the embedonomicon might be helpful too; also this twitter thread about getting bare-metal Rust working on a PIC32 might be quite useful too (though I don't know how far @jonas-schievink got in the end).

adamgreig avatar Jul 04 '21 11:07 adamgreig

I created crates for PIC32MX including runtime, some HAL modules, PACs generated from XML files provided by the manufacturer, etc. Have a look at my pic32-rs crate.

kiffie avatar Jul 04 '21 12:07 kiffie

Thank you for the exhaustive answer, @adamgreig. Otherwise, when things are working, what's involved in making PIC32 officially supported by Rust embedded? Are there various levels of "officially supported"? I assume @kiffie's work is a very good start for that.

I'm more interested personally in their very-low-power use cases (which some PIC32 series do support) — my use cases are a lot closer to blinking a led than to running something demanding in terms of compute power. So I'd love to have more low power MCU's officially supported.

chrish42 avatar Jul 04 '21 14:07 chrish42

@kiffie If you'd like a bit more exposure for those crates PRing them to https://github.com/rust-embedded/awesome-embedded-rust might be a good start. 😉

therealprof avatar Jul 04 '21 14:07 therealprof

So I'd love to have more low power MCU's officially supported.

@chrish42 @adamgreig Exactly. Especially with the current MCU shortage.

0x433 avatar Jul 04 '21 15:07 0x433

This is likely out of scope for the WG, as we don't have any folks maintaining PIC/PICMX targets.

I'd suggest folks interested follow up with https://github.com/kiffie/pic32-rs/issues/15

If anyone disagrees, feel free to let me know and we can discuss in the next meeting on Matrix.

jamesmunns avatar Jun 11 '24 18:06 jamesmunns