linux笔记(7):东山哪吒D1H使用framebuffer控制HDMI直线

news2025/1/16 20:55:28

文章目录

  • 1.测试流程和结果
    • 1.1 使能HDMI
    • 1.2 framebuffer操作流程
    • 1.3 测试结果
  • 2.测试过程详述
    • 2.1 编译源码
    • 2.2上传可执行文件
    • 2.3修改文件的权限,执行文件
  • 3.源码解释
    • 3.1 HDMI使用的颜色格式是ARGB
  • 4.源码工程链接

这部分linux笔记是记录我入门的过程,内容基本都是照着别人的文章,自己操作一遍,重走一次别人走过的路。
参考文章:
1.作者:闪耀大叔,文章《 嵌入式Linux入门-Framebuffer应用编程在Linux系统下画个点》。

1.测试流程和结果

1.1 使能HDMI

我前2天想把韦东山老师的《buildroot_dongshannezhastu》工程改成启动时有HDMI输出,结果没有成功。只能先利用上一篇文章的方法启动HDMI《linux笔记(6):东山哪吒D1H测试HDMI显示内置图片-命令行调试》。

1.2 framebuffer操作流程

1.打开设备节点:open(“/dev/fb0”, O_RDWR)

2.获取LCD参数:ioctl(fd_fb, FBIOGET_VSCREENINFO, &var)

3.映射Framebuffer:mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0)

4.操作Framebuffer

5.取消映射 munmap (fb_base, screen_size)

6.关闭设备节点 close(fd_fb)

1.3 测试结果

在屏幕上描出不同颜色:
在这里插入图片描述

2.测试过程详述

2.1 编译源码

把源码fb001 – https://gitee.com/huangweide001/linux-d1-h-test/tree/master/fb001 下载下来,进入工程,直接使用 make 命令编译。

2.2上传可执行文件

我上传应用程序到开发板的步骤是不是太复杂?
在这里插入图片描述

2.3修改文件的权限,执行文件

> chmod 777 test
> ./test
1.open /dev/fb0
2.get V Screen INFO
width:800,hight:1280,bits_per_pixel:32
3.get framebuffer base address
fb_base:0xf1f6f000
4.flush screen in different colors
5.draw 30 lines in different colors

3.源码解释

3.1 HDMI使用的颜色格式是ARGB

可以参考这个文章《ARGB与RGB区别及透明度和RGB颜色对照表》。
ARGB从表面看比RGB多了个A,也是一种色彩模式,是在RGB的基础上添加了Alpha(透明度)通道。透明度也是以0到255表示的,所以也是总共有256级,透明是0,不透明是255。
用十六进制的格式来表示ARGB就是:0xAARRGGBB。
东山哪吒开发板的HDMI驱动使用的是ARGB,如果直接使用RGB格式,相当于ARGB的透明格式,显示出来是黑色的。
比如上面的参考文章使用的是RGB格式:
在这里插入图片描述
我画30条线使用的30种颜色数据:
在这里插入图片描述
举个例子,要正常显示红色(0x00FF0000),要使表示透明度的字节不为0.上面的A=0xFF和A=0x7F都可以正常显示。

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <linux/fb.h>
#include <unistd.h>
 
static int fd_fb;
static struct fb_var_screeninfo var;	/* Current var */
static int screen_size;
static unsigned char *fb_base;
static unsigned int line_width;
static unsigned int pixel_width;
 
void lcd_put_pixel(int x, int y, unsigned int color)
//传入的 color 表示颜色,它的格式永远是 0x00RRGGBB,即 RGB888。
//当 LCD 是 16bpp 时,要把 color 变量中的 R、 G、 B 抽出来再合并成 RGB565 格式。
{
    unsigned char *pen_8 = fb_base+y*line_width+x*pixel_width;
    //计算(x,y)坐标上像素对应的 Framebuffer 地址。
 
    unsigned short *pen_16;
    unsigned int *pen_32;
    
    unsigned int red, green, blue;
    
    pen_16 = (unsigned short *)pen_8;
    pen_32 = (unsigned int *)pen_8;

    switch (var.bits_per_pixel)
    {
      //对于 8bpp, color 就不再表示 RBG 三原色了,这涉及调色板的概念, color 是调色板的值。
        case 8:
            {
                *pen_8 = color;
                break;
            }
        case 16:
            {
                //  R5 G6 B5 
                //先从 color 变量中把 R、 G、 B 抽出来。
                red = (color >> 16) & 0xff;
                green = (color >> 8) & 0xff;
                blue = (color >> 0) & 0xff;
                //把 red、 green、 blue 这三种 8 位颜色值,根据 RGB565 的格式,
                //只保留 red 中的高 5 位、 green 中的高 6 位、 blue 中的高 5 位,
                //组合成一个新的 16 位颜色值。
                color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
                //把新的 16 位颜色值写入 Framebuffer
                *pen_16 = color;
                break;
            }
        case 32:
            {
                //对于 32bpp,颜色格式跟 color 参数一致,可以直接写入Framebuffer
                *pen_32 = color;
                break;
            }
        default:
            {
                printf("can't surport %dbpp\n",var.bits_per_pixel);
                break;
            }
     }
}

void    blushScreen2(unsigned int color)
{// 这里只考虑24色,也就是HDMI的情况
    unsigned int * p32=(unsigned int *)fb_base;
    unsigned int h,w;
    for(h=0;h<var.yres;h++)
        for(w=0;w<var.xres;w++){
            *p32= color;
            p32++;
        } 
}
int main(int argc,int **argv)
{	
	int i;
    
	printf("1.open /dev/fb0\n");
	fd_fb = open("/dev/fb0", O_RDWR);
	if (fd_fb < 0)
	{
		printf("can't open /dev/fb0\n");
		return -1;
	}	
	printf("2.get V Screen INFO\n");
	if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
	{
		printf("can't get var\n");
		return -1;
	}
	
	line_width = var.xres * var.bits_per_pixel / 8;
	pixel_width = var.bits_per_pixel / 8;
	screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
    printf("width:%d,hight:%d,bits_per_pixel:%d\n",var.xres,var.yres,var.bits_per_pixel);
	
	printf("3.get framebuffer base address\n");
	fb_base = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
	if (fb_base == (unsigned char *)-1)
	{
		printf("can't mmap\n");
		return -1;
	}else{        
		printf("fb_base:0x%8x\n",fb_base);
    }
    unsigned char colorData[10]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xff};

    unsigned int cData[30] = {0xFFFF0000,0xFF00FF00,0xFF0000FF,
                            0xFFFFFF00,0xFFFF00FF,0xFF00FFFF,
                            0xFF7F7F7F,0xFF007F7F,0xFF7F007F,0xFF7F7F00,//  0-9     FF开头
                            0x7FFF0000,0x7F00FF00,0x7F0000FF,
                            0x7FFFFF00,0x7FFF00FF,0x7F00FFFF,
                            0x7F7F7F7F,0x7F007F7F,0x7F7F007F,0x7F7F7F00,//  10-19   7F开头
                            0x00FF0000,0x0000FF00,0x000000FF,
                            0x00FFFF00,0x00FF00FF,0x0000FFFF,
                            0x007F7F7F,0x00007F7F,0x007F007F,0x007F7F00};//  20-29  00开头
          
	printf("4.flush screen in different colors\n");                      
    for(i = 0;i<10;i++)
    {
        memset(fb_base,colorData[i],screen_size );
        sleep(1);//usleep(100*1000);
    }
	printf("5.draw 30 lines in different colors\n"); 
    for (int j = 0; j < 30;j++){
	    for (i = 0; i < 100; i++)	{
            lcd_put_pixel(var.xres/3+i, var.yres/4+20*j+0, cData[j] );
            lcd_put_pixel(var.xres/3+i, var.yres/4+20*j+1, cData[j] );
            lcd_put_pixel(var.xres/3+i, var.yres/4+20*j+2, cData[j] );
            lcd_put_pixel(var.xres/3+i, var.yres/4+20*j+3, cData[j] );
        }
    }
    munmap (fb_base, screen_size);            
	close(fd_fb);
	return 0;
}

