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)这个结构体的信息是硬件固化好的参数,不能调整。这个结构体是系统框架帧缓存提供的一个结构体
image


结构体可调整
image


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);

image

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;
}

image


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;
}

image

posted @ 2024-07-09 18:31  WJnuHhail  阅读(8)  评论(0编辑  收藏  举报