Skip to content
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

Rust embedded pic32mz #308

Closed
RevoluPowered opened this issue Feb 7, 2019 · 26 comments
Closed

Rust embedded pic32mz #308

RevoluPowered opened this issue Feb 7, 2019 · 26 comments

Comments

@RevoluPowered
Copy link

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?

@japaric
Copy link
Member

japaric commented Feb 7, 2019

@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.

@RevoluPowered
Copy link
Author

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.

@therealprof
Copy link
Contributor

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.

@RevoluPowered
Copy link
Author

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

@nagisa
Copy link

nagisa commented Feb 11, 2019

"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
Copy link

nagisa commented Feb 11, 2019

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.

@RevoluPowered
Copy link
Author

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
Copy link
Author

RevoluPowered commented Feb 15, 2019

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
Copy link
Author

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
Copy link
Author

RevoluPowered commented Feb 18, 2019

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.

@kiffie
Copy link

kiffie commented Mar 10, 2019

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.

@skrapi
Copy link

skrapi commented Apr 30, 2020

@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.

@RevoluPowered
Copy link
Author

RevoluPowered commented May 1, 2020

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.

@skrapi
Copy link

skrapi commented May 1, 2020

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

@RevoluPowered
Copy link
Author

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

@0x433
Copy link

0x433 commented Sep 6, 2020

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

@jonas-schievink
Copy link
Contributor

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.

@kiffie
Copy link

kiffie commented Nov 2, 2020

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.

@0x433
Copy link

0x433 commented Nov 2, 2020

Great job, @kiffie ! Thank you!

@chrish42
Copy link

chrish42 commented Jul 4, 2021

Link to the (now merged) pull request: rust-lang/rust#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?

@adamgreig
Copy link
Member

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).

@kiffie
Copy link

kiffie commented Jul 4, 2021

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.

@chrish42
Copy link

chrish42 commented Jul 4, 2021

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.

@therealprof
Copy link
Contributor

@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. 😉

@0x433
Copy link

0x433 commented Jul 4, 2021

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

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

@jamesmunns
Copy link
Member

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 kiffie/pic32-rs#15

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests