紧接着上一篇(Android GNSS 模块分析(三)JNI 层),继续来分析下 Android GNSS HAL 层的功能,本篇准备先介绍下 HIDL 层的封装。至于后面的 HAL 层的功能,由于使用的厂商 Hal 实现,这里先不描述。后续可能更新(或者可以按照原生的先看看)。

下面的整理基于 GNSS HIDL 1.0 的分析

IGnss.hal

Hidl 接口 功能描述 参数 返回值
setCallback(IGnssCallback callback) 给 IGnss 服务添加回调,回调对象是 IGnssCallback IGnssCallback bool
start() 启动定位服务,使用 IGnssCallbck 的 gnssLocationCb() 的回调方法通知上层。定位服务的设置从 setPositionMode() 接口传下来 bool
stop() 停止定位服务,停止 gnssLocationCb() 回调方法提供定位服务 bool
cleanup() 关闭 芯片GNSS 服务,此时芯片可以选择掉电以节省电力
injectTime(GnssUtcTime timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs) 注入当前时间 GnssUtcTime、int64_t、int32_t bool
injectLocation(double latitudeDegrees, double longitudeDegrees, float accuracyMeters) 从另一个 location provider 中注入 location 到 Hal 层 double、double、float bool
deleteAidingData(GnssAidingData aidingDataFlags) 指定要启动的下一个调用将不使用标志中定义的信息 GnssAidingData
setPositionMode(GnssPositionMode mode, GnssPositionRecurrence recurrence, uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs) 设置gnspositionmode参数、其关联的递归值、修复之间的时间、请求的修复精度和首次修复的时间 GnssPositionMode、GnssPositionRecurrence、uint32_t、uint32_t、uint32_t bool
getExtensionAGnssRil() 这个方法返回 IAGnssRil 接口 IAGnssRil
getExtensionGnssGeofencing() 这个方法返回 IGnssGeofencing 接口 IGnssGeofencing
getExtensionAGnss() 这个方法返回 IAGnss 接口 IAGnss
getExtensionGnssNi() 这个方法返回 IGnssNi 接口 IGnssNi
getExtensionGnssMeasurement() 这个方法返回 IGnssMeasurement 接口 IGnssMeasurement
getExtensionGnssNavigationMessage() 这个方法返回 IGnssNavigationMessage 接口 IGnssNavigationMessage
getExtensionXtra() 这个方法返回 IGnssXtra 接口 IGnssXtra
getExtensionGnssConfiguration() 这个方法返回 IGnssConfiguration 接口 IGnssConfiguration
getExtensionGnssDebug() 这个方法返回 IGnssDebug 接口 IGnssDebug
getExtensionGnssBatching() 这个方法返回 IGnssBatching 接口 IGnssBatching

IGnssCallback.hal

Hidl 接口 功能描述 参数 返回值
gnssLocationCb(GnssLocation location) 通过此回调接口通知上层 Location 位置信息。以 GnssLocation 结构对象返回。其中数据包括:纬度、经度、高度、速度、航向、预期的水平位置精度、预期的垂直位置精度、预期速度精度、预期轴承精度、时间戳 GnssLocation
gnssStatusCb(GnssStatusValue status) 调用该函数以通知GNSS底层服务的状态。 GnssStatusValue
gnssSvStatusCb(GnssSvStatus svInfo) 调用该函数以通知GNSS可见卫星状态 GnssSvStatus
gnssNmeaCb(GnssUtcTime timestamp, string nmea) 调用该函数以通知上层NMEA语句 GnssUtcTime、string
gnssSetCapabilitesCb(bitfield<Capabilities> capabilities) 回调函数通知上层GNSS引擎的功能。@param capabilities能力参数是Capability枚举的位字段 bitfield<Capabilities> capabilities)
gnssAcquireWakelockCb() 用于获取GNSS wakelock的回调实用程序。这可以用来防止CPU在处理GNSS事件时挂起。
gnssReleaseWakelockCb() 用于释放GNSS wakelock的回调实用程序。
gnssRequestTimeCb() 请求NTP时间的回调
gnssSetSystemInfoCb(GnssSystemInfo info) 回调函数通知上层GNSS引擎的硬件版本信息。返回到上层的信息包含最后一次获取底层硬件信息的年份 GnssSystemInfo

IGnssXtra.hal

