Laman

New

a

Tampilkan postingan dengan label wince. Tampilkan semua postingan
Tampilkan postingan dengan label wince. Tampilkan semua postingan

Jumat

port libcurl to wince

libcurl is a powerful network transfer library. It has support for many popular protocols and can make our application easier to integrate with other network servers.
libcurl requires some posix headers to compile, which isn't available on windows ce platform. In order to port it, we must provide a  posix adapter layer, which can be achieved with wcecompat library.
It's not enough to only have wcecompat library, because the source code of libcurl isn't fully wince compatible. We can apply this patch to libcurl source code to make it compile fine.

Senin

conditional compilation on wince

While designing BSP, it's very common to enable or disable some features based on our requirements. Subsequently, we may need to change our code according to the feature's availability.
On a wince system, the status of a feature's availability is controlled via batch files, either cesysgen.bat (controls standard ce modules and functions) or {platform_name}.bat (controls platform specific settings). The status of a feature is set through environment variable in the batch file. The build system will build the image according to environment variables. For instance, the following line in a batch file instruct not to support SDMMC boot.

set BSP_NOSDMMC_BOOT=1

It may be desired to change our code based on the aforementioned setting. But the problem is the compiler (to be specific, preprocessor) can't see the value of BSP_NOSDMMC_BOOT environment variable. So, in order to pass the value to compiler, we need the help of build system. Just like gnu make, the wince build system can see the environment variable and define a macro for the compiler.
The code snippet below is extracted from a sources file, and shows how to define macro according to the BSP_NOSDMMC_BOOT's value.

!IF "$(BSP_NOSDMMC_BOOT)"=="0"
CDEFINES = $(CDEFINES) -DBSP_NOSDMMC_BOOT
!ENDIF


Then, in our code, we can use the BSP_NOSDMMC_BOOT macro to do conditional compilation.
And if we want to disable the whole module based on the environment variable's value, we can define SKIPBUILD in sources file, like this:

!if "$(BSP_NOSDMMC_BOOT)"=="1"
SKIPBUILD = 1
!endif

Kamis

port protobuf-lite to wince

protobuf is a wonderful project that helps us implement communication protocol. There are a lot of benefits to use it in practical project, including:
  1. It has an efficient binary serialization algorithm
  2. It runs cross platforms
  3. It support mainstream programming languages, c++, python and java. there are also lots of porting out there for other popular languages.
  4. It's designed to make protocols both backward and forward compatible.
  5. It enables developers to focus on protocol design.
 Currently, there is no official windows CE version for protobuf. It's not an easy task to port protobuf full version to windows CE. But the lite version, which supports less feature than full version (check the explanation for optimize_for option in this page for what's the difference), is easier to port. Here is how I port it:

  1. Create a Win32 Smart Device Project library project, name it protobuf-lite-ce
  2. Copy all source files from protobuf-lite project to protobuf-lite-ce project in Solution Explorer
  3. Create a ce_port folder in the project's directory, and copy the errno.h header file from (Visual_Studio_Root)/VC/include into the folder. This is because Windows CE doesn't have this file, so we need to provide one. Actually, this errno.h can be a pure empty file.
  4. Add "../src;.;./ce_port" to the project's Additional Include Directories.
  5. The windef.h header file already defines OPTIONAL macro, it conflicts with Cardinality::OPTIONAL enum. So the extension_set.cc fails to compile, to solve this, add following code before enum Cardinality definition to undefine OPTIONAL:

#if defined(OPTIONAL)
#if defined(_MSC_VER)
#pragma message ("Unexpected OPTIONAL macro definition, #undefine OPTIONAL")
#else
#warning  "Unexpected OPTIONAL macro definition, #undefine OPTIONAL"
#endif
#undef OPTIONAL
#endif
namespace {

enum Cardinality {
  REPEATED,
  OPTIONAL
};

}  // namespace


Now the protobuf-lite-ce project should compiles fine.
Here is the project file for downloading. Just get everything there and place them in protobuf/vsprojects/ directory.

Minggu

modify CE code for our platform

