Developing DSS Services for Windows CE

Decentralized Software Services (DSS), supports development of services and applications that will run directly on a Windows CE device. This document will go though the most common scenarios a developer will encounter when programming for Windows CE using DSS. These scenarios require some more steps compared to the desktop programming due to the fact that the development of the application happens on the desktop PC, but the application actually runs on the device.

Using DSS the programmer can develop distributed services that are hosted by .NET Compact Framework. This means that the programmer can deploy and run DSS applications on a wide range of embedded platforms that support .NET Compact Framework 2.0 such as Windows CE Embedded devices, Windows Mobile Pocket PCs and SmartPhones.

Requirements

Bb483099.hs-note(en-us,MSDN.10).gif To develop .NET Compact Framework applications, Microsoft Visual Studio 2008 is required.

In order to develop applications for .NET Compact Framework and deploy them to a Windows CE device there are several things that you will need:

  • An embedded device with Windows CE 5.0 or later. Windows CE is already integrated with Windows Mobile devices. You can always use the Windows CE emulator and VS2005 to test your applications.
  • Download and install .NET Compact Framework 2.0 SP2 Redistributable on your desktop machine as well as on the Windows CE 5.0 or higher device.
  • Visual Studio 2005 Standard Edition or higher. Visual Studio Express Editions do not support mobile and embedded development.
  • If your target CE platform is a Single Board Computer (SBC) such as ICOP eBox embedded system, you will also need to download and install the latest Board Support Package (BSP) from the manufacturer’s web site.

In this guide we assume that the operating system is already installed and ready to use on your embedded device. For instructions on preparing and installing an OS image on your embedded platform please contact the manufacturer of your device.

Creating a DSS Service for CF

To create a DSS service that will run on the Windows CE operating system using .NET Compact Framework 2.0 you will first need a service that will run on Windows XP or later using the full desktop .NET Framework 2.0. This is required to properly generate proxy and transform assemblies and to allow Compact Framework (CF), and desktop services to communicate with each other.

For example let's create a new desktop service using the DSS New Service Generation Tool (DssNewService.exe) tool by running it out of the DSS command prompt:

 cd samples
DssNewService.exe /service:simpleExample

