2012-06-03 2 views
0

Немного о проблеме,
Я попытался найти об этом в google/stack, прежде чем публиковать его, но большинство из них были неясны.
У меня есть плата на базе cortex-a8, на которой я запускаю ОСРВ с открытым металлом. Дисплей (фреймбуфер) немного медленный, потому что я не реализовал DMA для своей цели прямо сейчас, но не все так медленно, однако Я заметил возможность улучшения. На моем процессоре и комбинации инструментальных средств, 32-битная математика, доступ к данным быстрее, чем 16-битный доступ, а дисплей 16 бит rgb565, поэтому некоторые операторы framebuffer немного медленнее, чем они могли бы быть (некоторые из них используют memcpy, memmove и memset, который заботится о выравнивании данных и т. д.)хранение двух типов данных в одном большем типе данных

Что я пытался сделать, чтобы скопировать два пикселя в один 32-битный тип данных и использовать их для доступа к памяти (выровненный, насколько я помню, даже если нет, мой процессор поддерживает inaligned доступ к памяти в аппаратном обеспечении, поэтому проблема не должна быть такой.) Обратите внимание, что я не говорю о скорости моей реализации, но о странном эффекте, который я получаю, о чем я подозреваю, потому что, как я забиваю два пикселя в один 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++; 
} 

Любая помощь относительно того, где я пошло не так? Я немного новичок в программировании и делаю это как хобби.

ответ

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 

Update несколько проще код

+0

Из того, что я полагаю, вторая команда должна обнулить r5, но почему? Спасибо за вашу помощь и усилия. – sgupta

+0

О, получилось, так что вы используете r5 для хранения результата слияния временно, прежде чем писать .. должны были прочитать полностью, прежде чем писать. Еще раз спасибо. – sgupta

0

Я исправил хранение двух пикселей за один раз, используя asm после того, как компилятор поежил мою голову в течение последних нескольких часов, но теперь, похоже, есть еще одна проблема, поскольку символы появляются искаженными, за исключением некоторых из них, я я не уверен, что в мире является причиной этого ...

Что касается упаковки пикселей, вот что я наконец-то использовал (только упаковывают кто-то в будущем, возможно, придется сделать это)

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++; 
} 
Смежные вопросы