QMI QMI:Qualcomm Messaging Interface(高通通信接口),QMI是高通提供的一种多处理器进程间通信的功能接口,用于AP和BP侧的交互,通俗说法就是让终端设备TE(可以是手机,PDA,计算机)对高通BP侧的AMSS系统进行操作,如调用函数,读取数据,设置其中的NV项等。 2005-2006年部署(原高通MSMTM接口),所有服务最初都是由DATA团队设计和维护的,功能是按照AT命令标准构建的,主要用于连接管理器类型应用程序,可通过USB连接(QMUX传输)连接到电脑。 2009年QMI取代RPC(Remote Procedure Call),QMI的范围开始扩大,无线电接口层(RILs)开始向QMI过渡,并定义了必要的支持;底层由更健壮的通信(IPC路由器传输)替代,通过共享内存方式(SMD)在片上SOC之间可用。 高通平台目前都是非对称多核心,最主要的是AP和Modem。两个处理器怎么进行通信呢,我们把AP和Modem当作两个主机,问题就变得了很简单,TCP/IP协议不是一种非常成功的进程间跨主机通信方式。高通没有采用这种方式,但是借鉴了TCP/IP的框架设计。它的框架是这样的,内核态:基于共享内存(SMD)实现链路层,扩展协议域;用户态,封装出类似于socket函数的接口,用于用户态使用。而我所描述的QMI就是用户态使用的API接口,这些接口非常类似于socket。 QMI提供了一下几点: 1、异步消息传递接口:在客户端和服务器之间的通信 2、设备的控制接口:不提供数据路径 3、高通芯片的通用接口 4、具有扩展能力 5、向后兼容 6、支持多客户端并发运行 7、支持多个服务端并发运行,且每个服务端还对应多个客户端 8、每个服务端还支持版本信息 QMI的消息路由通过IPC Router来完成,IPC路由器是一个面向消息(message-oriented)的路由器,用于支持Qualcommcommo client interface(QCCI)以及Qualcommcommon service interface(QCSI)。 QCCI是一套用于客户端从服务器接收信息或者发送消息到服务器的API集合。 QCSI则是与QMI IDL(interface definition language)自动编译生成的代码一起使用,用于接收客户端的请求及对其作出响应。另外,它也用来发送指示消息(indication message)以及对消息进行编解码(encode/decode),这个消息由server端主动发出。 每一个服务都对应于一个service.idl的文件定义。.idl文件定义了每一个massage相关的常量,枚举类型以及和消息相关的数据结构。消息的类型有如下三种: QMI架构: Messages:message消息具有三种类型:Clientrequest、Service response、Service indication Request message——一条request消息由客户端发往服务端,并由服务端进行处理。 Reponsemessage——每一个request的消息都会有一个reponse消息与之对应,类似于一个函数的返回值。如果请求消息等效于调用函数,则响应消息等效于返回给调用方的结果。 Indiction message——这类消息是由服务端发给客户端的异步消息。sensor1 API的规范要求:在任何indicationmessage发送之前,客户端首先需要通过request message与服务端建立连接。indication消息可以在任何时候发送。 Message的特点: 消息由Type-Length-Value(TLV)单元构成; 类型和长度是固定大小,而值是可变长度的; 每个消息中可以出现多个tlv值; 可以在该值中显示多个数据元素; 对于每个消息的TLV id都是唯一的; Message结构: 由传输头和服务级消息组成 每个传输的传输头都是唯一的 Service Message服务级负载对于所有传输都是通用的,并包含以下元素 消息ID 消息长度 零或多个可变长度的tlv Clients:任何想要使用QMI的内部或外部客户端应用程序 Services:任何想要使用QMI的内部应用服务程序 Common Libraries: 为客户端(QCCI)和服务(QCSI)提供功能 通用API适用于所有平台/传输 封装传输和特定于平台的更改,以便共享客户机/服务代码 为每个服务消息提供编码/解码支持 Transports QMUX: 高通多路复用协议(QMUX); 原始传输通过一个有线USB以太网适配器; 支持MPSS处理器上的服务; 支持在应用程序(APPS)处理器或usb连接的主PC上的客户端; QMUX的客户端是用于特定于平台的,不同平台可能有差异; IPC Router: IPC路由器是一个面向消息(message-oriented)的路由器,用于支持Qualcomm QCCI QCSI; 增强了同一设备上处理器之间的传输; 通过SMD在路由节点之间传递QMI有效负载; 支持任何处理器上的客户端和服务; API对于所有平台都是通用的,即使实现不同; QMI IDL QMI接口是用接口定义语言(IDL)编写的,IDL编译器自动生成文件 .c和.h 编码/解码库 库是独立的,并且与自动生成的文件解耦 编码/解码消息的元信息将在.c作为Service_Object生成 在服务/客户机启动期间,元信息将注册到QCSI/QCCI进行消息编码/解码 客户端/服务可以使用QCCI/QCSI API发送/接收消息 QMI消息编码标准 1. 不使用浮点型数据,而是使用Q16类型的固定点数,即提供16位2位补码整数部分和16位小数部分的定点实现。 2. 命名约定 为了使所有消息实现保持一致,service端需要固定的独有的前缀 结构体以_type结尾 枚举以_enum结尾 请求消息以_req_msg结尾,类型以_REQ结尾 消息回应以_resp_msg结尾,类型以_RESP结尾 指示消息以_ind_msg结尾,类型以_IND结尾 QMI QCCI QCCI是一套用于客户端从服务器接收信息或者发送消息到服务器的API集合。 以下步骤描述初始化客户机: 1. QMI客户机创建一个通知句柄来接收服务到达和退出事件通知。然后是客户端 用notifier句柄注册一个通知回调函数; 2. 当服务到达时,将设置信号,并调用通知回调函数来客户端关于服务到达的消息; 3.QMI客户机在收到服务到达通知后解析服务地址; 4. QMI客户机初始化服务的客户机句柄,该服务的地址在步骤3中解析。然后,这个客户端句柄用于与相关的QMI服务交换QMI消息; 5. 初始化客户端句柄时,将向客户端句柄注册一个错误回调函数。此错误回调用于接收关于服务重启或子系统重启的任何通知; 6. 此时,QMI客户机可以释放notifier句柄,以避免任何资源泄漏; 7. QMI客户机同步或异步发送请求消息,如上图所示; 8. 当所有相关的QMI消息通信完成时,QMI客户机释放客户机句柄。 QCCI APIs Callback function prototypes qmi_client_recv_raw_msg_async_cb qmi_client_recv_msg_async_cb qmi_client_ind_cb Connection APIs qmi_client_notifier_init qmi_client_init qmi_client_get_service_list Message sending APIs qmi_client_send_raw_msg_sync qmi_client_send_msg_sync qmi_client_delete_async_txn Release connection APIs qmi_client_release Encode and decode APIs qmi_client_message_encode qmi_client_message_decode QMI QCSI QCSI是用于接收客户端的请求及对其作出响应。另外,它也用来发送指示消息(indication message)以及对消息进行编解码(encode/decode),这个消息由server端主动发出。 消息的类型有如下三种: Request message ——一条request消息由客户端发往服务端,并由服务端进行处理。 Reponse message——每一个request的消息都会有一个reponse消息与之对应,类似于一个函数的返回值。如果请求消息等效于调用函数,则响应消息等效于返回给调用方的结果。 Indiction message——这类消息是由服务端发给客户端的异步消息。在任何indication message发送之前,客户端首先需要通过requestmessage与服务端建立连接。indication消息可以在任何时候发送。Callback function prototypes qmi_csi_connect qmi_csi_disconnect qmi_csi_process_req Registration APIs qmi_csi_register qmi_csi_unregister Message sending APIs qmi_csi_send_resp qmi_csi_send_ind qmi_csi_send_broadcast_ind Event handling APIs qmi_csi_handle_event QMI SERVER 这个api构建在QCSI框架之上 其主要目的是方便客户机以更少的工作量实现服务器 该框架允许用户编写基于对象的服务器,扩展核心服务器对象。核心服务器对象提供每个服务都需要的通用功能 Callback Function Prototypes qmi_csi_connect qmi_csi_disconnect qmi_csi_process_req Constructor/Destructor APIs qmi_core_server_new qmi_core_server_delete Registration APIs qmi_core_server_register qmi_core_server_unregister qmi_core_server_register_client qmi_core_server_unregister_client Message Dispatch APIs qmi_core_server_dispatch_msg qmi_core_server_send_ind qmi_core_server_send_resp QMUX QMI Multiplexing Protocol(QMUX):QMI的复用协议 消息从控制点经过类似socket的线程传到QMI接口后,QMI负责对数据进行封装,加上QMUX消息的头,发送到QMUX层, 再通过QMUX层传到共享内存到BP侧。 QMUX消息的格式: 整个QMUX控制信道的结构如上图, I/FType:QMI将控制点数据封装后,发送到QMUX前,加的消息头,长度为一个byte,值通常为0x01,表示这个消息为QMUX消息,如果是其他值,则为其他消息。 Length: QMUX消息的长度,不包括I/F Type。 ControlFlags:控制位,表示消息传输的方向。长度为1个byte,只有第7个bit是标志位,其他位为0,bit7=1说明QMUX消息由服务端发送,bit7=0由控制点发送。 Clien ID: 控制点的标识,在控制点和服务端都需要赋值,当在服务端发出的消息Client ID的值为0xFF,表示该消息为广播消息,由服务端主动发出,被所有控制点搜到。 QMUX SDU和TLV结构: 在整个控制信道的消息中,出去消息标识头I/F Type,和QMUX消息头,数据传输在QMUXSDU中完成,QMUX SDU里面的数据需要支持TypeLength Value(TLV)的格式。 TLV格式的数据存放在QMI Service Message里面的Value中。 Control Flags:表示消息是请求、响应还是指示。
|