2012-06-03 3 views
0

문제 소개 소개 비트,
글을 게시하기 전에 이것에 대한 검색을 시도했지만 대부분은 분명하지 않았습니다.
필자는 bort metal RTOS를 실행하는 cortex-a8 기반 보드를 가지고 있습니다. 디스플레이 (framebuffer)는 약간 느립니다. 왜냐하면 필자는 지금 목표를 위해 DMA를 구현하지 않았지만 그다지 느리지는 않습니다. 나는 개선의 기회를 발견했다. 내 CPU와 툴체인 콤보에서 32 비트 수학, 데이터 액세스는 16 비트 액세스보다 빠르며 디스플레이는 16 비트 rgb565이므로 일부 프레임 버퍼 연산은 느린 연산입니다 (일부는 memcpy, memmove) 데이터 정렬을 담당하는 memset 등)두 개의 데이터 형식을 하나의 더 큰 데이터 형식으로 저장합니다.

내가 시도한 것은 하나의 32 비트 데이터 유형으로 두 개의 픽셀을 과도하게 밀어 넣어 메모리에 액세스하는 것입니다. 하드웨어에서 정렬되지 않은 메모리 액세스를 지원하므로 문제가되어서는 안됩니다.) 구현 속도는 중요하지 않지만 이상한 결과는 내가 두 픽셀을 하나의 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에서보다 효율적으로 수행 할 수있는 방법이 있습니다. 루프 풀기는 좋은 생각입니다. 이것은 bitonal 글꼴 데이터의 각 바이트를 처리하는 코드입니다.

@ 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 

업데이트 약간 간단한 코드

내가, 제 2 지시가 R5를 제로로한다 무엇을 믿는에서
+0

하지만, 왜? 도움과 노력에 감사드립니다. – 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++; 
} 
관련 문제