To make it work with the iRobot Create™ requires doing some modifications:

  • Open the project simpleExample.csproj in Visual Studio.

  • Add a reference to IRobot.Y2007.M01.proxy that is located in the bin sub-directory of a DSS installation.

  • Open simpleExample.cs file and make the following changes:

    • Add the following, using, statements at the beginning:

       using lite = Microsoft.Robotics.Services.IRobot.Lite.Proxy;
      using sensorupdates = Microsoft.Robotics.Services.IRobot.SensorUpdates.Proxy;
      using irobot = Microsoft.Robotics.Services.IRobot.Roomba.Proxy;
      using create = Microsoft.Robotics.Services.IRobot.Create.Proxy;
      
    • Add an iRobot™ partner service and a couple of global variables to the SimpleExample class declaration:

       [Partner("irobotlite", Contract = lite.Contract.Identifier,
      CreationPolicy = PartnerCreationPolicy.UsePartnerListEntry,
      Optional = false)]
      lite.IRobotLiteOperations _irobotPort = new lite.IRobotLiteOperations();
      lite.IRobotLiteOperations _irobotNotify = new lite.IRobotLiteOperations();
      
      private int _initialized = 0;
      
    • Add the subscription to the iRobot™ service to the Start() method of SimpleExample service class:

       _irobotPort.Subscribe(_irobotNotify);
      Activate<ITask>(
        Arbiter.Receive<sensorupdates.UpdateMode>(true, _irobotNotify, UpdateModeHandler),
        Arbiter.Receive<sensorupdates.UpdatePose>(true, _irobotNotify, UpdatePoseHandler),
        Arbiter.Receive<sensorupdates.UpdateBumpsCliffsAndWalls>(true, _irobotNotify, UpdateBumpsHandler)
      );
      
    • Finally add the declarations of the notification methods used above:

       private void UpdateModeHandler(sensorupdates.UpdateMode mode)
      {
        if (mode.Body.RoombaMode == irobot.RoombaMode.Full)
        {
              if (_initialized == 0)
              {
              _initialized = 1;
              _irobotPort.CreateDriveDirect(200, 200);
              }
        }
        LogInfo(LogGroups.Console, "Mode: " + mode.Body.RoombaMode.ToString());
      }
      private void UpdatePoseHandler(sensorupdates.UpdatePose pose)
      {
        LogInfo(LogGroups.Console, "Distance: " + pose.Body.Distance.ToString() + " Angle: " + pose.Body.Angle.ToString());
        if (_initialized == 1 && pose.Body.Distance > 200)
        {
              _initialized = 2;
              _irobotPort.CreateDriveDirect(-100, 100);
              _irobotPort.RoombaPlaySong(2);
        }
      
        if (_initialized == 2 && (pose.Body.Angle > 90 || pose.Body.Angle < -90))
        {
              _initialized = 3;
              _irobotPort.CreateDriveDirect(0, 0);
              _irobotPort.RoombaPlaySong(1);
        }
      }
      
      private void UpdateBumpsHandler(sensorupdates.UpdateBumpsCliffsAndWalls update)
      {
        if ((update.Body.BumpsWheeldrops & (irobot.BumpsWheeldrops.BumpLeft | irobot.BumpsWheeldrops.BumpRight)) != 0)
        {
              LogInfo(LogGroups.Console, update.Body.BumpsWheeldrops.ToString());
        }
      }
      
  • Open simpleExample.manifest.xml to add the correct startup information to the manifest file:

     <?xml version="1.0" ?>
    <Manifest
            xmlns="https://schemas.microsoft.com/xw/2004/10/manifest.html"
            xmlns:dssp="https://schemas.microsoft.com/xw/2004/10/dssp.html"
            xmlns:example="https://schemas.tempuri.org/2007/04/simpleexample.html"
            >
      <CreateServiceList>
            <ServiceRecordType>
              <dssp:Contract>https://schemas.tempuri.org/2007/04/simpleexample.html</dssp:Contract>
              <dssp:PartnerList>
                    <dssp:Partner>
                      <dssp:Name>example:irobotlite</dssp:Name>
                    </dssp:Partner>
              </dssp:PartnerList>
            </ServiceRecordType>
            <ServiceRecordType>
              <dssp:Contract>https://schemas.microsoft.com/robotics/2007/02/irobotlite.html</dssp:Contract>
              <dssp:Service>https://localhost:0/irobotlite</dssp:Service>
              <dssp:PartnerList>
                    <!--Initialize Roomba config file -->
                    <dssp:Partner>
                      <dssp:Service>irobot.ce.config.xml</dssp:Service>
                      <dssp:Name>dssp:StateService</dssp:Name>
                    </dssp:Partner>
              </dssp:PartnerList>
              <Name>example:irobotlite</Name>
            </ServiceRecordType>
      </CreateServiceList>
    </Manifest>
    
  • Add a new XML file to the project, and call it irobot.ce.config.xml and add the following configuration information to it:

     <?xml version="1.0" encoding="utf-8"?>
    <RoombaState xmlns:s="https://www.w3.org/2003/05/soap-envelope"
                             xmlns:wsa="https://schemas.xmlsoap.org/ws/2004/08/addressing"
                             xmlns:d="https://schemas.microsoft.com/xw/2004/10/dssp.html"
                             xmlns="https://schemas.microsoft.com/robotics/2007/01/irobot.html">
      <BaudRate>57600</BaudRate>
      <Name>Dave</Name>
      <SerialPort>1</SerialPort>
      <IRobotModel>Create</IRobotModel>
      <ConnectionType>CreateSerialPort</ConnectionType>
      <MaintainMode>Full</MaintainMode>
      <PollingInterval>201</PollingInterval>
      <WaitForConnect>false</WaitForConnect>
      <CreateNotifications />
    </RoombaState>
    

The programmer can compile this service that has been created in Visual Studio or by running the following command in the samples\simpleExample directory:

 msbuild simpleExample.csproj

Once the programmer has the desktop DSS service C# project created they can convert it to the CF project using DSS New Service Generation Tool (DssNewService.exe) with the /generateCFproject command line argument. Here's how it works for for the sample service:

 DssNewService.exe /generateCFproject:simpleExample.csproj

As a result the programmer will have a project that will compile for CF using the same code used for a desktop version. The generated CF project will target the Windows CE 5.0 platform. Compile the new project.

 msbuild "cf.simpleExample.csproj"

This new project is used in the Debugging a DSS Service on the CE device using Visual Studio section later in this guide.

The programmer can use define statements to separate specific x86 and CE code sections, as in the C# example here:

 #if !URT_MINCLR
  // Desktop specific code 
#endif

The URT_MINCLR preprocessor symbol is defined in the CF project generated by DssNewService.

Creating a DssDeploy package for CE deployment

Deploying a DSS Service to CF is very similar to deployment of the services to full .NET. The same tool, DSS Deploy Tool (DssDeploy.exe), is used with the same overall approach.

DssDeploy will create a self extracting executable that will work on the Windows CE device. To deploy  the package the programmer needs to copy it over to the device as a regular file, and then run it on the device. It will extract its contents into the directory where it is located.

To create the deployment package the programmer can specify a particular service that they want to package by contract, a manifest file with the needed services and configuration, a particular dynamic linked library, or any combination of these parameters. In addition the programmer might want to specify explicit dependencies that are not going to be found automatically such as documentation files, native references, media files, etc. The programmer has to make sure that all the services they are trying to package exist for CF. This can be done by verifying that the assemblies are present in the bin\CF sub-directory under the DSS installation. This example shows how to create a package for the Simple Example service for a Windows CE device.

