嵌入式Linux驱动开发(LCD屏幕专题)(二)
一、结合APP分析LCD驱动程序
1、open
app: open("/dev/fb0", ...) 主设备号: 29, 次设备号: 0
--------------------------------------------------------------
kernel:fb_open // fbmem.cstruct fb_info *info;info = get_fb_info(fbidx);if (info->fbops->fb_open) {res = info->fbops->fb_open(info,1); // 硬件相关的驱动if (res)module_put(info->fbops->owner);}
2、获得可变信息(含有分辨率等)
app: ioctl(fd, FBIOGET_VSCREENINFO, &fb_info->var);
-------------------------------------------------------------------------
kernel:fb_ioctl // fbmem.cstruct fb_info *info = file_fb_info(file);do_fb_ioctl(info, cmd, arg);var = info->var; // 硬件相关的驱动设置的ret = copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0;
3、获得固定信息(含有显存信息)
app: ioctl(fd, FBIOGET_FSCREENINFO, &fb_info->fix);
-------------------------------------------------------------------------
kernel:fb_ioctl // fbmem.cstruct fb_info *info = file_fb_info(file);do_fb_ioctl(info, cmd, arg);fix = info->fix; // 硬件相关的驱动设置的ret = copy_to_user(argp, &fix, sizeof(fix)) ? -EFAULT : 0;
4、mmap
app:void *ptr = mmap(0,fb_info->var.yres_virtual * fb_info->fix.line_length,PROT_WRITE | PROT_READ,MAP_SHARED, fd, 0);
-------------------------------------------------------------------------
kernel:fb_mmap // fbmem.cstruct fb_info *info = file_fb_info(file);start = info->fix.smem_start;len = info->fix.smem_len;return vm_iomap_memory(vma, start, len);
二、分析内核自带的LCD驱动程序
刚拿到手一款新的芯片进入目录 drivers/video/fbdev/ 目录下查看有哪些.o文件,就可以得知有没有LCD驱动程序。
LCD驱动程序核心就是:
- 分配fb_info
- 设置fb_info
- 注册fb_info
- 硬件相关的设置
2.1、入口函数注册

2.2、设备树有对应节点

三、编写硬件相关的代码
我们只需要针对IMX6ULL的编写硬件相关的代码,涉及3部分:
- GPIO设置
- LCD引脚
- 背光引脚
- 时钟设置
- 确定LCD控制器的时钟
- 根据LCD的DCLK计算相关时钟
- LCD控制器本身的设置
- 比如设置Framebuffer的地址
- 设置Framebuffer中数据格式、LCD数据格式
- 设置时序
3.1、GPIO设置
有两种方法:
- 直接读写相关寄存器
- 使用设备树,在设备树中设置pinctrl
- 本课程专注于LCD,所以使用pinctrl简化程序
设备树arch/arm/boot/dts/100ask_imx6ull-14x14.dts中:

3.2 、时钟设置
IMX6ULL的LCD控制器涉及2个时钟:

