0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux帧缓冲注册OLED驱动(上)

嵌入式技术 来源:嵌入式技术 作者:嵌入式技术 2022-09-26 15:47 次阅读

Linux帧缓冲注册OLED驱动(上)

1.帧缓冲Framebuff

在 linux 系统中 LCD 这类设备称为帧缓冲设备,英文 frameBuffer 设备。

frameBuffer 是出现在 2.2.xx 内核当中的一种驱动程序接口

帧缓冲( framebuffer)是 Linux 系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成。

用户可以将 Framebuffer 看成是显示内存的一个映像, 将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。

帧缓冲驱动是字符类设备的一种,主设备号为29,生成的设备节点为/dev/fb*。

使用帧缓冲完成屏幕驱动注册,应用层只需调用open函数打开失败,再通过ioctl函数获取屏幕的参数信息,再调用mmap函数将屏幕显存地址映射到进程空间,接下来对地址的写入即是对屏幕的刷。

2.帧缓冲Framebuff应用编程

帧缓冲应用层编程步骤
打开LCD设备open(“/dev/fb0”,2);
获取固定参数和可变参数ioctl;
将屏幕缓冲区映射到进程空间mmap;
实现屏幕最核心函数画点函数;

2.1 帧缓冲Framebuff设备节点

通过帧缓冲完成屏幕驱动注册,会在/dev下生成设备节点,主设备号为29,注册的一个设备驱动为/dev/fb0,第二个为/dev/fb1,依此类推,最大可以注册32个设备。

2.2 固定参数

通过ioctl函数,命令参数为FBIOGET_FSCREENINFO,固定参数结构体为struct fb_fix_screeninfo。在固定参数可获得的屏幕信息有:smem_len屏幕缓冲区大小、line_length一行的字节数。

#define FBIOGET_FSCREENINFO	0x4602 /*获取屏幕固定参数*/
/*固定参数结构体*/
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 屏幕缓冲区大小*/
	__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 一行的字节数   */
	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 可变参数

  通过ioctl函数,命令参数为FBIOGET_VSCREENINFO,固定参数结构体为struct fb_fix_screeninfo。在固定参数可获得的屏幕信息有:屏幕宽度xres、屏幕高度yres、颜色位数bits_per_pixel。

#define FBIOGET_VSCREENINFO	0x4600 /*获取屏幕可变参数*/
/*可变参数结构体*/
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	颜色位数		*/
	__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 将屏幕缓冲区映射到进空间

#include 
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
函数功能: 将文件映射到进程空间
形参: addr --映射的虚拟地址,一般填NULL,有系统自行分配
   length --要映射的空间大小
   prot --PROT_READ可读;PROT_WRITE可写
   flags --MAP_SHARED可读写,读写内容同步到文件;MAP_PRIVATE修改的内容不会同步到文件
   fd --文件描述符
   offset --一般填0,表示映射整个文件
返回值: 成功返回映射的地址
   失败返回-1


int munmap(void *addr, size_t length);
形参: addr --mamp函数返回值
   length --映射空间大小

2.5 帧缓冲获取固定参数和可变参数示例

int main()
{
	/*1.打开设备*/
	int fd=open("/dev/fb0", 2);
	if(fd<0)
	{
		printf("打开设备失败n");
	}
	/*2.获取固定参数*/
	memset(&fb_fix,0, sizeof(fb_fix));
 	ioctl(fd,FBIOGET_FSCREENINFO,&fb_fix);
	printf("屏幕缓存大小:%dn",fb_fix.smem_len);
	printf("一行的字节数:%dn",fb_fix.line_length);
	/*3.获取屏幕可变参数*/
	memset(&fb_var,0, sizeof(fb_var));
	ioctl(fd,FBIOGET_VSCREENINFO,&fb_var);
	printf("屏幕尺寸:%d*%dn",fb_var.xres,fb_var.yres);
	printf("颜色位数:%dn",fb_var.bits_per_pixel);
	/*4.将屏幕缓冲区映射到进程空间*/
	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");
		return 0;
	}
	memset(lcd_p,0xff,fb_fix.smem_len);//将屏幕清空为白色
	//取消映射
	munmap(lcd_p,fb_fix.smem_len);
	return 0;
}
/*画点函数实现*/
static inline void LCD_DrawPoint(int x,int y,int c)
{
	//获取要绘制的点的地址
	unsigned int *p= (unsigned int *)(lcd_p+y*fb_fix.line_length+x*fb_var.bits_per_pixel/8);
	*p=c;//写入颜色值
}
审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • OLED
    +关注

    关注

    119

    文章

    6171

    浏览量

    223662
  • Linux
    +关注

    关注

    87

    文章

    11204

    浏览量

    208701