A majority of windows CE core and drivers code is available to us, they reside in public directory of CE installation folder. Occasionally, we may want to modify that part of code, either to change some system behaviors, or add some log messages for debugging our platform's code.
It's strongly recommended not to change the original code in place. Because this part of code is shared by all platforms. All platforms will be affected by the modification. The right way is before making any change, copy the module into our own platform directory, and modify the copy there.
Let's say we want to modify public/common/oak/bootpart module's code.
1. We first copy it into platform/platform_name/src/common/bootpart
2. Exclude public/common/oak/bootpart from our build

3. Include  platform/platform_name/src/common/bootpart into our build

4. The last step is to update other modules' sources file. For any module that depends our modified bootpart module, we should change its sources file so that it can find the new bootpart instead of the original bootpart shipped with CE. For instance, change $(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\bootpart.lib to $(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\bootpart.lib     

Kamis

extend windows ce platform with oalioctl

Though not being a open source platform, windows ce is designed to be flexible so that device venders can extend it easily. oalioctl is a feature that makes it possible to do things in kernel space on behalf of application.

Features
1. Extensibility
The essential feature of oalioctl is it enables us to extend windows ce kernel's functions, and new functions are directly accessible to application layer developers.
2. Separation
oalioctl is completely separated from kernel source code. From the sense of code organization, it doesn't differ from a normal device driver. The separation makes it easy to maintain and port oalioctl module.
3. Easy to use

Compared to a normal ce driver, the usage of oalioctl is easier from an application developer's perspective. In order to make use of a normal driver, application usually follows below sequence:
CreateFile -> DeviceIoControl -> CloseHandle
But the application can simply call KernelIoControl to make use of oalioctl library, which is a far more easy way.

Implementation
oalioctl is implemented as a standalone dynamic library. And it will be loaded automatically during kernel initialization (relevant code is in LoaderInit() function in X:\WINCE600\PRIVATE\WINCEOS\COREOS\NK\KERNEL\loader.c). So it's not necessary to register this module in platform.reg as other stream drivers do.
When an application calls KernelIoControl, the call stack goes like this:
IOControl //our own oalioctl.cpp
OEMIOControl  // platform/common/src/common/ioctl/ioctl.c
IOControl // public/common/oak/oalioctl/oalioctl.cpp
EXTKernelIoCtl // private/winceos/coreos/nk/kernel/kwin32.c

How to implement our own oalioctl
It's a fair simple task to implement oalioctl layer for our own platform with following steps:
  1. copy public/common/oak/oalioctl directory to platform/platform_name/src/drivers
  2. change TARGETTYPE to DYNLINK in sources file
  3. define our own iocontrol code with CTL_CODE macro
  4. add a case branch for the new iocontrol code

Selasa

resolve windows ce remote tool connection issue

remote tools for windows ce is a set of powerful tools for debugging. I have Visual Studio 2005, Windows Embedded CE 6.0 R3 installed, but the remote tools don't work. They fail to connect to device with following error message:
The Microsoft ActiveSync reported the following error: Unable to load device side components. Please check server configuration settings.

There are two ways to resolve the connection issue.

1. Run remote tools from windows start menu (e.g., Microsoft Visual Studio 2005\Visual Studio Remote Tools\Remote Process Viewer, which is a shortcut to C:\Program Files\CE Remote Tools\5.01\bin\ccpview.exe), instead of starting from visual studio menu (e.g., Target/Remote Tools/Process Viewer, which is a shortcut to C:\Program Files\Common Files\Microsoft Shared\Windows CE Tools\Platman\bin\wce600\cepview.exe). remote tools version 5.01 work fine.

2. Copy
c:\Program Files\Common Files\Microsoft Shared\Windows CE Tools\Platman\target\wce600\armV4i\
to
c:\Program Files\Common Files\Microsoft Shared\Windows CE Tools\Platman\target\wce600\armV4\
. The lack of the second directory is a bug in remote tools version 6 that causes the connection issue.

Kamis

perform profiling on windows ce

Profiling is an effective way of finding out bottlenecks in an application. On windows ce platform, profiling can also be done easily.