Hidl 接口 功能描述 参数 返回值
setCallback(IGnssXtraCallback callback) 设置 IGnssXtraCallback 回调接口 IGnssXtraCallback bool
injectXtraData(string xtraData) 将下载的XTRA数据注入GNSS接收器 string bool

IGnssXtraCallback.hal

Hidl 接口 功能描述 参数 返回值
downloadRequestCb() 回调请求客户端下载XTRA数据。客户端应该下载XTRA数据并通过调用injtxtradata()进行注入

IAGnssRil.hal

Hidl 接口 功能描述 参数 返回值
setCallback(IAGnssRilCallback callback) 设置 IAGnssRilCallback 回调接口 IAGnssRilCallback
setRefLocation(AGnssRefLocation agnssReflocation) 设置 AGNSS CellID 引用位置,跟 AGNSS 提供服务对应,基站定位 AGnssRefLocation
setSetId(SetIDType type, string setid) 设置 SETID。设置标识唯一订阅用户ID的字符串:IMSI 对应 GMS电话的IMSI、MSISDN 对应 GSM电话的MSISDN,NONE 对应 空字符串 SetIDType、string bool
updateNetworkState(bool connected, NetworkType type, bool roaming) 将网络变化通知到底层GNSS。@param connected表示网络是否连通建立连接和传递数据是可能的。@param type网络类型。手机、wifi等。@param roaming设备当前是否在该网络中漫游 bool、NetworkType、bool bool
updateNetworkAvailability(bool available, string apn) 将网络状态变化和当前APN通知底层GNSS。@param available网络连接是否可用。@param apn包含电话首选接入点名称的字符串。 bool、string bool

IAGnssRilCallback.hal

Hidl 接口 功能描述 参数 返回值
requestSetIdCb(bitfield<ID> setIdflag) Hal 使用这个API请求一个SET ID。@param setIdflag指定HAL需要的SET ID类型 bitfield
requestRefLocCb() Hal使用这个API请求参考位置。

IAGnss.hal

Hidl 接口 功能描述 参数 返回值
setCallback(IAGnssCallback callback) 设置 IAGnssCallback 回调接口 IAGnssCallback
dataConnClosed() 通知AGNSS数据连接已关闭 bool
dataConnFailed() 通知AGNSS无法使用数据连接 bool
setServer(AGnssType type, string hostname, int32_t port) 设置AGNSS服务器的主机名和端口。@param type指定是SUPL还是C2K。@param hostname AGNSS服务器的主机名。@param port与服务器关联的端口号。 AGnssType、string、int32_t bool
dataConnOpen(string apn, ApnIpType apnIpType) 通知有一个数据连接可用,并设置APN的名称及其IP类型,以便用于SUPL连接。@param apn接入点名称(遵循常规apn命名约定)。@param apnIpType指定是SUPL还是C2K。 string、ApnIpType bool

IAGnssCallback.hal

Hidl 接口 功能描述 参数 返回值
agnssStatusIpV4Cb(AGnssStatusIpV4 status) 带有AGNSS(IpV4)状态信息的回调。@param status将为AGnssStatusIpV4类型。 AGnssStatusIpV4
agnssStatusIpV6Cb(AGnssStatusIpV6 status) 带有AGNSS(IpV6)状态信息的回调。@param status将为AGnssStatusIpV6类型。 AGnssStatusIpV6

IGnssNavigationMessage.hal

Hidl 接口 功能描述 参数 返回值
setCallback(IGnssNavigationMessageCallback callback) 初始化接口并向HAL注册回调例程。成功调用'setCallback'后,HAL必须开始提供可用的更新。@param回调句柄到IGnssNavigationMessageCallack接口 IGnssNavigationMessageCallback
close() 停止来自HAL的更新,并注销回调例程。在调用close()之后,HAL必须认为之前注册的回调是无效的。如果在没有setCallback之前调用close(),则此函数必须不执行任何工作。

IGnssNavigationMessageCallback.hal

Hidl 接口 功能描述 参数 返回值
gnssNavigationMessageCb(GnssNavigationMessage message) 从HAL报告GNSS导航消息的可用片段的回调。@param message - GNSS导航子消息/子帧表示。 GnssNavigationMessage

IGnssMeasurement.hal

