Note that there are some explanatory texts on larger screens.

plurals
  1. POFunction not working unless called in same file
    primarykey
    data
    text
    <p>So I'm following the <a href="http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/" rel="nofollow">tutorial</a> , but doing it in <em>C</em> because assembly is just too unwieldy. This is the first "real project" I've done in <em>C</em>, so this is bound to be either a silly mistake, or some nuance to how <em>C</em> works.</p> <p>Anyway, I have this code:</p> <pre> /*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 } }</pre> <pre> /*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</pre> <pre> /*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) &lt; 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 &lt; /*(*_gpu_buffer).size* / 1366*768*2) { *(volatile unsigned short *)((*_gpu_buffer).buffer+i) = colour; i +=2; }*/ int y = 0; while(y &lt; 100) { y ++; int x = 0; while(x &lt; 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 &lt; 16) { unsigned int x = 0; while(x &lt; 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 ++; } }</pre> <p>(Validation was removed for both testing and brevity in this post)</p> <p>Okay, so inconsistent and "wacky" would be words I'd have used to describe how it works. At the moment, I think at least one problem is calling drawPixel from anything other than the file it's in. Calling drawPixelBridge from blink.c works, as does drawAsciiCharacter, but calling drawPixel directly from blink.c seems to both not work and (probably) causing any future attempt to draw anything fail.</p> <p>I suppose I should explain how drawing works. Generally, gpu_makeBuffer sends "mail" to the GPU with a pointer to a gpu_request structure. The GPU then responds to this by setting the "buffer" property of that structure to a pointer to a sequence of bytes which will draw on the screen. Given that stuff appears on the screen in the right place (albeit the size and pitch are not what I expect them to be), I assume this works.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload