1. 程式人生 > >【Tiny6410 And Linux】—(6.1)—LCD 驅動測試程式——程式碼

【Tiny6410 And Linux】—(6.1)—LCD 驅動測試程式——程式碼

又過了好幾天了,呵呵,應該說玩了好幾天!

貌似要找工作了,有點發愁啊,不過現在還是堅持寫寫東西吧,暫時不想去想那麼多(如果突然有那麼份工作擺在面前,那該多好啊!)。

由於這裡沒有涉及到寫驅動,所以也就沒有這部分,不過把測試程式弄完,然後就寫一篇驅動程式出來應該問題也就不會那麼大了吧!

1、測試程式

#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

#define FB_DEVICE_NAME "/dev/fb0"


#define RED_COLOR565		0X0F100
#define GREEN_COLOR565		0X007E0
#define BLUE_COLOR565		0X0001F

typedef struct fb_dev	{
	int fd;				/* 幀緩衝裝置硬體描述符 */
	void *pfb;			/* 指向幀緩衝對映到使用者空間的首地址 */
	int xres;			/* 一幀影象的寬度 */
	int yres;			/* 一幀影象的高度 */
	int size;			/* 一幀影象的大小 */
	int bits_per_pixel;	/* 每個畫素的大小 */
} fb_dev_t;

int fb_open(fb_dev_t *fbd, char *fbn)
{
	struct fb_var_screeninfo vinfo;

	if((fbd->fd = open(fbn, O_RDWR)) == -1)	{
		printf("Error: Cannot open framebuffer device.\n");
		_exit(EXIT_FAILURE);
	}

	/* 獲取LCD 的可變引數 */
	ioctl(fbd->fd, FBIOGET_VSCREENINFO, &vinfo);

	fbd->xres = vinfo.xres;
	fbd->yres = vinfo.yres;
	fbd->bits_per_pixel = vinfo.bits_per_pixel;

	/* 計算一幀影象的大小 */
	fbd->size = fbd->xres * fbd->yres * fbd->bits_per_pixel / 8;

	printf("%d * %d,%d bits_per_pixel,screensize = %d.\n",fbd->xres,fbd->yres,fbd->bits_per_pixel,fbd->size);

	/* 將幀對映到記憶體 */
	/* mmap的應用 */
	/* mmap可以把檔案內容對映到一段記憶體中,準確說是虛擬記憶體,通過對這段記憶體的讀取和修改,實現對檔案的讀取和修改。 */
	/* addr:指定對映的起始地址,通常為NULL,由系統指定 */
	/* length:將檔案的多大長度對映到記憶體 */
	/* prot:對映區的保護方式,可以是可被執行(PROT_EXEC),可被寫入(PROT_WRITE),可被讀取(PROT_READ),對映區不能存取(PROT_NONE) */
	/* flags:對映區的特性,對對映區的寫入資料會複製迴文件,且允許其他對映檔案的進城共享(MAP_SHARED),對對映區的寫入操作會產生一個對映的複製,對此區域所做的修改不會寫會原始檔(MAP_PRIVATE) */
	/* fd:由open返回的檔案描述符,代表要對映的檔案 */
	/* offset:以檔案開始出的偏移,必須是分頁大小的整數倍,通常為0,表示從頭開始對映 */

	/* 注意:在修改對映檔案時,只能在原長度上修改,不能增加檔案長度,因為記憶體是已經分配好的 */
	
	fbd->pfb = mmap(NULL, fbd->size, PROT_READ | PROT_WRITE, MAP_SHARED, fbd->fd, 0);

	if((int)fbd->pfb == -1)	{
		printf("Error: Failed to map frambuffer device to memory!\n");
		_exit(EXIT_FAILURE);
	}

	return 0;
}

int fb_close(fb_dev_t *fbd)
{
	/* 解除對映 */
	munmap(fbd->pfb,fbd->size);

	/* 關閉裝置檔案 */
	close(fbd->fd);
}

int fb_drawrect(fb_dev_t *fbd, int x0, int y0, int w, int h, int color)
{
	int x,y;

	for(y=y0; y<y0+h; y++)	{
		for(x=x0; x<x0+w; x++)	{
			*((short *)(fbd->pfb) + y*fbd->xres +x) = color;
		}
	}

	return 0;
}

int main(int argc, char **argv)
{
	fb_dev_t *fbd;

	fbd = (fb_dev_t *)malloc(sizeof(fb_dev_t));

	fb_open(fbd, FB_DEVICE_NAME);

	if(fbd->bits_per_pixel == 16)	{
		printf("Red/Green/Blue Screen!");

		fb_drawrect(fbd, 0, 0, fbd->xres, fbd->yres/3, RED_COLOR565);
		fb_drawrect(fbd, 0, fbd->yres/3, fbd->xres, fbd->yres/3, GREEN_COLOR565);
		fb_drawrect(fbd, 0, fbd->yres*2/3, fbd->xres, fbd->yres/3, BLUE_COLOR565);
	}

	else	
		printf("16 bits only!");

	fb_close(fbd);

	return 0;
}


2、實驗結果2、實驗結果

具體板子上的影象顯示就不貼了,無非就是螢幕顯示了3種顏色罷了!

但是本來想上傳一個串列埠列印的資訊,但是由於網站不穩定吧原因吧,沒成功!那就先到這裡吧(完全可以從程式碼中看到列印資訊)!