Hidl 接口 功能描述 参数 返回值
setCallback(IGnssMeasurementCallback callback) 初始化接口并向HAL注册回调例程。成功调用'setCallback'后,HAL必须开始以1Hz的平均输出速率提供更新(可以容忍0-2000msec范围内偶尔的测量内时间偏移)。 IGnssMeasurementCallback GnssMeasurementStatus
close() 停止来自HAL的更新,并注销回调例程。在调用close()之后,HAL必须认为之前注册的回调是无效的。如果在没有setCallback之前调用close(),则此函数必须不执行任何工作。

IGnssMeasurementCallback.hal

Hidl 接口 功能描述 参数 返回值
GnssMeasurementCb(GnssData data) 回调函数,以便hal将GnssData结构传递回客户端。 GnssData

IMeasurementCorrections.hal

Hidl 接口 功能描述 参数 返回值
setCorrections(MeasurementCorrections corrections) 注入测量修正以供HAL使用,以改善GNSS定位输出。这些不是用来调整IGnssMeasurementCallback的输出值-那些仍然是原始的,未校正的测量。一般来说,当平台定义的条件得到满足时,例如,根据IGnssCallback中报告的GNSS芯片组的能力,以足够高的精度请求GNSS Location时,这些将被注入。@param corrections HAL使用的计算修正值。 MeasurementCorrections bool
setCallback(IMeasurementCorrectionsCallback callback) 注册 IMeasurementCorrectionsCallback 回调接口 IMeasurementCorrectionsCallback bool

IMeasurementCorrectionsCallback.hal

Hidl 接口 功能描述 参数 返回值
setCapabilitiesCb(bitfield<Capabilities> capabilities) 回调通知框架GNSS HAL实现的测量校正特定功能。GNSS HAL必须在框架打开测量校正接口后立即调用此方法。@param capabilities支持测量校正功能。它必须支持LOS_STATS或EXCESS_PATH_LENGTH功能。 bitfield<Capabilities>

IGnssDebug.hal

Hidl 接口 功能描述 参数 返回值
getDebugData() 该方法向HAL请求位置、时间和卫星星历的调试信息。@return ret debug来自GNSS Hal的数据信息,包含当前最知名的位置,最知名的时间估计和设备可以跟踪的星座的完整列表 DebugData

IGnssNi.hal

Hidl 接口 功能描述 参数 返回值
setCallback(IGnssNiCallback callback) 注册 IGnssNiCallback 回调对象 IGnssNiCallback
respond(int32_t notifId, GnssUserResponseType userResponse) 向HAL发送响应。@param notiffid由HAL生成的用于关联NI通知和框架响应的ID。@param userResponse GNSS Ni响应,指示通知是否被接受、拒绝或不响应。 int32_t、GnssUserResponseType

IGnssNiCallback.hal

Hidl 接口 功能描述 参数 返回值
niNotifyCb(GnssNiNotification notification) 带有网络发起请求的回调。@param通知网络发起请求。 GnssNiNotification

IGnssConfiguration.hal

Hidl 接口 功能描述 参数 返回值
setSuplEs(bool enabled) 此方法启用或禁用 NI紧急SUPL限制。 bool bool
setSuplVersion(uint32_t version) 此方法设置运营商要求的SUPL版本。如果支持,GNSS HAL必须使用该版本的SUPL协议。@param version运营商要求的SUPL版本。这是一个位掩码,位0:7表示服务指示字段,位8:15表示次要版本,位16:23表示主要版本。 uint32_t bool
setSuplMode(bitfield<SuplMode> mode) 此方法用于设置SUPL模式。@param mode指定SUPL模式的位掩码,通过SUPL mode枚举设置。 bitfield<SuplMode> bool
setGpsLock(bitfield<GpsLock> lock) 此方法配置当用户关闭GPS On设置时,GPS功能应该如何锁定。@param lock位掩码,指定GPS功能被锁定,根据GpsLock enum。 bitfield<GpsLock> bool
setLppProfile(bitfield<LppProfile> lppProfile) 此方法用于设置“LTE定位配置文件”的配置信息。@param lppProfile位掩码,指定根据lppProfile enum设置的LTE定位配置文件配置。 bitfield<LppProfile> bool
setGlonassPositioningProtocol (bitfield<GlonassPosProtocol> protocol) 此方法在A-Glonass系统上选择定位协议。@param protocol位掩码,指定要设置为glonasspoprotocol enum的定位协议。 bitfield <GlonassPosProtocol> bool
setEmergencySuplPdn(bool enable) 此方法配置要使用的PDN。@param enable如果为真,使用紧急PDN,如果为假,使用普通PDN。 bool bool