To perform profiling for native code, we can use the /callcap compiler option to enable callcap profiling. After it's enabled, the compiler will inject method invocation to _CAP_Enter_Function and _CAP_Exit_Function upon entering and returnning from a function respectively. We can print or log current time in these method to achieve profiling.
It's notable that while compiling the source file contains _CAP_Enter_Function and _CAP_Exit_Function's definition, we must disable /callcap option, otherwise, these function will call themself recursively. In most cases, it's a wise idea to create a library project to implement these profiling hook fuction and trun /callcap off for the project. Then link the library to other applications to be profiled.
For demonstration, here is a visual studio project shows how to do profiling:
http://code.google.com/p/rxwen-blog-stuff/source/browse/trunk/wince/ce_profiling/

After we run the application, we get below output:
Enter function (at address 00011068) at 73875892
Enter function (at address 00011030) at 73875897
Enter function (at address 00011000) at 73875902
bar
Leaving function (at address 00011000) at 73876907
foo
Leaving function (at address 00011030) at 73879912
Leaving function (at address 00011068) at 73879916
 
As you can see, it's a very rough sample that only prints the address of function being called. Not convenient to analyse. We may improve it by mapping and translating the address to function name, because we, as the application developer, possess the private symbol file. This task doesn't need to be done on the windows ce box, it's much easier to save the log file then parse and analyse it on a pc.

References:
Remote call profiler
A tour of windows ce performance tools

Jumat

capture network traffic on windows ce

When developing network applications, it's always necessary to capture network traffic. Windows ce has built-in sniffer tool, netlog for this purpose. It captures network traffics to a file that can be examined with wireshark or network monitor.
To enable it, we need to select NDIS Packet Capturing DLL and NDIS User-mode I/O Protocol Driver in visual studio, as shown below.



Then, we can capture network traffic with following commands.

1. set capture file lacation:
netlogctl file "\Storage Card\net"
2. start capture
netlogctl start
3. perform network activities
4. stop capture
netlogctl stop
5. copy \Storage Card\net.cap[i].cap to computer and open with wireshark



NetLogctl usage:
netlogctl start - start the loggging.
netlogctl load - start the loggging.
netlogctl stop - stops the loggging.
netlogctl unload - causes networking to unload the netlog component. (may destabilize system)
netlogctl pkt_size  XX - sets maximum packet size captured.
netlogctl cap_size  XX - sets maximum  size of half capture file.
netlogctl file  XXX - sets the name of the file to log.
netlogctl usb  XXX - 1 => log usb , 0 => stop logging usb.
netlogctl state  - print state.
netlogctl trace  - print trace message state for all modules.
netlogctl trace <module> - print trace message state for specified module.
netlogctl trace <module> <filter> - set trace message state for specified module.

Senin

use googletest on windows ce

I've been trying to use googletest on windows ce platform to do unit testing. But gtest doesn't provide a windows ce project file, so I had to modify the project myself. Here is how to do so:

1. Add a new platform
I added a new windows ce based platform (Windows Mobile 5.0 Pocket PC SDK (ARMV4I), for example) in the configuration manager of the gtest project.


2. Add below preprocessor definitions
 In order to compile gtest library for windows ce, I used below preprocessor definitions:
 "NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_CONSOLE;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE"

Not all of them are mandatory, but missing the bold ones may cause gtest fail to compile.


3. Create a windows ce console project
The sample project is available at:
http://code.google.com/p/rxwen-blog-stuff/source/browse/#svn/trunk/wince/ce_gtest_proj
This project expects to find gtest header file (gtest\gtest.h) and static library (gtestd.lib) in googletest folder in parent directory.

4. Run the application on emulator/device and verify output
Finally, I run the unit testing application on a windows ce device, and get below outputs in visual studio and serial port output respectively. The output shows that the test case passed successfully.
visual studio output window

device serial port output



It's not always necessary to run unit testing application on windows ce device. If we write our application with care, it's possible that the application can compile and run on both win32 and windows ce platform. Then we can do unit testing on a normal pc, which will be easier and faster.
But I still would like to run the unit testing on windows ce if our product is supposed to run on it. Any subtle differences between win32 and win ce may cause the unit testing succeed on one platform but fail on the other. It's wise to do unit testing on the platform that the application will actually run.