当前位置: 首页 > news >正文

嵌入式学习 D31:系统编程--Framebuf帧缓冲

(1)framebuf帧缓冲  :linux提供的显示设备驱动的接口。

设备路径 : 设备/dev/fb0

*        分辨率:像素点是w * h。
每个像素点色深 RGB:0-255  红绿蓝各3字节(byte)即可描述色深。
访问的显存默认左上角为坐标原点。

*        xres yres真实分辨率
        xres_vitrual虚拟分辨率:

        一般可访问显存小一些,即虚拟分辨率,真实分辨率就是打开设置查看得到的分辨率。

*        每个像素点色深RGB用三字节描述,即3*8bit,用十六进制就是0x00rrggbb,具体颜色对应16进制可以搜索w3cschool,在里面的htmlyanse查看。

*        文件解压:tar -xvf 压缩包.tar.xz

*        ctrl alt f3文字终端,没有图形界面。
ctrl alt f1图形界面,伪终端即图形界面打开的终端。
ctrl alt鼠标出现
直接操作硬件运行时sudo ./out

*        简单的操作像素点,比如画直线等,可以通过简单的循环控制xy坐标就能实现,但汉字图像等需要的像素点坐标就比较复杂了。

*        文字可以通过字模工具获取要操作的像素点坐标数组,也可以通过字库进行操作,最原始的图像是位图,文件信息中前54字节是头信息,包含图像的大小等参数,剩下的就是连续了BGRBGR像素点数据,我们可以循环取三字节,再倒序就得到RGB参数了,然后输出。

(2)利用帧缓存点亮第一个点。

*        步骤:open打开设备-》ioctl获取屏幕信息-》mmap映射:获得显存 -》draw根据坐标操作像素点 -》unmap显存回收

#include <stdio.h>   
#include <stdlib.h>   
#include <string.h>   
#include <unistd.h>   
#include <fcntl.h>   
#include <sys/ioctl.h>   
#include <sys/mman.h>   
#include <linux/fb.h>   
#include <math.h>
   
// 颜色定义   
#define RGB888_FMT 32   
#define RGB565_FMT 16   
#define WHITE     0x00FFFFFF   
#define BLACK     0x00000000   
#define RED       0x00FF0000   
#define GREEN     0x0000FF00   
#define BLUE      0x000000FF   
#define YELLOW    0x00FFFF00   
#define PURPLE    0x00FF00FF   
#define CYAN      0x0000FFFF
   
// 全局变量   
struct fb_var_screeninfo vinf;   
void *pmem = NULL;
   
// 函数声明   

#ifndef __FRAMEBUFFER_H__
#define __FRAMEBUFFER_H__

#include "utf.h"

#define RGB888_FMT 32
#define RGB565_FMT 16


extern int init_fb(char *devname);
extern void draw_point(int x,int y, unsigned int col);
extern void uninit_fb(int fd);
extern void draw_clear(unsigned int col);

extern void draw_h_line(int x, int y, int len, unsigned int col);
extern void draw_s_line(int x, int y, int len, unsigned int col);
extern void draw_rectangle(int x, int y, int w, int h, unsigned int col);
extern void draw_x_line(int x1, int y1, int x2, int y2, unsigned int col);
extern void draw_circle(int x0, int y0, int r, unsigned int col);
extern void draw_bmp(int x, int y, char *picname, int w, int h);
extern void draw_word(int x, int y, unsigned char *word, int w, int h, unsigned int col);
extern int draw_utf8(UTF8_INFO *info, int x, int y, char* zi, unsigned int col, unsigned int col1);
extern int draw_utf8_str(UTF8_INFO *info, int arg_x, int arg_y,  char* zi, unsigned int col, unsigned int col1);

#endif