4.源码工程链接

源码工程fb001

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

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

相关文章

【Flutter】【widget】Table 表格widget

文章目录前言一、Table 是什么&#xff1f;二、使用步骤1.Table 基础使用2.宽度3.设置边框4.TableCell设置单元格式widget等其他设置总结前言 Table 表格widget&#xff0c;其实很少使用到的&#xff0c;等有需要的时候在查看该widget 一、Table 是什么&#xff1f; 表格widg…

Trino源码Gitlab CICD单测环境建设

在中大型公司&#xff0c;由于对Presto源码的定制魔改量越来越大&#xff0c;会随着时间推移而增大出现冷门bug的概率&#xff0c;所以建立一套自动测试机制&#xff0c;在魔改源码合入主分支时可以自动触发test case&#xff0c;通过特定单测的执行失败&#xff0c;来更清晰的…

多云管理产品组合VMware Aria,开启多云管理新篇章

今年8月份&#xff0c;VMware Explore美国大会上宣布了多云管理产品组合VMware Aria&#xff0c;宣布之后&#xff0c;市场上关注度非常高&#xff0c;而且受到了热捧。Aria这个名字动听且贴切&#xff0c;中文意思是 “咏叹调”&#xff0c;也就是说要用统一的、一致的曲调来歌…

big.LITTLEDynamIQ

最近看到了DynamIQ&#xff0c;于是来了解一下什么是DynamIQ&#xff1f; 前言 首先要知道DynamIQ&#xff0c;那么你肯定得知道big.LITTLE。因为DynamIQ可以说是big.LITTLE新一代或者是升级版。 那么在这之前你肯定得知道什么是big.LITTLE&#xff1f; 然后知道了后你就会…

旋转框目标检测mmrotate v0.3.1 训练DOTA数据集(三)——配置文件优化技巧

1、 目标检测比赛中的tricks DOTAv2遥感图像旋转目标检测竞赛经验分享&#xff08;Swin Transformer Anchor free/based方案&#xff09; 目标检测比赛中的tricks&#xff08;已更新更多代码解析&#xff09; 水下目标检测算法赛解决方案分享 | 2020年全国水下机器人&#xf…

基于布谷鸟搜索混合灰狼优化算法求解单目标优化问题(AGWOCS)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

【工具】typora的一些配置

文章目录1. 自动编号1.1 大纲编号1.2 目录编号3. 正文部分2. 自定义快捷键1. 自动编号 我们在查看文档时候&#xff0c;希望编译器能够自动根据标题样式按顺序编号&#xff0c;不需要用户自行添加相应标题。这样也方便用户随时更新文档时候不会因为修改了某个编号而要去修改其…

分享3个文字配音软件,帮助你们轻松制作短视频

有没有刚踏入自媒体行业的小伙伴呀&#xff1f;那你们是不是为视频的后期工作所困惑着呢&#xff1f; 大家平时刷到的视频虽然看起来简短又有趣&#xff0c;但其实后期制作并没那么简单&#xff0c;是由许多道工序环环相扣而成的&#xff0c;其中比较重要的&#xff0c;就是为视…

JavaEE进阶:Spring 更简单的读取和存储对象

文章目录前言一、存储 Bean 对象1、前置⼯作&#xff1a;配置扫描路径&#xff08;重要&#xff09;2、添加注解存储 Bean 对象① Controller&#xff08;控制器存储&#xff09;② Service&#xff08;服务存储&#xff09;③ Repository&#xff08;仓库存储&#xff09;④ C…

栈的实现.

文章目录1.栈的概念及结构2.栈的实现&#xff08;数组实现&#xff09;2.1栈头文件2.2函数实现3.栈的习题3.1有效的括号3.1.1思路分析3.1.2代码实现1.栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删…

