高通平台驱动常见问题





 @[TOC]基础知识
 计算法:
int 0x23 <<1
	0x23 *2= 0x46 = 70
	
int 0x23 <<2
	0x23*4 = 0x8c = 170
	2*4 = 0x8  3*4 =0xc  0x8c
	

int 0x23 >>1
	0x23 /2= 0x11 = 17 //取整
	
int 0x23 >>2
	0x23/4 = 0x8 = 8 
	转换10进制
	2*16+3 = 35/4 = 8
	
	
char类型是8位,最高位是符号位,01负,所以01111111127-12710000001,而10000000换算过来就是-12801111111  //127  127+1 = -128
10000001 //-128

&&的短路功能,当第一个表达式的值为false的时候,则不再计算第二个表达式;
&则两个表达式都执行。


对a的第三位清0,第四位置1.
#define BIT3 (1<<3)
#define BIT4 (1<<4)
 a&=~BIT3;
 a|=BIT4;
 
 
一、指定的某一位数置1
#define setbit(x,y)  x|=(1<<y)

二、指定的某一位数置0
#define clrbit(x,y)  x&=~(1<<y)

三、指定的某一位数取反
#define reversebit(x,y)  x^=(1<<y)

三、获取的某一位的值
#define getbit(x,y)   ((x) >> (y)&1)











int *p  char *p  都占四个字节   指针变量里面保存的是地址,地址在操作系统中是固定长度的

数据类型长度
        32  64
char    1   1       2^8
short   2   2
int     4   4       2^32
float   4   4
double  8   8
long    4   8
long long 8 8
size_t  4   8
sszie_t 4   8
@[TOC]空间分配
sizeof,测量一个变量或数据类型所占的字节长度,统计字符串长度的时候加上'\0',在编译阶段的时候就可以计算出长度
strlen,计算字符串长度,在统计字符串长度的时候不加上'\0',在函数运行的时候才计算出长度



用户空间供为3G,分为:栈空间,堆空间,数据区,代码段

栈空间保存:局部变量,函数形参,自动变量。栈空间特点,先进后出,空间由系统管理;栈空间生命周期所在函数执行结束
后释放;栈空间保存的局部变量未初始化时,默认初始化为随机值。

堆空间:由malloc , calloc ,ralloc,这些好函数分配的控件位堆空间,堆空间特点:先进先出,由用户管理

数据区:又分为.bss段、.data段、常量区。其中.bss段保存的是未初始化的全局变量,当全局变量未初始化时,系统默认初始
化为0,常量区保存的是常量,里面保存的值不能被修改,只能做读操作。.data段是保存已经初始化的全局变量以及被static修饰的
变量(静态变量)。数据区的声明周期是整个程序执行完之后再释放。

代码段保存的是代码。

//栈空间 有系统管理 存放局部变量 自动变量 函数执行完释放  先进后出
//堆空间 用户管理  malloc等函数分配 需要用户释放空间     先进先出


@[TOC]关于终端

中断:
上半部分 硬件操作  IRQ_GPIO 读取寄存器中断状态 
触发方式:
        上升沿 下降沿 高电平 低电平 快速中断 共享中断
下半部分 耗时操作  软中断 工作队列  tasklet



    
// 软中断
中断下半部实现 
软中断、tasklet机制、工作队列。

软中断作为下半部机制的代表
tasklet是通过软中断实现的,所以它本身也是软中断。


总结下tasklet的优点:
  (1)无类型数量限制;
  (2)效率高,无需循环查表;
  (3)支持SMP机制;
    缺点 :
        不能阻塞 不能休眠 



下半部实现机制之工作队列(work queue)
工作队里线程是用内核线程实现的。而工作者线程是如何执行被推后的工作——有这样一个链表,
它由结构体work_struct组成,一旦这个工作被执行完,相应的work_struct对象就从链表上移去,
当链表上不再有对象时,工作者线程就会继续休眠。因为工作队列是线程,
所以我们可以使用所有可以在线程中使用的方法。  
                
                
                
    //kmalloc vmalloc malloc
malloc分配的是用户的内存 
kmalloc和vmalloc是分配的是内核的内存
kmalloc保证分配的内存在物理上是连续的
vmalloc保证的是在虚拟地址空间上的连续
kmalloc能分配的大小有限, 4M
vmalloc和malloc能分配的大小相对较大

