Latest Posts
A new customer came to me late last week with an interesting problem. They have
hundreds of Motorola/Symbol MC70 barcode scanners in the field and occasionally the
flash memory on the devices gets corrupted.
The current "solution" these guys are using involves removing the flash chips from
the board, reprogramming it in a separate device, re-balling the BGA pins, and re-soldering
it to the board. That explains why they desperately want an application that can do
it.
They know the range where the corruption occurs and wanted an application that would
allow a user to read, update and rewrite the corrupted bytes in flash. They
had talked with five separate developers before they found me, and all 5 had agreed
that it was impossible, so naturally I took that as a challenge.
First, there are lots of things to know about how flash access works. Most importantly,
it's not like RAM. You can't just map to it, then go about your merry way doing
32-bit reads and writes. You can read it that way, sure, but writing is a whole
new game. Flash is broken up into "blocks" (which aren't even always the same
size - in the case of the MC70, the first 4 blocks are 64k long, and the rest are
256k long.) and writes must be done following this general procedure:
-
Read the *entire* block that contains the byte you want to change into RAM
-
Change to flash to Lock mode (a flash register write)
-
Unlock the block of flash (another register write)
-
Change the flash to erase mode (register write)
-
Erase the *entire* block of flash (which writes all FF's to it)
-
Change the flash to write mode (register write)
-
Update the RAM buffer with your changes
-
Write in the *entire* block block to flash
-
Tell the flash to commit (register write)
-
Wait for the flash to finish (register read)
-
Put the flash back into read mode (register write)
Oh, and if you get any of this wrong, you've made yourself an expensive brick.
The only solution at that point is the de-soldering and reprogramming route, and I
don't have that kind of hardware in my office.
So I started writing the app Monday morning, using C# since I had to create a UI for
the editor, and on Wednesday morning this is what I delivered:
So, in just 2 days I did what was "impossible". I not only wrote all of the flash
access code, I also wrote a hex editor control and an app UI to make use of the flash
library.
Managed Code in the Embedded World
A customer recently contacted me with a Padarn
Web Server problem. They wanted users to be able to download data files
from their device to a client browser, but they were running out of device memory
when the file got large (38MB in their case, but the size would be completely hardware
and environment dependent).
What you have to understand is that Padarn caches your Page's response in memory until
such time as you either tell it to Flush explicitly, or until the Page has full rendered
(in Padarn's view) at which point it will call Flush for you.
For a large file, it's going to be bad to try to hold the entire thing in memory before
pushing it across the wire, so the strategy would be to read the local file in packets,
then send those packets across to the client using Response.BinaryWrite.
Now BinaryWrite simply puts the data
into the memory cache, so you have to actually tell Padarn to send it across the wire
by calling Flush. The issue there, though, is that on the first Flush, Padarn
has to assemble and send the payload header to the client, and part of that header
is the total length of the content. If you haven't explicitly set the content
length, Padarn has no idea how big it might be, so it defaults to the length what
it has in the buffer, and sends the header. The browser then decodes that header
and expects a length of only that first packet.
The solution is to set the Response.ContentLength property before you
send any data. Padarn will use your override value when it sends it to the client,
and all will be well.
Here's a quick example of a page that I used to send a 1.1GB media file from a page
request with no problem. You might want to tune the packet size based on device
memory and speed, but 64k worked pretty well for my test.
1: class LargeFileDownload
: Page
2: {
3: protected override void Render(HtmlTextWriter
writer)
4: {
5: var
largeFilePath = @"D:\Media\Movies\short_circuit.mp4";
6:
7: var
packetSize = 0x10000; // 64k packets
8:
9: using(var
stream = new FileStream(
10: largeFilePath,
11: FileMode.Open,
12: FileAccess.Read))
13: {
14: var
toSend = stream.Length;
15: var
packet = new byte[packetSize];
16:
17: //
set the response content length
18: Response.ContentLength
= toSend;
19: //
set the content type as a binary stream
20: Response.ContentType
= "application/octet-stream";
21: //
set the filename so the browser doesn't try to render it
22: Response.AppendHeader("Content-Disposition",
23: string.Format("attachment;
filename={0}",
24: Path.GetFileName(largeFilePath)));
25:
26: //
send the content in packets
27: while (toSend
> 0)
28: {
29: var
actual = stream.Read(packet, 0, packetSize);
30:
31: if (!Response.IsClientConnected)
32: {
33: Debug.WriteLine(
34: "Client
disconnected. Aborting file send.");
35: return;
36: }
37: else
38: {
39: Debug.WriteLine(
40: string.Format("Sending
{0} bytes. {1} to go.",
41: actual,
toSend));
42: }
43:
44: if (actual
== packetSize)
45: {
46: Response.BinaryWrite(packet);
47: }
48: else
49: {
50: //
partial packet, so crop
51: var
last = new byte[actual];
52: Array.Copy(packet,
last, actual);
53: Response.BinaryWrite(packet);
54: }
55:
56: //
send the packet acrtoss the wire
57: Response.Flush();
58:
59: toSend
-= actual;
60: }
61: }
62: }
63: }
Managed Code in the Embedded World
There's no doubt in my mind that code libraries and frameworks are fantastic for saving
time and work, after all I want to spend time solving my business problem, not writing
infrastructure. Nowhere is this more true than it is with Object-Relational
Mapping, or ORM, libraries.
Broadly speaking, if you're still writing application code that requires that you
also write SQL, you're wasting your time. Wasting time thinking about SQL syntax.
Wasting time writing it. Wasting time testing, debugging and maintaining it.
I believe this so much, but was so dissatisfied with any existing ORM offering, that I
wrote my own ORM. It wasn't a trivial task, but I have something that does exactly
what I need, on the platforms I need, and does it at a speed that I consider more
than acceptable. Occasionally I hit a data storage requirement that ORMs, even
my own, aren't so good at.
ORM usage is usually viewed as one of two approaches: code first or data first.
With the code-first approach, a developer defines the storage entity classes and the
ORM generates a backing database from them. With data first, the developer feeds
a database into the ORM or an ORM tool, and it then generates the entity classes for
you.
But this doesn't cover all scenarios - which is something no ORM that I'm aware of
seems to acknowledge. Consider the following use-case (and this is a real-world
use case that I had to design for, not some mental exercise).
I have an application that allows users to define storage for data at run time in
a completely ad-hoc manner. They get to choose what data items they want to
save, but even those data items are dynamically available so they are available only
at run time.
So we need to store effectively a flat table of data with an unknown set of columns.
The column names and data types are unknown until after the application is running
on the user's machine.
So the entities are neither data first nor code first. I've not thought of a
catchy term for these types of scenarios, so for now I'll just call it "user first"
since the user has the idea of what they want to store and we have to accommodate
that. This is why I created support in the OpenNETCF ORM for the DynamicEntity.
Let's assume that the user decides they wanted to store a FirstName and LastName for
a person. For convenience, we also want to to store a generated ID for the Person
entities that get stored.
At run time, we generate some FieldAttributes that define the Person:
1: var
fieldList = new List<FieldAttribute>();
2: fieldList.Add(new FieldAttribute()
3: {
4: FieldName
= "ID",
5: IsPrimaryKey
= true,
6: DataType
= System.Data.DbType.Int32
7: });
8:
9: fieldList.Add(new FieldAttribute()
10: {
11: FieldName
= "FirstName",
12: DataType
= System.Data.DbType.String
13: });
14:
15: fieldList.Add(new FieldAttribute()
16: {
17: FieldName
= "LastName",
18: DataType
= System.Data.DbType.String,
19: AllowsNulls
= false
20: });
And then we create and register a DynamicEntityDefinition with the DataStore:
1: var
definition = new DynamicEntityDefinition(
2: "Person",
3: fieldList,
4: KeyScheme.Identity);
5:
6: store.RegisterDynamicEntity(definition);
Now, any time we want to store an entity instance, we simply create a DynamicEntity
and pass that to the Insert method, just like any other Entity instance, and the ORM
handles storage for us.
1: var
entity = new DynamicEntity("Person");
2: entity.Fields["FirstName"]
= "John";
3: entity.Fields["LastName"]
= "Doe";
4: store.Insert(entity);
5:
6: entity
= new DynamicEntity("Person");
7: entity.Fields["FirstName"]
= "Jim";
8: entity.Fields["LastName"]
= "Smith";
9: store.Insert(entity);
The rest of the CRUD operations are similar, we simply have to name the definition
type where appropriate. FOr example, retrieving looks like this:
1: var
people = store.Select("Person")
Updating like this:
1: var
person = people.First();
2: person.Fields["FirstName"]
= "Joe";
3: person.Fields["LastName"]
= "Satriani";
4: store.Update(person);
And Deleting like this
1: store.Delete("Person",
people.First().Fields["ID"]);
We're no longer bound by the either-or box of traditional ORM thinking, and it leads
to offering users some really interesting and powerful capabilities that before were
relegated to only those who wanted to abandon an ORM and hand-roll the logic.
Managed Code in the Embedded World
You don't have to be a developer to create useful, customized applications for maintenance
workers. See what's happening on the vehicle in real time, see it how you want
and get it done in seconds. Take a look at the new Transit and Telematics
hands-on lab for Solution Family.
Managed Code in the Embedded World
I've recently started refactoring a customer's code base for a working application.
They recognize the need to make their code more extensible and maintainable so I'm
helping to massage the existing code into something that they will be able to continue
shipping and upgrading for years to come without ending up backed into a corner.
One of my first suggestions was to start eliminating the abundance of static variables
in the code base. In this case, static classes and methods abound, and it looks
like it was used as a quick-and-dirty mechanism to provide singleton behavior.
Now I'm not going to go into depth on why an actual singleton might have been better,
or the pitfalls of all of these statics. Write-ups on that kind of thing about
in books and on line.
Instead, let's look at what it means to migrate from a static, an instance or a singleton
over to using a DI container, specifically
OpenNETCF's IoC framework.
First, let's look at a "service" class that exposes a single integer and how we might
consume it.
1: class MyStaticService
2: {
3: public static int MyValue
= 1;
4: }
And how we'd get a value from it:
1: var
staticValue = MyStaticService.MyValue;
Simple enough. Some of the down sides here are:
-
There's no way to protect the Field value from unwanted changes
-
To use the value, I have to have a reference to the assembly containing the class
-
It's really hard to mock and cannot be moved into an interface
Now let's move that from a static to an instance Field in a constructed class:
1: class MyInstanceService
2: {
3: public MyInstanceService()
4: {
5: MyValue
= 1;
6: }
7:
8: public int MyValue
{ get; set; }
9: }
Now we have to create the class instance and later retrieve the value.
1: var
service = new MyInstanceService();
2:
3: //
and at a later point....
4: var
instanceValue = service.MyValue;
We've got some benefit from doing this. We can now control access to the underlying
value, making the setter protected or private, and we're able to do bounds checking,
etc. All good things. Still, there are downsides:
-
I have to keep track of the instance I created, passing it between consumers or maintaining
a reachable reference
-
I have no protection from multiple copies being created
-
The consumer must have a reference to the assembly containing the class (making run-time
plug-ins very hard)
Well let's see what a Singleton pattern buys us:
1: class MySingletonService
2: {
3: private static MySingletonService
m_instance;
4:
5: private MySingletonService()
6: {
7: MyValue
= 1;
8: }
9:
10: public static MySingletonService
Instance
11: {
12: get
13: {
14: if (m_instance
== null)
15: {
16: m_instance
= new MySingletonService();
17: }
18: return m_instance;
19: }
20: }
21:
22: public int MyValue
{ get; set; }
23: }
And now the consumer code:
1: var
singleTonValue = MySingletonService.Instance.MyValue;
That looks nice from a consumer perspective. Very clean. I'm not overly
thrilled about having the Instance accessor property, but it's not all that painful.
Still, there are drawbacks:
-
The consumer must have a reference to the assembly containing the class (making run-time
plug-ins very hard)
-
If I want to mock this or swap implementations, I'll got to go all over my code base
replacing the calls to the new instance (or implement a factory).
How would all of this look with a DI container?
1: interface IService
2: {
3: int MyValue
{ get; }
4: }
5:
6: class MyDIService
: IService
7: {
8: public MyDIService()
9: {
10: MyValue
= 1;
11: }
12:
13: public int MyValue
{ get; set; }
14: }
Note that the class is interface-based and we register the instance with the DI container
by *interface* type. This allows us to pull it back out of the container later
by that interface type. The consumer doesn't need to know anything about the
actual implementation.
1: //
Note that the Services collection holds (conceptually) singletons. Only one instance
per registered type is allowed.
2: //
If you need multiple instances, use the Items collection, which requires a unique
identifier string key for each instance
3: RootWorkItem.Services.AddNew<MyDIService,
IService>();
4:
5: //
and at a later point....
6: var
diValue = RootWorkItem.Services.Get<IService>().MyValue;
Mocks, implementation changes based on environment (like different hardware) and testing
become very easy. Plug-in and run-time feature additions based on configuration
or license level also are simplified.
Managed Code in the Embedded World
Yes, VS 2012 will support CE development, including Compact Framework
3.9. Support is scheduled to be released in Q1 of next year. See
this video for more details.
Managed Code in the Embedded World
I'm (finally) trying to publish some better, more formal documentation for the
ORM. I just posted a simple example of how you can create a one-to-many
relationship between Entities and how you can get the ORM to fill in the references
when you do a Select call. Take
a look at the ORM documentation for more details.
Managed Code in the Embedded World
I've just checked in new code changes and rolled a full release for the
OpenNETCF ORM. The latest code changes add transaction support. This
new release adds a load of features since the last (the last was way back in February),
most notably full support for SQLite on
all of the following platforms: Windows Desktop, Windows CE, Windows Phone and Mono
for Android.
Managed Code in the Embedded World
If you needed another excuse to try out IoC,
here it is. It's now even easier to create intuitive UIs. I just checked in
a new feature to the OpenNETCF.IoC.UI
assembly. Workspaces now have basic gesture support, so you get an even
on a swipe in the four primary directions (up/down/left/right).
Managed Code in the Embedded World
The OpenNETCF ORM has supported
SQLite for a while now - ever since I needed an ORM for Android - but somehow I'd
overlooked addeing SQLite support for the Compact Framework. That oversight
has been addressed and support is now in the
latest change set (99274). I've not yet rolled it into the Release as it
doesn't support Dynamic Entities yet, but that's on the way.
Managed Code in the Embedded World
Back in May 2008, I wrote a blog post about checking
for Win32 methods. I was recently reminded of this when a customer emailed us
about a scenario that exactly matched the intended use case.
The customer was using the Smart Device
Framework with a Windows CE 5.0 device and was receiving a MissingMethodException
"Can't find an Entry Point 'xxx' in a PInvoke DLL 'yyy'". The exception message
is detailed enough to explain the situation -- since Windows CE is modular, whoever
created the OS image had not added a required component, resulting in the native functions
to be missing from coredll.dll. This is not an uncommon scenario in the Windows CE
world.
Below is an example of how you can gracefully handle calling the PlaySound function
from coredll.dll even on devices that don't support the function. The important
part is the call to Device.Win32Library("coredll").HasMethod("PlaySound").
This is return false if coredll.dll does not exist or if coredll.dll does not export
the PlaySound function. Of course, you could raise a PlatformNotSupportedException or
try another mechanism for playing the sound file instead of just returning without
calling the native PlaySound function. The important point is that you should code
in a way that can handle scenarios where the native function is not available and
adapt accordingly.
Imports System.Runtime.InteropServices
Imports OpenNETCF.Reflection
Partial Public Class MainForm
Friend Class NativeMethods
Private Const SND_ASYNC As Integer = &H1
Private Const SND_FILENAME As Integer = &H20000
Public Shared Sub SafelyPlaySound(ByVal soundFile As String)
If Not Device.Win32Library("coredll").HasMethod("PlaySound") Then
Exit Sub ' Function is not exported so we silently return
End If
' Coredll exists and the PlaySound function has been exported
' so we can safely make the P/Invoke call
PlaySound(soundFile, IntPtr.Zero, SND_ASYNC And SND_FILENAME)
End Sub
_
Private Shared Function PlaySound(ByVal szSound As String, _
ByVal hMod As IntPtr, _
ByVal flags As Integer) As Integer
End Function
End Class
End Class


Last week we quietly launched a fantastic new promotion for our Padarn
Web Server product:
Padarn is a lightweight, single-purpose web server that supports a growing subset
of ASP.NET. It is written entirely in C# and can be used as stand-alone web server,
or embedded into an existing application. Padarn can be used to create elegant, data-driven
web sites using SQL Server Compact Edition, or interface with a whole myriad of hardware
peripherals, such as web cams, sensors, controllers, etc.
If you would like more information on Padarn, please send an email to padarn@opennetcf.com.

Note: This blog post only applies to Smart Device Framework Standard or Professional
Edition customers.
>
If you open the SDF Public Source solution that ships with Smart Device Framework
2.3 and then build the source, you'll come across the following error:
Friend access was granted to 'OpenNETCF,PublicKey=...', but the output assembly is
named 'OpenNETCF, Version=2.3.0.21, Culture=neutral, PublicKeyToken=null'. Try
adding a reference to 'OpenNETCF,PublicKey=...' or changing the output assembly name
to match.
(Note that I've replaced the actual public key with ellipses in the above. You will
see an extraordinarily long hexadecimal number in your errors list in Visual Studio.)
The easiest way to remedy this is through a quick search & replace. Hit Ctrl-H to
bring up the Find & Replace window. In the Find what text box, enter
the following:
,PublicKey=00240000048000009400000006020000002400005253413100040000010001002beeba3
bfe7c548e085cffb8c2b6fd61ddd02b06d70864bb7de8bb22473edf5ab4b2196ff98e232c3e87f11fd
7986b743d5d3fdd6ecaf624bacfed116e1cefa50cd652365371d0ebd2702eb1084fed46df79ac0f59f4
d66c547918613d56dcf106843f3458516d3cd26f057a346d9f645fc24a7410a095c754835916e13cdbe
Make sure the Replace with text box is empty and the Look in combobox
is showing Entire Solution. Click the Replace All button. When the search
& replace has completed, build the solution again and it will succeed.
If you wish to do this manually (you may only want to use 1 or 2 of the 16 projects),
you will need to modify the AssemblyInfo.cs file for the following projects:
-
OpenNETCF
-
OpenNETCF.Configuration
-
OpenNETCF.Net
-
OpenNETCF.Windows.Forms
>

Today, we released Smart Device Framework
2.3. This is the long awaited release of the Smart Device Framework for Visual
Studio 2008.
It's been a painful path to get to this point, what with contending with frustrating
bugs in Visual Studio 2008 forms designer and all, but we finally got there. Thanks
for you patience and understanding.
Along with the new version is a new naming convention. We've dropped the name Smart
Device Framework Extensions for Visual Studio with its Standard and Premium editions.
Instead, say hello to Smart Device Framework Standard Edition and Professional
Edition. Be sure to check out the new feature
matrix to find out how each edition differs.
We've got some pretty cool stuff features in the libraries, notably OpenNETCF.Core which
contains a dozen or so extension methods for common scenarios, as well as OpenNETCF.Net.Mail,
for sending mail via SMTP directly from the device -- this eliminates the need to
configure a mail account on the device.

When you reference an assembly compiled against .NET Compact Framework 2.0 in a project
targeting .NET Compact Framework, it's quite likely you will receive a number of ResolveAssemblyReferences warnings,
similar to this:
ResolveAssemblyReferences:
Consider app.config remapping of assembly "System.Windows.Forms, Culture=neutral,
PublicKeyToken=969db8053d3322ac, Retargetable=Yes" from Version "2.0.0.0" [] to
Version "3.5.0.0" [C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\
WindowsCE\System.Windows.Forms.dll] to solve conflict and get rid of warning.
This warning occurs when the compiler has loaded the .NET Compact Framework 3.5 base
class libraries (BCLs) and the referenced assembly, but the metadata contained in
the referenced assembly references the .NET Compact Framework 2.0 BCLs.
To remove the warnings you can add an App.Config to your project and redirect the
assembly bindings from the 2.0 versions to the 3.5 equivalents. Below is an example
of the XML required in the App.Config to redirect the 2.0 version of System.dll to
the 3.5 version.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentassembly>
<assemblyidentity name="System" culture="neutral" publickeytoken="969db8053d3322ac" />
<bindingredirect newVersion="3.5.0.0" oldVersion="2.0.0.0" />
</dependentassembly>
</assemblybinding>
</runtime>
</configuration>
You will need to add a dependentassembly element for each of the ResolveAssemblyReferences
warnings that you receive.
Make sure the Build Action property of the App.Config is set to Content and
the Copy To Output Directory property is set to Only if newer. Then,
rebuild your solution and the warnings should not appear.

There's been a lot of internal discussion today on how to leverage C# 3.0 features
without requiring .NET Compact Framework 3.5. Mark has the low down on using extension
methods with a little compiler misdirection hack.
The discussions kicked off because I discovered that you can use lambda
expressions with .NET Compact Framework 2.0 projects in Visual Studio 2008. I
even twittered about it yesterday. (Note: it didn't take me too long to realize it's
not a bug, but due to Visual Studio 2008 using the C# 3.0 compiler.) Code
like the following just works -- no hacks required:
delegate double PowerOf(double x, double y);
static void Main()
{
PowerOf pwr = (x, y) => Math.Pow(x, y);
double result = pwr(2, 3);
}
If you are using Visual Studio 2008 and still need to target .NET Compact Framework
2.0, the little things like this go a long way to creating and maintaining reusable
code.

Over the last few months we've been working hard to attain the Gold Level partner
status in the Microsoft Partner Program and I'm extremely pleased to say that we've
done it! For our customers, this is an assurance that by choosing to work with OpenNETCF
products and our consultants, you really are choosing a high calibre company.
Massive amounts of credit for Mark for
driving this internally. Good job!

The next Smart Device Development Chat will take place on MSDN at 10am PST on Wednesday,
July 16.
Please join experts from the Windows Mobile, Windows CE, SQL Server CE and .NET Compact
Framework communities in a chat around application development for smart devices.
These chats are a great opportunity to have your questions answered by experts from
around the world.
Add
to Calendar
If you cannot attend the MSDN Chat, there is a permanent chat room available on the web and
via IRC (irc://irc.freenode.net/mobiledev).
Engage with your peers online today!

A little later than I intended, but here is the transcript to Smart Device Development
chat from May 13, 2008: Read
it here

I was browsing around over lunch when I came across an upcoming title from Wrox that
I thought might be interesting to someone out there.
The book, being writing by Samuel Phung of ICOP,
is titled Professional
Microsoft Embedded CE 6.0. A book like this is sorely needed as most of the knowledge
exists primarily in the embedded newsgroup or scattered around in a handful of blogs.
The 20-chapter book will cover everything from creating an image to development in
C# and VB.NET, as well as C++ and is scheduled to be released in November. Wrox have
made a number of chapters available through
their Wrox First subscription service.
