Linux下的freambuffer(帧缓存驱动 -- Linux平台的系统框架) --- 自适应显示
概念引入--- 何为自适应显示
通过使用一个特殊的接口ioctl去获取液晶显示器的硬件参数:LCD_w 和 LCD_h
当然除了获取基本的显示宽度和长度之外,linux下获取LCD硬件的底层信息如下:
① 显存的大小 smem_len (虚拟区的大小):专门用来显示的空间叫做显存。这个空间就是用来存放像素点的
② 可见区的大小就是LCD全屏显示的大小:w h
③ 虚拟区的大小跟整个显存有关系(一样大)= 可见区+不可见区
我如何通过代码获取LCD中的 显存大小,屏幕的w和h
使用ioctl:对硬件进行输入输出控制,设置硬件参数,获取硬件参数
观察以下几幅图 --- 关于linux的freambuffer如何存放控制LCD显示的设备信息
1)理解思路
ioctl的代码 属于文件IO接口
所以可以通过设备文件的文件描述符 --控制--> 对应的设备文件 --间接控制-->设备的驱动 --最终控制--> 最终能获取和设置设备信息
2)这个结构体的信息是硬件固化好的参数,不能调整。这个结构体是系统框架帧缓存提供的一个结构体
结构体可调整
ioctl ---- 设置、获取 硬件设备的参数和信息 ioctl经常控制设备文件
1)ioctl用法
ioctl --控制--> fb0 --控制--> freambuffer --控制--> LCD
ioctl: 输入输出控制 获取或者设置硬件参数
#include <sys/ioctl.h>
关于第三个参数:
如果是获取:提供缓存区存放获取到的参数
如果是设置:提供缓存区存放要设置的参数
int ioctl(int fd, unsigned long request, ...);
形参1:文件描述符,open函数的返回值,ioctl里面填文件的描述符是哪个文件的? fb0
形参2:request 控制命令
函数参数:从第三个参数,实际的参数个数由控制命令决定
疑问:如何获取你要的信息的命令
命令一般都是宏定义命令,命令有很多,找命令根据硬件都有对应的头文件。/usr/include/linux/fb.h
返回值:
0:成功
-1:失败
总结:
获取LCD的显存等信息的ioctl的命令是:#define FBIOGET_FSCREENINFO 0x4602
获取LCD的长宽等信息的ioctl的命令是:#define FBIOGET_VSCREENINFO
切记你获取出来的显存等信息要存放在对应的结构体变量里面 struct fd_fix_screeninfo
譬如:
获取设备硬件的信息
int size;
ioctl(int fd, ,&size);
设置设备硬件的信息
int size = 1024; //单位MB
ioctl(int fd, SET_XC_SIZE,&size);
2)如何获取想要的控制设置命令?
基本所有的硬件有对应的设备文件控制,所有的设备在系统里面除了有对应的设备文件之外,肯定有对应的设备的头文件:
譬如:
触摸屏 event0 linux/input.h
LCD fb0 linux/fb.h
毫无疑问的,你的控制命令就是存放在设备对应的头文件里面。控制命令基本上是宏定义。
3)如何获取硬件的显存大小
/******************************************************************************************************
* @file name: : 获取硬件显存大小.c
* @brief :获取硬件显存大小
* @author :wvjnuhhail@126.com
* @date :2024/07/09
* @version 1.0 :V1.0
* @property :暂无
* @note :None
* CopyRight (c) 2023-2024 wvjnuhhail@126.com All Right Reseverd
******************************************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
int main()
{
int lcd = open("/dev/fb0",O_RDWR);
if(lcd == -1)
{
perror("open ...");
return -1;
}
struct fb_fix_screeninfo fix_inf;
if(ioctl(lcd,FBIOGET_FSCREENINFO,&fix_inf) == -1)
{
perror("ioctl获取液晶显示器信息失败!");
return -1;
}
else
{
printf("帧缓存驱动初始化成功!\n显存大小:【%u】\n",fix_inf.smem_len);
}
if(close(lcd) == -1)
{
perror("close ...");
return -1;
}
return 0;
}
4)如何获取硬件的可见区也就是屏幕的W和H:
/******************************************************************************************************
* @file name: : 获取液晶显示器参数.c
* @brief :通过ioctl获取液晶显示器参数
* @author :wvjnuhhail@126.com
* @date :2024/07/09
* @version 1.0 :V1.0
* @property :暂无
* @note :None
* CopyRight (c) 2023-2024 wvjnuhhail@126.com All Right Reseverd
******************************************************************************************************/
#include <sys/ioctl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv)
{
// 打开设备fb0
int lcd = open("/dev/fb0", O_RDWR);
if (-1 == lcd)
{
perror("open...");
exit(1);
}
// 定义一个结构体变量
struct fb_fix_screeninfo fix_inf;
struct fb_var_screeninfo var_inf;
memset(&fix_inf, 0, sizeof(fix_inf));
memset(&var_inf, 0, sizeof(var_inf));
// 结构体大小
int fixRet = ioctl(lcd, FBIOGET_FSCREENINFO, &fix_inf);
int varRet = ioctl(lcd, FBIOGET_VSCREENINFO, &var_inf);
if (fixRet == -1 || varRet == -1)
{
perror("ioctl获取液晶屏显示信息失败...");
return -1;
}
else
{
printf("帧缓存驱动初始化成功\n 显存大小:[%u]\n可见区宽度:[%u]-----可见度高度:[%u]\n",
fix_inf.smem_len,
var_inf.xres,
var_inf.yres);
}
close(lcd);
return 0;
}