IGnssGeofencing.hal

Hidl 接口 功能描述 参数 返回值
setCallback(IGnssGeofenceCallback callback) 打开geofence接口,并向HAL提供回调例程。 IGnssGeofenceCallback
addGeofence(int32_t geofenceId, double latitudeDegrees, double longitudeDegrees, double radiusMeters, GeofenceTransition lastTransition, bitfield<IGnssGeofenceCallback.GeofenceTransition> monitorTransitions, uint32_t notificationResponsivenessMs, uint32_t unknownTimerMs) 添加一个Geofence区域。这个api目前支持圆形地球围栏。@param geofenceId geofence的id。如果这个id的geoofence已经存在,则必须返回一个错误值(ERROR_ID_EXISTS)。@param latitudeDegrees geoofence lastTransition的纬度(单位为度)。@param geoofence lastTransition的经度(以度为单位)。@param radiusMeters geoofence lastTransition的半径(米)。@param lastTransition地球围栏的当前状态。例如,如果系统已经知道用户在geoofence内,这将被设置为enter。在大多数情况下,这是不确定的。@param monitorTransitions -要监视哪些转换。进入,退出和不确定的位或。@param notificationResponsivenessMs -定义当与Geofence相关的转换被触发时,回调必须多快被调用的最佳描述。例如,如果用ENTERED设置为1000毫秒,那么回调必须在进入geoofence的1000毫秒内调用。该参数以毫秒为单位定义。注意:不要将此与GNSS轮询的速率相混淆。为了省电,可以动态地改变GNSS的采样速率;因此,采样速率可能比这快或慢。@param unknownTimerMs -不确定转换必须被触发的时间限制。该参数以毫秒为单位定义。 int32_t、double、double、double、GeofenceTransition、bitfield<>、uint32_t、uint32_t
pauseGeofence(int32_t geofenceId) 暂停监视一个特定的地理围栏。@param geofenceId geofence的id。 int32_t
resumeGeofence(int32_t geofenceId,bitfield <IGnssGeofenceCallback.GeofenceTransition> monitorTransitions) 恢复监控一个特定的地理围栏。@param geofenceId - geoofence的id。@param monitorTransitions指定要监视的转换。它可以是“进入”、“退出”和“不确定”的位或。这将取代addGeofenceArea调用中提供的相关值。 int32_t、bitfield<>
removeGeofence(int32_t geofenceId) 移除Geofence区域。函数返回后,不需要发送任何通知。@param geofenceId地球围栏id。 int32_t

IGnssGeofenceCallback.hal

Hidl 接口 功能描述 参数 返回值
gnssGeofenceTransitionCb( int32_t geofenceId, GnssLocation location, GeofenceTransition transition, GnssUtcTime timestamp) 与地球围栏转换相关的回调。只有当调用者对特定的转换感兴趣时,才必须调用回调函数。例如,如果调用者只对ENTERED转换感兴趣,那么就不能使用EXITED转换调用回调。重要:如果转换被触发导致这个回调,GNSS子系统将唤醒应用程序处理器,如果它处于挂起状态。@param geofenceId addGeofenceArea关联的id。@param location GNSS当前位置。@param transition可以是ENTERED, exit或uncertainty中的一个。@param timestamp检测到转换的时间戳。 int32_t、GnssLocation、GeofenceTransition、GnssUtcTime
gnssGeofenceStatusCb( GeofenceAvailability status, GnssLocation lastLocation) 回调与GNSS系统用于地理围栏监测的可用性相关。如果GNSS系统确定由于缺乏可靠性或GNSS信号不可用而无法监测地栅栏,它将调用带有UNAVAILABLE参数的回调。@param status -不可用或可用。@param lastLocation -最后的已知位置。 GeofenceAvailability、GnssLocation
gnssGeofenceAddCb(int32_t geofenceId, GeofenceStatus status) 与addGeofence调用关联的回调。@param geofenceId地球栅栏Id。@param status如果geoofence添加成功,将为OPERATION_SUCCESS。如果geofence极限已经达到,将会是ERROR_TOO_MANY_GEOFENCES。如果带id的geofence已经存在,则将为ERROR_ID_EXISTS。如果monitorTransition包含无效的转换,则将为ERROR_INVALID_TRANSITION。对于其他错误将是ERROR_GENERIC。 int32_t、GeofenceStatus
gnssGeofenceRemoveCb(int32_t geofenceId, GeofenceStatus status) 与removegofence调用相关联的回调。@param geofenceId地球栅栏Id。@param status成功返回OPERATION_SUCCESS对于无效id将是ERROR_ID_UNKNOWN,对于其他id将是ERROR_GENERIC。 int32_t、GeofenceStatus
gnssGeofencePauseCb(int32_t geofenceId, GeofenceStatus status) 与pauseGeofence调用关联的回调。@param geofenceId地球栅栏Id。@param status如果成功,将为OPERATION_SUCCESS。无效的id将是ERROR_ID_UNKNOWN。当monitorTransitions无效时,将是ERROR_INVALID_TRANSITION。将是ERROR_GENERIC用于其他err错误。 int32_t、GeofenceStatus
gnssGeofenceResumeCb(int32_t geofenceId, GeofenceStatus status) 与resumeGeofence调用关联的回调。@param geofenceId -地球围栏Id。@param status成功则返回OPERATION_SUCCESS。对于无效id将是ERROR_ID_UNKNOWN,对于其他id将是ERROR_GENERIC。 int32_t、GeofenceStatus

