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

Write an embedded-hal backend for AVR #93

Open
dylanmckay opened this issue Feb 22, 2018 · 12 comments
Open

Write an embedded-hal backend for AVR #93

dylanmckay opened this issue Feb 22, 2018 · 12 comments
Labels
enhancement help wanted This is a good candidate issue to fix library-request

Comments

@dylanmckay
Copy link
Member

It would be worthwhile writing an AVR HAL implementation for embedded-hal.

embedded-hal:

@jhwgh1968
Copy link

I've been thinking about doing this for a while, and after @shepmaster gave me a nudge elsewhere, decided to create a repo for playing around with it. It doesn't quite compile yet, but hopefully the ideas should be clear pretty soon.

@jhwgh1968
Copy link

Progress has been made! In short:

  • I have an early version of an application-facing peripheral called GpioPort, which handles GPIO access and configuration.
  • I have a skeleton for the concept of platforms. It is designed to look similar to the Cortex stuff done by @japaric.
  • I have implemented the lowest-level API with a trait called HwRegister. All peripherals are implemented by manipulating these, and they are invisible to the application.
  • The actual register definitions are done with macros. They are a really long and ugly, but should only end up being snippets of inline assembly.

Because I still don't have a working AVR Rust compiler (sigh), I am making sure it will cargo check on a recent nightly, and doing verification with avr-gcc where I can. I also need to use feature(asm) and a little bit of feature(const_fn), which hopefully the master branch of this repo (from November 2017) is new enough to support.

I would encourage heading over to my repo and opening issues there, rather than cluttering up this thread. I am eager for comments and design suggestions -- and someone with a working compiler to tell me it actually works. 🤞

@TimNN
Copy link

TimNN commented Oct 28, 2018

Note that there is also https://github.com/Rahix/atmega32u4-hal by @Rahix, specifically for the atmega32u4.

@Rahix
Copy link

Rahix commented Oct 29, 2018

@TimNN: Hey, thanks for mentioning this :) I haven't yet posted it here, because I wanted to get it more feature complete first ... (Currently, only the Pins+PWM and Delay is supported)

I have also started working on similar crates for the ATtiny85, but while doing so, I hit some strange compiler bugs ... I hope they magically solve themselves, once I get the latest compiler version working

@shepmaster
Copy link
Member

once I get the latest compiler version working

We've merged @TimNN's upgrades to LLVM 8, so now might be a good time to give it a shot!

@Rahix
Copy link

Rahix commented Nov 3, 2018

@shepmaster, @TimNN: I have been able to build the compiler from his branch, but I can't compile libcore using it :(

Should I recompile the compiler again or is there something else I might have missed?

@TimNN
Copy link

TimNN commented Nov 3, 2018

@Rahix: What kind of error are you getting? How are you compiling libcore? Feel free to reach out here / in this repo or on gitter.

@Rahix
Copy link

Rahix commented Nov 3, 2018

Hey, thanks for the quick response! My bad for not describing the issue further ...

I am currently recompiling the compiler, I have a suspicion that I used a wrong llvm version. I'll get back to you once I have tested it!

@dylanmckay
Copy link
Member Author

dylanmckay commented Nov 4, 2018

@Rahix

I have also started working on similar crates for the ATtiny85, but while doing so, I hit some strange compiler bugs ... I hope they magically solve themselves, once I get the latest compiler version working

As you've noticed, Tiny support isn't very well supported. The likely cause of bugs is; originally, when I forked the AVR backend, there was no proper subtarget feature support in the backend, meaning that every instruction that the backend supported could be generated, regardless or not if the chip supports it. A few years ago I wrote in subtarget feature support, based on the device families used by GCC (avr1, avr2, ..).

The subtarget features and chip definitions can be found here.

I don't own any tiny devices and so I haven't really got around to testing the support for it. I'm certain the subtarget feature matrix is accurate, being based on GCC, but I suspect there may be lingering pieces of code in the backend that unconditionally insert new machine instructions (for example, in one of the various AVR passes or custom ISel lowering routines). I've fixed a few of these in the past.

In these cases, the fix in LLVM is to wrap the BuildMI call like:

if (Subtarget->has<FeatureName>()) { // Branch for devices that support the new 'X' feature
  BuildMI(original instruction)
} else { // Branch for more minimal devices which do not support the 'X' feature
  BuildMI(instruction 1); // Do the same thing as above, but potentially with extra instructions
  BuildMI(instruction2);  // because not all devices support the more modern instruction X'
}

If you encounter any bugs, raise an issue!

N.B. I have a side project that is an integration test suite for the AVR backend. It executes all programs in an AVR emulator. Currently, the only blocker for me setting it up permanently on a Jenkins instance is that currently clang does not know how to link AVR CRT and libgcc libraries, so it doesn't even attempt to. The integration tests compile the same C/C++ program under avr-gcc and avr-clang, then executing in an AVR simulator. I've patched clang locally to link these libraries, but I cannot upstream it until I generalize the logic from my system-specific avr-gcc sysroot to any sysroot on anybody's machine. I mention this because the AVR simulator supports the Tiny cores, giving us an easy way to test that a complex program can be compiled and executed on a Tiny, and any other chip. The simulator should be able to tell us any specific machine code instructions that it hits that are not supported by that device, which will immediately let us grep for the instruction name in the AVR backend to find the offending piece of code.

@Rahix
Copy link

Rahix commented Nov 4, 2018

First of all: Thank you all so much for your work on the compiler!

After running out of both RAM and harddrive space, I was finally able to compile the latest version today. I will update my crates as soon as I can.

The attiny issue seems to be fixed as far as I can tell. 👍 I believe the bug was LLVM allocating a register twice, which lead to strange behaviors ... But as I said, I can't reproduce it with the latest compiler

@jhwgh1968
Copy link

I'm finally able to dig back into this subject again... and after an unrelated shuffle, seem to have lost the Arduino board I was going to test with. 🙄

But when I took at the library @Rahix wrote, they're quite ahead of me. So I'm deprecating my library, and if I ever find that board, I might open a PR or two.

Keep it up, @Rahix!

@Rahix
Copy link

Rahix commented Jan 7, 2019

Hi @jhwgh1968! Well, I am currently planning on rewriting my crates after a long talk with the guy behind tinygo. We plan to unify the different layers in a way that reduces code duplication for us and hopefully allows easier maintenance. Not sure yet, how exactly that is going to work ... If you are interested in helping, please get in touch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement help wanted This is a good candidate issue to fix library-request
Projects
None yet
Development

No branches or pull requests

5 participants