-
Notifications
You must be signed in to change notification settings - Fork 2k
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
cpu/native: Allow Access to Hardware SPI Bus on Linux #11352
Conversation
@fhessel thank you for your PR and welcome to the RIOT community! 😉 The PR already looks quite nice. I'll try to test it ASAP. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found some minor style issues.
@kaspar030 Thank you for the feedback! If I can anyhow support testing, just let me know. I addressed the styling issue already. Regarding the failing CI build, I assume that the failing tests are now run for the first time for the native CPU (all of them are for drivers which require The only other issue that I could see was a binary constant in As that's not directly related to the suggested change, maybe you could suggest what's the best way to address this. |
@kaspar030 Is there there anything else I can or should do to push the PR forward? The style issues should be resolved, and for the Murdock failure, I again had a look at the output, with this being my interpretation of it: tests/driver_adt7310 #define ADT7310_EXPECTED_MANUF_ID (0b11000000) which could easily be changed to using its hexadecimal representation: tests/driver_pcd8544 tests/driver_sdcard_spi So I'd suggest:
If these changes are also reasonable from your perspective, I think there are to ways to go to get the build running:
For the sake of clarity, I'd assume the second option being the best, as it would also allow an individual review by a maintainer for each driver. Would one of those ways be suitable? |
Option two would be the way to go! Thanks for dealing with these unrelated issures... |
@kaspar030 As the PRs for the drivers are now merged into master: How should I proceed? Should I rebase my branch on the current master and force-push it to verify with Murdock? And should I already squash the requested formatting changes into the original commit? |
@kaspar030 Is there anything else I can do to bring this PR forward, or is there just no capacity for review at the moment? |
yes please!
reviewing time is always scarce, sorry... |
Thanks for the feedback! It looks like the llvm toolchain has another issue with the adt3710. I'll try to fix it like the other issues and then rebase the PR again. I might need some time however, as I'm less familiar with llvm than with gcc. |
Sorry for the long period of radio silence, I hope you are still with us! The only failing unit test is Just piggy-back a commit that casts the argument to --- a/tests/driver_adt7310/main.c
+++ b/tests/driver_adt7310/main.c
@@ -80,7 +80,7 @@ int test_adt7310_sample_print(adt7310_t *dev)
fractional = modff(celsius_float, &integral);
printf("0x%04" PRIx16 " %7" PRId32 " mC %4d.%07u C)\n", raw, millicelsius,
- (int)integral, abs(fractional * 10000000.f));
+ (int)integral, abs((int) (fractional * 10000000.f)));
return 0; |
I myself didn't get to setting up the llvm toolchain, so sorry for that too. However, I'd be really nice to get this through now. I think the most meaningful next step would be a rebase, as this PR has been stale for some time now, and to fix that llvm error. Do you think just piggy-backing the driver_adt7310 fix is the right choice here, as all the other required changes have also been done in separate PRs? Otherwise I'd just file such a PR, wait until it made its way to master and then do the rebase. |
You don't need to setup a llvm toolchain just for that. |
Regarding your suggested change to just cast to printf("0x%04" PRIx16 " %7" PRId32 " mC %4d.%07lu C)\n", raw, millicelsius,
(int)integral, labs((long) (fractional * 10000000.f))); This might not be a problem with the native CPU, but maybe it is for some other boards? |
Good catch! Using |
It seems like Murdock is finally happy with this PR. @benpicco – I added you suggestions in 002368b after rebasing the PR to the current master. @kaspar030 – The requested changes to code style should also be implemented, if I'm not mistaken. What's the best way to proceed from here? As the formal checks have passed, only testing the new functionality on actual hardware would remain, if you'd like to try that before merging. If I should squash 002368b on top of 6726279, just let me know. I didn't want to do that while there are some pending review comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
I just tried it on a raspberry pi in loopback mode and it's working well!
The code looks good too, I just have some minor stylistic suggestions for improvement.
@kaspar030 what do you think?
I added all the suggested changes in beea452, |
Reviewing the docs myself again, I found another typo/mistake where I confused |
I think the comments by @kaspar030 have been addressed. Feel free to squash already! |
Squashed and rebased onto current master. |
Sorry for coming in so late to the review, but can we make this a |
( |
I separated the SPI code in 6187ae8 as an optional module However, there are some things for which I'm not sure if there is a better solution:
Maybe you could especially have a look at these points, as you know the build system much better than I do. Other than that, without adding |
I'd say Keep the ifeq ($(OS),Linux)
FEATURES_PROVIDED += periph_spi
endif But add a entry to ifneq (,$(filter periph_spi,$(USEMODULE)))
USEMODULE += periph_spi_linux
endif |
@benpicco – I now use the pesudomodule like you suggested, but I kept the I tested the commit with examples/hello_world and tests/periph_spi on a Raspberry Pi and also in a VM with FreeBSD to have a non-Linux build environment. The module is only used in the periph_spi application, which ran successfully on the Pi and failed to build on FreeBSD with the error message that SPI is only supported on Linux. @miri64 – Does this sound reasonable to you, too? If |
I just tested it again and it still works. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have just some style comments left.
Thanks! As @benpicco already asked: you may squash :-). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks good, tested working on a raspberry pi.
Contribution description
Motivation: For my thesis, I need to be able to run the same code on a testbed consisting of microcontrollers as well as SoC platforms like the Raspberry Pi (not on bare metal but as process in Linux userspace, so I'll use the native cpu in RIOT).
Problem: The native cpu/board cannot make use of the underlying hardware, even if the CPU does support peripherals like SPI.
Suggested Solution: I wrote a wrapper around the Linux userspace SPI API that allows to map the devices from
/dev/spidevB.D
to SPI devices in RIOT. Basically, these device files represent SPI busses, where the first number (B) represents the bus itself, and the second number (D) represents the connected device / hardware CS line. If the RIOT application is compiled for Linux with thePERIPH_SPI
feature being required, it will provide the--spi
command line parameter, which can be used to dynamically map those device files to the application. For example, calling:... will allow to use
SPI_DEV(0)
in RIOT with eitherSPI_HWCS(0)
orSPI_HWCS(1)
. Using arbitrary lines for CS isn't possible until native also has access to GPIOs (related PRs #1737 or #7530 seem to be stuck, and #8048 is more or less raspi-only and also possibly outdated).In addition to my use case, I think that SPI access under native might as well become handy for development and debugging on device drivers.
Testing procedure
Board: Native CPU/Board on a Linux-based SoC with hardware SPI. I used a Raspberry Pi, where the pinout for Rev. 2 and 3 would be: more details
This means we have one physical bus with two hardware-based CS lines.
Loopback test
The easiest way would be a loopback test with the periph_spi test, as it does not require any additional hardware. For the Raspberry Pi, one would connect MISO and MOSI with each other. Then, in the periph_spi directory:
And in the application's shell:
... or
init 0 0 2 -1 1
for the seconds CS line.This should output something like this:
Further Testing
Any further tests, especially with real SPI hardware, are a bit complicated as most drivers also require GPIO functionality in addition to SPI (for CS, RST or IRQ lines), which is not supported by now. I did most of my tests with a LoRa GPS Hat which provides a SX1276-compatible transceiver. However, the sx127x driver also requires GPIO, so I ported some of my former code to RIOT. The code can be found here, if that helps testing in any way.
I did the best I could to find errors in the code, but if you have any suggestions how I could verify the implementation more formally, a hint would be appreciated.
Other Build Environments
I also used a VM with FreeBSD to verify that the non-Linux build does not break (unless you require
PERIPH_SPI
as feature). However, due to the lack of hardware, I couldn't verify it for macOS right now.Issues/PRs references
Besides the aforementioned PRs regarding GPIOs, I did not find any Issues/PRs related to SPI on native.