Linux幀緩沖注冊(cè)OLED驅(qū)動(dòng)(上)
1.幀緩沖Framebuff
在 linux 系統(tǒng)中 LCD 這類設(shè)備稱為幀緩沖設(shè)備,英文 frameBuffer 設(shè)備。
frameBuffer 是出現(xiàn)在 2.2.xx 內(nèi)核當(dāng)中的一種驅(qū)動(dòng)程序接口。
幀緩沖( framebuffer)是 Linux 系統(tǒng)為顯示設(shè)備提供的一個(gè)接口,它將顯示緩沖區(qū)抽象,屏蔽圖像硬件的底層差異,允許上層應(yīng)用程序在圖形模式下直接對(duì)顯示緩沖區(qū)進(jìn)行讀寫操作。用戶不必關(guān)心物理顯示緩沖區(qū)的具體位置及存放方式,這些都由幀緩沖設(shè)備驅(qū)動(dòng)本身來(lái)完成。
用戶可以將 Framebuffer 看成是顯示內(nèi)存的一個(gè)映像, 將其映射到進(jìn)程地址空間之后,就可以直接進(jìn)行讀寫操作,而寫操作可以立即反應(yīng)在屏幕上。
幀緩沖驅(qū)動(dòng)是字符類設(shè)備的一種,主設(shè)備號(hào)為29,生成的設(shè)備節(jié)點(diǎn)為/dev/fb*。
使用幀緩沖完成屏幕驅(qū)動(dòng)注冊(cè),應(yīng)用層只需調(diào)用open函數(shù)打開(kāi)失敗,再通過(guò)ioctl函數(shù)獲取屏幕的參數(shù)信息,再調(diào)用mmap函數(shù)將屏幕顯存地址映射到進(jìn)程空間,接下來(lái)對(duì)地址的寫入即是對(duì)屏幕的刷。
2.幀緩沖Framebuff應(yīng)用編程
幀緩沖應(yīng)用層編程步驟
打開(kāi)LCD設(shè)備open(“/dev/fb0”,2);
獲取固定參數(shù)和可變參數(shù)ioctl;
將屏幕緩沖區(qū)映射到進(jìn)程空間mmap;
實(shí)現(xiàn)屏幕最核心函數(shù)畫點(diǎn)函數(shù);
2.1 幀緩沖Framebuff設(shè)備節(jié)點(diǎn)
通過(guò)幀緩沖完成屏幕驅(qū)動(dòng)注冊(cè),會(huì)在/dev下生成設(shè)備節(jié)點(diǎn),主設(shè)備號(hào)為29,注冊(cè)的一個(gè)設(shè)備驅(qū)動(dòng)為/dev/fb0,第二個(gè)為/dev/fb1,依此類推,最大可以注冊(cè)32個(gè)設(shè)備。
2.2 固定參數(shù)
通過(guò)ioctl函數(shù),命令參數(shù)為FBIOGET_FSCREENINFO,固定參數(shù)結(jié)構(gòu)體為struct fb_fix_screeninfo。在固定參數(shù)可獲得的屏幕信息有:smem_len屏幕緩沖區(qū)大小、line_length一行的字節(jié)數(shù)。
#define FBIOGET_FSCREENINFO 0x4602 /*獲取屏幕固定參數(shù)*/
/*固定參數(shù)結(jié)構(gòu)體*/
struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */
unsigned long smem_start; /* Start of frame buffer mem 屏幕物理地址 */
/* (physical address) */
__u32 smem_len; /* Length of frame buffer mem 屏幕緩沖區(qū)大小*/
__u32 type; /* see FB_TYPE_* */
__u32 type_aux; /* Interleave for interleaved Planes */
__u32 visual; /* see FB_VISUAL_* */
__u16 xpanstep; /* zero if no hardware panning */
__u16 ypanstep; /* zero if no hardware panning */
__u16 ywrapstep; /* zero if no hardware ywrap */
__u32 line_length; /* length of a line in bytes 一行的字節(jié)數(shù) */
unsigned long mmio_start; /* Start of Memory Mapped I/O */
/* (physical address) */
__u32 mmio_len; /* Length of Memory Mapped I/O */
__u32 accel; /* Indicate to driver which */
/* specific chip/card we have */
__u16 capabilities; /* see FB_CAP_* */
__u16 reserved[2]; /* Reserved for future compatibility */
};
2.3 可變參數(shù)
??通過(guò)ioctl函數(shù),命令參數(shù)為FBIOGET_VSCREENINFO,固定參數(shù)結(jié)構(gòu)體為struct fb_fix_screeninfo。在固定參數(shù)可獲得的屏幕信息有:屏幕寬度xres、屏幕高度yres、顏色位數(shù)bits_per_pixel。
#define FBIOGET_VSCREENINFO 0x4600 /*獲取屏幕可變參數(shù)*/
/*可變參數(shù)結(jié)構(gòu)體*/
struct fb_var_screeninfo {
__u32 xres; /* visible resolution屏幕寬度 */
__u32 yres; /*屏幕高度*/
__u32 xres_virtual; /* virtual resolution */
__u32 yres_virtual;
__u32 xoffset; /* offset from virtual to visible */
__u32 yoffset; /* resolution */
__u32 bits_per_pixel; /* guess what 顏色位數(shù) */
__u32 grayscale; /* 0 = color, 1 = grayscale, */
/* >1 = FOURCC */
struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; /* transparency */
__u32 nonstd; /* != 0 Non standard pixel format */
__u32 activate; /* see FB_ACTIVATE_* */
__u32 height; /* height of picture in mm */
__u32 width; /* width of picture in mm */
__u32 accel_flags; /* (OBSOLETE) see fb_info.flags */
/* Timing: All values in pixclocks, except pixclock (of course) */
__u32 pixclock; /* pixel clock in ps (pico seconds) */
__u32 left_margin; /* time from sync to picture */
__u32 right_margin; /* time from picture to sync */
__u32 upper_margin; /* time from sync to picture */
__u32 lower_margin;
__u32 hsync_len; /* length of horizontal sync */
__u32 vsync_len; /* length of vertical sync */
__u32 sync; /* see FB_SYNC_* */
__u32 vmode; /* see FB_VMODE_* */
__u32 rotate; /* angle we rotate counter clockwise */
__u32 colorspace; /* colorspace for FOURCC-based modes */
__u32 reserved[4]; /* Reserved for future compatibility */
};
2.4 將屏幕緩沖區(qū)映射到進(jìn)空間
#include
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
函數(shù)功能: 將文件映射到進(jìn)程空間
形參: addr --映射的虛擬地址,一般填NULL,有系統(tǒng)自行分配
???length --要映射的空間大小
???prot --PROT_READ可讀;PROT_WRITE可寫
???flags --MAP_SHARED可讀寫,讀寫內(nèi)容同步到文件;MAP_PRIVATE修改的內(nèi)容不會(huì)同步到文件
???fd --文件描述符
???offset --一般填0,表示映射整個(gè)文件
返回值: 成功返回映射的地址
???失敗返回-1
int munmap(void *addr, size_t length);
形參: addr --mamp函數(shù)返回值
???length --映射空間大小
2.5 幀緩沖獲取固定參數(shù)和可變參數(shù)示例
int main()
{
/*1.打開(kāi)設(shè)備*/
int fd=open("/dev/fb0", 2);
if(fd<0)
{
printf("打開(kāi)設(shè)備失敗n");
}
/*2.獲取固定參數(shù)*/
memset(&fb_fix,0, sizeof(fb_fix));
ioctl(fd,FBIOGET_FSCREENINFO,&fb_fix);
printf("屏幕緩存大小:%dn",fb_fix.smem_len);
printf("一行的字節(jié)數(shù):%dn",fb_fix.line_length);
/*3.獲取屏幕可變參數(shù)*/
memset(&fb_var,0, sizeof(fb_var));
ioctl(fd,FBIOGET_VSCREENINFO,&fb_var);
printf("屏幕尺寸:%d*%dn",fb_var.xres,fb_var.yres);
printf("顏色位數(shù):%dn",fb_var.bits_per_pixel);
/*4.將屏幕緩沖區(qū)映射到進(jìn)程空間*/
lcd_p=mmap(NULL,fb_fix.smem_len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
close(fd);
if(lcd_p==(void *)-1)
{
printf("內(nèi)存映射失敗n");
return 0;
}
memset(lcd_p,0xff,fb_fix.smem_len);//將屏幕清空為白色
//取消映射
munmap(lcd_p,fb_fix.smem_len);
return 0;
}
/*畫點(diǎn)函數(shù)實(shí)現(xiàn)*/
static inline void LCD_DrawPoint(int x,int y,int c)
{
//獲取要繪制的點(diǎn)的地址
unsigned int *p= (unsigned int *)(lcd_p+y*fb_fix.line_length+x*fb_var.bits_per_pixel/8);
*p=c;//寫入顏色值
}
-
OLED
+關(guān)注
關(guān)注
120文章
6286瀏覽量
228057 -
Linux
+關(guān)注
關(guān)注
87文章
11511瀏覽量
213765
發(fā)布評(píng)論請(qǐng)先 登錄
Linux幀緩沖注冊(cè)OLED驅(qū)動(dòng)(下)

基于Linux使用spidev驅(qū)動(dòng)OLED

請(qǐng)問(wèn)如何在Linux中使用幀緩沖區(qū)更新epdc顯示?
迅為4412開(kāi)發(fā)板Linux驅(qū)動(dòng)教程——總線_設(shè)備_驅(qū)動(dòng)注冊(cè)流程詳解
嵌入式linux學(xué)習(xí)筆記20160907-每天進(jìn)步一點(diǎn)點(diǎn),向嵌入式進(jìn)軍-LCD驅(qū)動(dòng)
【HarmonyOS HiSpark Wi-Fi IoT 套件試用OLED驅(qū)動(dòng)】oled屏的使用和oled驅(qū)動(dòng)測(cè)試
IMX6上的幀緩沖區(qū)會(huì)阻塞原因?如何讓它更快?
如何為iMX8 LVDS1添加第二個(gè)幀緩沖區(qū)?
基于嵌入式Linux的TFT LCD IP及驅(qū)動(dòng)的設(shè)計(jì)
幀緩沖記憶接口引腳功能
Linux下的LCD驅(qū)動(dòng)程序?qū)崿F(xiàn)

Linux下的幀緩沖lcd應(yīng)用編程及Framebuffer驅(qū)動(dòng)程序模型
STM32驅(qū)動(dòng)OLED屏設(shè)計(jì)方案完成漢字滾動(dòng)顯示

Linux驅(qū)動(dòng)開(kāi)發(fā)-編寫OLED顯示屏驅(qū)動(dòng)

評(píng)論