目录
一:VirtIO和Passthrough的区别
二:配置逻辑
三:配置方法
步骤一:QNX SPI资源配置 & 测试
配置
测试
步骤二:BE配置 &测试
配置
测试
步骤三:Hypervisor配置
配置
测试
步骤四:Android侧配置
配置-config相关
组入config的方法
确认config的方法
配置-DTS相关
测试
参考网站
黑莓官方资料:
通信调试方法:
一:VirtIO和Passthrough的区别
二:配置逻辑
以上章节内容 可参照我的这篇文章,本质上是一样的:
高通8255 Android Virtio Virtio-IIC 配置方法_virtio i2c-CSDN博客
三:配置方法
因为Virtio的逻辑是分 BE(后端) FE(前端),所以依然要先保证QNX配置成功,然后再调试Android侧
步骤一:QNX SPI资源配置 & 测试
配置
正常配置一路QNX spi资源:
SD-QNX4.5.6.0/apps/qnx_ap/boards/core/dalconfig/lemans_rumi/config/spi_props_lemans.xml
SD-QNX4.5.6.0/apps/qnx_ap/boards/core/dalconfig/lemans_rumi/config/pin_config.c
测试
使用 QNX spidbgr 命令 进行测试
测试工具代码路径:/SD-QNX4.5.6.0/apps/qnx_ap/AMSS/platform/services/applications/spidbgr
使用方法参照:spidbgr.use%C :
Usage: spidbgr -m [master_node] -d [slave_id] -M [mode] -f [freqency] -w -l [master_wlen] -o [master_wmsg] //write onlyspidbgr -s [slave_node] -d [slave_id] -M [mode] -f [freqency] -R -B [slave_rlen] //read onlyspidbgr -m [master_node] -d [slave_id] -M [mode] -f [freqency] -w -l [master_wlen] -o [master_wmsg] -s [slave_node] -R -B [slave_rlen] //master write and slave readspidbgr -m [master_node] -d [slave_id] -M [mode] -f [freqency] -x -l [master_wlen] -o [master_wmsg] -s [slave_node] -X -L [slave_wlen] -O [slave_wmsg] //exchange between master and slavecmd list:-m --master master portid (range is 1-12)-s --slave slave portid (range is 1-12)-d --device slaveid (default 0, range is 0-3)-G --setcfg set config-M --mode mode (default 0x2608)-f --freq freq (default 1000000HZ)-w --master_write master write-W --slave_write slave write-r --master_read master read-R --slave_read slave read-x --master_xchange master xchange-X --slave_xchange slave xchange-c --master_cmdread master cmdread-C --slave_cmdread slave cmdread-i --master_cmdwrite master cmdwrite-I --slave_cmdwrite slave cmdwrite-g --get_info get info-l --master_wlen master write msg len (default 0)-b --master_rlen master read msg len (default 0)-L --slave_wlen slave write msg len (default 0)-B --slave_rlen slave read msg len (default 0)-o --master_wmsg master write message-O --slave_wmsg slave write message-v --verbose verbose (default disable)-t --timeout_value_set_sec timeout value set sec(default 5s)-T --timeout_value_set_nsec timeout value set nsec(default 0ns)-n --timeout_value_get timeout value get-p --random_data_padding random data padding-z --iteration_count iteration_count(default 1)-h --help helpThe meaning of each bit of the mode parameter:
0-7 bit the number of bits in a data frame
8 bit CPOL, 0:SCLK is low when idle, 1:SCLK is high when idle
9 bit CPHA, 0:input bit is shifted in first transition edge, 1:output bit is shifted in first transition edge
10 bit spi bit order, 0:LSB first 1:MSB first
11 bit spi cs polarity, 0:active low 1:active high
13 bit cs mode, 0:CS is deasserted after transferring data for N clock cycles 1:CS is asserted as long as the core is in Run state
22-25 bit inter-word delay(1-15 cycles)
30 bit SW loopback enable, 0:disable 1:enableEg. Get SPI configurationspidbgr -m 2 -gThis will read back something like :device info, name-A2B SPI / Mercu:mode-0x00002608:clock-5000000Hzdriver info, name-QCOM SPI Master:version-1:feature--2147483648Eg. hw loopback between spi2 and spi9(spi2 write spi9 read)spidbgr -d 0 -M 0x2608 -f 2000000 -m 2 -w -l 2 -o 0x55 0xaa -s 9 -R -B 2Eg. spi master write(spi_write)spidbgr -d 0 -M 0x2608 -f 2000000 -m 2 -w -l 2 -o 0x55 0xaaEg. spi master read(spi_read)spidbgr -d 0 -M 0x2608 -f 2000000 -m 2 -r -b 2Eg. spi master xchange(spi_xchange)spidbgr -d 0 -M 0x2608 -f 2000000 -m 2 -x -l 2 -o 0x55 0xaaEg. spi master write and read(spi_cmdread)spidbgr -d 0 -M 0x2608 -f 2000000 -m 2 -c -l 2 -o 0x55 0xaa -b 2Eg. spi cmdwrite:spidbgr -d 0 -M 0x2608 -f 2000000 -m 2 -i -l 2 -o 0x55 0xaaNotes:- Port ID range is 1-12. Slave ID range is 0-3.- This debugger can handle at max 64K bytes per transaction.- It can use the random data padding mode through the -p flag, specify the wlen is enough, no need to manually input wmsg in the cmd, such as:spidbgr -m 2 -d 0 -M 0x40002608 -f 1000000 -x -l 500 -p- It can log the transfer info through the -v flag, such as:# spidbgr -m 2 -d 0 -M 0x40002608 -f 1000000 -x -l 10 -p -v=========spi transfer info=========iteration_times: 1master_portid: 2 slave_portid: 0cs_num: 0mode: 0x40002608freq: 1000000HZmaster_wlen: 10 master_rlen: 10slave_wlen: 0 slave_rlen: 0master_cmd: SPI_XCHANGEslave_cmd: Nonemaster_wmsg: 0x28 0xac 0x87 0xda 0x70 0x19 0x9d 0x8c 0xb1 0x1===================================- It can set the timeout value with the -t & -T flags, -t is sec, -T is nsec , such as:spidbgr -m 2 -d 0 -M 0x40002608 -f 100000 -x -l 2 -p -t 10 -T 1000000- It can get the timeout value with the -n flag, such as:spidbgr -m 2 -d 0 -M 0x40002608 -f 100000 -x -l 2 -p -t 10 -T 1000000 -n/dev/spi2 timeout_sec is 10s, timeout_nsec is 1000000ns- The iteration count can be specified with the -z flag, such asspidbgr -m 2 -d 0 -M 0x40002608 -f 100000 -x -l 2 -p -z 5
测试示例:
spidbgr -d 0 -M 0x2608 -f 10000000 -m 3 -w -l 1 -o 0xaaspidbgr -d 0 -M 0x2608 -f 10000000 -m 3 -w -l 1 -o 0xaa
QNX 测试 结果 OK
步骤二:BE配置 &测试
配置
Virtio机制是BE以.so形式进行加载运行,所以要求确保上述使用的文件生成so并再车机中运行。
因此在此文件中追加相关内容,将so推送到机器中
SD-QNX4.5.6.0/apps/qnx_ap/target/hypervisor/host/build_files/system.build.tmpl
测试
确认 /mnt/lib64/dll 中存在此
测试结果:ok
步骤三:Hypervisor配置
配置
/SD-QNX4.5.6.0/apps/qnx_ap/target/filesets/secpol/gvm_la.txt
/SD-QNX4.5.6.0/apps/qnx_ap/target/hypervisor/gvm/ivi/lemans/la/linux-la.config
#virtio-SPI Tunervdev vdev-virtio-spi.so loc 0x1cd12000 intr gic:111 verbose 3 device spi1 cs_num 4
上述代码简要描述
vdev vdev-virtio-spi.so
步骤二中提到的 .so,用于将此so提供给Android侧使用loc
0x1cd12000
intr gic:111
给Android侧虚拟的一段地址和中断号,这两个参数随意编写即可,但不要和其他资源地址和中断号发生重复和覆盖,同时要和后续步骤四中DTS描述匹配
verbose 3
:设置日志输出级别为3(较详细的调试信息,可以不必过多关注)
device spi1
:指定关联的QNX配置的 SPI设备为spi1,因为上述qnx配置的是/dev/spi1 所以这里要配置spi1
cs_num 4
:设置芯片选择(CS)信号 固定配置不用关心
测试
对于hypervisor参照QNX log即可,如果QNX和Android侧配置都OK后,QNX启动时没有提示异常log ,暂且认为此处配置正常。(基于高通的base代码,hypervisor需要修改的配置并不多,所以如果配置出现明显错误,例如上述提到的地址或者资源不正确,会有相关明显报错信息) 测试结果: 无异常log OK
步骤四:Android侧配置
配置-config相关
首先保证Android侧 IIC可用,前提是 Android kernel的三个config需要打开,需要配置为 y或者m
CONFIG_SPI_MSM_GENI=m
CONFIG_SPI_SPIDEV=m
CONFIG_VIRTIO_SPI=m
组入config的方法
修改/SD-HQX4.5.6.0/lagvm/LINUX/android/kernel_platform/msm-kernel/arch/arm64/configs/vendor/autogvm_GKI.config
在 高通流程中,defconfig位于 /SD-HQX4.5.6.0/lagvm/LINUX/android/kernel_platform/msm-kernel/arch/arm64/configs/gki_defconfig
从Android编译相关log可以看到,高通处理过程中会将上述autogvm_GKI.config merge 到 gki_defconfig中,所以不建议直接更新gki_defconfig。
log如下:
Using msm-kernel/arch/arm64/configs/gki_defconfig as baseMerging msm-kernel/arch/arm64/configs/vendor/autogvm_GKI.config
确认config的方法
在build out文件中确认当前config值build out文件路径:/SD-HQX4.5.6.0/lagvm/LINUX/android/out/target/product/gen4_gvm/obj/DLKM_OBJ/kernel_platform/msm-kernel/.config
确认结果 OK
上述config 我是以模块形式进行的加载(m),所以还需要更新文件 /SD-HQX4.5.6.0/lagvm/LINUX/android/kernel_platform/msm-kernel/autogvm.bzl 使得启动时,自动加载相关 .ko文件
这几个.ko文件路径参照相关driver编译路径和makefile即可
例如 /SD-HQX4.5.6.0/lagvm/LINUX/android/kernel_platform/msm-kernel/drivers/spi/Makefile 中
obj-$(CONFIG_SPI_SPIDEV) += spidev.o所以路径为 drivers/spi/spidev.ko
配置-DTS相关
按照正常DTSI配置 SPI节点即可
/SD-HQX4.5.6.0/apps_kernel/kernel_platform/qcom/proprietary/devicetree/qcom/lemans-vm-la.dtsi
aliases {
spi1 = &virtio_spi; // virtio-spi
};
/SD-HQX4.5.6.0/apps_kernel/kernel_platform/qcom/proprietary/devicetree/qcom/quin-vm-common.dtsi
virtio_spi:virtio_spi@1cd12000{
compatible = "virtio,mmio";
reg = <0x1cd12000 0x1000>;
interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
virtio,id = <0xC009>;
status = "ok";
spidev@0 {
compatible = "qcom,spi-msm-codec-slave";
reg = <0>;
spi-max-frequency = <10000000>;
spi-cpha;
// qcom,disable-dma;
status = "ok";
};
};
这里需要注意两点
1 DTSI中的节点地址和中断号要和 上述步骤三中 la.config一致, PS:中断号一致不是数值一样,而是符合linux规则,软件中断号和硬件中断号相差32,即对应关系 是 79+32=111
这两个数值在这两处一致即可,可任意编写,但不要和其他数值冲突 PS:建议同时比对 la.config (现状不冲突)和 DTS中其他值(防止和未来某项冲突)
2 本身希望生成的设备节点和QNX一致为 /dev/spi1 ,但由于高通base设计
3 virtio,id = <0xC009>; 这个数值是怎么来的
需要阅读 /SD-HQX4.5.6.0/lagvm/LINUX/android/kernel_platform/msm-kernel/drivers/spi/virtio-spi.c 代码
从这基本能看到 Virtio-spi的加载逻辑,通过 module_virtio_drviver加载了对应模块,再通过id_table查找对应设备,而设备ID的宏值 VIRTIO_ID_SPI 定义如下 49161
通过HEX转换,即为C009
测试
spidev_test 命令
详细参考:/SD-HQX4.5.6.0/lagvm/LINUX/android/kernel_platform/msm-kernel/tools/spi/spidev_test.c
spidev_test -D /dev/spidev1.0 -H 1 -p '\x7c\x50'
测试结果 OK
(●'◡'●)~,此方法简要描述了配置和测试方法, 是不是很简单!。
点到为止,举一反三!
参考网站
黑莓官方资料:
- VirtIO (qnx.com)
- Physical devices (qnx.com)- vdev ioapic (qnx.com)
通信调试方法:
高通 8255 基本通信(QUP)Android侧控制方法说明_高通8255-CSDN博客
高通8255 Uart IIC SPI 测试方法_i2cdbgr-CSDN博客