【问题标题】:Why doesn't my small C loop print correctly to the frame buffer, but its unrolled version does?为什么我的小 C 循环不能正确打印到帧缓冲区,但它的展开版本却可以?
【发布时间】:2018-07-17 01:01:03
【问题描述】:

我正在尝试编写一个简单的 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

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

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

【问题讨论】:

    标签: c for-loop embedded-linux framebuffer


    【解决方案1】:

    问题来了:

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

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

    您可以通过为外部 for 循环的每次迭代初始化 i 来克服这个问题。

    选项 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
        }
    }
    

    【讨论】:

    • 选项4:将int i = 0;的声明和初始化移动到j循环:)
    • @DavidC.Rankin:哦,确实。谢谢:-)
    • 谢谢。我很确定我再也不会掉进这个陷阱了!
    猜你喜欢
    • 2014-11-03
    • 2011-11-11
    • 1970-01-01
    • 2022-08-13
    • 2021-12-29
    • 2017-11-24
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多