I'm trying to write a simple C program that draws a 4x4 pixels white solid square at position (x, y) = (50, 50).
The idea is to write directly to the Linux frame buffer, which starts at the mapped memory fb->fp.
Now, the problem is that the following code is working well:
uint16_t color = 0xffff;
memcpy(fb->fp + (50+0) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
However, the following doesn't. It produces a 1x4 line instead of a 4x4 square.
uint16_t color = 0xffff;
int i = 0;
int j = 0;
for (; j < 4; j++) {
for (; i < 4; i++) {
int y_offset = 50 + j;
int x_offset = 50 + i;
memcpy(fb->fp + y_offset * fb->line_length + x_offset * fb->bytes_per_pixel,
&color, fb->bytes_per_pixel);
}
}
As far as I can see, they should be equivalent. The assembly version I've got from the compiler doesn't look very easy to understand.
This runs in a ARM embedded Linux device. There's no X server or anything else writing to the frame buffer at this point.
fb->bytes_per_pixel equals 2.
I couldn't find any documentation on exactly how the frame buffer is mapped into memory. The offsets I've got are from random code I found on Google.
Maybe there is something wrong with these offsets. But at least the two codes should be equivalent, isn't it? Am I going crazy?
Here is the problem:
for (; j < 4; j++) {
for (; i < 4; i++) {
//some code
}
}
The outer for loop is expected to execute 4 times, which it must be because there is no conditional break; statement in the body.
The inner for loop however needs a change. For the first iteration of outer for loop, inner for loop is executed 4 times as expected.
On the second iteration of outer for loop, the value of i is 4, the condition i>4 in inner for loop is false, so it doesn't execute. The same happens for all next iterations of outer for loop.
You can get over this by initialising i for each iteration of outer for loop.
Option 1:
for( ; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
// Some code
}
}
Option 2:
for( ; j < 4; j++)
{
for (; i < 4; i++)
{
// Some code
}
i = 0;
}
Option 3:
for( ; j < 4; j++)
{
i = 0;
for ( ; i < 4; i++)
{
// Some code
}
}
Option 4: As suggested by David C. Rankin:
int j = 0;
// int i = 0;
for( ; j < 4; j++)
{
int i = 0;
for ( ; i < 4; i++)
{
// Some code
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With