Qt第二十一章:Qt Designer 之 布局

简单场景&#xff1a;页面上放一个QTextEdit控件 预览后发现&#xff0c;拖拽放大窗口&#xff0c;QTextEdit控件不会进行缩放&#xff0c;就像下边自适应缩放 我们看到了QTextEdit控件撑满了整个界面&#xff1a;在控件sizePolicy属性的允许范围中尽可能的撑满界面。 如果换成…

基于h5的风云网球网站的设计

目 录 1绪 论 1 1.1 选题背景及意义 1 1.2 国内外研究现状 2 1.3本章小结 2 2 前端开发及相关技术 4 2.1 HTML5前端开发环境 4 2.2 HTML5前端开发工具 4 2.3 HTML5前端开发相关技术 5 2.3.1 javascript简介 5 2.3.2 javascript基本特点 5 2.3.3 css简介 6 2.3.4 jQuery 7 2.4 本…

Python精髓之括号家族:方括号、花括号和圆括号,你真的会用吗?

Python独一无二的特色除了缩进还有哪些特色呢&#xff1f;大多数的回答一定是 语法简洁、简单易学、代码高效、功能强大四项。那究竟是Python的哪些语言特性使得人们普遍认为Python具有这些特点呢&#xff1f;其实很大程度上&#xff0c;这要归功于列表&#xff08;list&#x…

公众号免费题库使用方法

公众号免费题库使用方法 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 题库&#xff1a;题库后台&#xff08;点击跳转&#xf…

haoop启动正常,但上不去网页hadoop102:9870

haoop启动正常&#xff0c;但上不去网页hadoop102:9870 症状如下: hadoop启动正常&#xff0c;jps正常 网页上不去 查下cmd&#xff0c;ping不通 解决方法 一、 先查hdfs 命令&#xff1a;vim /opt/module/hadoop-3.1.3/etc/hadoop/hdfs.site.xml 二、查hosts&#xff0c;我就是…

Redis实战篇(五)好友关注

1、点赞 ------------ Set 2、点赞排行 ------SortedSet 3、共同关注 -------set sinter 一、共同关注 Overridepublic Result followCommons(Long id) {// 1.获取当前用户Long userId UserHolder.getUser().getId();String key "follows:" userId;// 2.求交集St…

Gradle (史上最全): 5W字文

Gradle是绕不开的一个构建工具 对于用惯了 maven的人来说&#xff0c; Graddle不好用&#xff0c; 非常不好用&#xff0c; 主要是环境 会遇到各种各样的问题 但是&#xff0c;越来越多的 场景使用到了 Graddle&#xff0c;但是 spring 的源码&#xff0c;使用 Gradle 构建 …

【Fiddler】安卓7.0以上添加Fiddler/Charles证书到系统根证书(模拟器-雷电)

目录 一、安装工具 1、安装open-ssl 2、配置环境变量 3、验证安装 二、Fiddler 1、导出证书 2、转化cer格式变成PEM 3、查看PEM的哈希值 三、Charles 1、导出证书 2、查看PEM的哈希值 四、证书安装到安卓模拟器 &#xff08;雷电&#xff09; 1、使用模拟器的adb命令 2、…

【实战案例】——实战渗透某不法网站

作者名&#xff1a;Demo不是emo 主页面链接&#xff1a;主页传送门 创作初心&#xff1a;舞台再大&#xff0c;你不上台&#xff0c;永远是观众&#xff0c;没人会关心你努不努力&#xff0c;摔的痛不痛&#xff0c;他们只会看你最后站在什么位置&#xff0c;然后羡慕或鄙夷座…

RPA-机器人流程自动化

RPA-机器人流程自动化RPA-机器人流程自动化简介RPA是什么&#xff1f;RPA历史上的演变RPA原理RPA特点RPA技术框架及功能1.TagUI2.RPA for Python3.Robot Framework4.Automagica5.Taskt6.OpenRPARPA部署模式1 环境配置的参数调整2 将自动化程序整体打包部署3 版本的管理和控制机…