0

問題を少し紹介し
ます。これを投稿する前に google/stack で検索してみましたが、ほとんどが不明でした。
ベアメタル RTOS を実行している cortex-a8 ベースのボードがあります。ディスプレイ (フレームバッファ) は少し遅いです。これは、現在ターゲットに DMA を実装していないためですが、それほど遅くはないことに気付きました。改善の機会。私の CPU とツールチェーンの組み合わせでは、32 ビット演算、データ アクセスは 16 ビット アクセスよりも高速で、ディスプレイは 16 ビット rgb565 であるため、一部のフレーム バッファ操作は本来よりも少し遅くなります (一部は memcpy、memmove を使用します)。そして、データの整列などを処理する memset .)

私が試みたのは、2 つのピクセルを 1 つの 32 ビット データ型に詰め込み、それを使用してメモリにアクセスすることでした (覚えている限り、整列していなくても、私の CPU はハードウェアで整列されていないメモリ アクセスをサポートしているため、問題はこれではないはずです)。私は実装の速度について話しているのではなく、2つのピクセルを1つの32ビットデータ型に詰め込んでいると思われる奇妙な効果があることに注意してください。

ここに私の fb_putc のほとんどの部分があります

if (((unsigned char)c > 32) && ((unsigned char) c < 127)) {
    check_for_scroll(49);

    // fontdata starts from ASCII 33 shifted by logarithm(base2, font_height)
    c -= 33;
    c <<= 4;

    uint16_t pallete_16[2] = {fb.fg_color, fb.tg_color};

    uint32_t y;
    uint32_t *pixel_32;
    uint32_t fb_shifter;
    uint32_t pixel_32_holder;
    uint32_t fb_bg_32 = ((pallete_16[1] << 16) | (pallete_16[1]));
    /*
     * Each pixel is 16 bits, we access them using 32 bit data type,
     * which is faster for aligned memory access. Also many architectures
     * have free bit shifts with each instruction so we use that too.
     */
    pixel_32 = (uint32_t *) fb.config->base;
    pixel_32 += ( ((fb.cursor.y * (FONT_HEIGHT * fb.config->width)) + ((fb.cursor.x * (FONT_WIDTH))))
                    / ((sizeof(uint32_t))/(sizeof(uint16_t))) );
    for (y = 0; y < 16; y++) {
        for ( unsigned x = 7; x >= 0; x -= 2 )
        {
            if (fontdata[c + y] & (1 << x)) {   
                pixel_32_holder = (pallete_16[0] << 16);
            } else {
                pixel_32_holder = (pallete_16[1] << 16);
            }
            if (fontdata[c + y] & (1 << (x -1))) {
                pixel_32_holder |= (pallete_16[0] & 0xffff);
            } else {
                pixel_32_holder |= (pallete_16[1] & 0xffff);
            }
            *pixel_32++ = pixel_32_holder;
        }
        // Panel stride = width (480) - font_width (8)
        pixel_32 += (472 / ((sizeof(uint32_t))/(sizeof(uint16_t))));
    }

    fb.cursor.x++;
}

私が間違った場所に関する助けはありますか?私はプログラミングに少し慣れておらず、これを趣味としてやっています。

4

2 に答える 2

1

メモリに書き込む前に 2 つのピクセルを組み合わせるというあなたの考えは正しいです。ARM の書き込みバッファ ハードウェアは、この方法でより効率的に使用され、コードはより高速に実行されます。そのような形で C と ASM を混在させても、最良の結果が得られるとは思いません。純粋な ASM に固執することで、条件付きで実行される命令を使用していることを保証できます。また、パレットに配列を使用すると、コンパイラが非常に効率の悪いコードを出力する場合があります。純粋な ASM でより効率的に行う方法を次に示します。ループを展開することをお勧めします。これは、モノクロ フォント データの各バイトを処理するためのコードです。

@ Register usage
@ R0 = source data pointer
@ R1 = destination data pointer
@ R2 = foreground color (loaded outside of loop)
@ R3 = background color (loaded outside of loop)
@ R4,R5 = temp registers
@ Assumes that the most significant short of each 32-bit word is on the left

  ldrb r4,[r0],#1  @ source bitonal image data
@ first pair of pixels
  tst r4,#0x80
  movne r5,r5,r2,LSL #16
  moveq r5,r5,r3,LSL #16
  tst r4,#0x40
  orrne r5,r5,r2
  orreq r5,r5,r3
  str r5,[r1],#4
@ second pair of pixels
  tst r4,#0x20
  movne r5,r5,r2,LSL #16
  moveq r5,r5,r3,LSL #16
  tst r4,#0x10
  orrne r5,r5,r2
  orreq r5,r5,r3
  str r5,[r1],#4
