Posts
76
Comments
208
Trackbacks
0
January 2009 Entries
What's wrong with my build?
Windows CE build is quite a complex process.
It involves different tools to parse makefiles, build and link code, merge resouces, make the OS image etc. and if something fails during the build is not always easy to understand what's wrong.
The first place where you can check is the build ouput window.
Most of the errors can be solved from there: compilation errors, link errors, files missing during makeimg etc.

If the output window does not provide the information you need, you should check two files: build.err and build.log under the windows CE root directory (usually C:\WINCE600).
Build.err usually has a single error message. Most of the times it simply tells you to check build.log.
build.log contains a detailed log of the whole build process and can be useful to understand where the process stopped and a mean to check all files, command line parameters etc. passed to the tool that failed its build step.

If even build.log can't help you, you can enable extra outputs to try to understand your problem.
If you open a build window (you can use the "build\Open release directory in build window" option of Visual Studio main menu) you can enable the full output of the build process by setting the _ECHOON environment variable to 1:
set _ECHOON=1
Then you can start a Windows CE build from the command line:
blddemo clean -q > buildoutput.txt
This performs a clean sysgen of your OSDesign (it seems that someone did not change the name of this bat since the times when CE was simply a demo OS).
At the end of the build, In buildoutput.txt you'll have the most detailed report of the build process you can get, including each step performed by the build bat files, build tools, compiler etc.
Setting _ECHOON to a non-null value simply disables the call to ECHO OFF performed at the beginning of the build batch file, echoing all the commands performed during the build on the console.
If even that doesn't lead to an explanation for your problem, at least gaves you something useful to attach to a question posted to the Windows CE support newsgroups.

