量产工具——显示系统(学习课程来源百问网后附视频链接)

目录

一、数据结构抽象

二、Framebuffer编程

三、显示编程

1.大概思路

2.具体步骤:

四、单元测试 

五、总结

一、抽象出统一的结构体

二、去实现上面的统一的结构体(struct DispOpr)

三、抽象出一个用来选择显示设备的代码

 


一、数据结构抽象

从两个不同设备中抽象出一个相同的结构体。

display_manager.h

#ifndef _DISPLAY_MANAGER_H
#define _DISPLAY_MANAGER_H

typedef struct Region{
	int iLeftUpx;
	int iLeftUpf;
	int iWidth;
	int iHeigh;
}Region, *PRegion;

typedef struct DispOpr{
	char *name;
	char *GetBuffer(int *pXres, int *pYres, int *pBpp);
	int FlushRegion(PRegion ptRegion, char *buffer);
	struct DispOpr *ptNext;
}DispOpr, *PDispOpr;

#endif

二、Framebuffer编程

根据这个结构体,完善具体的代码,编写所需要的函数。

static DispOpr g_tFramebufferOpr = {
	.name = "fb",
	.DeviceInit = FbDeviceInit,
	.DeviceExit = FbDeviceExit,
	.GetBuffer = GetBuffer,
	.FlushRegion = FbFlushRegion,
};

三、显示编程

1.大概思路

下面的代码会构造各自的g_tFramebufferOpr结构体,需要用一个链表将他们管理起来

使用一个函数将他们放入链表

framebuffer.c中需要有个函数将g_tFramebufferOpr注册进链表中

2.具体步骤:

1.应用程序首先调用DispInit,DispInit会去调用到底层的初始化函数FramebufferInit

2.FramebufferInit里会去调用注册函数RegisterDisplay,注册LCD硬件相关的结构体g_tFramebufferOpr

3.注册函数RegisterDisplay,会把这些结构体放入链表

4.假设这个链表里有很多项,需要调用SelectDefaultDisplay来选择默认得输出设备

5.选择好之后,还要去调用InitDefaultDisplay来初始化这个设备

6.然后就可以调用PutPixel函数在上面绘制图片了

7.在调用FbFlushRegion把绘制好的这块区域刷到硬件上去

四、单元测试 

	void lcd_put_ascii(int x, int y, unsigned char c)
	{
		unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
		int i, b;
		unsigned char byte;
	
		for (i = 0; i < 16; i++)
		{
			byte = dots[i];
			for (b = 7; b >= 0; b--)
			{
				if (byte & (1<<b))
				{
					/* show */
					PutPixel(x+7-b, y+i, 0xffffff); /* 白 */
				}
				else
				{
					/* hide */
					PutPixel(x+7-b, y+i, 0); /* 黑 */
				}
			}
		}
	}
	
	int main(int argc, char **argv)
	{
		Region region;
		PDispBuff ptBuffer;
	
		DisplayInit();
		SelectDefaultDisplay("fb");
		InitDefaultDisplay();
	
		lcd_put_ascii(100, 100, 'A');
		
		region.iLeftUpX = 100;
		region.iLeftUpY = 100;
		region.iWidth = 8;
		region.iHeigh = 16;
	
		ptBuffer = GetDisplayBuffer();
		FlushDisplayRegion(&region, ptBuffer);
	
		return 0;	
	}

五、总结

 对于学习显示系统框架的总结:

对于两个不同的设备,我们要抽象出同一个结构体/结构体类型

在后面的实现中,他们要分别实现自己的结构体

一、抽象出统一的结构体:

以绘制一个按钮为例: 首先,我们要获得一个buffer,我们可以在这个buffer里进行绘制,这个buffer可以用一个结构体来表示

绘制好某个区域之后,我们需要把这个区域刷到设备上去

如何去构造这个结构体:

第一,这个结构体有名字,我们可以通过这个名字取得不同的结构体

第二,设备初始化,也就是获得设备信息;有初始化也要有退出函数。

第三,应用程序想要去绘制图片,首先我们需要有个buffer,所以我们要去获得一个buffer

第四,绘制好之后,我们需要把那块区域刷到设备上,这块区域我也可以用一个结构体来表示

我们可以从多个设备中选择一个,所以我们还应该加一个链表

这样我们就抽象出了统一的结构体

typedef struct DispOpr { 
    char name; 
    int (DeviceInit)(void); 
    int (DeviceExit)(void); 
    int (GetBuffer)(PDispBuff ptDispBuff); 
    int (*FlushRegion)(PRegion ptRegion, PDispBuff ptDispBuff); 
    struct DispOpr *ptNext; 
}DispOpr, *PDispOpr;

这是buffer和区域的结构体

typedef struct DispBuff { 
    int iXres; int iYres; 
    int iBpp; char *buff; 
}DispBuff, *PDispBuff;

typedef struct Region { 
    int iLeftUpX; int iLeftUpY; 
    int iWidth; int iHeigh; 
}Region, *PRegion;

以后,上层的代码,调用这些结构体,就可以显示数据了。

二、去实现上面的统一的结构体(struct DispOpr)

你想将绘制好的图片在什么设备上面显示,用那个具体的设备去实现上面的结构体。

三、抽象出一个用来选择显示设备的代码

第一、管理各个设备的结构体,通过统一结构体中的链表去管理。

为下层代码提供一个注册函数,将这些结构体放入链表

下层代码又将这个注册函数封装进自己的注册函数中,将自己构造的结构体注册到上层的链表中

第二、写一个函数去调用底层不同设备注册函数

第三、写一个去选择注册哪个设备的函数,将链表头的name和传入的name比较,如果找到了就再定义一个结构体,将他存进去

第四、找到选择的设备后,需要去初始化这个设备,获得这个设备的信息,将信息放入buffer结构体中

第五、实现描点函数

第六、提供一个将绘制好后的图片,刷到设备某个位置上去的函数,这函数主要是用来获得要刷的位置信息。

 

2-1_显示系统_数据结构抽象_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1it4y1Q75z?p=3&vd_source=3a9afee9fda50350a1c881b4325e007d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值