With the new Skewworks standard for Applications on NETMF finally done, documented, and just waiting for deploy I wanted to create a few really slick examples of using Gadgeteer Modules across AppDomains.
While I was completely unsurprised that not a single module was safe for crossing domains I was floored to find that Microsoft themselves failed to mark simple things such as their Serial wrapper safe. System.IO.Ports.Serial can cross domains with the greatest of ease…so it seems silly to me that this would be overlooked by MS for Gadgeteer.
Luckily there are a couple of methods to send messages between applications using the Skewworks way. So, instead of passing the modules to the applications, I am passing commands back to the original domain and then responding back with the result.
The simplest of case being with the Bluetooth module where I created a real SerialPort to pass to the application and for resets simply sent a command back to the calling domain to toggle to OutputPort.
There’s a lot of silly things like this and, while I know Gadgeteer is still very young, I hope MS will take the time to resolve soon.
Perhaps they want you to use encapsulation? I would consider it bad practice to pass references to real hardware devices around. You have no idea who is going to do what to it.
Well that is kind of the point for developers isn’t it?
And that aside it still doesn’t excuse Gadgeteers Serial object. If pure NETMFs serial port can be passed safely Gadgeteers should be too. It’s Eother lazy coding or not thinking ahead on their part. Most likely the second.
But there isn’t a single intended purpose. And if AppDomains weren’t meant to be used they wouldn’t be included. Point of fact they aren’t included on devices too small to use them. But with something like the Hydra it’s almost a waste to use it for a single app. I mean if you can create an entire operating environment and still have space left over then you really ought use the power you have, or get a smaller device.
I don’t think that the Pyxis/Pyxis2/Gadgetos use case lines up very well with the more traditional embedded development use case. In traditional embedded development, encapsulation is not a concern, nor is generality, nor abstractions. You’re talking directly to the hardware, and utilizing the hardware to its fullest is the goal.
Hardware independence might be the name of the game for Gadgetos, and that’s fine, but the general embedded development pattern has different focuses.
I’m just envisioning taking things in a slightly new direction. With making application launching easy for everyone I think there may be more of that in the future.
My point is I’m not sure why sound OOP concepts, proven patterns, high cohesion and loose coupling is considered bad when developing for micro controllers.
I believe that’s why there are options to include or exclude these types of features, based on whether or not they will be necessary.
IMO, AppDomains are a feature that aren’t useful on small platforms, such as USBizi and even Cerberus&co, and it would be worth it to save the space for user code. On Hydra, EMX, and Chipworkx, it makes sense, because you have the resources available to take advantage of it.
Just my opinion. I’m sure there are others have have found valid use cases for AppDomains and other features that I haven’t.
I’m sorry, allow to me clarify the title. I don’t mean that Gadgeteer is bad in general, I actually like Gadgeteer. What I’m saying here is that it’s bad for multiple applications or any application that needs to use multiple AppDomains.
Though, that’s not the only issue with Gadgeteer, as others have pointed out, it’s bloated. And part of the reason it’s bad for AppDomains is the bloat. Go look through the Gadgeteer source and tell me why there’s an entire new interface to InterruptPorts when they could have simply done a Gadgeteer.InterruptFromSocket. The SPI sharing and Mainboard.Mount are the exceptions to “useless bloat” as I see it.
Though you’re welcome to disagree.
This is just my opinion for my project. Nothing more or less.
In a microcontroller environment, it is (usually) a given that you’re dealing with systems that JUST BARELY have enough resources to do what you’re doing. If you have more resources than you need, then you use a lower-spec microcontroller because it’s (definitely) cheaper, (probably) smaller and (usually) consumes less power. All these things are good when you’re working at the low end. Indirection, layering, loose coupling, abstractions, patterns that increase code maintainability at the expense of even a few bytes of memory and a few processor cycles are not generally used here, because using a few extra bytes of memory could mean a few pennies per widget more expense, which could mean millions of dollars to the bottom line annually.
Gadgeteer isn’t built for a normal microcontroller environment, it’s built for a hobbyist electronics environment, where people use 240 MHz microcontrollers with 16 MB of RAM and 4 MB of flash to do the job that a professional would accomplish with an 8-bit 8 MHz micro in a couple K of code and a few hundred bytes of RAM.
Neither is bad, they’re just different. Hobbyists don’t want to be constrained by the hardware, they want plenty of headroom available. That’s just fine.
Now, there’s yet another environment here, which is the “embedded OS” environment, and this is where Skewworks is playing, and what he’s saying Gadgeteer isn’t good for. Again, that’s just fine, but it’s not the environment Gadgeteer was built for. Gadgeteer makes some assumptions about having complete control over the hardware, assumptions that aren’t valid in a shared-resources environment like an embedded OS.
There isn’t a lot of overhead writing maintainable code. Cost is not just hardware, it’s how easy it is to maintain the code, fix, find bugs and change code with confidence.
We are using C#. It’s OOP. Running on .netmf. If you want the smallest possible footprint you probably shouldn’t have started with this platform to begin with.
We are already trading memory and cost for easy of use, maintainability and tooling.
There are whole MVC frameworks written for low end devices which are about 2K lines of code. I see no reason to use global variables, pass device pointers around instead of wrapping this in a small class which controls how it’s being interacted with. And perhaps just some simple DI for injecting the hardware devices into this wrapper upon construction.
I thought the whole idea of this was to get away from the arduino; “oh I wonder if GPIO 5 is used somewhere else?”, “hmm… are all the interrupt timers used somewhere else?” etc.
As an aside, this is why I get much more excited about the smaller, cheaper, less capable NETMF platforms. It’s why I was so excited about the STM32F103 port Oberon did (64KB ram, 512KB flash). In order for NETMF to become the most popular embedded development platform, it’s necessary to race to the BOTTOM, not the top.
In the world of mass-produced electronics, pennies count. When we have a Cortex-M0 port, we’ll have hit the big time.
Another way to look at this is, “I’m already wasting enough cycles because it’s managed code, I might as well not waste more using an additional layer of abstraction”.
When I wrote the software for my sprinkler timer, I did some of this. I had an XML configuration where I could change the hardware pins used for various I/O functions. Then, I thought to myself, “self, that’s nonsense. It’s not like this is going to be changed around. The pins in use are dictated by the board the chip is soldered onto.”