EmbeddedRelated.com
Forums

root2xmem problem (getting very annoying)

Started by rooijan18 October 15, 2003
I have an issue I can't resolve when using xmem2root. I am writing a
set of functions to create bmp files from raw pixel data held in
extended memory. Basically the function i have trouble with takes the
row of input pixels and adds zero bytes to the end until it has a
length which is a multiple of 4 (bmp's require this).

Because a bmp must store the first display row last, the function
writes such processed row to a position j * bytesperrow bytes from the
end of the allocated xmem for the bmp, where j counts down the number
of rows to be stored and bytesperrow holds the length in bytes of each
processed row.

I store each processed row in root memory (in an array) and then use
xmem2root to transfer it to the xmem location. My problem is that the
program bombs out on the xmem2root call with an "Unexpected Interrupt"
error after a certain number of rows has been processed. In my current
case, each row has 248 pixels, and the program bombs out after writing
134 rows. I really can't figure out what the issue may be. I include
the function below in the hope that someone may be able to enlighten
me. The problem occurs when j = 131 in the following function (rowlen
= 248 and rownum = 265). The code works fine if less than 130 rows are
processed.

void BMP_UPDATE_IMAGE(unsigned long addrin, setupstruct *BMPdata,
unsigned long addrout){

char imagein[IMAGE_IN_ROWLEN]; // array long enough to
hold 8 rows of the raw input data
char imageout[IMAGE_OUT_ROWLEN]; // array long enough to
hold one row of processed output data
unsigned long addrbase; // hold the first
position in the allocated xmem for the bmp
// in which to store the
output rows
unsigned int unitswrittenin; // track the number of
pixels read of the input rows
char inbit;
int j;
char k;
unsigned int l; //stores the number of 8
row passes made
unsigned int bytesper8row; //hold the number of
bytes 8 input rows occupies
unsigned long lastwritelength;

addrbase = 4 + BMPdata->setuplength + addrout; //Set to
position where first pixel byte
// must go in
xmem (skips past bmp header)
k = 7;
bytesper8row = (8 * BMPdata->rowlen) / BMPdata->unitsperbyte;
l = 0;

/* j decreases from (the number of rows - 1) to 0 */

for(j = BMPdata->rownum - 1; j >= 0; j--){

k++;

/* determine if 8 rows of input data have been read yet) */

if(k == 8){
unitswrittenin = inbit = 0;
k = 0;

/* If there aren't 8 input rows left, grab all that remain
*/

if( j < 8){
lastwritelength = ((unsigned long)BMPdata->rownum *
(unsigned long)BMPdata->rowlen) - ((unsigned long)l * (unsigned long)
bytesper8row);

//write the remaining input rows to root memory

xmem2root(imagein, addrin + ((unsigned long)l *
(unsigned long)bytesper8row), (unsigned int)lastwritelength);
} else {

//write the next 8 input rows to root memory

xmem2root(imagein, addrin + ((unsigned long)l *
(unsigned long)bytesper8row), bytesper8row);
l++; // l tracks how many sets of 8
input rows have been read
}
} // Set the output row array to be all zeroes
BMP_RESET_IMAGE(BMPdata->bytesperrow, imageout);

//Create an output row based on the current set of input rows
BMP_PACK_IMAGE_ROW(imagein, BMPdata, &unitswrittenin, &inbit,
imageout);

//Write the created output row to xmem. Ensure that it is
stored j rows back from
//the end of the allocated memory

root2xmem(addrbase + (j * BMPdata->bytesperrow), imageout,
BMPdata->bytesperrow);

if(j == 132){
printf("j is now 80!!");
}

}

}



Try making your local arrays static, you may be running out of stack.

--- In rabbit-semi@rabb..., "rooijan18" <rooijan18@y...>
wrote:
> I have an issue I can't resolve when using xmem2root. I am writing
a
> set of functions to create bmp files from raw pixel data held in
> extended memory. Basically the function i have trouble with takes
the
> row of input pixels and adds zero bytes to the end until it has a
> length which is a multiple of 4 (bmp's require this).
>
> Because a bmp must store the first display row last, the function
> writes such processed row to a position j * bytesperrow bytes from
the
> end of the allocated xmem for the bmp, where j counts down the
number
> of rows to be stored and bytesperrow holds the length in bytes of
each
> processed row.
>
> I store each processed row in root memory (in an array) and then
use
> xmem2root to transfer it to the xmem location. My problem is that
the
> program bombs out on the xmem2root call with an "Unexpected
Interrupt"
> error after a certain number of rows has been processed. In my
current
> case, each row has 248 pixels, and the program bombs out after
writing
> 134 rows. I really can't figure out what the issue may be. I
include
> the function below in the hope that someone may be able to
enlighten
> me. The problem occurs when j = 131 in the following function
(rowlen
> = 248 and rownum = 265). The code works fine if less than 130 rows
are
> processed.
>
> void BMP_UPDATE_IMAGE(unsigned long addrin, setupstruct *BMPdata,
> unsigned long addrout){
>
> char imagein[IMAGE_IN_ROWLEN]; // array long enough
to
> hold 8 rows of the raw input data
> char imageout[IMAGE_OUT_ROWLEN]; // array long
enough to
> hold one row of processed output data
> unsigned long addrbase; //
hold the first
> position in the allocated xmem for the bmp
>
// in which to store the
> output rows
> unsigned int unitswrittenin; // track the
number of
> pixels read of the input rows
> char inbit;
> int j;
> char k;
> unsigned int l;
//stores the number of 8
> row passes made
> unsigned int bytesper8row;
//hold the number of
> bytes 8 input rows occupies
> unsigned long lastwritelength;
>
> addrbase = 4 + BMPdata->setuplength + addrout; //Set to
> position where first pixel byte
>

// must go in
> xmem (skips past bmp header)
> k = 7;
> bytesper8row = (8 * BMPdata->rowlen) / BMPdata->unitsperbyte;
> l = 0;
>
> /* j decreases from (the number of rows - 1) to 0 */
>
> for(j = BMPdata->rownum - 1; j >= 0; j--){
>
> k++;
>
> /* determine if 8 rows of input data have been read
yet) */
>
> if(k == 8){
> unitswrittenin = inbit = 0;
> k = 0;
>
> /* If there aren't 8 input rows left, grab
all that remain
> */
>
> if( j < 8){
> lastwritelength = ((unsigned long)
BMPdata->rownum *
> (unsigned long)BMPdata->rowlen) - ((unsigned long)l * (unsigned
long)
> bytesper8row);
>
> //write the remaining input rows to
root memory
>
> xmem2root(imagein, addrin +
((unsigned long)l *
> (unsigned long)bytesper8row), (unsigned int)lastwritelength);
> } else {
>
> //write the next 8 input rows to root
memory
>
> xmem2root(imagein, addrin +
((unsigned long)l *
> (unsigned long)bytesper8row), bytesper8row);
> l++;
// l tracks how many sets of 8
> input rows have been read
> }
> } > // Set the output row array to be all zeroes

> BMP_RESET_IMAGE(BMPdata->bytesperrow, imageout);
>
> //Create an output row based on the current set of
input rows
> BMP_PACK_IMAGE_ROW(imagein, BMPdata, &unitswrittenin,
&inbit,
> imageout);
>
> //Write the created output row to xmem. Ensure that
it is
> stored j rows back from
> //the end of the allocated memory
>
> root2xmem(addrbase + (j * BMPdata->bytesperrow),
imageout,
> BMPdata->bytesperrow);
>
> if(j == 132){
> printf("j is now 80!!");
> }
>
> }
>
> }




99% of the time, an "unexpected interrupt" is the result of stack
corruption; local variables overflow their bounds and destroy the return
address. Are you aware that stack space is only 4K?