LCD/HDMI OUT调试经验(2)------驱动流程与基本操作

本章先接上章描述一下LCD/HDMI OUT在开机过程中显示的流程,并介绍一些UEFI阶段的权限配置与屏幕参数配置,最后是一些需要掌握的驱动中常添加功能。

注意:本文从内核开发角度介绍,接触到上层后本文一些概念不适用

 

一、BP侧文件的配置及程序流程

我们调试的机器开机大致可分为两个阶段,UEFI阶段以及kernel阶段,UEFI阶段类似于一段程序的初始化,而kernel阶段就是程序在执行功能函数。

b786fd1bf93c4552885dfcce69732502.png

上图为UEFI的运行流程,包括初始化和引导操作系统,最后进入kernel系统。

对应到项目文件,大体可以把BP的文件中的一些操作对应UEFI阶段,而AP对应kernel;对于内核调试的同事来说,BP侧管理一些权限与配置类的文件,当然因为它开机就会执行,所以一些kernel阶段的功能也可以提前实现,比如本来在kernel阶段才能让屏幕显示画面,可以把原本在AP的代码移植到BP,让它开机就显示画面。

 

(1)BP侧的权限问题

在本节主要说明模块一些引脚的权限。你可以把BP当作一位管理者,而AP是一位执行者,管理者规定一些规则,执行者在规则内执行任务,在引脚权限上就可以充分体现。

我们所用的模块比如高通sdm845总共就一百多个引脚,需要控制不同外设和实现不同功能,这就需要合理利用与释放引脚。在bp侧sdm845_Android10_BP\trustzone_images\core\settings\buses\qup_accesscontrol\hoya\config\QUPAC_845_Access.c这个文件中,管理了一些引脚的权限,如果不打开一些引脚的权限,在AP侧使用时就会导致重启或者进dump。

在文件的qupv3_perms_default的常量中

b884ce8ecfb84598bf8681cd8ed11884.png

定义了一些se组与其对应的权限,se组号可以问硬件同事确定或者根据AP中pinctrl的定义来确定。se不同组代表了不同的桥接芯片,北桥是0-7,也就是qupv3_0_se0到qupv3_0_se7,东桥是0-5,也就是qupv3_1_se0到qupv3_1_se5,南桥是0-5,也就是qupv3_2_se0到qupv3_2_se5。比如上一章节的9611设备树为se14,并且该组脚是用作i2c通信,就需要在常量另起一行(如果已配,不需要自己写)定义QUPV3_2_se0(注意AP BP两侧都是从0开始数,se14代表第15组se,那可以从北桥开始数第十五个),后面配上QUPV3_PROTOCLO_I2C。 后面几个参数代表这几组的权限,如果需要用作普通的引脚随时可以控制的话就配成

QUPV3_MODE_FIFO,AC_HLOS,      TRUE,TRUE,FALSE。

 

ca093ea17b644eb2b661172e029a7d18.png

上图为确定SE组的另一种方法,注意不同文件的第一组的序号是1还是0。文件位置为sdm845_Android10_BP\boot_images\QcomPkg\SDM845Pkg\Settings\I2C\core\i2c_devcfg.c,平台不同,位置不同,有时候是core文件夹有时候是loader,如果需要对其做修改,保险一些可以两个都改。

 

(2)BP侧配置MIPI参数

 MIPI参数就是一种可以让屏幕显示出来的参数,有些是直接接收mipi参数显示如手机屏幕,有些需要将mipi信号转换为hdmi lvds信号。mipi参数只需要将供应商提供的参数进行转换就行了,再配一些识别屏幕的文件,开机时模块就会发出mipi信号。

首先第一步是找到配置mipi参数的地方,按照目前平台规范大致分两处:

sdm845_Android10_BP\boot_images\QcomPkg\SDM845Pkg\Library\MDPPlatformLib\MDPPlatformLib.c    和   QCM6490_LA2.0_BP\boot_images\boot\QcomPkg\Settings\Panel

模块型号不同位置不同,需要自己找,因为两者没什么差别,我们先找MDDPlatformLib中的参数,打开.c文件,找到

1d94d6d060af4c7eb81594446437716a.png

这样一长串的常量,下面还有很多就不截图了,每一组常量代表一块屏幕的mipi参数,开机时机器会在这边解析mipi参数发出mipi信号来显示,至于怎么配这些参数以及需要加哪些逻辑代码,之后会用一个实例来讲解;最后是Settings/Panel中的xml文件,一种文件代表一种屏幕只是把上图中的双引号和换行符号去掉而已,之后该类配置也会有示例来讲。在本章中只需要了解机器开机在这些地方拿mipi信号就可以。

另外,如果未来你主要调试显示类的驱动,会接触比较多MDPPlatformLib.c这个文件,可以先看一下文件结构及各个功能函数大致是什么意思。

 

(3)BP的驱动移植

移植就是将AP侧的驱动复制粘贴到BP侧,让机器开机便去初始化芯片让它跑起来。但是也不是简单的复制粘贴,需要利用BP的各种函数接口改写驱动,之后也会有一示例来讲解,在这里只需要知道驱动写在AP侧和移植到BP侧有什么不同就行。

 

二、驱动常用的功能添加

(1)创建节点

