Welcome to the Adeneo-Embedded blog. This is the centralized home for our engineers to post content of interest for our customers and the embedded community at large.

We specialize in BSP's, solutions and training for Windows Embedded CE, the Microsoft .NET Micro Framework, and Windows Embedded Standard. For more information, please visit our corporate website at http://www.adeneo-embedded.com/.


Tuesday, January 19, 2010

Thank you Microsoft!

It's only been a couple of years since I left Microsoft, but they decided to honor me this year by making me an Embedded MVP!

So, I would like to thank Microsoft for the award, and say that I look forward to working for the embedded community in every way I can this year. It should be a great one!

-Joe

YouTube Videos

I've created a couple of YouTube videos that might be of interest to everyone, thought I would post the links.

The first is about a network projector I created using a Gumstix OMAP module running our BSP and a Pico Projector from Texas Instrument.

The second talks about Silverlight for Windows Embedded (new with Windows Embedded CE 6.0 R3). It gives a general overview as well as a demo on creating a very simple UI with Platform Builder and Expression Blend.

I hope you guys enjoy them!

-Joe

Friday, December 11, 2009

Device Emulator Networking on Windows 7

I was an early adopter of Windows 7. Most Windows CE developers that I talk to are still running Windows XP, but more and more are switching. About half of the developers in our office are now running 7.

I understand why people have been slow to transition - especially after the difficulties many experienced with Vista, but I've been running Platform Builder on 7 since before it RTM'd, and I've been very happy with it.

... with one exception. If you enable networking in Device Emulator, you will get an error; it just won't work. This is because of a dependency on the Virtual Network Service from Virtual PC 2007. Even if you install Virtual PC for Windows 7, it won't work -- they made some changes to the drivers.

I've made it for months without needing this feature, but of course once I needed it, I *really* needed it. The good news is, that part of Virtual PC is a nice little stand alone service that you can install and get this to work. Rather than digging in and figuring out how to fix this myself, I decided to first see if anyone else had already managed to get it to work.

I found a great blog entry from Brian Peek - it's a great step-by-step document that explains how to get VPC2007, extract, and install the service needed. Thanks Brian!

-Joe

Friday, September 25, 2009

Highlights from ESC

I just got back from the Embedded Systems Conference in Boston, and the conference was great this year. I was running some of the labs in the "Build Your Own Embedded System" (BYOES) track this year on Windows Embedded Standard 2011 (Windows 7 Embedded).

The labs went very well and we got great feedback from everyone that attended. I wrote a lot of code for these labs including a Managed wrapper that allows for discovery and control of devices that use the WSDAPI and PnP-X. I did a lot of research while preparing for the show and found that there is no code out there today to do this. I will be posting the code in the coming weeks, so if you are interested, keep an eye open for that.

Besides the work I did on these labs, some of our other engineers were working on an amazing demo for the Kevin Dallas keynote address. It is a webpad style device running a very cool XAML based UI running on Windows Embedded CE 6.0 R3 (codenamed Cashmere). We had the device in our booth for the rest of the show and were able to show it to everyone that came by.

Because of the new Silverlight features in R3, a design company was able to create the look and feel for this demo, put together a UI, and provide us the XAML. Once we had this, Nick McCarty (one of our eMVPs) worked with a couple of other engineers to hook up the code-behind to make the demo work. It only took them about a week and a half to get this working.

This ability to seperate the UI design from the code is a great feature that people have been doing on desktop Windows using WPF and Silverlight for quite some time, but now with R3, we can do the same on Windows CE. Very cool.

You can take a look at the keynote on YouTube. Nick's project is shown at 0:22-2:30 in this video. They didn't seem to capture much of the device in the videos they posted, but it should give you an idea.

-Joe

Monday, September 14, 2009

Upcoming trainings and ESC-East