内存只有在要被DMA(Direct Memory Access,直接内存存取)访问的时候才需要物理上连续

//同步机制包括:原子操作、自旋锁和信号量。
自旋锁同时只会允许一个任务来访问临界区 ,不允许休眠
信号量允许多个任务同时访问临界区,允许休眠,适用较长的共享区  
原子操作可以保证指令以原子的方式执行,执行过程不被打断         
                
                
                
init_module()是真正的入口,module_init是宏,如果在模块中使用, 






保护共享资源的方式有很多,例如:中断屏蔽、自旋锁、信号量...

自旋锁 spin_lock_init(); 同时只会允许一个任务来访问临界区 ,不允许休眠 资源被占用时,不断消耗cpu尝试获取该锁
互斥锁 mutex_init() 会有睡眠 资源被占时 会挂起 其他线程释放互斥锁时该线程被系统激活
信号量 semaphore 允许多个任务同时访问临界区,允许休眠,适用较长的共享区   
原子操作 atomic_inc() 可以保证指令以原子的方式执行,执行过程不被打断
@[TOC]高通I2C配置
dts 把系统平台上的总线(I2C SPI UART)描述成节点
 kernel启动时解析出dts保存在allnode链表中,然后加载系统总线和设备,将其注册在系统中。
 
 高通BLSP配置
    一个I2C 对应的BLSP和QUP
    配置dts
    根据列表计算APPS BLSP值
    
    通过计算的值在TZ中配置
    trustzone_images\core\hwengines\bam\8974\bamtgtcfgdata_tz.h
    在/usr/share/data/adsp/blsp.config中定义串口设备和BAM端口的映射
    
    @[TOC]DDR降频计算
DDR降频
     //  19.2(40+(2/3))/2     780.8M
     DDR 2GB 换3GB 增加ldo1供电 
     
    @[TOC]camera
camera imx214 imx350
    camera_config.xml配置
        id  sensorname  方向  CSI_ID lane
    
    dts
    供电配置 DOVDD AVDD PWDM REST
    
    imx350_lib.h
    上电时序
    power_setting_array
    @[TOC]TP
TP      敦泰8719  汇顶
    TP供电电压异常
    射频干扰  ----  打电话引起TP电压上下波动
    TP校准异常
    充电器干扰测试
    
    阀值:
        灵敏度
        防水上线阀值 一只手按CTP 一只手按地
        报点频率
        1. input 机制
        2. 中断
        3. I2C
        
        初始化硬件
        注册I2C设备
        注册中断
        注册input设备
         
         中断函数中上报坐标值
    

    I2C
     时钟在高电平时  数据从高到底 开始 
     时钟在高电平时  数据从低到高 结束
     写:发送(7+1)写地址 收应答(ACK) 发送地址 ACK 发送数据 ACK
     读:发送写地址        ACK      发送地址 ACK 发送读(7+0) ACK  获取数据
    @[TOC]FP
 
FP  信炜科 汇顶
    流程:
        给中断
        主控驱动收到中断之后通过netlink或者其他的跨进程上报信息给hal
        hal收到中断开始识别
            从IC中获取指纹图像 然后预处理为算法格式
            进行模板库匹配
            生成识别结果 用binder回调fingerprintseriver
            
    keystore service 保存支付指纹
    
    SPI
    输入 MOSI
    输出 MISO
    时钟 
    片选

@[TOC]LCD
LCD
参数
    Hsync Pulse Width  行同步   4  水平脉冲宽度  
    Hori. Back Porch            16  水平后沿值   表示从水平同步信号开始到一行的有效数据开始之间的VCLK的个数
    Hori. Front Porch           16  水平前沿    表示一行的有效数据结束到下一个水平同步信号开始之间的VCLK的个数
    
    Vsync Pulse Width 帧同步  4 垂直脉冲宽度
    Vert. Back  Porch         4
    Vert. Front Porch        108(下半部宽度比较大)
    
    
    kernel dts
    lk  UEFI Display Panel 
    tz
    
    
sensor ADSP 
    上报方式 : Polling  
                DRI
                FIFO

                
                

                