代码里直接使用时钟子系统的代码。
-
在设备树里指定频率:
-
文件:arch/arm/boot/dts/100ask_imx6ull-14x14.dts
-
代码:clock-frequency
-
display-timings {native-mode = <&timing0>;timing0: timing0_1024x768 {clock-frequency = <50000000>;
-
从设备树获得dot clock,存入display_timing
-
文件:drivers\video\of_display_timing.c
-
代码:
ret |= parse_timing_property(np, "clock-frequency", &dt->pixelclock);
-
-
使用display_timing来设置videomode
-
文件:drivers\video\videomode.c
-
代码:
-
void videomode_from_timing(const struct display_timing *dt,struct videomode *vm)
{vm->pixelclock = dt->pixelclock.typ;vm->hactive = dt->hactive.typ;vm->hfront_porch = dt->hfront_porch.typ;vm->hback_porch = dt->hback_porch.typ;vm->hsync_len = dt->hsync_len.typ;vm->vactive = dt->vactive.typ;vm->vfront_porch = dt->vfront_porch.typ;vm->vback_porch = dt->vback_porch.typ;vm->vsync_len = dt->vsync_len.typ;vm->flags = dt->flags;
}
根据videomode的值,使用时钟子系统的函数设置时钟:
- 文件:drivers\video\fbdev\mxc\ldb.c
- 代码

3.3、LCD控制器的配置
以设置分辨率为例。
-
在设备树里指定频率:
-
文件:arch/arm/boot/dts/100ask_imx6ull-14x14.dts
-
代码:clock-frequency
display-timings {native-mode = <&timing0>;timing0: timing0_1024x768 {hactive = <1024>;vactive = <600>;
-
-
从设备树获得分辨率,存入display_timing
-
文件:drivers\video\of_display_timing.c
-
代码:
ret |= parse_timing_property(np, "hactive", &dt->hactive);ret |= parse_timing_property(np, "vactive", &dt->vactive);
-
-
使用display_timing来设置videomode
-
文件:drivers\video\videomode.c
-
代码:
void videomode_from_timing(const struct display_timing *dt,struct videomode *vm) {vm->hactive = dt->hactive.typ;vm->vactive = dt->vactive.typ;
-
-
根据videomode的值,设置fb_videomode
-
文件:drivers\video\fbdev\core\fbmon.c
-
代码:
int fb_videomode_from_videomode(const struct videomode *vm,struct fb_videomode *fbmode) {unsigned int htotal, vtotal;fbmode->xres = vm->hactive;fbmode->yres = vm->vactive;
-
-
根据fb_videomode的值,设置fb_info中的var:
-
文件:drivers\video\fbdev\core\modedb.c
-
代码:
void fb_videomode_to_var(struct fb_var_screeninfo *var,const struct fb_videomode *mode) {var->xres = mode->xres;var->yres = mode->yres;
-
-
根据var的分辨率,设置寄存器
-
文件:drivers\video\fbdev\mxsfb.c
-
代码:
-
writel(TRANSFER_COUNT_SET_VCOUNT(fb_info->var.yres) |TRANSFER_COUNT_SET_HCOUNT(fb_info->var.xres),host->base + host->devdata->transfer_count);
相关文章:
嵌入式Linux驱动开发(LCD屏幕专题)(二)
一、结合APP分析LCD驱动程序 1、open app: open("/dev/fb0", ...) 主设备号: 29, 次设备号: 0 -------------------------------------------------------------- kernel:fb_open // fbmem.cstruct fb_info *info;info get_fb_info(fbidx);if (info->fbop…...
React的jsx的用法
React是一个流行的JavaScript库,用于构建用户界面。它使用一种名为JSX的语法扩展来描述组件的结构和样式。JSX是React的核心语言之一,它允许开发人员在JavaScript中编写HTML,从而使代码更加简洁和易于阅读。 JSX是一种语法扩展,它…...
Ei Scopus检索 | 2024年第四届能源与环境工程国际会议(CoEEE 2024)
会议简介 Brief Introduction 2024年第四届能源与环境工程国际会议(CoEEE 2024) 会议时间:2023年5月22日-24日 召开地点:意大利米兰 大会官网:www.coeee.org CoEEE 2024将围绕“能源与环境工程”的最新研究领域而展开,为研究人员、…...
习题练习 C语言(暑期第四弹)
自我小提升! 前言一、数组二、指针运算三、统计每个月兔子的总数四、双指针的应用五、判断指针六、珠玑妙算七、两数之和八、数组下标九、指针十、寻找峰值十一、二级指针十二、大端小端十三、无符号参数十四、数对十五、截取字符串总结 前言 重要的事说三遍&#…...
【docker快速部署微服务若依管理系统(RuoYi-Cloud)】
工作原因,需要一个比较完整的开源项目测试本公司产品。偶然发现RuoYi-Cloud非常适合,它有足够多的中间件,而且官方提供docker安装,但我本人在安装过程中遇到了很多坑,在这里记录一下防止下次会再次遇到。 项目地址 ht…...
面试求职-简历编写技巧
没有高水平简历 只有高匹配的简历 试问一下:如果一个非常牛逼的软件工程的硕士,投递市场营销岗位,结果会是什么样呢? 这位同学大概率没办法通过简历。 不是因为他不够优秀,而是因为简历和岗位不够匹配。 在公司的招…...
云原生安全性:构建可信任的云应用的最佳实践
文章目录 云原生安全性的重要性1. 数据隐私2. 恶意攻击3. 合规性要求4. 业务连续性 构建可信任的云应用的最佳实践1. 安全开发2. 身份验证与授权3. 容器安全性4. 监控与审计5. 持续集成与持续交付(CI/CD)6. 安全培训和教育 未来趋势:服务网格…...
第一章 数据库SQL-Server(及安装管理详细)
❄️作者介绍:奇妙的大歪❄️ 🎀个人名言:但行前路,不负韶华!🎀 🐽个人简介:云计算网络运维专业人员🐽 前言 21 世纪,人类迈入了“信息爆炸时代”,…...
chrome extension无法获取window对象
背景见上一篇博客修改网页内容的方法 上一篇博客之后,我要修改的网页有一个新改版,然后有个数据存在了window中,我直接在js中使用window.xxx发现无法获取。所以有本文。 https://juejin.cn/post/7145749643316428830 https://onelinerhub.com…...
在linux虚拟机上安装docker(我的实践)
参考文章: https://blog.csdn.net/qq_29479041/article/details/82659218 步骤: 1.安装docker 参考文章: https://blog.csdn.net/qq_29479041/article/details/82659218 https://blog.csdn.net/qq_38345468/article/details/110128659 2.…...
Spring之事务开发
什么是事务? 事务是指数据库管理系统中的一个执行单位或一个逻辑工作单元,它由一个或多个数据库操作序列组成。事务具有以下四个特性,通常被称为ACID特性: 原子性(Atomicity):事务是一个不可分…...
干了三年的功能测试,让我女朋友跑了,太难受了...
简单概括一下 先说一下自己的情况,普通本科,19年通过校招进入深圳某软件公司,干了3年多的功能测试,21年的那会,因为大环境不好,我整个人心惊胆战的,怕自己卷铺盖走人了,我感觉自己不…...
JavaScript函数的使用
前言 程序中的foo、bar、baz 在学习编程的过程中,你可能会经常看到foo、bar、baz这些名词: 它们通常被用来作为函数、变量、文件的名词;目前已经编程了计算机编程的术语一部分;但是它们本身并没有特别的用途和意义;…...
【算法】Java-使用数组模拟单向链表,双向链表
目录 试题1:实现一个单链表,并实现以下功能: 试题2:实现一个双链表,并实现以下功能 思路总结: 什么情况下可能涉及到用数组实现链表呢? 在学习时了解到了可以用数组模拟链表,使其…...
Nessus简单介绍与安装
Nessus简单介绍与安装 1.Nessus简介 Nessus号称是世界上最流行的漏洞扫描程序,全世界有超过75000个组织在使用它。该工具提供完整的电脑漏洞扫描服务,并随时更新其漏洞数据库。Nessus不同于传统的漏洞扫描软件,Nessus可同时在本机或远端上遥…...
【每天一道算法题】day2-认识时间复杂度
认识时间复杂度: O:读作big O,在数学上指的是上限的意思 常数时间的操作 一个操作如果和样本的数据量没有关系,每次都是固定时间内完成的操作,叫做常数操作。时间复杂度为一个算法流程中,常数操作数量的一…...
前端报错合集
error Component name “index“ should always be multi-word vue/multi-word-component-names 的解决办法 原因组件命名是 没有采用驼峰 error Component name “index“ should always be multi-word vue/multi-word-component-names 的解决办法_error component name &qu…...
Milvus以及Web UI 安装
向量数据库懂的都懂 版本数据 [rootiZ7xv7q4im4c48qen2do2bZ project]# cat /etc/redhat-release CentOS Stream release 9 [rootiZ7xv7q4im4c48qen2do2bZ project]# docker version Client: Docker Engine - CommunityVersion: 24.0.5API version: 1.43Go v…...
Go for循环中的defer
背景 写个后台程序,定时抓取服务器指标,代码逻辑如下,使用一段时间后内存不断增加 func CollectInfo() {for {// 获取服务器信息代码// ...............resp, err : http.Post("http://server", "application/json", str…...
创建开机自启的脚本
在启动许多ros节点时有多种方式,我推荐使用launch来启动所有的节点,这也是一种规范的方式。以后会慢慢向这个方向靠。 除此之外还可以通过创建的脚本来启动: 脚本位置不限,只需要: sudo gedit xxx.sh在里面添加相应的…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