Using the SimpleExample.manifest.xml manifest as an example located in the samples\simpleExample directory. The command line for this looks like this:

 DssDeploy.exe /p /cf /m:"SimpleExample.manifest.xml" mySimpleIRobot.exe 

This produces the file mySimpleIRobot.exe that the programmer will be able to run to extract on the CE device.

Deploying a package on a CE device

The package that's created with DssDeploy should have everything the programmer needs to run the application on the device, except for the .NET Compact Framework itself.

Bb483099.hs-note(en-us,MSDN.10).gif The programmer must have .NET Compact Framework 2.0 SP2 (CF) installed on the device before they can deploy and run a package. There are several ways of deploying CF on the device, for example ActiveSync can be used to install it. If the device does not support ActiveSync, find the appropriate version of the cab file. For example, C:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE\wce500\x86\NETCFv2.wce5.x86.cab - for Windows CE 5.0. Copy it to the device, and run it on the device to have it installed. There is a specific CF installation for each CPU architecture. Refer to the user's manual of your device to find out about the type of processor used in the device such as XSCALE, ARM, x86, SH, MIPS, etc. Then locate the right CF 2.0 cab file to install on the device. See How to: Install the .NET Compact Framework.

When the CF is installed copy over the package created, in the example above it is called, mySimpleIRobot.exe, use ActiveSync or any other method of getting files over to the device. Since the deployment package contains all the necessary files needed to run the service, including the DSS and CCR runtimes, the location of the folder where it is unpacked on the device is optional. However, for consistency assume the packaged is copied to a new directory called, \Program Files\MSRS, on the device.

The created package does not take any command line parameters and when run will extract its contents into the directory where it’s located. Note that the files from the bin\CF directory will now be located just in, bin, which is required for DSS to run correctly. The rest of the files will preserve their file tree location if they were located previously in the tree of desktop DSS installation.

Running a DSS Service on the CE device

Running a DSS service on the CE device is very similar to running one on the desktop. The programmer will need to start DssHost passing in parameters, such as the HTTP and TCP/IP ports that are used for communication, as well as the manifest for the services to start. In the example it will be:

 cd \Program Files\MSRS
bin\cf.dsshost /p:50000 /t:50001 /m:..\samples\simpleExample\simpleExample.manifest.xml

Please note that in the above command, unlike in desktop command, the manifest path is relative to cf.dsshost.exe rather than to the current directory. Also the programmer cannot enclose the manifest path in quotation marks when calling the CE version of DssHost.

If your CE device does not have a command line to start DssHost, you can use Visual Studio (VS) to remotely run your service on the device. To do this follow the steps in next section, which talks about debugging the service using Visual Studio, make sure no break points are set, the application will stop for them.

In order for the service to work on the iRobot Create™, the programmer  should set up a Bluetooth™ or wired serial connection and configure the SerialPortand ConnectionType settings in the, irobot.ce.config.xml, file created earlier.

Bb483099.hs-caution(en-us,MSDN.10).gif If your desktop computer has a DSS node running either directly of via VPL or DSS Manifest Editor then the desktop node must have security disabled in order to communicate with the DSS node running on Windows. Otherwise the communication will not be possible. See DSS Node Security Model

Debugging a DSS Service on the CE device using Visual Studio

Debugging the service on the Windows CE device will require the programmer to go through several steps. Now go through them using the iRobot service for CF from the steps above as an example:

  • Using Visual Studio open the CF project that was generated by DssNewService, in the example it is called, cf.simpleExample.csproj.

  • Open the properties for the project by right-clicking on it in Solution Explorer and click Properties.

  • Go to the Debug tab.

  • Click Start External Program and fill it out with the following:

     \Program Files\MSRS\bin\cf.dsshost.exe       
    

    which assumes that the extracted package is in the \Program Files\MSRS folder on the device.

  • In the, Command Line Arguments, put the following:

     /p:50000 /t:50001 /m:file:///Program%20Files/MSRS/samples/simpleexample/simpleexample.manifest.xml       
    

    which sets the ports and the manifest of the service to start.

  • In the Solution Explorer window, right-click on the Solution node (top most) and click Properties to open the solution properties page.

  • Under Configuration Properties\Configuration, uncheck the Deploy and Build check boxes next to the cf.simpleExample.csproj project.

  • Add a breakpoint on the Start routine of the Simple Example service.

  • Now press F5 to start the service on the device.

  • On the Windows CE device notice a new window pops up that shows the node starting.

  • Eventually the service starts and the breakpoint is hit.

Bb483099.hs-note(en-us,MSDN.10).gif In the very first run from a deployment, the service cache is built, which takes about 30 seconds on an ICOP eBox2300 embedded system.
See Also 

DSS User Guide: DSS Node Security Configuration

 

 

© 2009 Microsoft Corporation. All Rights Reserved.