公司平板电脑以前都是不带GPS功能的,今年过完年来,公司新开了一个带GPS功能的项目,软件部分由我来负责。说实话,平时调试的外设模块驱动也是很多了,但是真正调试像GPS这样的串口通讯模块,接触的还是比较少。虽然蓝牙模块也是通过串口通讯工作的,但是每次蓝牙配置都只需要在内核board里面配置好相应的电源,复位,中断,串口等gpio口就够了,最多考虑一下接口的复用就可以了,都是属于内核层的gpio口调用。
这次gps模块的调试,需要涉及到的是用户层的gpio口调用,首先需要在内核里开启
Device Drivers —> GPIO Support —> /sys/class/gpio/… (sysfs interface)。
然后在kernel/arch/arm/mach-rk30/include/mach/gpio.h找到相应gpio口对应的计算表达式,比如gpio3_d7在文档中对应的计算表达式是 #define RK30_PIN3_PD7 (3*NUM_GROUP + PIN_BASE + 31) 、其中kernel/arch/arm/plat-rk/include/plat/gpio.h中有定义#define NUM_GROUP 32 irqs.h中定义了#define PIN_BASE 5*32,由此可以计算出RK30_PIN3_PD7 的值为287.然后在init.rk30board.rc文件的on post-fs地方写入相关节点的脚本:
#broadcom gps init reset standby
write /sys/class/gpio/export 287
write /sys/class/gpio/export 255
write /sys/class/gpio/gpio287/direction out
write /sys/class/gpio/gpio255/direction out
write /sys/class/gpio/gpio287/value 1
write /sys/class/gpio/gpio255/value 1
write /dev/ttyS1 123456
#end gps IO control
# for gps
# chmod 0664 /data/gps
# mkdir /data/gps/log
# chmod 0664 /data/gps/log
# chmod 0664 /system/bin/glgps
# for gps
mkdir /data/gps
chmod 0777 /data/gps
mkdir /data/gps/log
chmod 0777 /data/gps/log
chmod 0777 /system/bin/glgps
chmod 0777 /system/bin/scmd
chmod 0777 /dev/ttyS1
chmod 0777 /sys/class/gpio/gpio255/value
chmod 0777 /sys/class/gpio/gpio287/value
#broadcom gps init end
在service相关的脚本处写入:
#start gps service 4571
service gps-daemon /system/bin/glgps -c /system/etc/gps/gpsconfig.xml
class main
user system
group system
socket gps seqpacket 0777 root root
# disabled
# oneshot
##start gps service
#service gps-daemon /system/bin/glgps -c /system/etc/gps/glconfig.xml
# user root
# group root
# socket gps seqpacket 0777 root root
# class main
device\rockchip\rk30sdk\gps\gpsconfig.xml
RfType="GL_RF_47511_BRCM" 内部放大器
RfType="GL_RF_47511_BRCM_EXT_LNA" 外部放大器
system\bin目录下:
gl-gps 只能用adb命令控制查看搜星信号
1./system/bin/gl-gps -c /system/etc/gps/gpsconfig.xml Periodic
2.另开窗口:cat /data/gps/nmea
glgps 可以使用gps相关APK软件查看搜星信号
1./system/bin/glgps -c /system/etc/gps/gpsconfig.xml Periodic
2.另开窗口:cat /data/gps/nmea
scmd用于检测串口通讯是否正常,scmd /dev/ttyS1可以检测是否侦测到了GPS芯片。
调试总结:
Android的gps的apk无法打开的情况
1. system/etc/permissions/android.hardware.location.gps.xml这个文件是否存在
2. logcat 有报缺少gps.conf的错误,检查是否缺少如下的文件
out/target/product/rk30sdk/system/etc/gps.conf
3. logcat 报不能加载gps jni的错误,检查是否有生成相应的.so文件
out/target/product/rk30sdk/system/lib/hw/gps.rockchip.so
Gps内核调试
1. 检查出口通讯是否正常./scmd /dev/ttS1
2. 检查/sys/class/gpio/gpio287和gpio255,是否出现这样的节点
3. 检查内核进程(ps)有没有glgps进程
4.检查out/target/product/rk30sdk/system/etc/gps/glconfig.xml
和\device\rockchip\rk30sdk\init.rk30board.rc的控制脚是否一致
------------------------------------------------以下部分为参考文档----------------------------------------------------------------------------------------------------------
/sys/class/gpio 的使用说明:
01 |
gpio_operation 通过/sys/文件接口操作IO端口 GPIO到文件系统的映射 |
02 |
* 控制GPIO的目录位于/sys/ class /gpio |
03 |
* /sys/ class /gpio/export文件用于通知系统需要导出控制的GPIO引脚编号 |
04 |
* /sys/ class /gpio/unexport 用于通知系统取消导出 |
05 |
* /sys/ class /gpio/gpiochipX目录保存系统中GPIO寄存器的信息,包括每个寄存器控制引脚的起始编号base,寄存器名称,引脚总数 导出一个引脚的操作步骤 |
06 |
* 首先计算此引脚编号,引脚编号 = 控制引脚的寄存器基数 + 控制引脚寄存器位数 |
07 |
* 向/sys/ class /gpio/export写入此编号,比如12号引脚,在shell中可以通过以下命令实现,命令成功后生成/sys/ class /gpio/gpio12目录,如果没有出现相应的目录,说明此引脚不可导出: |
08 |
echo 12 > /sys/ class /gpio/export |
09 |
* direction文件,定义输入输入方向,可以通过下面命令定义为输出 |
10 |
echo out > direction |
11 |
* direction接受的参数:in, out, high, low。high/low同时设置方向为输出,并将value设置为相应的1/0。 |
12 |
* value文件是端口的数值,为1或0. |
13 |
echo 1 > value |
用户空间访问gpio,即通过sysfs接口访问gpio,下面是/sys/class/gpio目录下的三种文件:
--export/unexport文件
--gpioN指代具体的gpio引脚
--gpio_chipN指代gpio控制器
必须知道以上接口没有标准device文件和它们的链接。
/sys/class/gpio/export,该接口只能写不能读
用户程序通过写入gpio的编号来向内核申请将某个gpio的控制权导出到用户空间当然前提是没有内核代码申请这个gpio端口
比如 echo 19 > export
上述操作会为19号gpio创建一个节点gpio19,此时/sys/class/gpio目录下边生成一个gpio19的目录
/sys/class/gpio/unexport和导出的效果相反。
比如 echo 19 > unexport
上述操作将会移除gpio19这个节点。
指代某个具体的gpio端口,里边有如下属性文件
direction 表示gpio端口的方向,读取结果是in或out。该文件也可以写,写入out 时该gpio设为输出同时电平默认为低。写入low或high则不仅可以
设置为输出 还可以设置输出的电平。 当然如果内核不支持或者内核代码不愿意,将不会存在这个属性,比如内核调用了gpio_export(N,0)就
表示内核不愿意修改gpio端口方向属性
(echo out > /sys/class/gpio/gpio287/direction )
value 表示gpio引脚的电平,0(低电平)1(高电平),如果gpio被配置为输出,这个值是可写的,记住任何非零的值都将输出高电平, 如果某个引脚
能并且已经被配置为中断,则可以调用poll(2)函数监听该中断,中断触发后poll(2)函数就会返回。
(echo 1 > /sys/class/gpio/gpio287/value)
edge 表示中断的触发方式,edge文件有如下四个值:"none", "rising", "falling","both"。
none表示引脚为输入,不是中断引脚
rising表示引脚为中断输入,上升沿触发
falling表示引脚为中断输入,下降沿触发
both表示引脚为中断输入,边沿触发
这个文件节点只有在引脚被配置为输入引脚的时候才存在。 当值是none时可以通过如下方法将变为中断引脚
echo "both" > edge;对于是both,falling还是rising依赖具体硬件的中断的触发方式。此方法即用户态gpio转换为中断引脚的方式
active_low 不怎么明白,也木有用过
gpiochipN表示的就是一个gpio_chip,用来管理和控制一组gpio端口的控制器,该目录下存在一下属性文件:
base 和N相同,表示控制器管理的最小的端口编号。
lable 诊断使用的标志(并不总是唯一的)
ngpio 表示控制器管理的gpio端口数量(端口范围是:N ~ N+ngpio-1)