#include "framebuffer.h"
#include <linux/fb.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <math.h>void *pmem;
struct fb_var_screeninfo vinf;int init_fb(char *devname)
{//1. 打开显示设备int fd = open(devname, O_RDWR);	if (-1 == fd){perror("fail open fb");return -1;}//2、获取显示设备相关参数 分辨率 位深度int ret = ioctl(fd, FBIOGET_VSCREENINFO, &vinf);if (-1 ==ret){perror("fail ioctl");return -1;}printf("xres = %d, yres = %d\n", vinf.xres, vinf.yres);printf("xres_virtual = %d, yres_virtual = %d\n", vinf.xres_virtual, vinf.yres_virtual);printf("bits_per_pixel : %d\n", vinf.bits_per_pixel);size_t len = vinf.xres_virtual * vinf.yres_virtual * vinf.bits_per_pixel/8;//3, 建立显存和用户空间的映射关系pmem = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if ((void *)-1 == pmem){perror("fail mmap");return -1;}return fd;
}void draw_point(int x, int y, unsigned int col)
{if (x >= vinf.xres || y >= vinf.yres){return ;}if (vinf.bits_per_pixel == RGB888_FMT){unsigned int *p = pmem;*(p + y * vinf.xres_virtual + x) = col;}else if (vinf.bits_per_pixel == RGB565_FMT){unsigned short *p  = pmem;	*(p + y * vinf.xres_virtual + x) = col;}return ;
}void uninit_fb(int fd)
{size_t len = vinf.xres_virtual * vinf.yres_virtual * vinf.bits_per_pixel/8;munmap(pmem, len);close(fd);
}void draw_clear(unsigned int col)
{for (int j = 0; j < vinf.xres; j++){for (int i = 0; i < vinf.yres; i++){draw_point(i, j, col);}}
}void draw_h_line(int x, int y, int len, unsigned int col)
{for (int i = x; i < x+len; i++){draw_point(i, y, col);}
}
void draw_s_line(int x, int y, int len, unsigned int col)
{for (int i = y; i < y+len; i++){draw_point(x, i, col);}
}void draw_rectangle(int x, int y, int w, int h, unsigned int col)
{draw_h_line(x, y, w, col);draw_s_line(x, y, h, col);draw_s_line(x+w, y, h, col);draw_h_line(x, y+h, w, col);
}void draw_x_line(int x1, int y1, int x2, int y2, unsigned int col)
{int x = 0;int y = 0;if (x1 == x2){if (y2 > y1){draw_s_line(x1, y1, y2-y1, col);}else{draw_s_line(x2, y2, y1-y2, col);		}}double k = (double)(y2-y1)/(double)(x2-x1);double b = y1 - k*x1;for (int x = (x1 > x2 ? x2 : x1); x <= (x1 > x2 ? x1 : x2); x++){y = x * k + b;draw_point(x, y, col);}return ;
}void draw_circle(int x0, int y0, int r, unsigned int col)
{int x = 0;int y = 0;for (double si = 0; si <= 360; si+=0.01){x = r * cos(2 * 3.14159/360 *si) + x0;y = r * sin(2 * 3.14159/360 *si) + y0;draw_point(x, y, col);draw_point(x-1, y, col);draw_point(x+1, y, col);draw_point(x, y-1, col);draw_point(x, y+1, col);}}void draw_bmp(int x, int y, char *picname, int w, int h)
{int fd = open(picname, O_RDONLY);if (-1 == fd){perror("fail open bmp");return ;}lseek(fd, 54, SEEK_SET);unsigned char r, g, b;unsigned char *buff = malloc(w*h*3);read(fd, buff, w*h*3);unsigned char *p = buff;for (int j = h-1; j >= 0; j--){for (int i = 0; i < w; i++){b = *p; p++;g = *p; p++;r = *p; p++;if (vinf.bits_per_pixel == RGB888_FMT){unsigned int col = (r << 16) | (g << 8) | (b << 0);draw_point(i+x, j+y, col);}else if (vinf.bits_per_pixel == RGB565_FMT){unsigned short col = ((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0);draw_point(i+x, j+y, col);}}}free(buff);close(fd);
}void draw_word(int x, int y, unsigned char *word, int w, int h, unsigned int col)
{for (int j = 0; j < h; j++){for (int i = 0; i < w; i++){unsigned char tmp = word[i+j*w];for (int k = 0; k < 8; k++){if (tmp & 0x80){draw_point(i*8+k+x, j+y, col);}else{//文字的背景色}tmp = tmp << 1;}}}
}int draw_utf8(UTF8_INFO *info, int x, int y, char* zi, unsigned int col, unsigned int col1)
{unsigned long  out = 0 ;int ret = enc_utf8_to_unicode_one((unsigned char*)zi,&out);unsigned char* data = get_utf_data(info,out);unsigned char temp = 0 ;unsigned int i,j,k;unsigned int num = 0;for(i=0;i<info->height;i++){for(j=0;j<info->width/8;j++){temp = data[num++];for(k=0;k<8;k++){if(0x80&temp){draw_point( x+k+j*8, y+i, col);}else{//   draw_point( x+k+j*8, y+i, col1);}temp= temp<<1;}}}return ret;
}int draw_utf8_str(UTF8_INFO *info, int arg_x, int arg_y,  char* zi, unsigned int col, unsigned int col1)
{char* temp = zi;unsigned int x = arg_x ;unsigned int y =  arg_y;while(*temp != '\0'){int ret = draw_utf8(info, x, y, temp, col, col1);x += info->width;if(x > vinf.xres){x = 0;y += info->height;if(y > vinf.yres){y = 0;}}temp += ret;}return 0;
}
#include <stdio.h>
#include "framebuffer.h"// unsigned char pu[29*32/8] = {
// /*--  文字:  普  --*/// /*--  幼圆22;  此字体下对应的点阵为:宽x高=31x29   --*/
// /*--  宽度不是8的倍数,现调整为:宽度x高度=32x29  --*/
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0xF0,0x00,
// 0x3F,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xF8,0x7B,0xC0,0xF0,0x00,0x7B,0xC0,0xF0,0x00,
// 0x7B,0xFF,0xFF,0xF0,0x7B,0xFF,0xFF,0xE0,0x7B,0xDF,0xFF,0xC0,0x7B,0xFF,0xFF,0xE0,
// 0x7B,0xFC,0x01,0xE0,0x7B,0xF8,0x01,0xE0,0x7B,0xF8,0x00,0xE0,0x7B,0xFF,0xFF,0xE0,
// 0x7B,0xFF,0xFF,0xE0,0x7B,0xCF,0x07,0x00,0x7B,0xFF,0xFF,0xF8,0x7B,0xFF,0xFF,0xFC,
// 0x7B,0xFF,0xFF,0xF8,0x7B,0xFF,0xFF,0xE0,0x7B,0xFF,0xFF,0xF0,0x7B,0xF8,0x00,0xF0,
// 0x7F,0xF8,0x00,0xF0,0x7F,0xF8,0x00,0xF0,0x00,0x78,0x00,0xF0,0x00,0x3F,0xFF,0xF0,
// 0x00,0x3F,0xFF,0xE0,// };int main(int argc, const char *argv[])
{//初始化utf8字库UTF8_INFO utf8_info;bzero(&utf8_info, sizeof(UTF8_INFO));strcpy(utf8_info.path, ZIKUK_FILE_BIG);utf8_info.width = 32;utf8_info.height = 32;init_utf8(&utf8_info);int fb_fd = init_fb("/dev/fb0");if (-1 == fb_fd){return -1;}draw_clear(0x00000000);draw_point(400, 300, 0x00ff0000);draw_rectangle(100,100, 100,200, 0x00ff0000);draw_x_line(200, 200, 300, 300, 0x0000ffff);draw_x_line(200, 200, 300, 100, 0x0000ffff);draw_x_line(300, 300, 100, 100, 0x00ff00ff);draw_circle(200,200, 200, 0x00ffffff);// 	sleep(2);// 	draw_bmp(0, 0, "./res/1.bmp", 800, 600);// draw_word(100, 100, pu, 32/8, 29, 0x00ff0000);draw_utf8_str(&utf8_info, 100, 100, "水产品养殖远程监控系统", 0x00ff0000, 0x00ffffff);// 	uninit_fb(fb_fd);return 0;
}

相关文章:

  • 使用 Version Catalogs统一配置版本 (Gradle 7.0+ 特性)
  • Windows 优化及推荐工具
  • llama.cpp:纯 C/C++ 实现的大语言模型推理引擎详解一
  • Kerberos面试内容整理-在 Linux/Windows 中的 Kerberos 实践
  • 2025 Java面试大全技术文章(面试题2)
  • 文生图模型的dev、fast、full版本的区别
  • 移动端H5输入框调起手机软键盘,导致底部固定定位被顶起解决方法
  • 计算机基础知识(第三篇)
  • 力扣面试150题--二叉搜索树中第k小的元素
  • 线程池RejectedExecutionException异常
  • 用 PyQt5 打造一个可视化 JSON 数据解析工具
  • Playwright 多浏览器并行测试与数据隔离实战指南
  • 【算法设计与分析】实验——汽车加油问题, 删数问题(算法实现:代码,测试用例,结果分析,算法思路分析,总结)
  • ARM架构推理Stable Diffusiond
  • Foundation Models for Generalist Geospatial Artificial Intelligence(NASA发布Prithvi)论文阅读
  • 【运维】统信UOS操作系统aarch64自制OpenSSH 9.6p1 rpm包(含ssh-copy-id命令)修复漏洞
  • OD 算法题 B卷【代码编辑器】
  • Flotherm软件许可与硬件要求
  • 【复习】软件测试
  • RTOS:初始化新任务(含源码复杂点解读)
  • 网站建设 常见问题/营销网站都有哪些
  • 网站开发的英文/全网营销渠道
  • 寮步镇仿做网站/seo的基础优化
  • 做网站首选智投未来1/宁波正规优化seo公司
  • 作文素材/长春seo顾问
  • 虚拟服务器建网站/公司网站的作用