In my experience the two most common reasons for "strange" errors during build (with "strange" I mean errors not related to your own code or configuration files) are file or directory names with spaces or wrong installation of QFEs.
When you install QFEs you should install them in chronological order and remember to install the latest yearly QFE and all the QFEs of the monts up to the last QFE you decided to install. If you don't install some QFEs you may have new files (in more recent QFEs) that use some functions declared or implemented in another QFE and this could lead to compilation errors or linking failures inside the OS code branches.
Posted On Monday, January 19, 2009 1:10 PM | Comments (1)
HTTP request class for the .NET Microframework
As I wrote in my first blog entry, I've been selected for round 2 of the "dare to dream different" challenge.
My idea involves a lot of internet connectivity and I needed a way to make HTTP requests from my .NET framework device (I'm stil waiting for the real device, but the emulator is great to test network connectivity).
I found a very good sample on Elze Kool's blog and I used it as a starting point for my own HTTP request class.
It's a simple class that allows you to send a request to any HTTP server.
It parses the reply and implements a stream interface, allowing you to read data from it using a TextReader, an XML reader or reading its contents in any way you like.
It's main method (Send) accept a URL as input. The URL must be formatted as:
<protocol>://<servername>:<port>/<path>

<protocol> is usually "http" but you may use other http-based protocols.
<port> is optional and, if not specified, the object will use HTTP default port (80).
Don't forget to call Close when you are done using the object to avoid "zombie" TCP/IP connections that can waste resources on your device and on the server.
It's not a coding masterpiece and I tested it only with a couple of different serves, so if you want to suggest improvements, feel free to do that in the comments section.

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Microsoft.SPOT;

namespace Calendar
{
    class HTTPException : Exception
    {
        int code;

        public HTTPException(int code) : base("HTTP error "+code.ToString())
        {
            this.code = code;
        }

        public HTTPException() : base("Invalid HTTP reply")
        {
            code = -1;
        }
    }

    class HTTPRequest : Stream
    {
        // socket used for HTTP connection
        protected Socket httpsocket;
                        
        // content length
        protected long size;
        
        // current position
        protected long position;

        public HTTPRequest()
        {
            size = 0;
            position = 0;
        }

        /**
         * We need a custom readline function. Using a standard textreader could prevent usage of other kind of readers (XML etc.) on the stream.
         */
        protected string ReadLine()
        {
            string line = "";

            byte[] data = new byte[1];

            while (Read(data, 0, 1) != 0)
            {
                // checks for carriage return
                if (data[0] == 0x0d)
                {
                    // discards line feed
                    Read(data, 0, 1);

                    // returns the string
                    return line;
                }

                char[] chars=UTF8Encoding.UTF8.GetChars(data);

                line += chars[0];
            }
            return line;
        }

        /**
         * Sends an HTTP reply and initializes the stream that may be used to read the reply
         */
        public void Send(string url)
        {
            // parses the url, splitting server and path
            int serverindex = url.IndexOf("//");

            if (serverindex == -1)
                throw new ArgumentException("Invalid URL, can't find server name.");

            string server;
            string path;

            int port = 80;

            int pathindex = url.IndexOf("/",serverindex+2);

            if (pathindex == -1)
                throw new ArgumentException("Invalid URL, can't find resource path.");

            int portindex = url.IndexOf(":",serverindex+2);

            // port is not mandatory, if no port is specified, port 80 is used
            if (portindex != -1)
            {
                string portstring = url.Substring(portindex + 1, pathindex - portindex - 1);

                server = url.Substring(serverindex + 2, portindex - serverindex - 2);
                path = url.Substring(pathindex + 1);
                port = Int32.Parse(portstring);
            }
            else
            {            
                server = url.Substring(serverindex+2,pathindex-serverindex-2);
                path = url.Substring(pathindex);            
            }

            // tries to solve server name
            IPHostEntry host = Dns.GetHostEntry(server);

            // connects to the server
            httpsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            // builds up the HTTP request
            string requestheader =  "GET "+path+" HTTP/1.1\r\nHost:"+server+"\r\nConnection: Close\r\nAccept-Charset: utf-8;\r\nPragma:    no-cache\r\nCache-Control: no-cache\r\n\r\n";

            httpsocket.Connect(new IPEndPoint(host.AddressList[0], port));

            Byte[] requestarray = Encoding.UTF8.GetBytes(requestheader);

            httpsocket.Send(requestarray);

            // parses the HTTP reply
            string line = ReadLine();

            // the first line contains the return code
            if (line.IndexOf("HTTP") != 0)
                throw new HTTPException();

            string codestring = line.Substring(line.IndexOf(" ")+1, 3);

            int httpcode = Int32.Parse(codestring);

            if (httpcode != 200)
                throw new HTTPException(httpcode);

            while (line.Length != 0)
            {
                line = ReadLine();

                //searches content lenght header
                if (line.IndexOf("Content-Length:") == 0)
                {
                    string lengthstring = line.Substring(15).Trim();

                    size = Int32.Parse(lengthstring);
                }
            }

            // position starts to count from here
            position = 0;

            // does not close the stream (there's no way to detach it from the socket)
        }

        public override void Close()
        {
            if (httpsocket != null)
                httpsocket.Close();
        }

        public override bool CanRead
        {
            get { return true; }
        }

        public override bool CanSeek
        {
            get { return false; }
        }

        public override bool CanWrite
        {
            get { return false; }
        }

        public override long Length
        {
            get { return size; }
        }

        public override long Position
        {
            get { return position; }
            set { throw new NotImplementedException(); }
        }

        public override void Flush()
        {
            throw new NotImplementedException();
        }

        public override void SetLength(long value)
        {
            throw new NotImplementedException();
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            int readt=httpsocket.Receive(buffer,offset,count,SocketFlags.None);

            position += readt;
            return readt;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            throw new NotImplementedException();
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new NotImplementedException();
        }
    }
}
Posted On Friday, January 16, 2009 2:00 PM | Comments (0)
Pasta alla Silana

The name of this pasta came from mount Sila (Calabria), in the southernmost part of the Italian peninsula ("on the other side of Italy" from where I live).
I eated it in a restaurant when working for a very kind customer (they brought me out to eat in great places and also offered me a tour of the city center of Cosenza, a very nice place to visit). I didn't asked for the recipe, so this is a sample of cooking through reverse-engineering.
Remember that I'm not a professional cooker!

Ingredients (for 4 people):

  • Pasta (it's better to use bucatini or thick spaghetti) - 350g
  • Fresh sausage (google for "salsiccia" to see it :)) withut spices - 250g
  • Dried mushroom ("porcini" are great)
  • Tomato sauce (250g) or fresh boiled and peeled tomatoes.
  • Scamorza affumicata (smoked cheese) 100g
  • a small pinch of chili pepper powder
  • Salt
  • Olive oil

You should cook the pasta  in the "traditional way": put water in a pot, let it boil and then add salt (I never measured the amount of salt, a simple rule is to use 1lt of water, 10g of salt for 100g of pasta), wait until it boils again and then add the pasta. Cooking time vary depending on the kind of pasta you use and is usually written on the box.
In the meantime you should peel and cut the sausage in small pieces (1-2cm long) and put the dried mushrooms in some water.
Put a couple of tablespoons of olive il in a pan and. when the oil is hot, add the sausage, cook it for a few minutes and then add tomato sauce and mushrooms. Add salt and chili pepper (the sauce should not be spicy, just tasteful), let the tomato reduce in half and then reduce heat to the minimum to keep the sauce warm.
Grate the cheese in not-so small chunks or cut it into small pieces.
Use a colander to retrieve the pasta when is cooked and put it back (without any water) inside the pot.
Put the pot back on the stove and add sauce and cheese to the pasta.
Mix the pasta until the cheese is melt and the sauce is evenly distributed and then serve... and enjoy.
Posted On Wednesday, January 14, 2009 1:19 PM | Comments (2)
Did you install Windows CE shared source?

If you don't have a "PRIVATE" subfolder in your Windows CE installation subtree or if it's almost empty, go finding the installation CD and re-launch the installation.
If you choose "custom setup" you have a chance to install Windows CE shared source.
Do it as soon as possibile.
When I talk about Windows CE at conferences here in Italy to people that don't know the OS, many of their mouths opens in disbelief when I say that the OS is realtime (hard-realtime), and show proofs of that.
But jaw bones fall on the floor when I say that they can have the source code of the kernel and of most of the components of the OS.
For many people microsoft and source code are related like orangutans and ice skating: technically they may be able to do that... but will never try it.
Windows CE, instead, comes with a lot of commented source code that can be an invaluable help in finding bugs, undestanding performance issues or learning how some OS components work "under the hood".
It's like an orangutans performing during "Holiday on Ice"!
Sometimes (and that's bad!) source code is the only documentation you have, but the amount and quality of Windows CE documentation is improving.
Having zillion of lines of working code is great to really have control over what you are developing.
If you use Windows CE you are usually not developing a single software component, you are developing a solution, a device made by hardware, OS, and application software and it's great to be able to have all the information you need on those three layers.
If you still haven't installed the shared source, go installing it!
If you did, spend some time wandering around the directories, open source files and let your curiosity drive you.
And don't limit your exploration to the PRIVATE folder. Inside WINCE600 (and also older releases of the OS, of course) you'll find millions of lines of code, useful tools and samples. If you have to write a new driver or an application that uses some of the OS features is very likely that you'll be able to find a good sample that you can use as starting point for your development.
Posted On Wednesday, January 14, 2009 1:12 PM | Comments (1)
About me and this blog

Ciao,
I'm Valter Minute, I'm a software developer working for Fortech Embedded Labs (www.fortechembeddedlabs.it), in Saronno, Italy.
I'm Italian, and this should explain my poor english and excuse it, I hope.
I was born in 1973 and I work on Windows CE since the beginning of this century (sounds like a lot of time written in this way).
I started developing application on version 2.12 of the OS and then moved to BSP, drivers and other low-level stuff from version 3.0 on.
I try to provide some helpful replies on usenet, mostly on microsoft.public.windowsce.platfbuilder.
If you are Italian, you may have seen me speaking at some conferences or training sessions.
I'm a Windows Embedded Trainer (on CE and XPE/WES) and I also managed to pass the MCP exam, so I'm a Certified Professional on Windows CE.
I like to write code (I hope that my code is more understandable than my written English), learn new things and try to understand them better by explaining them to others.
I hated to be a student... and now I like being a teacher, life is strange sometimes.
I think that exchanging knowledge is also a good way to learn, and each time I reply to a question on usenet newsgroups or do a training session, I try to learn something new from the people asking or attending.
I also try to learn by reading more experienced people's replies to questions I'm not able to answer. Usenet is a great tool for this kind of "real life" learning.
You can learn clever solutions to problems you are used to solve always in the same (maybe not so smart) way or, at least, force yourself to "clean" some concepts in your mind to be able to explain them to others.
Having to teach is also a great excuse to have some time on my own to learn something new.
So now you may ask why this blog is named "Windows Embedded Cookbook".
I was thinking about having my own blog since a long time, knowing how blogs can be a useful source of knowledge and being an avid reader of most of the blogs related to Windows Embedded (Bruce Eitman's blog, Mike Hall's blog, Loke Uei Tan's blog etc.).
I kept telling myself that I have not enough free time to have my own blog.
At the beginning of this year I qualified for round 2 of both the "dare to dream different" contest (microframework) and, with my co-workers, in the "Sparks Will Fly" (Windows CE), so now my free time will be reduced and used to develop something nice for those challenges... so what a better moment to start also my own blog?
Ok, this explains the blog, but why a "cookbook"?
I spend most of my time developing software and finding bugs. Most of the times I try to find bugs I put inside my code, other times (and this is also a great chance to learn) I try to find someone else's bugs.
I'm so good in putting bugs in my own code that it seems that I'm quite able also in finding other people's ones.
I like programming and technology but I like also to do other things during my free time. I like to travel with my wife, play basketball with my friends (I'm not a good player but my teammates are too kind to remind me that) and cook.
Cooking is one of my favorite hobbies. Unluckily I also eat a large part of what I cook... and my figure isn't exactly thin (sometimes this may help on a basketball court, anyway).
I think I like to cook because in some aspects it's not so different from programming. You start from some simple "elements" and try to build something that works or that tastes good (at least something that is not immediately dangerous for your health).
You have to follow some rules, but also use your own fantasy. What I like in cooking a good dish is that, unlikely to what happens with a large software project, you can finish it in a short time, eat and enjoy it and then forget about it, remembering, at most the good taste (ok, the last point requires that what you made isn't poisonous).
In software you have long development times, you have to do maintenance etc. And never ate what you make!
In this blog I'll try to mix programming and technology with some good recipes I created (usually looking at what remained inside my fridge after an "after-hour" programming session) or "borrowed" from somebody, adding my own mistakes.
I hope you'll like the mix and provide me suggestions and corrections (also spelling and grammar ones!).
I also learn to take pictures (saying that I like photography is  too much), so in some of my posts you'll find some pictures not related in any way to the text, it's my way to try to keep your reading more entertaining, I hope you'll appreciate it.
I'm here to learn, remember that.
Posted On Wednesday, January 14, 2009 1:05 PM | Comments (1)
Toradex logo

Tag Cloud