收藏 人收藏

    评论

    相关推荐

    Linux缓冲注册OLED驱动(下)

    OLED,即有机发光二极管( Organic Light Emitting Diode)。 OLED 由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、 构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用
    的头像 发表于 09-26 15:54 2367次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>帧</b><b class='flag-5'>缓冲</b><b class='flag-5'>注册</b><b class='flag-5'>OLED</b><b class='flag-5'>驱动</b>(下)

    基于Linux使用spidev驱动OLED

    如果不想编写spi设备驱动,那么linux内核提供了一个通用的spidev设备驱动,提供统一的字符设备操作,那么只需要在应用层读写和控制即可。以SPI OLED为例子,使用spidev
    发表于 06-16 10:36 4166次阅读
    基于<b class='flag-5'>Linux</b>使用spidev<b class='flag-5'>驱动</b><b class='flag-5'>OLED</b>

    迅为4412开发板Linux驱动教程——总线_设备_驱动注册流程详解

    /platform/ 驱动注册驱动注册– 很重要,牢牢掌握,以后写任何Linux驱动都会
    发表于 08-12 14:13

    嵌入式linux学习笔记20160907-每天进步一点点,向嵌入式进军-LCD驱动

    fb_var_screeninfo var 和struct fb_fix_screeninfo fix 成员。2.根据具体LCD 屏幕的特点,完成LCD 控制器硬件的初始化。3.申请缓冲设备的显示缓冲区空间。4.
    发表于 09-07 11:13

    Linux总线设备驱动注册流程

    Linux总线设备驱动注册流程
    发表于 09-16 19:11

    【HarmonyOS HiSpark Wi-Fi IoT 套件试用OLED驱动oled屏的使用和oled驱动测试

    在测试HarmonyOS Wi-Fi IoT 套件Hi3861过程,套件oled屏幕不亮了,最后排查发现是测试新程序的时候把之前的测试程序入口更改了,无法驱动oled了。论坛上有连
    发表于 11-15 20:37

    IMX6缓冲区会阻塞原因?如何让它更快?

    我对 IMX-6 板Linux 缓冲区有疑问。要将 ioctl 命令 FBIOPAN_DISPLAY 发送到 /dev/fb0,它会阻塞 5 秒。这个问题就在关机/开机之后,正
    发表于 03-15 07:16

    如何为iMX8 LVDS1添加第二个缓冲区?

    为 lvds1 创建第二个缓冲区?Linux 内核版本为 5.4.70 (linux-imx)。请注意,我确实找到了一篇 NXP 社
    发表于 04-10 08:34

    基于Linux的嵌入式LCD设计

    本文介绍了基于Linux 的嵌入式LCD 设计的实现,以ARM 处理器S3C2410X 嵌入式芯片为平台,设计了嵌入式Linux 下的设备驱动程序和
    发表于 09-01 09:50 18次下载

    基于嵌入式Linux的TFT LCD IP及驱动的设计

    基于嵌入式Linux 的TFT LCD IP 及驱动的设计:Nios II 处理器在SDRAM 中开辟缓冲(Frame buffer),可以是单
    发表于 03-18 17:48 4次下载

    缓冲记忆接口引脚功能

    缓冲记忆接口引脚功能 缓冲记忆接口引脚功能PIN TYPE PIN NO 功能MAI[9:0] O 113-112
    发表于 01-16 23:54 623次阅读

    Linux下的LCD驱动程序实现

    通过对LCD和Framebuffer原理的说明,以ARM处理器S3C2410嵌入式芯片为平台,设计了嵌入式Linux下的基于缓冲的LCD设备驱动程序。通过测试程序的编译运行,在LCD
    发表于 02-09 15:10 68次下载
    <b class='flag-5'>Linux</b>下的LCD<b class='flag-5'>驱动</b>程序实现

    Linux下的缓冲lcd应用编程及Framebuffer驱动程序模型

    缓冲(framebuffer)是 Linux 为显示设备提供的一个接口,把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。
    发表于 04-28 17:40 1392次阅读

    STM32驱动OLED屏设计方案完成汉字滚动显示

    OLED实现字符串滚动显示。   0.96寸OLED分辨率为128*64(128列,64行)。我们可以定义二维数组缓冲区buff[64][128],先将要显示的数据放在
    的头像 发表于 05-31 17:31 6409次阅读
    STM32<b class='flag-5'>驱动</b><b class='flag-5'>OLED</b>屏设计方案完成汉字滚动显示

    Linux驱动开发-编写OLED显示屏驱动

    OLED显示屏在是智能手环,智能手表用的非常的多,功耗低,不刺眼,优点特别多。本篇文章就介绍,在Linux系统里如何使用OLED显示屏,要使用OL
    的头像 发表于 09-17 15:19 4191次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>驱动</b>开发-编写<b class='flag-5'>OLED</b>显示屏<b class='flag-5'>驱动</b>