?

Log in

No account? Create an account

Cross development (for ARM)

Preface

For a demo on C64 I need a program to paint some sprites, i.e. a bitmap painter. What is better suitable for digital-painting than a touch screen? Among my devices with a touch sensitive screen - Nintendo DS and PocketPC(*) - I chose the latter one.
(*) with an OMAP 850 multipurpose processor

Story

With PellesC there is a free dev-Tool for Win32 and PocketPC available, featuring a custom c-compiler, derived from lcc-compiler. The IDE is comfortable, allowing to upload the built executable and to execute it with simple key-shortcuts.

Program sketch, first three steps: Allow to
(a) draw on the screen, i.e. read stylus position and draw points (SetPixel) or lines (MoveTo, LineTo),
(b) load a bmp file into the drawing area,
(c) save the drawing area to a bmp.
Steps (a) and (b) were simple to implement. Saving wasn't.

Examination

The file was opened, but 0 (zero) bytes were written. Slowly debugging line per line I realized that

bfh->bfSize = dwFileHeaderSize + bmi->bmiHeader.biSizeImage;

caused the error (which was not reported).
After reading lots of online-material I stumbled across the explanation:
The ARM processor requires long integers (DWORDS), i.e. 4-byte variables to be aligned to memory adresses which are a multitude of 4.

The struct storing the BITMAPFILEHEADER bfh is packed though, i.e.

#pragma pack( 2 ) 
   short bfType;       // byte [0..1]
     int bfSize;       // byte [2..5]
     ...
#pragma pack( )

which apparently causes bfType to be packed. Accessing bfSize then causes a data misalignment error.
So I cloned the BITMAPFILEHEADER struct

struct MYBITMAPFILEHEADER
{
   short bfType;       // byte  [0..1]
     int bfSize;       // bytes [4..7]
   short bfReserved1;
   short bfReserved2;
     int bfOffBits;
};

and aligned it's variable pointer to multiple of 4 adresses:

__unaligned struct MYBITMAPFILEHEADER  *bfh;   // ARM processor!!!

Now, the above assignment doesn't cause any data misalignment fault, yet the struct size is 16 bytes when it shall be 14.
In the end I use a simple char-array, fill it

char mybfh[14];
WORD p_shortint;
DWORD p_int;
p_shortint =0x4d42;
memcpy(mybfh,&p_shortint,2);
p_int = dwFileHeaderSize +bmi->bmiHeader.biSizeImage;
memcpy(mybfh+2,&p_int,4);
p_shortint =0;
memcpy(mybfh+6,&p_shortint,2);
memcpy(mybfh+8,&p_shortint,2);
p_int = dwFileHeaderSize;
memcpy(mybfh+10,&p_int,4);

...and write it into the bitmap file.

Comments