IGnssBatching.hal

Hidl 接口 功能描述 参数 返回值
init(IGnssBatchingCallback callback) 打开接口并为该接口的实现提供回调例程。 IGnssBatchingCallback bool
getBatchSize() 返回此硬件实现中可用的批处理大小(以GnssLocation对象的数量为单位)。 uint16_t
start(Options options) 开始批处理位置。该API主要在AP处于休眠状态时使用,设备可以批处理硬件中的位置。IGnssBatchingCallback用于返回位置。当缓冲区已满且使用WAKEUP_ON_FIFO_FULL时,必须调用IGnssBatchingCallback来返回位置。当缓冲区已满且WAKEUP_ON_FIFO_FULL未设置时,最老的位置对象将被丢弃。在这种情况下,AP不能被唤醒。然后,AP通常负责使用flushBatchedLocation根据需要显式地请求位置,以避免它被丢弃。 Options bool
flush() 检索当前存储的所有批处理位置。IGnssBatchingCallback用于返回位置。在响应中必须调用IGnssBatchingCallback,即使没有要刷新的位置(在这种情况下Location向量必须为空)。
stop() 停止处理 bool
cleanup() 关闭接口。如果任何批处理操作正在进行中,则必须停止它们。如果任何位置在硬件批处理中,它们必须被删除(并且不能通过回调发送)。如果要恢复使用,需要重新调用init()接口

IGnssBatchingCallback.hal

Hidl 接口 功能描述 参数 返回值
gnssLocationBatchCb(vec<GnssLocation> locations) 在输出一批位置时,通过各种方式调用,包括刷新请求和缓冲区已满(如果设置了适当的选项)。 vec<GnssLocation>

IGnssVisibilityControl.hal

Hidl 接口 功能描述 参数 返回值
enableNfwLocationAccess(vec<string> proxyApps) 启用/禁用GNSS HAL中的非框架实体位置访问权限。 vec<string> bool
setCallback(IGnssVisibilityControlCallback callback) 给Hal层注册IGnssVisibilityControlCallback回调 IGnssVisibilityControlCallback bool

IGnssVisibilityControlCallback.hal

Hidl 接口 功能描述 参数 返回值
nfwNotifyCb(NfwNotification notification) 向用户回调一个NfwNotification信息。包括 NfwNotification
isInEmergencySession() 告知设备当前是否处于紧急会话中。紧急会话定义为设备处于用户发起的紧急呼叫中或处于紧急呼叫后扩展时间段。如果GNSS HAL实现不能确定设备是否处于紧急会话模式,它必须在服务网络发起紧急SUPL和控制平面位置请求之前调用此方法来确认设备处于紧急会话。 bool

以上就是 1.0 版本所封装的 HIDL 服务接口了。不同厂商只需要实现这一套接口,便可以为 Android 提供 GNSS 的服务。

如果文中有错,烦请告知作者,必当有则改之,无则加勉。在此,小弟先行告谢!

联系作者:

上一篇:Android GNSS 模块分析(三)JNI 层

下一篇:Android GNSS模块分析(五)NMEA  协议

Android GNSS 模块分析(四)HAL 层相关推荐

  1. Android GNSS 模块分析(五)NMEA 协议

    紧接着上一篇<Android GNSS 模块分析(四)HAL 层>,本篇简述下导航硬件设备与卫星导航系统之间的通信协议. NMEA 协议 简介: NMEA(National Marine ...

  2. Android 源码分析 - 蓝牙 - HAL层

    Bluetooth模块接口定义在hardware/libhardware/include/hardware/bluetooth.h中.模块ID为"bluetooth"或者" ...

  3. Android 语音遥控器的整体分析-HAL层的AudioFlinger

    上篇说到语音部分最后会通过AudioFlinger来操作HAL层. 一.首先我们看下硬件接口层的接口(奇怪为什么只有Audio的hardwareinterface): (1)hardware\libh ...

  4. android wifi模块分析

    声明:本文纯属网上资料收集,版权归源作者所有,转载时请标明为转载文章 现在对android平台的wifi模块了解了一段时间,现在做一些简要总结,以便以后查阅和与修正,上正文. [Wifi模块学习流程] ...

  5. android camera fragment,Android Camera 模块分析(三)

    第三部分 Camera的主要实现分析 3.1 JAVA程序部分 在packages/apps/Camera/src/com/android/camera/ 目录的Camera.java文件中,包含了对 ...

  6. Android libcore添加JNI调用Hal层接口问题

    undefined reference to 'hw_get_module' collect2: error: ld returned 1 exit status

  7. Android 系统(4)---Android HAL层与Linux Kernel层驱动开发简介

    Android HAL层与Linux Kernel层驱动开发简介 近日稍微对Android中的驱动开发做了一些简要的了解,稍稍理清了一下Android驱动开发的套路,总结一下笔记. HAL:Hardw ...

  8. Android HAL层与Linux Kernel层驱动开发简介

    Android HAL层与Linux Kernel层驱动开发简介 阅读数:5070 近日稍微对Android中的驱动开发做了一些简要的了解,稍稍理清了一下Android驱动开发的套路,总结一下笔记. ...

  9. Android HAL层浅析

    文章目录 1.HAL层在Android系统中的位置 2.HAL层概述 3.旧的HAL架构module 4.新的HAL架构module stub 5.HAL Stub框架分析 1.HAL层在Androi ...

最新文章

  1. easyui 添加 自定义图标
  2. 萌新向Python数据分析及数据挖掘 第一章 Python基础 第三节 列表简介 第四节 操作列表...
  3. 逻辑分析推理(五小姐问题)
  4. LeetCode 954. 二倍数对数组(map计数)
  5. 如何在SQL Server中实现错误处理
  6. Win7系统下网站发布IIS配置
  7. 大数据分析有哪些分析模型
  8. 【转】Roberts 算子
  9. QBackingStore::flush() called with non-exposed window, behavior is undefined
  10. Caffe傻瓜系列(3):激活层(Activiation Layers)及参数
  11. 万圣节头像挂件微信小程序前端
  12. docker的一些使用技巧
  13. Qt界面无法切换输入法的解决方法
  14. cpar文件的导入导出及注意事项
  15. matlab实验报告井字棋,有偿井字棋游戏300+
  16. AI虚拟人物 数字人直播,不用出镜,不用露脸的直播方式(附教程 软件)
  17. 强基计划生命科学和计算机,问计问策 促“强基计划”落细落小落实
  18. Django 重写authenticate实现输入账号、邮箱、手机号登录验证
  19. 浅析JWT| JWT是啥子,Java构建JWT
  20. CSS--ps的常见操作

热门文章

  1. 【C++】操作符重载
  2. 使用git拉取项目、创建分支、提交代码教程
  3. UVa 10115 - Automatic Editing
  4. 新闻列表 android,- Android中实现简单的新闻列表
  5. 24.STM32的IO口扩展PCF8574
  6. 安卓开发为什么选择用Java语言
  7. 56个JavaScript 实用工具函数助你提升开发效率!
  8. 电子邮箱的工作原理以及SMTP、POP3、IMAP之间的联系和区别
  9. 利用百度(或者360搜索等)的快照解决公司网络限制
  10. github上如何删除自己的仓库