Adeneo has some trainings coming up, the links are at the end of this post (I'll be doing the ones in Dallas and Boston). But, in addition I will be doing some Hands-on-labs at the Embedded Systems Conference in Boston. These labs will be on Windows Embedded Standard 2010 (Windows 7 Embedded!).

For more information on the Hands-on-labs, check out the ESC web site.

Worldwide training:

http://www.adetelgroup.com/mailing/090928-Linux-Freescale-Paris/090928-Linux-Freescale-Paris.htm

http://www.adetelgroup.com/mailing/090928-US-wince-Freescale-Dallas/090928-US-wince-Freescale-Dallas.htm

http://www.adetelgroup.com/mailing/091005-wince-TI-Munich/091005-wince-TI-Munich.htm

http://www.adetelgroup.com/mailing/091019-US-wince-TI-Boston/091019-US-wince-TI-Boston.htm

http://www.adetelgroup.com/mailing/091019-wince-atmel-milano/091019-wince-atmel-milano.htm

Thanks!

Friday, August 14, 2009

Web Casts and Videos

I've been pretty busy the last few months delivering trainings and going to conferences, but there has been some of my content posted up to Microsoft.com that I thought I would let you all know about!

The first three are webcasts, they are all 100 level, but are a good explanation of some of the OTHER embedded technologies from Microsoft besides Windows Embedded CE. Here are the links:

MSDN Webcast: How to Tell If Your Project or Solution is "Embedded" (Level 100)
MSDN Webcast: Windows Embedded Standard 2009 for Windows Developers (Level 100)
MSDN Webcast: Windows Embedded POSReady for Windows Developers (Level 100)

The next link is to a set of videos I did at the Microsoft Studios. This is a web version of 4-day Windows CE 6.0 training that I deliver. I see this as a good introduction, or review if you've been through the training already, but it is not a replacement. The content is much shorter, and not nearly as dynamic as having a speaker standing in front of you talking. Instead of having the audience do labs, I also had to convert these to demostrations, I am pretty happy with those. I feel like this format for the training is a bit... dry... but it is a good first step for those of you that want to get an understanding of CE and learn the tools a little.

Building Solutions with Windows Embedded CE 6.0 R2

-Joe

Wednesday, January 21, 2009

Using Interop in the .NET Micro Framework

The .NET Micro Framework is a sleek and robust way of bringing high-level functionality, quickly and easily, to low-specification platforms. A developer can enable a standard suite of features on a device using the Micro Framework Porting Kit. But what do you do when the functionality you want isn't supported in the Porting Kit?

One of the coolest new features of Micro Framework version 3.0 is Interop - the ability to extend the Micro Framework's functionality, adding features with C# interfaces in a fairly straightforward way. As the .NET MF is still young, this is extremely useful for filling in the blanks in the Micro Framework specification. At Adeneo we've already used interop to implement real-time timekeeping, power management, audio playback, and other features not natively supported by the MF.

In the following piece, I'll walk through the process of adding an interop feature to an existing Micro Framework port, step by step - although Microsoft recommends a method using their SolutionWizard tool, we've found this to be pretty flimsy. I'll use the example of a GPIO-driven LED feature, which is fairly simple from the driver perspective, but should be suitable for demonstrating the vast possibilities that interop gives us. Some of what I describe below is by convention, and not strictly necessary, so if you're wondering about a particular step - feel free to experiment.




Step 0: The Starting Point

As is hopefully obvious, this walkthrough assumes you've already got a piece of MF-compatible hardware, as well as Visual Studio 2008 SP1 and the Micro Framework SDK 3.0 (the SDK is freely available from Microsoft) for creating Micro Framework projects.

The walkthrough additionally assumes that you have access to the .NET Micro Framework Porting Kit, version 3.0, as well as the ability to build ports within the kit. (I will not describe the build process, as the kit's included documentation does a sufficient job of this.) It also assumes, for the sake of example, an LED driver which already exists in C++ code, and can be compiled/linked into your port. I'll assume that this driver has the following example functions:
    // enable the selected pin for LED control
BOOL LED_Initialize(GPIO_PIN PinLED);

// return the pin to general availability
BOOL LED_Uninitialize(GPIO_PIN PinLED);

// turn the LED on (when passed TRUE) or off (when passed FALSE)
void LED_SetState(GPIO_PIN PinLED, BOOL TurnOn);

// return TRUE if the LED is on, or FALSE if the LED is off
BOOL LED_GetState(GPIO_PIN PinLED);

For brevity I will not go into detail on how to implement a GPIO-driven LED driver, the mechanics of which should be pretty straightforward.




Step 1: Create Your C# Interface (Library)

The process of implementing interop starts at the top: designing the C# class you'll use as the high-level interface. Open Visual Studio, and create a new project of type Micro Framework -> Class Library. For organizational purposes, I suggest that you create this project in your PortingKit\Solutions\[Your Solution]\ManagedCode\ folder, although you can put it wherever you want.

Within this library, name and describe the C# functions you'll use to access your driver. Note well that a later step compiles a checksum of this library into your project, and so you should try to finalize this interface first, else you'll have to update more files later.

Here's an example for C# control of an LED, starting from a Library project named LEDInterop:
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware; // for Cpu.Pin type
using System.Runtime.CompilerServices;

namespace LEDInterop
{
public class LED
{
public LED(Cpu.Pin PinLED)
{
_pin = (UInt32)PinLED;
LED_Enable(_pin);
}

~LED()
{
LED_Disable(_pin);
}

public bool IsOn
{
get
{
if (LED_Get(_pin) == 1)
return true;
else
return false;
}
set
{
if (value)
LED_Set(_pin, 1);
else
LED_Set(_pin, 0);
}
}

//--//

// this is the LED object's associated pin
private UInt32 _pin;

[MethodImpl(MethodImplOptions.InternalCall)]
private extern void LED_Enable(UInt32 PinLED);

[MethodImpl(MethodImplOptions.InternalCall)]
private extern void LED_Disable(UInt32 PinLED);

[MethodImpl(MethodImplOptions.InternalCall)]
private extern Byte LED_Get(UInt32 PinLED);

[MethodImpl(MethodImplOptions.InternalCall)]
private extern void LED_Set(UInt32 PinLED, Byte State);
}
}

There are a few things to note about this C# code sample:

• This example uses the Cpu.Pin type, which requires the Microsoft.SPOT.Hardware reference. Right-click on References in the Solution Explorer and select Add Reference..., then click the .NET tab and choose Microsoft.SPOT.Hardware - without this, the LEDInterop project will not build!

• "Interop" functions - that is, functions which are defined in C++, but accessible in C# - are marked with this attribute:
    [MethodImpl(MethodImplOptions.InternalCall)]

These properties are inherited from System.Runtime.CompilerServices and, together with extern, indicate that the function is implemented in C++.

• The above sample has some forms of artificial abstraction (bool to Byte, Cpu.Pin to UInt32) that may seem unintuitive. Interop functions can only accept parameters of, and return values in, a limited number of types. Per Microsoft's documentation, here is a table of the allowed types and how they link up, e.g. a Byte in the CLR (C#) is the same as a UINT8 in the Porting Kit (C++):

C# TypeC++ TypeC++ Array Type
System.ByteUINT8, BYTECLR_RT_TypedArray_UINT8
System.UInt16UINT16CLR_RT_TypedArray_UINT16
System.UInt32UINT32CLR_RT_TypedArray_UINT32
System.UInt64UINT64CLR_RT_TypedArray_UINT64
System.SByteINT8CLR_RT_TypedArray_INT8
System.Int16INT16CLR_RT_TypedArray_INT16
System.Int32INT32CLR_RT_TypedArray_INT32
System.Int64INT64CLR_RT_TypedArray_INT64
System.SinglefloatCLR_RT_TypedArray_float
System.DoubledoubleCLR_RT_TypedArray_double
System.StringLPCSTRNot Supported


The C++ array types can be accessed with subscripts (Array[i]), but otherwise do not behave quite like normal C arrays. See PortingKit\CLR\Include\TinyCLR_Interop.h for more information on these custom types.

• You can build this project in Debug or in Release mode; either is fine. The rest of this example will assume you've remained in Debug mode.




Step 2: Insert Stubbed Functionality Into Your Port

Once your C# interface is well designed, you're ready to move back down to C++. Open your project's Properties (by right-clicking on the project, or double-clicking Properties in the Solution Explorer panel) and click the .NET Micro Framework tab. Below your deployment options - which don't matter at all for your Library - is a checkbox labeled Generate native stubs for internal methods. Check this box, and Build your project; this will construct stubbed-out C++ files for your interop interface, in the directory named below the checkbox - by default, in a Stubs sub-folder within your project folder. It will also, of course, generate the binary form of your C# class for a reference assembly.

First, copy the compiled binary files (your project's bin folder) into your Porting Kit Solution. I suggest putting them in the base project folder, e.g. PortingKit\Solutions\[Your Solution]\ManagedCode\LEDInterop\. These files are required for building your port, and for Micro Framework applications to use your new functionality.

Open the stubbed driver folder, and you should see several generated C++, H, and Project files. Following the example above,

dotNetMF.proj — project file for the generated code
LEDInterop.cpp — properties of your class
LEDInterop.featureproj — project file for the C# feature
LEDInterop.h — methods of your class
LEDInterop_LEDInterop_LED.cpp — implementation of the C#/C++ link
LEDInterop_LEDInterop_LED.h — definitions for this implementation
LEDInterop_LEDInterop_LED_mshl.cpp — CLR wrappers for your interop functions

Take this folder and copy its contents into your Solution as well - I'd suggest PortingKit\Solutions\[Your Solution]\DeviceCode\LED\. You'll need to edit two files to add the driver to your port.

LEDInterop.featureproj - You'll need to change two paths in this file to accomodate your port. The tag that refers to an MMP_DAT_CreateDatabase path should point to the .pe file from your Library project:
    <MMP_DAT_CreateDatabase Include="$(SPOCLIENT)\Solutions\[Your Solution]\ManagedCode\LEDInterop\bin\Debug\LEDInterop.pe" />

You also want to point the RequiredProjects path to your stubbed files:
    <RequiredProjects Include="$(SPOCLIENT)\Solutions\[Your Solution]\DeviceCode\LED\dotNetMF.proj" />


TinyCLR.proj - You also need to add this library and feature to your CLR project, in PortingKit\Solutions\[Your Solution]\TinyCLR\TinyCLR.proj. Open up this file, and near the top should be a list of .featureproj Import references: add yours in here.
    <Import Project="$(SPOCLIENT)\Solutions\[Your Solution]\DeviceCode\LED\LEDInterop.featureproj" />

Note that this Import must be above the Import for $(SPOCLIENT)\tools\targets\Microsoft.SPOT.System.Interop.Settings - otherwise, your project will not build!

You must also add an inclusion statement for the project that builds your new interop library, and the library itself. (The name of your library is tagged as AssemblyName in the generated dotNetMF.proj file.) Somewhere in the list of included libraries for TinyCLR, add the project and driver library:
    <ItemGroup>
<RequiredProjects Include="$(SPOCLIENT)\Solutions\[Your Solution]\DeviceCode\LED\dotNetMF.proj" />
<DriverLibs Include="LEDInterop.$(LIB_EXT)" />
</ItemGroup>


That's it! Now if you rebuild and flash your port, it should include your new interop feature. You can verify this by checking the output log at CLR startup - an assembly reference of your feature's name (in our case, LEDInterop) should appear in the list of included assemblies.




Step 3: Implement Your Feature

Now that the pieces are in place, it's time to link them together. One of the C++ files you generated previously (for the example, LEDInterop_LEDInterop_LED.cpp) serves as a bridge between your C# interface and your C++ codebase. This file contains skeleton functionality for the C# functions you defined as InternalCall, and which you will now fill in.

Following the example, here's how you might fill in this file:
#include "LEDInterop.h"
#include "LEDInterop_LEDInterop_LED.h"

using namespace LEDInterop;

void LED::LED_Enable( CLR_RT_HeapBlock* pMngObj, UINT32 param0, HRESULT &hr )
{
// param0 == PinLED
if(LED_Initialize((GPIO_PIN)param0) == FALSE)
hr = CLR_E_INVALID_ARGUMENT;
}

void LED::LED_Disable( CLR_RT_HeapBlock* pMngObj, UINT32 param0, HRESULT &hr )
{
// param0 == PinLED
if(LED_Uninitialize((GPIO_PIN)param0) == FALSE)
hr = CLR_E_INVALID_ARGUMENT;
}

UINT8 LED::LED_Get( CLR_RT_HeapBlock* pMngObj, UINT32 param0, HRESULT &hr )
{
// param0 == PinLED
if(LED_GetState((GPIO_PIN)param0) == TRUE)
return 1;
else
return 0;
}

void LED::LED_Set( CLR_RT_HeapBlock* pMngObj, UINT32 param0, UINT8 param1, HRESULT &hr )
{
// param0 == PinLED
// param1 == TurnOn
if(param1 == 1)
LED_SetState((GPIO_PIN)param0, TRUE);
else
LED_SetState((GPIO_PIN)param0, FALSE);
}

The trickiest thing about this file is the function parameters. Note that the C# parameters are renamed when they come down to this level, in the form param0, param1, and so on. For this reason it's wise to put some documentation in this file explaining what each of the parameters means.

With this new implementation, build your port, and flash it again. Now everything is assembled.




Step 4: Use It!

To use your interop feature in a C# application, you'll need to include the library reference. Open a new or existing Micro Framework application project. Right-click on References in the Solution Explorer and select Add Reference..., then click the Browse tab and browse for the output of your interop library - for the example, PortingKit\Solutions\[Your Solution]\ManagedCode\LEDInterop\bin\Debug\LEDInterop.dll - and add this Reference to your project. Now, you have access to the interop class you defined in Step 1.

Here's an example Micro Framework console application to control two LEDs:
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
// NOTE: you'll also need a reference to your
// hardware assembly, to use its pins!
using LEDInterop;

namespace MFConsoleApplication
{
public class Program
{
public static void Main()
{
LED led1 = new LED(Pins.GPIO_PORT_A_00);
LED led2 = new LED(Pins.GPIO_PORT_B_01);

led1.IsOn = true;
if(led2.IsOn)
Debug.Print("led2 is on!");
else
Debug.Print("led2 is off!");
}
}
}




Controlling hardware through intuitive C# interfaces is what the .NET Micro Framework is all about, and with a little practice, it's fairly easy to use interop features to push your platform beyond the standard Micro Framework: CODEC control, PWM, and arbitrary GPIO peripherals are only a few examples. Interop opens the door to a whole world of new Micro Framework-driven applications.

- TS




NOTES

• Properties of your C# class - such as _pin in our LEDInterop example - will be made accessible to your C++ code in the stub-generation process. If you create a property of a type that isn't compatible with C++ (per the table in Step 1), your C++ project will not build; but if you aren't using this property in C++, you can comment out the declaration for it in the .h file.

• As remarked in Step 2, the order in which you Import .featureproj references matters. Make sure you place them correctly!

• Changing the layout of your interop library class will require that you update all of your generated C++/H files, as they contain, among other things, a checksum of the class's signature. Be sure you update all of the generated files (and the binary output!) every time you change your interop library.

• The .pe binary file will only contain the aforementioned checksum value if the Generate native stubs for internal methods box is checked. If you build your class library without this checked, your port will be unable to accept deployed applications!

Thursday, November 20, 2008

Welcome!

Hello everyone, and welcome to our new blog. Let me introduce myself, I am the Senior Development Lead for North America at Adeneo. Essentially it's my job to make sure that our projects run smoothly and to help out with the "hard problems" that always come up when you are doing embedded development.


Some of our world-wide dev's have their own blogs, but after seeing some of the complex and interesting issues that my developers have come across, I felt it was important that we have a centralized place to share these ideas and discoveries with the larger community.


We will cover a variety of topics since we work with a variety of technologies. We look forward to hearing your feedback as we being to post new entries.

If you have feedback or suggestions for topics that you would like to send me directly, please feel free to contact me at jbroxson at adeneo-embedded.com.