@CodeChief is there any information about GPIO event “realtimeness” in Windows IoT?
The documentation is sparse whilst Microsoft appear to be doing a major overhaul of MSDN. But there is no warning that it can only be used for occasional events or anything like that and the initial results are positive.
The main reason the decoding was missing some data is because it’s running synchronously with lots of slow operations (debugger attached and debug messages being formatted and returned over the network) in the same thread. Of course that’s no working design beyond first alpha testing. It’s critical to continue decoding the next packet immediately and separate the delivery of events and read operations. I knew that already, I just wanted to test the technology first.
Next I will switch to a more professional design like a network driver, in a producer/consumer pattern. The background thread (producer) filling a ring-buffer and the caller (consumer) waiting for the frame event or reading synchronously like a stream, on a separate thread.
This RC input device is the first part of the conversion which does not have any real hardware behind it (i.e. we have no physical decoder or PWM hardware just raw signals on a pin). The more time critical functions, bits and bytes we have to process (in the upcoming chipsets to convert) the more sense it makes to switch the hardware part of the framework to C++/CX and drivers.
For the user and developer it makes no difference. In the end we are looking at something like this:
- Custom image including Navio drivers (plug and play).
- Optional: Custom settings app allowing some hardware tuning at the OS level. Perhaps integrate some kind of basic diagnostics to ease support.
- User downloads the developer’s app from the store or it is pre-loaded for a “plug and fly” experience.
Hope you had a great vacation, is there already any progress on this topic?
Thanks, yes I was delayed by some extra work for my day job. But I did manage to do all the research and start work on the device driver. Expect a commit quite soon with the new layout.
It’s not too hard, but a significant re-write. As already guessed the RC Input must be a device driver to ensure the critical timing is kept. I’ve written a Windows filter driver before and reading the new KMDF/UMDF (universal kernel/user) documentation it feels like the same old methods just with better OS support. So I’m quite excited to get properly stuck-in to this.
If direct access to the hardware via the “runtime component” is not as intuitive as the original C# library, I will leave/re-create a class library there as a wrapper/helper.
To avoid a long delay without any useful stuff, I will build the new components alongside and make frequent check-ins. Once RC Input is finished, revisit the PWM implementation to convert that. Then continue with the remaining chips.
The ADK has also been released so we have the chance to use the imaging tool from Microsoft to make a proper pre-installed stand-alone Navio image with the driver ready to run. That should also help anyone who wants to run the system quickly as a second/plug-and-play hardware test.
Finally a NuGet package will deliver the development parts as requested on GitHub. That will ease the setup procedure for other developers and make updates easy.
Thanks for the quick response. All of this sounds hitech ;o). Do you already have an idea which way the you/community may/can contribute. I had an agriculture project in mind (rover) with lidar and gps.
Will the code (except for the driver) be in c#
Are we rebuilding everything from scratch or reuse things from ardupilot… c++
I started with ardupilot but the problem there was a large codebase to understand without any debugging capabilities
i have a pixhawk and BBB with sensors
Then i thought to go .net with the netduino (raptor) 400mhz
the readings of the sensors were going well but i had no idea how to get the input of the controller go to an PID output to control the motors. Its more about math than actually programming.
So i was looking how Navio+ with the codebase you were working on could/would help me in that process.
Yes I think so, after the Core SDK is done the next thing to do is to use it! So I’ll be scrambling to implement some kind of RC input + servo output + PID loop and get something flying, to see if all that work was worth it
In the long term if it performs (the big open question is Linux RT vs Windows IoT task scheduling), then we could be looking at a totally re-written APM which should be easier to maintain (not having Arduino/SoC limitations still baked into it).
The other big benefit of this platform, might not be clear… When Navio has proper drivers for all it’s individual sensors, then those sensors are also available to ALL Windows 10 Store applications. So everything from GCS and weather station apps to games ( got some crazy ideas here ) can use the GPS, accelerometer, barometer and serial ports from Navio.
I Have a question about the ‘driver’ system I’ve never programmed drivers for myself but how does it work together
Is it a driver per sensor or a driver per bus (i2c) or for the whole device Navio+ in one driver and what for external components we want to add on the i2c bus
Because the sensors needs to share a bus so does the app give a link to the address of the bus??
Do the sensor readings happen in a c++ thread and then passed to a app or is the mainloop the app which call the driver?
Yes on almost everything!
There are different types of drivers we can create and Windows arranges them into a tree with stacks at each node. Some have dual roles, providing both the physical hardware interconnect (e.g. PCI or USB Hub) and a kind of router along that bus to each functional driver (e.g. some card plugged into USB or PCI).
The individual drivers connected to that bus have no idea how the message got there, they just do their job and return the result. A very logical and extensible structure indeed.
Navio uses a few different types of hardware connections, all of which have the core Microsoft bus (low level) drivers provided, namely I2C, SPI, GPIO and UART.
The application level I2C, SPI, GPIO and UART interfaces from Microsoft were already used in the current source code. But the problem is they are high level, low priority interfaces to something we need to use at a low level, time critical. Also we need to share devices between potentially more than one application, without re-inventing the wheel.
The best example is RC input. As there is no DSP or other chip in the middle (hint for Emlid there for the next hardware revision) we must use the RasPi processor to listen to the signals and decode it. Not something to do in an application thread. As the current code shows, it kind of works but with random losses of data depending on how busy the system is. That’s a show stopper for a full autopilot hence the immediate change of plan to implement device drivers directly.
So we need a functional or filter style of driver sitting on top of the I2C, SPI and UART physical device drivers, owning them exclusively, adding the Navio/use case specifics (e.g. a simple GPIO pin becomes PWM input/protocol data stream), and making it available for shared access via the standard Windows API.
Access to drivers is via the standard IO control requests of Windows (which you don’t normally get access to in higher level frameworks like .NET). That’s similar to Linux, but mostly in contrast as it uses file system emulation/paths instead of binary interfaces/protocols. Seems a bit crude to me and makes me wonder if it performs as well (all that text conversion before making the driver call). We will see, but competing with Linux is not the aim here. Both systems can learn from each other and I hope to submit some improvements back to the Navio Linux code tree once the Windows core is out the way.
The other half of the Windows driver, sitting in the user space, normally exposes these low level groups of IO request “interfaces” as more meaningful, easy to access components. In IoT that’s a Windows Runtime Component (the new Universal one, not to be confused with the WinRT predecessor).
In end effect, your product/tool/user code which uses the device, will simply have something as easy to work with as the existing basic I2C classes, but encompassing the full functionality of the device at native speed. So we will not have an I2C device but really a Servo and LED device. The technical details and requirements (like the exact sequence to cause a reset of the PWM chip, the contents of the registers and that the first three are LEDs with inverse values) can all be hidden inside the driver and exposed as direct simple values. Similar to what I did with the PWM/LED code already, but baked into the runtime framework.
The only “no” to what you said, is no main loop will be in control (or causing issues with) device access or performance. There drivers get priority and there are also configurable buffering options and designs than can be used to ensure no user application misses any data/event they want. The drivers initialize themselves and will run in the kernel doing whatever is necessary (if anything) to keep the device running in the last requested or default state. When any application makes a call to a library function, the IO request comes down and it changes state or returns the data from it’s buffers. In the opposite direction you can also register for events and be triggered when some data arrives or state change occurs.
Finally regarding how it will look, how many devices, yes it will be possible to further simplify, maybe even necessary to join some together. I expect it will be similar to a Bluetooth device where one driver installation INF file actually installs several driver parts, but they appear to work together as a logical “Bluetooth”. We will also have a control panel which can have more or less of what we want.
The control panel is another new cool part of Windows 10 IoT. Microsoft really let you extend it/integrate properly. So we can tune our hardware For example it could be used to switch the protocol of the RC input from PPM to SBUS. You could set some hardware level fail-safes, anything like that. I was also wondering if the simple test apps should themselves be inside a control panel, but what I read from Microsoft said they don’t approve of control panels with junk/application helpers in there (just want core device support).
Oh yes one other cool thing I was thinking about since, going on from the point I already said that every driver will inherit a standard device. That means RC input could expose itself a joystick! Play any Windows 10 compatible game with the transmitter even if it doesn’t normally emulate that over USB. Perhaps we can even set one of the gimbals of the transmitter up as mouse emulation, the possibilities are endless
I haven’t looked into the HAT standard yet, but it would be good if the driver could detect the Navio HAT ID (I think there is some kind of ID) then know it should initialize it’s collection of driver extensions. Like a plug-and-play ID. Also that would make supporting multiple models possible in the future, e.g. Navio and Navio+ differ by only a few things. The driver could detect that, or even the new Reach device, and activate only the necessary components (second note to Emlid, please leave an ID somewhere, if not available in the HAT standard perhaps in the FRAM chip if you put one on all devices).
So I’ve started driver development and at the same time did some patches to the original C# RC Input device to see if I can at least get it working before it’s replaced by the driver.
Here’s my test bed, literally “living in a box”
Crude but it does the trick and is easier than having a quadcopter sitting on the desk. I’m using a BitScope to confirm the signals are okay (compared to the latency in the C# code) and also take a sneak peak at the difference between SBus and CPPM:
The white “Logic 0” line is CPPM and the brown “Logic 1” line is SBus (either side of the FrSky SBus to CPPM converter as shown in the photo above).
I’m giving the C# code one last chance with proper buffers and a bit better framing logic, separating the listening thread from the decoding and display (which had to be done anyway). I’ll check-in whatever I have soon as there were some other minor fixes I want to share.
On the SBus side, with a logic analyser I think I have a good chance at working it out. It’s supposed to be an inverse serial protocol and from the initial display appears to be batched-up into 15ms blocks (including sync pause), in contrast to CPPM which is ~20ms, The significant part is it has extremely fast signal timing (just 3ms compared to the 16ms of CPPM) and relatively long (350%) sync pause.
So user mode/C# has no chance at detecting SBus frequency changes in it’s current form. Not unless the buffering I’m adding right now is some kind of magic trick. Only the kernel driver can pump this data straight into a local buffer and syphon it off to the apps without getting interrupted.
Shame it’s taking longer than I wanted, originally I hoped to have something flying by now. At least the other hardware components are “real devices” (not GPIO tricks) so I expect the remaining work will be completed much faster after RC Input and the first driver is produced.
I’ve checked also the github seems there are no changes there so far…I guess you wanted to create the driver before putting the code online.
Is there already a timing when the code will be ready to share (for the driver)
The drivers based on the sensors on the emlid device will those be based on the sources in the c++ from emlid? or also in c#
Yes I’ve been busy on this. It wasn’t easy because:
- For some reason, Microsoft specifically DON’T fully support GPIO4 anymore! It’s written right in their current release notes: http://ms-iot.github.io/content/en-US/win10/ReleaseNotes.htm (quote below) and also NOT listed in their official list/diagram of supported pins on the RasPi 2 (starts at GPIO5).
GPIO pin 4 may behave unexpectedly when switching between drive modes (2938068) WORKAROUND: If you need to switch drive modes, use a pin other than GPIO 4
- Tests with “user mode” access confirm the delay was not the problem, but the GPIO4 hardware is permanently in “floating mode”. That’s why there was so much junk in the data stream.
- According to various sources (e.g. RasPi Foundation forum), setting the GPIO pin drive mode is the way to fix that. Which brings us back to the first limitation, exactly what is not supported right now.
I did a lot of work to make the RC Input “device” (non-driver C# code) multi-threaded and use FIFO queues. I had the latency down to less than 100 microseconds, more than enough to do CPPM (but perhaps not SBus).
Moving forwards, these are the main points of concern:
- The only way to get any sensible data out of GPIO4 right now is via kernel mode code. At least until Microsoft fix their bug.
- It’s a waste of CPU time to do all this low level DSP work in high level languages (even the best compiler is simply not going to be efficient).
- The C++/CX driver with runtime component is the only sensible way forwards.
On the positive side, Microsoft recently released some code to support software PWM and integrated it (half way) into the framework:
The even have the PCA9685 there! Looking at the code, which is C++/CX. it’s very badly documented but the content is understandable. They had to use a high priority background thread to do the decoding and make a Windows Runtime component for access from user code. Exactly as I planned to do next. But the Microsoft code is not usable in it’s current form, is just a sample of various aspects and needs to be properly implemented for our SDK. But at least this provides a good point of reference and a much needed boost.
One other positive side is that we have official framework parts into which the Emlid drivers/framework can plug-in. So we can re-use some of the official types (like PWM pins and providers). Although you may not see that as important if you just want to write code for Navio, it’s very useful if you want to re-use code written for other IoT devices.
Okay so I have a “working” (best effort) C# RC input which, after filtering all the junk, manages to get clean sets of CPPM channels (all 8) every second or less. That’s the best possible until MS fix their GPIO4 drive mode issue. But I’ll most likely have the C++/CX component and driver code done before. So for the record I’ll finalize things by hooking it up with the test GUI, so people can use it somehow, then create a NuGet package and check-in.
After that I will re-create the Emlid.Windows.Hardware project as C++/CX and continue with my driver development (already well under way). Of course no more code for devices will be written in C#. It’s okay for consumer applications, but I wouldn’t write any autopilot with C# either now I know, Microsoft explicitly block or ignore all requests to run tasks with higher priority in “user mode”.
Addendum re. RC Input “hardware”:
Knowing the hardware design for RC input now, it is a really compelling reason to seek an alternative input for remote control. We can save 30% or more CPU time by using hardware RC input (taking the Linux measurements mentioned elsewhere on this forum). Results from the Windows driver are yet to be seen but should be similar.
So if we wanted to squeeze every last CPU cycle out of our RasPI then I think this means we should choose WiFi or an RX with serial capability. For example the FrSky X series receivers have SPort which is serial (I made one of those Teensy adapters for my Pixhawk). Maybe an SBus to TTL adapter is possible so more devices could connect most efficiently with Navio.
It’s not a show stopper, as the forum article on here about CPU time concluded, there are 4 cores and 30% of one core (or was it 30% of all cores???) should be okay. But certainly a desirable feature (hardware assistance/DSP for RC input).
As a side note I wonder if, on the Linux image, the RC input component can be disabled if you are not using it (e.g. WiFi). It’s probably a limitation of APM if not, or you could try to disable that PIGPIO thing. For example on the Windows side, I will make this configurable via the control panel.
Version 1.0.4-Alpha has now been checked-in. Also new in this release, the first NuGet package. For people who know the Microsoft tools that means you don’t need to install or update anything to use it. Just add the reference to the NuGet package ID “Emlid.WindowsIoT.Hardware” to your Windows Universal Platform project, then start coding! You’ll get notified about updates and they install automatically (when you decide).
The NuGet package is hosted here: https://www.nuget.org/packages/Emlid.WindowsIoT.Hardware
The latest source code is in the usual place here: https://github.com/emlid/Navio-SDK-Windows-IoT
So as discussed previously, this is the last release with the C# hardware library, because of performance limitations in user mode (by Microsoft design). The next release is going to be low level C++ and drivers, which should us give “real time” performance, hopefully a proven concept!
Hey CodeChief thanks for sharing and trying this out in c#
I had some nice ideas to make a i2c class and then a device that inherits the i2c class, dispitely the performance is too poor to continue.
Is it possible in VS to debug c++ in realtime being attached to the emlid? in that case i think it wont be a big issue to understand the c++ code by stepping through the code.
Thanks for working on the driver i’m looking forward for more info in the next weeks/months on this topic.
Yes IoT has interactive debugging. It’s a bit flakey on the setup and reliability side but the basic stop and examine stack/variables is already there.
If you just want I2C, SPI, UART, etc… the existing classes are enough and should perform as the are already backed by device drivers. The showstopper for user mode code is if you need to do anything super fast with the signals like the PWM decoding.
The “bus providers” are already available so could be copied into your own code if you want to do “software PWM” now. But the Navio implementation won’t be a copy and paste of that, much more is needed around it and that example was a bit too generic.
Another limitation is the lack of constants and virtual members in runtime componemts. That stops us creating nice (logical, elegantly designed, maintainable) class hierarchies like we have in C# for Navio LED & PWM, i.e. specialising the base PCA9685 chip which leaves manufacturer specific parameters open and doesn’t know the first three channels represent an RGB LED on Navio.
So the hardware components will be much “flatter” in the new form. Actually you won’t have to wait long as I thought about how best to get something usable out quickly and decided to do the C++ conversion first “as-is” which can run without a driver if I copy parts of Microsoft’s bus provider (as a quick fix). Then if it passes acceptable performance tests (RC Input must not skip any frames) people could play around with it whilst I take a bit longer to do the drivers properly.
Programming the sensors which have hardware behind them is much easier. It’s just this software virtual PWM which put a spanner in the works. I learnt recently that Spektrum already have a serial protocol option on some of their receivers like FrSky have SBus. But more, that support for “serial receivers” (the term already exists! …and) is already implemented in APM and dozens of other flight controllers. So I think somebody should take a look at that on the Linux side because for normal (Linux) use of Navio there could be a big performance improvement (assuming you can also disable PIGPIO without causing any HAL faults).
I’m hoping to get something done with the IoT C++ this weekend.
Just a quick update to say this is not forgotten. There was a major setback with a tools & OS build update to Visual Studio and even going back to the RTM releases does not give full debugging capability for “normal” driver development.
I’ve opened a few issues with Microsoft and they seem to be responding efficiently, besides a new release of the Windows Driver Kit (WDK) and SDK are coming very soon, which appear to be the root cause of the problems.
On the technical side there are no apparent show-stoppers. I have been able to get the plug and play detection working, load and deploy custom drivers which attach to the various Navio resources. But until the new WDK & SDK are released it will be hit-and-miss development (= long winded and potentially buggy) which I don’t like as a professional developer. Shame because by design the whole WDK thing looks great (for desktop/non-IoT drivers).
Nevertheless this is and will remain my top hobby project. So I am putting maximum spare time into it and hope to have something useful soon.
p.s. I will be blogging/documenting and checking-in scripts, tools and procedures before the driver is complete. One of the other difficulties was to read between the lines of MSDN desktop WDK docs and limited IoT docs (sometimes duplicated with different instructions/settings). Before anyone starts driver development or contributing to existing code a real world quick start and some helper scripts I made save significant time. I’ve submitted changes to the MSDN docs but they don’t seem to come through so good (e.g. not so dynamic as the Emlid docs).
Any progress on this project?
Considering this, would it be possible to pinout navio+ to intel edison with some effort skipping raspberry pi altogether ?
After a long wait and much anticipation MS made a disappointing Visual Studio 2015 Update 1 release. Now instead of just some difficulties developing drivers the whole driver configuration interface is broken. See this MS Connect article (and please click both the vote-up arrow and “I can (repo) too” to get attention). Normally I would expect some support but it seems they just closed this without any comment as “external”. I’m waiting on the IoT Forum issue but that has also been lacking in direct MSFT responses.
I do have a driver running on the “old” RTM Visual Studio but it’s slow going. I had a lot of other work to do recently but am getting back onto this now and hope to have something before the end of the year. If only MSFT would get their tools tested and released properly. Basic capability to debug drivers on IoT as documented in MSDN/WDK is essential. Seems like only the desktop WDK is functioning.
On the positive side they did also make a major platform update to the 10586 build. But still no video driver for the RasPi so still no camera support and still a very slow UI. They appear to have focused on the network, USB and Bluetooth driver support since the last build. If you click the link to supported devices now the list is extensive.
Another positive side is that they are getting ready for the new processors and do not restrict their device drivers. That means, Intel already committed to providing the new processor drivers so they will work on other boards. So hopefully the UP Board works too, then maybe we get some of the clones working with Navio and the faster Intel processors Nevertheless focus stays with the RasPi2 and Navio+ which has always been the main platform. But nice to know.
I have one machine at work which doesn’t have the device driver tools problem. It’s so weird it fails on most new/updated installs but a few are successful. I will either copy my VM from work or try a minimum install in case some of the other tools installed with Visual Studio are conflicting.
Worst case, if there is no improvement to the situation by the end of the week I will probably go back to write the other chip support as simple classes. Then the Windows Navio would only fly with Joystick and WiFi to start with.
Microsoft have already dropped support for Intel Galileo boards and Edison was never supported. However this statement sounds promising:
The Windows 10 IoT Core image included in this drop supports the peripherals that are exposed on the MinnowBoard MAX board. Subsequently, Intel® will provide support of the full feature set of the Baytrail processors including the Intel Celeron™ Processors J1900/N2930/N2807 and Intel Atom™ Processors E38XX.
…from the current release notes.
The full list of hardware devices currently supported are here: