在虚拟机ubuntu上修改framebuffer桌面不能显示图像

目录

一、测试程序

二、排查原因

三、为什么 Xorg 会导致程序无法工作?


一、测试程序

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>static int width; //LCD X 分辨率
static int height; //LCD Y 分辨率
static unsigned int *screen_base = NULL; //映射后的显存基地址
/********************************************************************
* 函数名称: lcd_draw_point
* 功能描述: 打点
* 输入参数: x, y, color
* 返 回 值: 无
********************************************************************/
static void lcd_draw_point(unsigned int x, unsigned int y, unsigned int color)
{/* 对传入参数的校验 */if (x >= width)x = width - 1;if (y >= height)y = height - 1;/* 填充颜色 */screen_base[y * width + x] = color;
}
/********************************************************************
* 函数名称: lcd_draw_line
* 功能描述: 画线(水平或垂直线)
* 输入参数: x, y, dir, length, color
* 返 回 值: 无
********************************************************************/
static void lcd_draw_line(unsigned int x, unsigned int y, int dir,
unsigned int length, unsigned int color)
{unsigned int end;unsigned long temp;/* 对传入参数的校验 */if (x >= width)x = width - 1;if (y >= height)y = height - 1;/* 填充颜色 */temp = y * width + x;//定位到起点if (dir) { //水平线end = x + length - 1;if (end >= width)end = width - 1;for ( ; x <= end; x++, temp++)screen_base[temp] = color;}else { //垂直线end = y + length - 1;if (end >= height)end = height - 1;for ( ; y <= end; y++, temp += width)screen_base[temp] = color;}
}
/********************************************************************
* 函数名称: lcd_draw_rectangle
* 功能描述: 画矩形
* 输入参数: start_x, end_x, start_y, end_y, color
* 返 回 值: 无
********************************************************************/
static void lcd_draw_rectangle(unsigned int start_x, unsigned int end_x,
unsigned int start_y, unsigned int end_y,
unsigned int color)
{int x_len = end_x - start_x + 1;int y_len = end_y - start_y - 1;lcd_draw_line(start_x, start_y, 1, x_len, color);//上边lcd_draw_line(start_x, end_y, 1, x_len, color); //下边lcd_draw_line(start_x, start_y + 1, 0, y_len, color);//左边lcd_draw_line(end_x, start_y + 1, 0, y_len, color);//右边
}
/********************************************************************
* 函数名称: lcd_fill
* 功能描述: 将一个矩形区域填充为参数 color 所指定的颜色
* 输入参数: start_x, end_x, start_y, end_y, color
* 返 回 值: 无
********************************************************************/
static void lcd_fill(unsigned int start_x, unsigned int end_x,
unsigned int start_y, unsigned int end_y,
unsigned int color)
{unsigned long temp;unsigned int x;/* 对传入参数的校验 */if (end_x >= width)end_x = width - 1;if (end_y >= height)end_y = height - 1;/* 填充颜色 */temp = start_y * width; //定位到起点行首for ( ; start_y <= end_y; start_y++, temp+=width) {for (x = start_x; x <= end_x; x++)screen_base[temp + x] = color;}
}int main(int argc, char *argv[])
{struct fb_fix_screeninfo fb_fix;struct fb_var_screeninfo fb_var;unsigned int screen_size;int fd;/* 打开 framebuffer 设备 */if (0 > (fd = open("/dev/fb0", O_RDWR))) {perror("open error");exit(EXIT_FAILURE);}/* 获取参数信息 */ioctl(fd, FBIOGET_VSCREENINFO, &fb_var);ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix);printf("Solution: %d*%d\n""pixel depth bpp: %d\n""Number of bytes in a row: %d\n""Pixel format: R<%d %d> G<%d %d> B<%d %d> A<%d %d>\n",fb_var.xres, fb_var.yres, fb_var.bits_per_pixel,fb_fix.line_length,fb_var.red.offset, fb_var.red.length,fb_var.green.offset, fb_var.green.length,fb_var.blue.offset, fb_var.blue.length, fb_var.transp.offset, fb_var.transp.length);screen_size = fb_fix.line_length * fb_var.yres;width = fb_fix.line_length / (fb_var.bits_per_pixel / 8);height = fb_var.yres;/* 将显示缓冲区映射到进程地址空间 */screen_base = mmap(NULL, screen_size, PROT_WRITE, MAP_SHARED, fd, 0);if (MAP_FAILED == (void *)screen_base) {perror("mmap error");close(fd);exit(EXIT_FAILURE);}/* 画正方形方块 */int w = height * 0.25;//方块的宽度为 1/4 屏幕高度lcd_fill(0, fb_var.xres-1, 0, height-1, 0x0); //清屏(屏幕显示黑色)lcd_fill(0, w, 0, w, 0xFF0000); //红色方块lcd_fill(fb_var.xres-w, fb_var.xres-1, 0, w, 0xFF00); //绿色方块lcd_fill(0, w, height-w, height-1, 0xFF); //蓝色方块lcd_fill(fb_var.xres-w, fb_var.xres-1, height-w, height-1, 0xFFFF00);//黄色方块/* 画线: 十字交叉线 */lcd_draw_line(0, height * 0.5, 1, fb_var.xres, 0xFFFFFF);//白色线lcd_draw_line(fb_var.xres * 0.5, 0, 0, height, 0xFFFFFF);//白色线/* 画矩形 */unsigned int s_x, s_y, e_x, e_y;s_x = 0.25 * fb_var.xres;s_y = w;e_x = fb_var.xres - s_x;e_y = height - s_y;for ( ; (s_x <= e_x) && (s_y <= e_y);s_x+=5, s_y+=5, e_x-=5, e_y-=5)lcd_draw_rectangle(s_x, e_x, s_y, e_y, 0xFFFFFF);/* 退出 */munmap(screen_base, screen_size); //取消映射close(fd); //关闭文件exit(EXIT_SUCCESS); //退出进程
}

执行结果:

lientek@ubuntu:/home/linux_test/lcd$ sudo ./demo 
Solution: 800*600
pixel depth bpp: 32
Number of bytes in a row: 4704
Pixel format: R<16 8> G<8 8> B<0 8> A<0 0>

桌面无图形绘制效果

二、排查原因

        程序无法在虚拟机的 Ubuntu 桌面上绘制图形,主要原因在于现代 Linux 桌面环境(如 Ubuntu 使用的 GNOME、Unity 等)通常运行在 X Window 系统或 Wayland 等显示服务器上,而程序直接操作了/dev/fb0(帧缓冲设备),这在桌面环境中存在一些兼容性问题。

        显示服务器冲突:在桌面环境中,Xorg 或 Wayland 已经独占了帧缓冲设备,普通用户程序无法直接访问/dev/fb0进行绘图

确定当前使用的是 Xorg 还是 Wayland:

alientek@ubuntu:/home/linux_test/lcd$ echo $XDG_SESSION_TYPE
x11

三、为什么 Xorg 会导致程序无法工作?

Xorg 作为显示服务器,会独占 /dev/fb0 设备来管理桌面显示。当 Xorg 运行时:

  1. 它会优先打开并锁定 /dev/fb0,程序虽然可能成功 open("/dev/fb0")(取决于权限),但写入的内容会被 Xorg 的桌面渲染覆盖(因为 Xorg 会持续刷新屏幕)。

  2. 程序直接操作显存的像素数据,但 Xorg 有自己的渲染管线(如通过显卡驱动、窗口管理器等),两者的绘制逻辑冲突,导致你的图形无法显示在桌面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/93673.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/93673.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

语言模型的评估指标整理

语言模型&#xff08;Language Models&#xff09;是自然语言处理&#xff08;NLP&#xff09;的核心组件&#xff0c;广泛应用于机器翻译、文本生成、对话系统等领域。随着模型复杂度的提升&#xff0c;如何科学、系统地评估模型性能变得至关重要。评估指标不仅帮助我们理解模…

【开发技术】.Net中配置Serilog日志分级记录

目录 一、目的 二、解决方案 2.1 下载serilog包 2.2 Serilog配置 2.2.1 使用多个File sink配置不同的最小日志级别 2.2.2 使用Filter条件分流到不同文件 三、使用建议 四、文章总结 一、目的 在日常开发中&#xff0c;需要根据不同的场景去记录日志&#xff0c;根据实际…

聊聊如何判断发现的缺陷属于前后端

目录 一、观察缺陷现象 二、检查网络请求&#xff08;核心方法&#xff09; 三、模拟请求验证后端 四、查看日志 五、数据流分析 六、判断前后端缺陷方法 判断发现的缺陷是前后端&#xff0c;可以通过观察缺陷现象&#xff0c;检查网络请求&#xff0c;查看后端日志&…

Python3与MySQL的PyMySQL连接与应用

Python3与MySQL的PyMySQL连接与应用 引言 随着互联网技术的飞速发展,数据库在各个领域的应用日益广泛。MySQL作为一种开源的关系型数据库管理系统,因其稳定性和高效性,被广泛应用于各种场景。Python作为一种高级编程语言,以其简洁、易读、易学等特点,受到了广大开发者的…

智慧城市SaaS平台|市政公用管理系统

【道路监测运维系统】1.数据可视化a) 实时监控支持对道路监测数据进行分析评估&#xff0c;为道路养护、交通管理、环境保护等提供数据支撑2.道路基础设施监测支持对道路基础设施的运行状态进行实时监测&#xff0c;包括路面状况3.交通流量监测支持对道路交通流量进行实时监测&…

Maven 配置阿里云镜像加速

Maven 配置阿里云镜像加速&#xff1a; 完整配置步骤&#xff08;Windows 系统&#xff09; 1. 找到 Maven 的 settings.xml 文件 全局配置&#xff1a;D:\software\apache-maven-3.9.11\conf\settings.xml用户配置&#xff1a;C:\Users\Admin\.m2\settings.xml&#xff08;推荐…

去除视频字幕 3 : 继续研究 IOPaint,记录几个问题

1. 为什么单独运行&#xff0c;效果很好&#xff0c;批量运行&#xff0c;效果很差。 1. 我运行 iopaint start --modellama --devicecuda --port8080在浏览器中单独选择图片&#xff0c;涂选区域&#xff0c;然后处理&#xff0c;此时的效果非常好。2. 但是我进行 iopaint ru…

【深度之眼机器学习笔记】04-01-决策树简介、熵,04-02-条件熵及计算举例,04-03-信息增益、ID3算法

1. 决策树与熵 1.1 决策树简介 下面有一个贷申请样本表&#xff0c;有许多特征 我们根据特征数据生成一棵树&#xff0c;比如年龄有青年&#xff0c;中年&#xff0c;老年三个类别&#xff0c;那么就有三个分支&#xff0c;分别对应着三种类别。如果是青年那么就看工作&#xf…

八股文场景题

如何预估接口上线后的 QPS 问题引入 这个问题其实是一个非常实际的问题&#xff0c;因为我们在开发需求后&#xff0c;例如&#xff1a;新增了一个接口 有一个步骤是值得做的&#xff0c;那就是预估这个接口的QPS 因为我们是可以去调配对应服务器的数量和运行配置的 例如我…

【Web安全】深入浅出理解“SQL注入-伪静态注入”及空格限制绕过技巧

文章目录什么是伪静态注入&#xff1f;伪静态注入中如何绕过空格限制&#xff1f;1. 用注释符替代空格2. 用不可见字符&#xff08;URL 编码&#xff09;替代3. 用括号分隔语句4. 用特殊符号替代核心逻辑往期文章【Web安全】一次性搞懂 ReDOS 漏洞原理/检测/防御 【Web安全】一…

【读论文】Step-Audio 2 深度解读:迈向工业级语音交互的「全能型选手」

引言:step-Audio升级 语音交互技术,作为人机交互最自然、最直接的方式之一,正以前所未有的速度发展。从简单的语音指令到流畅的语音对话,我们对 AI 的期望越来越高。然而,要让 AI 真正成为我们的“知心伙伴”,仅仅能“听懂”和“说出”还远远不够。 一个理想的语音 AI,…

java web 重定向

目录结构 demo\day20\src\com\demo\service\Dome1.javademo\day20\src\com\demo\service\Dome2.javademo\day20\src\com\demo\service\Dome3.javademo\day20\src\com\demo\service\Dome4.javademo\day20\web\WEB-INF\lib\javax.servlet.jardemo\day20\web\index.jspdemo\day20\…

MySQL(配置)——MariaDB使用

一、简介 MariaDB 和 MySQL 作为两个流行的关系型数据库管理系统&#xff0c;它们的区别可以从多个角度来探讨。尽管 MariaDB 最初是 MySQL 的一个分支&#xff0c;但随着时间的推移&#xff0c;它们逐渐在功能、性能和开发方向上有所不同。MariaDB 是 MySQL 的一个分支&#x…

Web3:赛道划分与发展趋势解析

区块链技术现在已经从单一的加密货币支付系统发展为涵盖金融、艺术、组织治理和社区文化的多元生态系统。这次我们将深入解析 DeFi&#xff08;去中心化金融&#xff09;、NFT&#xff08;非同质化代币&#xff09;、DAO&#xff08;去中心化自治组织&#xff09;与 MEME&#…

LeetCode 283 - 移动零

思路 使用双指针法&#xff0c;一次遍历完成原地修改。 慢指针 slow&#xff1a;指向下一个非零元素应该被放置的位置。快指针 fast&#xff1a;遍历整个数组&#xff0c;寻找非零元素。 当 fast 遇到非零数时&#xff0c;将其值赋给 slow 指向的位置&#xff0c;然后 slow 前进…

8. 网络层

在复杂的网络环境中确定一个合适的路径.1. IP协议1. 基本概念IP协议&#xff1a;提供一种能力(有非常大的概率&#xff0c;做到某事)&#xff0c;把数据报从主机A&#xff0c;跨网络&#xff0c;送到主机B --> 必须要有方式&#xff0c;标识通信两端唯一性&#xff01;&…

【通识】线性代数(Linear Algebra)

线性代数被广泛应用于抽象代数和泛函分析中&#xff1b;通过解析几何&#xff0c;线性代数能被具体表示&#xff0c;线性代数被泛化为算子理论。而非线性模型被近似为线性模型&#xff0c;应用场景多为自然科学和社会科学。 费马和笛卡尔的工作&#xff0c;线性代数出现于十七世…

Qt 嵌入式界面优化技术

在嵌入式系统中&#xff0c;界面性能直接影响用户体验和系统稳定性。由于嵌入式设备通常资源受限&#xff08;如低性能 CPU、有限内存、小尺寸屏幕&#xff09;&#xff0c;需针对性优化 Qt 界面以实现流畅显示和高效交互。本文从渲染引擎、资源管理、布局优化到硬件加速&#…

去除视频字幕 4 : 下一步,打算研究 Video Inpainting (视频修复):

就是说&#xff0c;到现在&#xff0c;才算是真正开始&#xff0c;才发现真正的问题。 尝试去除视频上的字幕&#xff0c;使用 IOPaint, 效果很初级。。。问题描述 请帮我分析此时的效果。 此时的右侧字幕区域&#xff0c;闪烁不停&#xff01;我原本以为效果会很好。实际非常…

代码随想录算法训练营第五十五天|图论part5

并查集理论基础 初始化: void init() {for (int i 0; i < n; i) {father[i] i;} } 寻根&#xff1a; // 并查集里寻根的过程 int find(int u) {return u father[u] ? u : father[u] find(father[u]); // 路径压缩 } 判断u跟v是否同根 // 判断 u 和 v是否找到同一个根 b…