可以在任意一个驱动创建节点来查看驱动的状态,比如读写引脚的状态,读写显示驱动中的分辨率信息等等,下面是一个读写节点示例:

1.宏定义

025769827e3a40dead65bb0386c00bcb.png

 

补充mode定义:

400    拥有者能够读,其他任何人不能进行任何操作;

644    拥有者都能够读,但只有拥有者可以编辑;

660    拥有者和组用户都可读和写,其他人不能进行任何操作;

664    所有人都可读,但只有拥有者和组用户可编辑;

700    拥有者能够读、写和执行,其他用户不能任何操作;

744    所有人都能读,但只有拥有者才能编辑和执行;

755    所有人都能读和执行,但只有拥有者才能编辑;

777    所有人都能读、写和执行(该设置通常不是好想法)

 

2.定义一个设备属性名为my_device_test

5d924106d3b54254b55bd7aaae3f69b8.png

 

3.定义写和存储函数

d052339d685c47fc861963f58f82f69a.png

 

4.宏展开

1d2cb231fe64442cb35f9a9f0d09197c.png

 

5.在init与exit中初始化与注销

init中:

1a04456fb6424ce9a4c5881606538bac.png

 

exit中:

99e0b2c3331e4f3987b5bc5f2abc4673.png

 

6.在终端进行cat与echo,结果如下:

d4de9d0f02eb4db1a108b1ad6f02855d.png

 

 

(2)线程创建

进程线程的理论知识与系统线程程序的解析:

进程:处于执行期的程序及相关资源的总称,实际上,进程就是正在执行的程序代码的实时结果

线程:是在进程中活动的对象,每个线程都拥有一个独立的程序计数器、进程栈和一组进程计数器。内核调度的基本单位为线程而不是进程。

内核线程实现流程:

定义一个线程指针;编写线程函数;创建线程;开启线程;停止线程

内核通过kernel_thread函数创建一个线程

通过fork()函数创建一个子进程

04ff24f86521497585ce05a053921f4d.png

 

具体实现:

1.包含线程创建头文件

2.定义线程指针

3.创建内核线程,调用函数启动(wake_up函数)

如上图的创建线程并执行函数:创建了一个线程指针__k,线程执行的函数为threadfn,当__k不出错时唤醒,就可以执行线程,停止线程可以利用stop函数进行停止。

创建线程并运行:

1.内核线程接口函数头文件

708fb1215b0c4132838b18dfb15f5e7d.png

 

2.定义线程指针

aed8ca0a29de4b9fad966746731655eb.png

 

3.创建内核线程,返回值为创建线程的指针

8bce5c497b2745f89441d0c5f4bf9a67.png

 

参数1为线程函数,参数2为传给线程的私有数据,参数3为线程名称

下图为线程的执行函数,实现了log的打印

40f3f767f52d411c8d1e40b94e07e0cd.png

 

4.启动线程

e15b1a2f8574499d9f364cf4ac3ecf0c.png

 

5.停止线程

d64286801aac428aacbd899f06d4cffa.png

 

在编译烧录后抓取到如下log信息

0000a3b6fe984da6be5457f8cbea66fe.png

 

线程创建成功

 

(3)动态加载驱动

驱动如何动态加载:

静态加载就是把驱动程序直接编译到内核,系统启动后直接调用。这种办法调试起来麻烦,修改一次就需要重新编译所有程序加载,效率很低。

动态加载就是利用Linux的module特性,在系统启动后可以用命令insmod和rmmod进行驱动程序(.ko文件)加载和卸载。

生成ko文件,需要修改Makefile

32a7bd40a8f24a4d93fd937b068726a9.png

 

需要注意的是,编译文件的顺序不能错以及书写的格式要正确,如不能有空行。

obj-m为编译时生成ko文件,下面需要添加路径名。在中断make kernel成功编译后生成以下两个ko文件

f429bc1953af46bf821bcbc53f95f721.png

 

接下来进入终端连接设备。

首先获取权限,输入adb root。

再输入adb remount 如果不成功需要输入adb disable-verity,remount的作用是将system部分置入可写入模式

然后将生成的ko文件push进入设备。

以上步骤如下:

1c233543037047c5b1cd35ef3b9c9fa0.png

最后进行insmod。

7814ec5fa6a64c83afc407a75adf5d43.png

 

发现有如上错误:原因是该文件没有公钥也没有提供的签名,所以无法insmod

在文件中找到这个ko文件进行insmod

c527753ad6b94816be5886c826cc4af2.png

 终端中执行insmod成功

1408c3030ee54890813c28af87eae9d1.png

如果无法打印log信息,还需要加入setenforce 0关闭权限

再抓取信息后出现:

a01b5b3f5aec4033b7928bfce0df2db1.png

 

(4)建立工作队列利用中断读取设备信息

这个实践难度相对高一些,可以先熟悉中断的产生与作用。可以理解为在产生中断后去执行一些功能函数,比如在插拔HDMI线的时候产生中断,然后上报HDMI屏幕的分辨率信息等。之后会有这样一个例子来介绍。

 

三、总结

本章内容主要介绍了UEFI阶段机器如何获取mipi信号显示、开机对一些引脚的权限管理以及一些实践操作,关于UEFI只需要了解流程,而最后的一些功能操作希望可以去实践一下。下一章将介绍AP与BP的交互和GPIO的概念及操作。

 

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值