首页 > 解决方案 > 为什么我的小 C 循环不能正确打印到帧缓冲区,但它的展开版本却可以?

问题描述

我正在尝试编写一个简单的 C 程序,该程序在位置 (x, y) = (50, 50) 处绘制一个 4x4 像素的白色实心正方形。

这个想法是直接写入 Linux 帧缓冲区,它从映射内存 fb->fp 开始。

现在,问题在于以下代码运行良好:

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);

但是,以下没有。它产生一条 1x4 的线而不是 4x4 的正方形。

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);
    }
}

据我所知,它们应该是等价的。我从编译器得到的汇编版本看起来不太容易理解。

这在 ARM 嵌入式 Linux 设备中运行。此时没有 X 服务器或任何其他内容写入帧缓冲区。

fb->bytes_per_pixel等于2

我找不到任何关于帧缓冲区如何映射到内存的文档。我得到的偏移量来自我在谷歌上找到的随机代码。

这些偏移量可能有问题。但至少这两个代码应该是等价的,不是吗?我要疯了吗?

标签: cfor-loopembedded-linuxframebuffer

解决方案


这是问题所在:

for (; j < 4; j++) {
    for (; i < 4; i++) {
        //some code
    }
}

for循环预计执行4次,一定是因为break;body中没有条件语句。然而,内for循环需要改变。对于外for循环的第一次迭代,内for循环按预期执行了 4 次。
在外for循环的第二次迭代中,值为iis ,内循环4的条件为假,所以它不执行。外循环的所有下一次迭代都会发生同样的情况。i>4forfor

您可以通过初始化ifor循环的每次迭代来克服这个问题。

选项1:

for( ; j < 4; j++)
{
    for (i = 0; i < 4; i++)
    {
        // Some code
    }
}

选项 2:

for( ; j < 4; j++)
{
    for (; i < 4; i++)
    {
        // Some code
    }
    i = 0;
}

选项 3:

for( ; j < 4; j++)
{
    i = 0;
    for ( ; i < 4; i++)
    {
        // Some code
    }
}

选项 4:正如David C. Rankin所建议的那样:

int j = 0;
// int i = 0;
for( ; j < 4; j++)
{
    int i = 0;
    for ( ; i < 4; i++)
    {
        // Some code
    }
}

推荐阅读