输入子系统:
        linux内核 原始数据上报给用户空间
        InputManagerService java部分负责与WMS通讯   native部分是InputRead InputDispatcher 两个运行容器
        EventHub 访问底层设备节点返回数据
        InputRead 独立线程 从EventHub获取数据,做封装处理, 给InputDispatcher 进行派发
        
        例如HOME键被InputDispatcherPolicy截取到PhoneWindowManager中处理,并阻止窗口收到HOME键按下的事件
        
        
        由上到下:
            开机注册InputManagerService 
                InputManagerService开启两个线程 InputRead InputDispatcher 
                    InputRead 通过EventHub检测读取input上报的键值数据  将键值数据初步整理,封装之后,发送给InputDispatcher
                     InputDispatcher:不停的循环等待来自InputReader传过来的键值数据,在接收到键值数据之后,对键值进行整理分发,按键背光也会在该线程中点亮。



        
        
        
        
        
        
耳机 
    三段式 没有mic 只能接受声音    左声道 右声道 GND   //L   R   GND     
    四段式  有mic   
                    美标CTIA  //L R G M
                    欧标OMTP  //L R M G






//高通平台 BSP启动流程

一个dts文件确定一个项目

/*
/kernel/msm-4.4/arch/arm/boot/dts/qcom/sdm660-pm660a-qrd-h6630.dts 

/dts-v1/;

#include "sdm660.dtsi"
#include "sdm660-qrd-h6630.dtsi"
#include "msm-pm660a.dtsi"

/ {
        model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660A QRD h6630";
        compatible = "qcom,sdm660-qrd", "qcom,sdm660", "qcom,qrd";
        qcom,board-id = <0x0012000b 0>;
        qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
                        <0x0001001b 0x0002001a 0x0 0x0>,
                        <0x0001001b 0x0202001a 0x0 0x0>;
};

&pm660a_oledb {
        status = "okay";
        qcom,oledb-default-voltage-mv = <6400>;
};

&mdss_mdp {
        qcom,mdss-pref-prim-intf = "dsi";
};

&mdss_dsi {
        hw-config = "single_dsi";
};

&mdss_dsi0 {
        qcom,dsi-pref-prim-pan = <&dsi_rm69299_amoled_fhd_cmd>;
        pinctrl-names = "mdss_default", "mdss_sleep";
        pinctrl-0 = <&mdss_dsi_active &mdss_te_active>;
        pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
        lab-supply = <&lab_regulator>;
        ibb-supply = <&ibb_regulator>;
        qcom,platform-reset-gpio = <&tlmm 53 0>;
        qcom,platform-te-gpio = <&tlmm 59 0>;
};

&dsi_rm69299_amoled_fhd_cmd {
        qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs";
        qcom,mdss-dsi-bl-min-level = <1>;
        qcom,mdss-dsi-bl-max-level = <255>;
        qcom,panel-supply-entries = <&dsi_panel_pwr_supply_labibb_amoled>;
};
*/

//dts 符号含义
//		/	根节点
//		@	如果是设备地址 此符号指定
//		&	引用节点
//		:	给节点起别名
//		,	分割符
//		# #并不表示注释。如 #address-cells ,#size-cells 用来决定reg属性的格式。

//		ranges属性为一个地址转换表
//		interrupt-parent 标识此设备节点属性
//		interrupts 一个中断标识符列表



dts描述的设备树是如何通过register_device进行设备挂载的
//dts执行过程
dts是系统平台挂载总线 i2c spi uart 等,每个总线被描述成一个节点。
启动linux到kernel入口后会加载系统总线和设备
start_kernel ---> setup_arch ---> unflatten_device_tree
执行完unflatten_device_tree()后,dts的节点信息被解析出来,保存到allnodes链表中。
随后启动到board文件时,调用.init_machine,再调用of_platform_populate(....)接口,
加载平台总线和平台设备。至此,系统平台上的所有已配置的总线和设备将被注册到系统中


(对这句话更加正确的解释是:此时所说的设备指的是platform device,此时的总线指的是i2c,spi等,因为i2c总线和spi总线可以理解为注册在platform总线上的device)