@ third pair of pixels
  tst r4,#0x8
  movne r5,r5,r2,LSL #16
  moveq r5,r5,r3,LSL #16
  tst r4,#0x4
  orrne r5,r5,r2
  orreq r5,r5,r3
  str r5,[r1],#4
@ fourth pair of pixels
  tst r4,#0x2
  movne r5,r5,r2,LSL #16
  moveq r5,r5,r3,LSL #16
  tst r4,#0x1
  orrne r5,r5,r2
  orreq r5,r5,r3
  str r5,[r1],#4

少し単純なコードを更新する

于 2012-06-04T16:39:59.883 に答える
0

コンパイラが過去数時間頭を食べた後、asmを使用して一度に2ピクセルを格納するように修正しましたが、一部の文字を除いて文字が文字化けしているように見えるため、他の問題があるようです。世界でこれを引き起こしています...

ピクセルのパッキングに関しては、これが私が最終的に使用したものです(将来誰かがこれを行う必要があるかもしれない場合に備えて)

if (((unsigned char)c > 32) && ((unsigned char) c < 127)) {

    check_for_scroll(FB_MAX_Y_UNDER);

    uint32_t pixel_32_tmp;
    uint16_t pallete[2] = { (fb.fg_color), (fb.tg_color)};
    uint32_t *pixel_32 = (uint32_t *)fb.base +((((fb.cursor.y << 13)-(fb.cursor.y << 9))+(fb.cursor.x << 3)) >> 1);

    c -= 32;
    c <<= 4;

    for (int y = 0; y < 16; y++) {
        unsigned char font_bits = fontdata[c + y];

        if (font_bits & 0x80) {
            __asm__ volatile("mov %0, %1, lsl $16" : "=r" (pixel_32_tmp) : "r" (pallete[0]));
        } else {
            __asm__ volatile("mov %0, %1, lsl $16" : "=r" (pixel_32_tmp) : "r" (pallete[1]));
        }
        if (font_bits & 0x40) {
            __asm__ volatile("orr %0, %0, %1" : "=r" (pixel_32_tmp) : "r" (pallete[0]));
        } else {
            __asm__ volatile("orr %0, %0, %1" : "=r" (pixel_32_tmp) : "r" (pallete[1]));
        }
        *pixel_32++ = pixel_32_tmp;

        if (font_bits & 0x20) {
            __asm__ volatile("mov %0, %1, lsl $16" : "=r" (pixel_32_tmp) : "r" (pallete[0]));
        } else {
            __asm__ volatile("mov %0, %1, lsl $16" : "=r" (pixel_32_tmp) : "r" (pallete[1]));
        }
        if (font_bits & 0x10) {
            __asm__ volatile("orr %0, %0, %1" : "=r" (pixel_32_tmp) : "r" (pallete[0]));
        } else {
            __asm__ volatile("orr %0, %0, %1" : "=r" (pixel_32_tmp) : "r" (pallete[1]));
        }
        *pixel_32++ = pixel_32_tmp;

        if (font_bits & 0x08) {
            __asm__ volatile("mov %0, %1, lsl $16" : "=r" (pixel_32_tmp) : "r" (pallete[0]));
        } else {
            __asm__ volatile("mov %0, %1, lsl $16" : "=r" (pixel_32_tmp) : "r" (pallete[1]));
        }
        if (font_bits & 0x04) {
            __asm__ volatile("orr %0, %0, %1" : "=r" (pixel_32_tmp) : "r" (pallete[0]));
        } else {
            __asm__ volatile("orr %0, %0, %1" : "=r" (pixel_32_tmp) : "r" (pallete[1]));
        }
        *pixel_32++ = pixel_32_tmp;

        if (font_bits & 0x02) {
            __asm__ volatile("mov %0, %1, lsl $16" : "=r" (pixel_32_tmp) : "r" (pallete[0]));
        } else {
            __asm__ volatile("mov %0, %1, lsl $16" : "=r" (pixel_32_tmp) : "r" (pallete[1]));
        }
        if (font_bits & 0x01) {
            __asm__ volatile("orr %0, %0, %1" : "=r" (pixel_32_tmp) : "r" (pallete[0]));
        } else {
            __asm__ volatile("orr %0, %0, %1" : "=r" (pixel_32_tmp) : "r" (pallete[1]));
        }
        *pixel_32++ = pixel_32_tmp;

        pixel_32 += 236;
    }
    fb.cursor.x++;
}
于 2012-06-04T13:08:52.253 に答える