所以我关注tutorial,但是在 C 中进行操作,因为程序集太笨重了。这是我在 C 中完成的第一个“真实项目”,所以这肯定是一个愚蠢的错误,或者对 C 的工作方式有一些细微差别。
无论如何,我有这段代码:
/*blink.c*/ #include "gpio.h" #include "timer.h" #include "morse.h" #include "util.h" #include "mailbox.h" #include "gpu.h" #include "text.h" void blink() { gpio_setFunction(16, 1); gpio_setFor(16, 0, 0x3f0000, 1); gpu_makeDefaultBuffer(); gpu_fill(0xf8ff); //gpio_setFor(16, 0, 0x3f0000, 1); unsigned int i = 0; while(1) { gpu_drawPixelBridge(i, 0, i); //gpu_fill(i); if(i >= 0xffff) { break; } i ++; } //gpu_drawPixel(0, 0, 0x0000); gpu_drawAsciiChar(0x0, 0xffff, 0x0000, 50, 10); gpu_drawAsciiChar(0x0, 0b0011111, 0b00000011, 0, 50); //gpu_drawPixel(50, 50, 0x0000); gpu_drawAsciiChar(0x0, 0b0011111, 0b00000011, 0, 0); print("Hello World!"); gpu_drawPixelBridge(10, 10, 0xffff); gpu_drawPixel(100, 100, 0x0008); gpu_drawPixelBridge(101, 101, 0x000f); gpu_drawPixelBridge(102, 102, 0x0080); gpio_setFor(16, 0, 0x1f0000, 1); while(1) { // Stuff } }
/*gpu.h*/ #ifndef H_GPUH #define H_GPUH #define CHARACTER_WIDTH 8 #define CHARACTER_HEIGHT 16 typedef struct { unsigned int pwidth; unsigned int pheight; unsigned int vwidth; unsigned int vheight; unsigned int pitch; unsigned int depth; unsigned int x; unsigned int y; void* buffer; unsigned int size; } gpu_request __attribute__ ((aligned (16))); int gpu_makeDefaultBuffer(); int gpu_makeBuffer(volatile gpu_request* req); int gpu_fill(unsigned short colour); int gpu_drawPixelBridge(unsigned int x, unsigned int y, unsigned short colour); int gpu_drawPixel(unsigned int x, unsigned int y, unsigned short colour); int gpu_drawAsciiChar(unsigned char chr, unsigned short front, unsigned short back, unsigned int ox, unsigned int oy); #endif
/*gpu.c*/ #include "gpu.h" #include "mailbox.h" volatile gpu_request* gpu_buffer = 0; const unsigned char gpu_font[]; int gpu_makeDefaultBuffer() { volatile gpu_request r; r.pwidth = 1366; r.pheight = 768; r.vwidth = 1366; r.vheight = 768; r.pitch = 0; r.depth = 16; r.x = 0; r.y = 0; r.buffer = 0; r.size = 0; gpu_makeBuffer(&r); } int gpu_makeBuffer(volatile gpu_request* req) { gpu_buffer = req; if(mail_write((unsigned int)req+0x40000000, 1) < 0) { //Write fail gpio_errorHang(0, 1); return 1; } unsigned int resp = mail_read(1); if(resp) { //Fail gpio_errorHang(0, 2); return 2; } } int gpu_fill(unsigned short colour) { /*unsigned int i = 0; while(i < /*(*_gpu_buffer).size* / 1366*768*2) { *(volatile unsigned short *)((*_gpu_buffer).buffer+i) = colour; i +=2; }*/ int y = 0; while(y < 100) { y ++; int x = 0; while(x < 100) { x ++; gpu_drawPixel(x, y, colour); } } } int gpu_drawPixel(unsigned int x, unsigned int y, unsigned short colour) { unsigned int dest = (y * (*gpu_buffer).pitch) + x*2; *(volatile unsigned short *)((*gpu_buffer).buffer+dest) = colour; } int gpu_drawPixelBridge(unsigned int x, unsigned int y, unsigned short colour) { gpu_drawPixel(x, y, colour); } int gpu_drawAsciiChar(unsigned char chr, unsigned short front, unsigned short back, unsigned int ox, unsigned int oy) { unsigned int base = (chr*16)+((int)&gpu_font); unsigned int y = 0; while(y < 16) { unsigned int x = 0; while(x < 8) { if((*(unsigned char*)base >> x) & 0b1) { gpu_drawPixel(ox+x, oy+y, front); }else{ gpu_drawPixel(ox+x, oy+y, back); } x ++; } y ++; base ++; } }
(在这篇文章中,测试和简洁都删除了验证)
好吧,如此不一致和“古怪”将是我用来描述它是如何工作的词。目前,我认为至少有一个问题是从其所在的文件中调用drawPixel。从blink.c调用drawPixelBridge和drawAsciiCharacter一样工作,但直接从blink.c调用drawPixel似乎都不起作用(可能) )导致任何未来的尝试失败。
我想我应该解释一下绘画是如何工作的。通常,gpu_makeBuffer使用指向gpu_request结构的指针向GPU发送“mail”。然后,GPU通过将该结构的“buffer”属性设置为指向将在屏幕上绘制的字节序列的指针来响应此操作。鉴于屏幕上的东西出现在正确的位置(尽管尺寸和间距不是我预期的),我认为这样做有效。