注意:不是dtsi文件中所有的节点都会被注册,在注册总线和设备时,会对dts节点的状态作一个判断,如果节点里面的status属性没有被定义,或者status属性被定义了并且值被设为“ok”或者“okay”,其他情况则不被注册到系统中。




mach-qcom/board-660.c
 41 static void __init sdm660_init(void)
 42 {
   
 43     board_dt_populate(NULL);
 44 }
 45 
 46 DT_MACHINE_START(SDM630_DT,
 47     "Qualcomm Technologies, Inc. SDM 630 (Flattened Device Tree)")
 48     .init_machine = sdm660_init, // 匹配dts
 49     .dt_compat = sdm660_dt_match,
 50 MACHINE_END
--------------------- 
 18 static const char * sdm660_dt_match [] __initconst = {
                                                                                                             
 19     "qcom,sdm660",
 20     "qcom,sda660",
 21     NULL
 22 };

其中.dt_compat    = ******_dt_compat 这个结构体是匹配是哪个dts文件,:

 19 void __init board_dt_populate(struct of_dev_auxdata *adata)
 20 {
   
 21     of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 22 
 23     /* Explicitly parent the /soc devices to the root node to preserve
 24      * the kernel ABI (sysfs structure, etc) until userspace is updated
 25      */
 26     of_platform_populate(of_find_node_by_path("/soc"),
 27                  of_default_bus_match_table, adata, NULL);
 28 }   


