-
Notifications
You must be signed in to change notification settings - Fork 585
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
Update Board info for Pi 5 #2145
Conversation
RaspberryBoardInfo.Model.RaspberryPi5 or | ||
RaspberryBoardInfo.Model.RaspberryPi400 => new RaspberryPi3LinuxDriver(), |
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.
The GPIO Hardware of the RPi5 seems to be quite different from previous versions. Is the RaspberryPi3LinuxDriver really working correctly?
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.
Fair point... I'll see if I can build it all locally and try it on my Pi5 and see what's what. :-)
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 read the pre-release datasheet for the new custom IC called RP1
which is new to the RPi5.
It governs all the I/O, serial ports, I2C, SPI, PWM, video and USB communications. The HW architecture is very different from the previous boards even if they apparently maintained the external pin compatibility (They also use MUXes for the I/O, meaning that you can remap the ping assignments).
The main point about that IC is to offload the communications from the main processor to support low-power communication while the rest of the board is in sleep mode. It also supports 1.8V levels but they have to be carefully used because, once set any voltage higher than 1.8V can damage the board.
Said that, the libgpiod could be enough to decouple the new functionalities but since there are more features, it will probably deserve a new separate RasperryPi5LinuxDriver
to support them.
I don't have a new RPi5, but any test you could do is more than welcome :)
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.
Is there a recommended workflow for development / debugging for GPIO? Are we able to debug directly on the Pi? @pgrawehr @raffaeler ...
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.
Is there a recommended workflow for development / debugging for GPIO? Are we able to debug directly on the Pi?
The point here is that there is no direct access for the C# code to the GPIO, therefore debugging the GPIO access does not help much. The dotnet/iot
library provides two "drivers": sysfs
(GPIOs mapped on files) and libgpiod
. They are just the C# code accessing the file system or the libgpiod
api.
sysfs
is the simpler (and slower) way. If you can successfully access the GPIOs using the default tools, it should work fromdotnet/iot
as well. Even if this works, it is not the best solution as file mapped GPIOs have a number of issues.libgpiod
provides access to the GPIOs via APIs. I understood that there is no current version forlibgpiod
for the RPi5. In this case there is nothing you can do from dotnet. A soon as the Raspberry Foundation should provide it, we will have to see if the APIs are exactly the same or not.
Alternate solutions are:
- fork
libgpiod
and provide support for theRPi5
, you should download and implement theRP1
specifications inside thelibgpiod
source code. This step is definitely not trivial. - implement the
RP1
specs directly in C# bypassing libgpiod. It is doable but, again, not trivial.
AFAIK we never did this for any other board.
P.S. As I mentioned in the previous message the RP1 specs have a number of new features that may not fit in the current libgpiod
API. This is why I believe we need something different on the C# wrapper side as well.
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.
@pjgpetecodes There are two options to work with the library:
Variant 1
- Check out the repo on the PC, build
- Create / update an example
- Publish it for arm64 and copy to the pi
- Run on the Pi, use SSH for remote debugging, if needed
Variant 2
- Checkout on the PI
- Build on the Pi
- Execute the examples / Integration tests
I'm normally going with 1, unless I'm running the GPIO testbench. Then I check out on the Pi and run dotnet test System.Device.Gpio.sln
. (For the GPIO tests to work, you need to have pins 5 and 6 connected with a resistor)
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'm guessing I'll have to clone, switch to my working branch, and build this on the pi, then manually add the system.device.gpio dlls to my project to begin with...?
You can just cross-compiling everything on Windows and then copy to the RPi5. Your test code could be any basic binding. I suggest you to directly reference the dotnet/iot libraries so that you recompile the libraries as well.
This is the typical way to cross-compile using self-contained to avoid any dependency and being able to sync the sources as suggested by Patrick.
- Release vs Debug: pick Debug if you want to avoid optimizations and sync the sources
- linx-arm vs linux-arm64. This depends on the OS on the RPi
dotnet deploy -c Release -r linux-arm --self-contained=true
Please note that the pdbs will point to sources that you just compiled.
In any case, if you just want to make a test, you don't need to debug. You can just deploy the release version as self-contained and see if if works (you can write on the console some message to have detailed info).
HTH
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.
Arghhh... My comments above (#2145 (comment)) were stuck in pending... Apologies @raffaeler and @pgrawehr ... Thanks for the help mind you!
As you can see it seems to work at a high level at least...
Need to figure out the best way to move forward now eh!
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.
Hey, that's good news, at least we have one driver that works for the Pi5. Can you (just for reference) do the same test with using the RaspberryPi3Driver and the SysFsDriver?
PinNumberingScheme.Board is only supported with the RaspberryPi3Driver, because it needs to know the mapping from the logical pins to the physical pins. Because most boards and drivers don't support that either, we've mostly given up support for that anyway and stick to the logical numbering.
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.
So...
With the original code;
RaspberryPi3Driver
driver givesNot a supported Raspberry Pi type:
(Fairly obviously)`SysFSDriver
just works!
With Raspberry Pi 5 added in the boardInfo.BoardModel
switch in the CreateInternalRaspberryPi3LinuxDriver
function, creating the RaspberryPi3Driver
and passing it into the GpioController gives An unhandled exception of type 'System.IO.IOException' occurred in System.Device.Gpio.dll: 'Error 13 Initializing the Gpio driver'
Interestingly, doing a sudo dotnet run
, gives Error 22 instead of Error 13 (But still System.IO.IOException
)... Not sure of the difference.
Also, doing an ls /dev/gpiomem
(as I see that mentioned in the RaspberryPiLinuxDriver.cs
) gives No such file or directory
, same with sudo ls /dev/gpiomem
.
sudo adduser <myusername> gpio
gives adduser: The user '<myusername>' is already a member of 'gpio'
ls /dev/mem
gives:
crw-r----- 1 root kmem 1, 1 Oct 10 21:11
This is all no doubt because the new RP1 IO chip does GPIO entirely differently.
For reference, standing up something like a PWM Servo means that we can't pass in which GPIO Driver we use, so this needs to be done behind the scenes I guess.
I mean, ideally we'd write a driver specifically for this, but I'm not sure what's involved in that of course.
@@ -141,6 +141,7 @@ RaspberryBoardInfo.Model.RaspberryPi3BPlus or | |||
RaspberryBoardInfo.Model.RaspberryPiZeroW or | |||
RaspberryBoardInfo.Model.RaspberryPiZero2W or | |||
RaspberryBoardInfo.Model.RaspberryPi4 or | |||
RaspberryBoardInfo.Model.RaspberryPi5 or |
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.
[Triage] Please remove this line to avoid using that driver for Raspberry Pi 5 because it's not fully working and as a next step right after this PR consider creating a separate PR/issue for Raspberry 5 driver.
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.
Thanks... Done... I've also added the Pi5 Board reference to the GpioController class along with a switch choosing the LibGpiodDriver when on windows.
However, I guess this will only be used if running on Windows 10 or the now (pretty much) defunct Windows 10 IoT?
Do let me know if you think this should be removed though?
I'll definitely go with a new PR for for any work on a Pi5 driver.
Add Pi 5 OProduct to GpioDriver.
@@ -506,6 +507,11 @@ private static GpioDriver GetBestDriverForBoardOnWindows() | |||
return new RaspberryPi3Driver(); | |||
} | |||
|
|||
if (baseBoardProduct == RaspberryPi5Product || baseBoardProduct.StartsWith($"{RaspberryPi5Product} ")) | |||
{ | |||
return new LibGpiodDriver(); |
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.
Shouldn't this be in the Linux method? AFAIK there's no supported windows version for rpi at this time and libgpiod is not for windows.
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 absolutely agree... Only, that function doesn't detect the board type nor does this class for Unix, where that code is within the RaspberryPi3Driver class sadly...
So, I figure, if I'm going to need to bring that code in to this class, or modify the RaspberryPi3Driver class, then I should submit a new PR for that as @krwq suggests perhaps?
Absolutely happy to take some direction though!
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.
For now, let's keep this simple. As you've already noticed above, Windows isn't really supported any more (the defunct Windows 10 Iot is only supported on the Raspberry Pi 3, and for Windows 11, there are no officially supported versions for any Pi at all at this time).
So for now, move this code to GetBestDriverForLinux()
so at least we get a valid driver there. If I understand correctly, you need to do new LibGpiodDriver(4)
though. After this, I would say this PR is ready to get merged.
After that, investigation is needed onto the next steps. We probably need a fully new RaspberryPi5Driver
then, that handles the GPIO device for the new RP1 chip. Don't forget to take a look at the RaspberryPiBoard
class, which contains the logic to program the mux for the different GPIO alternate functions. This logic will likely also change.
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.
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 tried PWM and a Servo out of interest and it doesn't seem to work interestingly... I wonder is this a limitation of the LibGpioDriver?
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.
With Python and
gpiozero
I get jittery servo movement from BCM18... But there's movement...
Could you re-try with C# after running the Python code?
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.
Nothing sadly... gpiozero, while jittery, works... I'm sure it's bit bashed PWM in gpiozero by default given that its jitterry and gives this warning;
/usr/lib/python3/dist-packages/gpiozero/output_devices.py:1509: PWMSoftwareFallback: To reduce servo jitter, use the pigpio pin factory.See https://gpiozero.readthedocs.io/en/stable/api_output.html#servo for more info warnings.warn(PWMSoftwareFallback(
No movement at all for .NET... Which will be trying to use Hardware PWM.
With that in mind... When I try software PWM from the bindings it works... But not ideal...
using SoftwarePwmChannel pwmChannel1 = new SoftwarePwmChannel(18, 50, 0.5, true);
using ServoMotor servoMotor1 = new ServoMotor(
pwmChannel1,
180,
900,
2100);
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.
There is probably some new initialization stuff needed to make it work on the RPi5 but it's hard to say.
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'll have a dig around and a play.... See what I can turn up...
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.
BTW... I tried adding the following to the config.txt file and rebooting;
dtoverlay=pwm-2chan,pin=18,func=2,pin2=13,func2=4
But, no dice.
Worth trying eh.
I've also asked the question around Pi 5 docs in the Raspberry pi Forums, see if there's some more info out there other than the RP1 Datasheet.
Looks like this is stuck for some reason... Not sure why... |
No worries, we just have to review the changes this week during the triage. |
/azp run dotnet.iot |
Azure Pipelines successfully started running 1 pipeline(s). |
Ahhh... Gotcha... Makes sense... Thanks. I thought I'd done something wrong! Interestingly it looks like something failed with the build though? |
@pjgpetecodes No, it's all fine with the build now. Because you're a first-time contributor, the build doesn't start automatically, though. Therefore I had to force it to run. |
Yes, a couple of builds failed because there are random (known) issues happening in the pipelines that makes some tests fail. The issues on the pipeline will be hopefully fixed soon. |
Wahoo... Awesome... Thanks! In the meanwhile... I'm doing some learning on how the current driver works and how to create a new one for the Pi 5! |
The Board info for the new Raspberry Pi 5 is missing.
Microsoft Reviewers: Open in CodeFlow