+++ b/BOOT.XF.1.4/boot_images/QcomPkg/Sdm660Pkg/Library/XBLLoaderLib/boot_cdt_array.c
 
 26 uint8 config_data_table[CONFIG_DATA_TABLE_MAX_SIZE] =
 27 {
   
 28     /* Header */
 29 
 30     0x43, 0x44, 0x54, 0x00,
 31     0x01, 0x00, 0x00, 0x00,
 32     0x00, 0x00, 0x00, 0x00,
 33     0x00, 0x00,
 34 
 35     /* Meta data */
 36 
 37     0x16, 0x00, 0x06, 0x00,
 38     0x1C, 0x00, 0xEF, 0x02,
 39 
 40     /* Block data */
 41 
 42     0x03, 0x0b, 0x12, 0x00,//mtp change to qrd qcom,board-id = <0x0012000b 0>;
 43     0x00, 0x00, 0x02, 0x00, 
 44     0x00, 0x00, 0x00, 0x52, 
 45     0x44, 0x44, 0xFF, 0xFF,

Platform id信息解析:

0x02, 0x08, 0x01, 0x00,

Byte 0: platform_idVersion
Byte 1: platform_id ID:
           0x01: Target is aSURF device
           0x08: Target is aMTP device
           0x0B: Target is aQRD device
Byte 2: platform_id Hardware version



SBL1的功能

        初始化memory子系统(总线,DDR,clock和CDT),加载和验证TrustZone,DEVCFG,RPM_FW,APPS BL image,dump memory通过usb2.0和Sahara协议,
usb driver support,usb charging(usb充电),thermal check(温度检测),PMIC 的驱动,配置DDR,flash L1/L2/ETB

//编译选择kernel
h6630/AndroidBoard.mk 
 19 # Compile Linux Kernel
 20 #----------------------------------------------------------------------
 21 ifeq ($(KERNEL_DEFCONFIG),)
 22    ifeq ($(TARGET_BUILD_VARIANT),user)
 23      KERNEL_DEFCONFIG := sdm660-$(OEM_PRODUCT_NAME)-perf_defconfig
 24    else
 25      KERNEL_DEFCONFIG := sdm660-$(OEM_PRODUCT_NAME)_defconfig
 26    endif                                                                                                                                                                                 
 27 endif


 
 
 开机流程

@[TOC]开机流程
//
上电加载引导程序BootLoader
主要是拷贝操作系统到RAM中 跳转到入口执行

第一阶段:
初始化硬件参数
加载stage2到ram
设置好堆栈
跳转C程序入口

第二阶段
初始化本阶段硬件
检测内存映射
见内核映像和文件系统从flash读到ram中
问内核设置启动参数
调用内核



kernel初始化

启动内核线程
驱动程序的初始化
启动用户空间的init进程

 init进程
 执行init.rc脚本

zygote进程
所有Java进程的父进程
startSystemServer
启动的SystemServer进程
        初始化原生服务库
        初始化系统上下文
         创建SystemServiceManager对象
         开启服务
         初始化ActivityManagerService  ----之后 广播形式---> Launcher程序
         初始化PowerManagerService,
         开启DisplayManagerService
         开启PackageManagerService
         




@[TOC]UEFI
/UEFI
 UEFI 代替LK  
 UEFI 由XBL  ABL组成 
 
 XBL负责芯片驱动及充电等核心应用功能
 ABL包括芯片无关的应用如fastboot。
 
 
 ABL 的编译非常简单,依次执行命令source build/envsetup.sh、lunch 32、make aboot,
 即可在out目录下生成abl.elf
 
 ABL 主要碰到了两个问题,
 一是没有生成abl.elf,
 二是生成abl.elf后没有做签名。高通原生代码并不存在问题,是项目中修改了代码导致的。费了一番周折,最终成功编译出可正常工作的abl.elf
 未签名的abl.elf大概98KB,签名后的abl.elf约108KB
 
 需要注意的是,ABL在Android代码树下,而签名工具(secimage)在高通私有代码目录(vendor/qcom/proprietary)下,
 在编译ABL时,一定要将高通提供的私有代码全部放到相应的目录下。
 未签名的abl.elf会让系统无法启动,上电直接进入EDL紧急下载模式。
 
 
 
 //UEFI启动流程:

对于高通平台启动过程依次为PBL->XBL->ABL.
一般用户定制化主要集中在ABL中
 
 //高通启动流程
 1,上电,加载PBL
                        ------>对XBL region #1 进行身份认证,并将其从引导设备(as TCM)加载到L2
                        ------>验证XBL region #2 (DDR/SDI equivalent)并将其加载到片上内部存储器(OCIMEM),然后跳转到XBL region #1

 
 2在 XBL region #1中,XBL对PMIC镜像进行身份认证并将其从引导设备加载到内部缓冲区 
        a. 对QSEE进行身份认证,并将其从引导设备加载到pIMEM QSEE - Qualcomm Secure Execution Environment 
        b. 对QHEE (Hypervisor) image 进行身份认证,并将其从引导设备加载到DDR QHEE - Qualcomm Hypervisor Execution Environment 
        c. 对RPM firmware image 进行身份认证,并将其从引导设备加载 RPM code RAM 
        d. 对little kernel(LK) boot (or XBL region #3)进行身份认证,并将其从启动设备加载到DDR

 
4,XBL region #1 结束工作,下一步由QSEE执行
5 QSEE使RPM退出reset状态,启动并执行RPM firmware
6 QSEE建立一个安全的环境,并跳转到QHEE image,启动并执行它
7 QSEE跳转到LK boot(or XBL region #3),启动并执行
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
高通平台WLAN驱动开发文档是用于指导开发人员在高通平台上开发WLAN驱动程序的文档。WLAN驱动程序是一种软件,用于控制和管理无线局域网(WLAN)设备的操作和功能。 该开发文档提供了关于WLAN驱动程序开发的详细信息,包括驱动程序的架构、功能、接口和具体的开发要求。它描述了WLAN设备与操作系统之间的通信方式,例如硬件抽象层(HAL)和操作系统驱动程序接口(OEM-OSI)等。此外,文档还提供了关于WLAN驱动程序编程接口(API)和相关函数的说明,以及如何实现WLAN功能集、网络管理和安全性等方面的指导。 开发人员可以根据这份文档中提供的信息,了解如何在高通平台上开发WLAN驱动程序,并且根据自己的需求进行定制和优化。文档中会包含一些常见问题和解决方案,以帮助开发人员克服开发过程中可能遇到的挑战。 由于WLAN驱动程序的开发涉及到硬件、操作系统和网络协议等多个领域的知识,因此该开发文档对于有经验的开发人员来说尤其有价值。通过合理利用这份文档,开发人员可以更高效地开发和调试WLAN驱动程序,从而提高WLAN设备的性能和稳定性。 总之,高通平台WLAN驱动开发文档是一份指导开发人员在高通平台上开发WLAN驱动程序的详细文档,通过阅读并按照其中的指导进行开发,开发人员可以更好地理解和掌握WLAN驱动程序的开发流程和技术要求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值