日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

安卓平台下的GPS架构介绍及驱动移植记录

發布時間:2023/12/3 综合教程 40 生活家
生活随笔 收集整理的這篇文章主要介紹了 安卓平台下的GPS架构介绍及驱动移植记录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、前言

我的工作是關于汽車車機BSP部分。

汽車車機,其實基本和人們日常所用的手機一樣,也是安卓平臺的。所謂安卓,就是一層安卓服務包裹著Linux內核所形成的操作系統。

BSP組,主要工作內容就是負責soc的Linux系統部分的驅動移植、調試,及BUG解決。

從畢業到現在,工作也有大半年了。跟著前輩學習GPS模塊的移植、調試,和BUG解決也有差不多兩個月了。心里想著,是時候寫一篇關于GPS驅動移植學習的總結和筆記了。

于是今天,我嘗試著動手開始梳理這兩個月來的所學所知。

二、U-blox m8l導航模塊

目前汽車車機,所用的GPS都是屬于高度集成的模塊,所有的功能都在模塊內部實現。用戶只需要通過串口對數據進行讀取與解析,就可以獲取GPS信息。

我們公司目前所用的GPS導航模塊有三種,這篇文章所要介紹,則是瑞士優北羅股份有限公司所研發制作的一款整合了運動、方向和高度傳感器的NEO-M8L汽車慣性導航(ADR, Automotive Dead Reckoning)模塊。該模塊將陀螺儀和加速度傳感器與u-blox領先的GNSS平臺 - u-blox M8集成在一起,使其成為市場上性能最佳的室內/室外定位解決方案,是所有道路車輛和高精度導航應用的理想選擇。

NEO-M8L模塊中內置了u-blox突破性的“3D汽車慣性導航”(3D ADR)芯片技術。它利用車輛的速度信息以及模塊的內置傳感器,即使當衛星信號完全被遮蔽或終端設備沒有安裝于水平位置時,仍能提供準確的三維定位信息。此外,基于ADR技術的里程表功能還能提供正確和連續的行駛距離。

該模塊能追蹤所有可視的GNSS衛星,包括GPS、GLONASS、北斗和所有的SBAS系統 (歐洲的伽利略系統將在未來的固件版本中支持)。該模塊目前支持兩種GNSS系統的并行接收,并且能以高達每秒20次的速度輸出定位信息。

三、安卓平臺下的GPS架構

安卓系統,實現了一系列的架構和分層,我們BSP移植驅動,主要完成兩部分工作。
- 實現Linux驅動模塊,保證Linux驅動對硬件的驅動能力;
- 對接安卓hal層架構,實現hal層接口。

因為GPS屬于高度集成的一體化模塊,所有的功能都在模塊內部實現,所以,對GPS的驅動移植,主要是為了匹配和實現安卓系統提供的HAL層接口,然后調用串口驅動的接口去讀取對應串口地址的數據即可。

我們先來看一下安卓的GPS架構圖。

由圖可以知道,安卓的GPS架構由上到下是:app->framework->jni->hidl->hal,我們這篇文章,主要介紹從jni->hidl->hal層。

3.1、HAL層標準接口

HAL 可定義一個標準接口以供硬件供應商實現,這可讓 Android 忽略較低級別的驅動程序實現。借助 HAL,您可以順利實現相關功能,而不會影響或更改更高級別的系統。

為了保證 HAL 具有可預測的結構,每個硬件專用 HAL 接口都要具有在 hardware/libhardware/include/hardware/hardware.h 中定義的屬性。這類接口可讓 Android 系統以一致的方式加載 HAL 模塊的正確版本。HAL 接口包含兩個組件:模塊和設備。

3.1.1、模塊

模塊代表打包的 HAL 實現,這種實現存儲為共享庫 (.so file)。hardware/libhardware/include/hardware/hardware.h 頭文件可定義一個代表模塊的結構體 (hw_module_t),其中包含模塊的版本、名稱和作者等元數據。Android 會根據這些元數據來找到并正確加載 HAL 模塊。

另外,hw_module_t 結構體還包含指向另一個結構體 hw_module_methods_t 的指針,后面這個結構體包含指向相應模塊的 open 函數的指針。此 open 函數用于與相關硬件(此 HAL 是其抽象形式)建立通信。

typedef struct hw_module_t {/** tag must be initialized to HARDWARE_MODULE_TAG */uint32_t tag;uint16_t module_api_version;
#define version_major module_api_versionuint16_t hal_api_version;
#define version_minor hal_api_version/** Identifier of module */const char *id;/** Name of this module */const char *name;/** Author/owner/implementor of the module */const char *author;/** Modules methods */struct hw_module_methods_t* methods;/** module's dso */void* dso;
} hw_module_t;typedef struct hw_module_methods_t {/** Open a specific device */int (*open)(const struct hw_module_t* module, const char* id, struct hw_device_t** device);
} hw_module_methods_t;

3.1.2、設備

設備是產品硬件的抽象表示。

設備由 hw_device_t 結構體表示。與模塊類似,每類設備都定義了一個通用 hw_device_t 的詳細版本,其中包含指向特定硬件功能的函數指針。

struct gps_device_t {struct hw_device_t common;const GpsInterface* (*get_gps_interface)(struct gps_device_t* dev);
};typedef struct hw_device_t {/** tag must be initialized to HARDWARE_DEVICE_TAG */uint32_t tag;uint32_t version;/** reference to the module this device belongs to */struct hw_module_t* module;/** padding reserved for future use */
#ifdef __LP64__uint64_t reserved[12];
#elseuint32_t reserved[12];
#endif/** Close this device */int (*close)(struct hw_device_t* device);
} hw_device_t;

3.2、HIDL —?HIDL HAL

hidl的官方標準定義為:HIDL是HAL接口定義語言(簡稱 HIDL,發音為“hide-l”),是用于指定 HAL 和其用戶之間的接口的一種接口描述語言 (IDL)。

安卓官方設計 HIDL 這個機制的目的,主要是想把框架(framework)與 HAL 進行隔離,使得框架部分可以直接被覆蓋、更新,而不需要重新對 HAL 進行編譯。

3.2.1、客戶端和服務器實現

HIDL 接口具有客戶端和服務器實現:

- HIDL 接口的客戶端實現是指通過在該接口上調用方法來使用該接口的代碼。

- 服務器實現是指 HIDL 接口的實現,它可接收來自客戶端的調用并返回結果(如有必要)。

在從libhardware HAL 轉換為 HIDL HAL 的過程中,HAL 實現成為服務器,而調用 HAL 的進程則成為客戶端。默認實現可提供直通和 Binder 化 HAL。

上圖為HAL的幾個發展歷程,方式2為目前我的開發環境所使用的直通方式,框架和HAL之間通過HIDL接口實現通信,硬件廠商負責服務器的實現。

3.2.2、系統服務啟動gps.ublox.so

下面從系統服務方面介紹一下系統啟動,獲取gps.ublox.so(gps hal驅動編譯生成的文件)流程。

①、首先介紹GNSS的HIDL接口,編譯生成"android.hardware.gnss@1.0"接口共享庫,客戶端和服務器之間就是通過這些接口來工作的,服務器端需要做的就是實現該接口。

接口編譯腳本如下:

hidl_interface {name: "android.hardware.gnss@1.0",root: "android.hardware",vndk: {enabled: true,},srcs: ["types.hal","IAGnss.hal","IAGnssCallback.hal","IAGnssRil.hal","IAGnssRilCallback.hal","IGnss.hal","IGnssBatching.hal","IGnssBatchingCallback.hal","IGnssCallback.hal","IGnssConfiguration.hal","IGnssDebug.hal","IGnssGeofenceCallback.hal","IGnssGeofencing.hal","IGnssMeasurement.hal","IGnssMeasurementCallback.hal","IGnssNavigationMessage.hal","IGnssNavigationMessageCallback.hal","IGnssNi.hal","IGnssNiCallback.hal","IGnssXtra.hal","IGnssXtraCallback.hal",],interfaces: ["android.hidl.base@1.0",],types: ["GnssConstellationType","GnssLocation","GnssLocationFlags","GnssMax",],gen_java: true,gen_java_constants: true,
}

②、rc文件啟動服務android.hardware.gnss@1.0-service

android.hardware.gnss@1.0-service.rc啟動服務android.hardware.gnss@1.0-service

android.hardware.gnss@1.0-service.rc文件內容如下:

service vendor.gnss_service /vendor/bin/hw/android.hardware.gnss@1.0-service
class hal
user gps
group system gps radio

android.hardware.gnss@1.0-service服務由Android.bp編譯得到,其次還包含了HIDL接口"android.hardware.gnss@1.0",Android.bp文件部分內容如下:

cc_binary {relative_install_path: "hw",vendor: true,name: "android.hardware.gnss@1.0-service",defaults: ["hidl_defaults"],init_rc: ["android.hardware.gnss@1.0-service.rc"],srcs: ["service.cpp"],shared_libs: ["liblog","libcutils","libdl","libbase","libutils","libhardware","libbinder","libhidlbase","libhidltransport","android.hardware.gnss@1.0",],
}

我們看到service.cpp,它將對提供的-impl 庫執行dlopen() 操作,并將其作為 Binder 化服務提供,service.cpp代碼如下:

#define LOG_TAG "android.hardware.gnss@1.0-service"
#include <android/hardware/gnss/1.0/IGnss.h>
#include <hidl/LegacySupport.h>
#include <binder/ProcessState.h>using android::hardware::gnss::V1_0::IGnss;
using android::hardware::defaultPassthroughServiceImplementation;int main() 
{// The GNSS HAL may communicate to other vendor components via// /dev/vndbinderandroid::ProcessState::initWithDriver("/dev/vndbinder");return defaultPassthroughServiceImplementation<IGnss>();
}

③、"android.hardware.gnss@1.0-impl"是接口的具體實現。

-impl 庫也由Android.bp編譯而成,其部分內容如下:

cc_library_shared {name: "android.hardware.gnss@1.0-impl",defaults: ["hidl_defaults"],vendor: true,relative_install_path: "hw",srcs: ["ThreadCreationWrapper.cpp","AGnss.cpp","AGnssRil.cpp","Gnss.cpp","GnssBatching.cpp","GnssDebug.cpp","GnssGeofencing.cpp","GnssMeasurement.cpp","GnssNavigationMessage.cpp","GnssNi.cpp","GnssXtra.cpp","GnssConfiguration.cpp","GnssUtils.cpp",],shared_libs: ["liblog","libhidlbase","libhidltransport","libutils","android.hardware.gnss@1.0","libhardware",],
}

④、HIDL_FETCH_IModuleName 函數

為了讓 HAL 在直通模式下運行,Gnss.cpp 必須具有 HIDL_FETCH_IModuleName 函數,函數內容如下:

IGnss* HIDL_FETCH_IGnss(const char* /* hal */) {hw_module_t* module;IGnss* iface = nullptr;int err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);if (err == 0) {hw_device_t* device;err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);if (err == 0) {iface = new Gnss(reinterpret_cast<gps_device_t*>(device));} else {ALOGE("gnssDevice open %s failed: %d", GPS_HARDWARE_MODULE_ID, err);}} else {ALOGE("gnss hw_get_module %s failed: %d", GPS_HARDWARE_MODULE_ID, err);}return iface;
}

這個函數會加載gps.ublox.so庫。

3.3、JNI

jni是framework與hidl hal之間的一層,為java語言實現的framework調用c++語言實現的hidl hal代碼提供接口。

四、源碼分析

4.1、獲取GPS驅動接口

4.1.1、hidl層獲取hal層接口

hidl文件位置android/hardware/interface/gnss/1.0/default/Gnss.cpp。

hal層文件位置android/hardware/u-blox/gps/。

由3.2內容,可以知道,系統服務起來之后,hidl層最開始運作起來的地方就是HIDL_FETCH_IModuleName函數了,通過名字,我們可以知道,這個函數的意思是獲取模塊名,換句話來說,也就是獲取3.1提到過的“hw_module_t”和“hw_device_t”這兩個結構體。

我們先看到這個HIDL_FETCH_IModuleName函數第5行,這里調用了hw_get_module函數,這個函數會根據GPS_HARDWARE_MODULE_ID去找到對應的“hw_module_t”,hal驅動層“hw_module_t”如下:

hw_module_t HAL_MODULE_INFO_SYM = {.tag = HARDWARE_MODULE_TAG,.version_major = 2,.version_minor = 0,.id = GPS_HARDWARE_MODULE_ID,.name = "u-blox GPS/GNSS library",.author = "u-blox AG - Switzerland",.methods = &CGpsIf::s_hwModuleMethods,.dso = NULL,.reserved = {0}
};

可以看到.id和hw_get_module第一個參數相同,也是GPS_HARDWARE_MODULE_ID這個宏。

繼續回到HIDL_FETCH_IModuleName函數,看到第8行,這里調用了module->methods->open函數,在函數內部,找到對應device之后,它會對第三個參數進行了填充,從而讓HIDL_FETCH_IModuleName函數獲取到對應的“hw_device_t”,open函數代碼如下:

struct hw_module_methods_t CGpsIf::s_hwModuleMethods = {.open = CGpsIf::hwModuleOpen // open a specific device
};int CGpsIf::hwModuleOpen(const struct hw_module_t *module, char const *name, struct hw_device_t **device)
{((void)(name));struct gps_device_t *dev = new (std::nothrow) gps_device_t{};if (!dev)return 1;dev->common.tag = HARDWARE_DEVICE_TAG;dev->common.version = 0;dev->common.module = const_cast<struct hw_module_t *>(module);dev->common.close = CGpsIf::hwModuleClose;dev->get_gps_interface = CGpsIf::getIf;*device = (struct hw_device_t *)(void *)dev;return 0;
}

我們再看到HIDL_FETCH_IModuleName函數第10行,在這里,new了一個名叫Gnss的類對象出來,Gnss類對象就是hidl hal層的具體類。我們知道,一個類對象被new出來之后,它的構造函數就會被調用,構造函數內容如下:

Gnss::Gnss(gps_device_t* gnssDevice) : mDeathRecipient(new GnssHidlDeathRecipient(this)) {/* Error out if an instance of the interface already exists. */LOG_ALWAYS_FATAL_IF(sInterfaceExists);sInterfaceExists = true;if (gnssDevice == nullptr) {ALOGE("%s: Invalid device_t handle", __func__);return;}mGnssIface = gnssDevice->get_gps_interface(gnssDevice);
}

在Gnss的構造函數第11行,它調用了gnssDevice->get_gps_interface函數,在上面hwModuleOpen函數第17行,可以看到有對gnssDevice->get_gps_interface賦值,那我們先來看看這個函數代碼內容:

const GpsInterface CGpsIf::s_interface = {IF_ANDROID23(.size = sizeof(GpsInterface), ).init = CGpsIf::init,.start = CGpsIf::start,.stop = CGpsIf::stop,
#if (PLATFORM_SDK_VERSION <= 8 /* <=2.2 */).set_fix_frequency = CGpsIf::setFixFrequency,
#endif.cleanup = CGpsIf::cleanup,.inject_time = CGpsIf::injectTime,IF_ANDROID23(.inject_location = CGpsIf::injectLocation, ).delete_aiding_data =
CGpsIf::deleteAidingData,.set_position_mode = CGpsIf::setPositionMode,.get_extension = CGpsIf::getExtension,
};const GpsInterface *CGpsIf::getIf(struct gps_device_t * /*dev*/) 
{return &s_interface; 
}

gnssDevice->get_gps_interface實際上指向的,就是上面的getIf,而在getIf中,直接返回了一個名為s_interface的結構體,其實,這個就是gps hal層的接口,接下來hidl的所有操作都是通過調用這個接口的函數來進行實現。

4.1.2、jni層獲取hidl接口

jni層文件位置:android/frameworks/base/services/core/jni/com_android_server_location_GnssLocationProvider.cpp。

jni若想使用hidl的各種函數,也需要獲取到hidl提供出來的接口。jni獲取hidl接口函數如下:

static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {gnssHal_V1_1 = IGnss_V1_1::getService();if (gnssHal_V1_1 == nullptr) {ALOGD("gnssHal 1.1 was null, trying 1.0");gnssHal = IGnss_V1_0::getService();} else {gnssHal = gnssHal_V1_1;ALOGD("gnssHal 1.1 is Ok!");}
}

4.2、設置回調函數

在安卓GPS架構中,非常重要的,無疑不是回調操作了。所有GPS的上報,都是通過回調函數完成的。

它的gps數據回調流程是:hal->hidl->jni,可以看到,所謂回調,其實就是由下而上。

不過,設置回調結構體卻是由上而下:jni->hidl->hal。

4.2.1、安卓gps標準回調結構體

gps回調結構體在android/hardware/libhardware/inlcude/gps.h中定義,以下代碼為非標準結構體:

typedef struct {/** set to sizeof(GpsCallbacks) */size_t      size;gps_location_callback location_cb;gps_status_callback status_cb;gps_sv_status_callback sv_status_cb;gps_nmea_callback nmea_cb;gps_set_capabilities set_capabilities_cb;gps_acquire_wakelock acquire_wakelock_cb;gps_release_wakelock release_wakelock_cb;gps_create_thread create_thread_cb;gps_request_utc_time request_utc_time_cb;gnss_gyr_callback gyr_cb;gnss_acc_callback acc_cb;gnss_set_system_info set_system_info_cb;gnss_sv_status_callback gnss_sv_status_cb;
} GpsCallbacks;

可以看到,代碼第13、14行,這是我們自己添加的回調,用于回調加速度、陀螺儀的信息,在標準結構體中沒有這兩行。

4.2.2、填充回調函數指針

因為gps hal層驅動上報信息需要用到回調結構體,而這個結構體則需要hidl層定義實現這個結構體,然后再傳遞給hal層,讓hal層得到這個結構體指針。

而hidl回調到jni層,也需要jni定義并傳遞一個類似的回調結構體。

所以,接下來,我們就來看一下,代碼中是如何填充回調函數指針的。

①、hidl hal

static GpsCallbacks sGnssCb;GpsCallbacks Gnss::sGnssCb = {.size = sizeof(GpsCallbacks),.location_cb = locationCb,.status_cb = statusCb,.sv_status_cb = gpsSvStatusCb,.nmea_cb = nmeaCb,.set_capabilities_cb = setCapabilitiesCb,.acquire_wakelock_cb = acquireWakelockCb,.release_wakelock_cb = releaseWakelockCb,.create_thread_cb = createThreadCb,.request_utc_time_cb = requestUtcTimeCb,.set_system_info_cb = setSystemInfoCb,.gnss_sv_status_cb = gnssSvStatusCb,.gyr_cb = gnssGyrCb,.acc_cb = gnssAccCb,
};Return<bool> Gnss::setCallback(const sp<IGnssCallback>& callback)
{……sGnssCbIface = callback;……return (mGnssIface->init(&sGnssCb) == 0);
}

可以看到第25行調用了mGnssIface->init函數,mGnssIface就是gps hal層的接口,忘記了的可以回到4.1看一下。

我們繼續看mGnssIface->init函數是如何實現的,代碼內容如下:

static CGpsIf s_myIf;
……int CGpsIf::init(GpsCallbacks *callbacks)
{……initializeGpsCallbacks(*callbacks);……
}void CGpsIf::initializeGpsCallbacks(GpsCallbacks &callbacks)
{int res = 0;char buf[92];if (callbacks.size == sizeof(GpsCallbacks)){s_myIf.m_callbacks = callbacks;res = property_get("persist.vendor.gps.debug", buf, 0);if (res && atoi(buf)){s_myIf.UBLOX_UNNECESSARY_LOG_FLAG = true;UBX_LOG(LCAT_WARNING, "UBLOX_UNNECESSARY_LOG_FLAG is ture");} else {s_myIf.UBLOX_UNNECESSARY_LOG_FLAG = false;UBX_LOG(LCAT_WARNING, "UBLOX_UNNECESSARY_LOG_FLAG is false");}} else {UBX_LOG(LCAT_WARNING, "callback size %zd != %zd", callbacks.size, sizeof(GpsCallbacks));}
}

第4行,init函數調用initializeGpsCallbacks函數,而在第14行,initializeGpsCallbacks函數則對s_myIf.m_callbacks(s_myIf就是gps module的類對象)進行了賦值,也就是填充回調函數結構體指針。

到這里,hal到hidl層的回調指針就填充完畢了,接下來看看hidl層到jni層的回調指針。

②、jni

struct GnssCallback : public IGnssCallback {Return<void> gnssLocationCb(const GnssLocation& location) override;Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;Return<void> gnssAcquireWakelockCb() override;Return<void> gnssReleaseWakelockCb() override;Return<void> gnssRequestTimeCb() override;Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;//fce added for acc/gryReturn<void> gnss_gyr_callback(const IGnssCallback::AutoNaviGyr& gry) override;Return<void> gnss_acc_callback(const IGnssCallback::AutoNaviAcc& acc) override;// New in 1.1Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;// TODO(b/73306084): Reconsider allocation cost vs threadsafety on these staticsstatic const char* sNmeaString;static size_t sNmeaStringLength;
};static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj)
{……sp<IGnssCallback> gnssCbIface = new GnssCallback();Return<bool> result = false;if (gnssHal_V1_1 != nullptr) {result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);} else {result = gnssHal->setCallback(gnssCbIface);}……
}

這是jni層中的代碼,可以看到上面代碼第32行調用了hidl接口的setCallback函數,其中傳遞的參數就是jni層所定義的回調結構體,我們回到hidl層中的setCallback函數:

sp<IGnssCallback> Gnss::sGnssCbIface = nullptr;
……Return<bool> Gnss::setCallback(const sp<IGnssCallback>& callback)
{……sGnssCbIface = callback;……return (mGnssIface->init(&sGnssCb) == 0);
}

可以看到hidl接口的setCallback函數其實就是hidl層為gps hal層填充回調結構體指針的函數。

在這個函數中,有這么一段代碼——“sGnssCbIface = callback;”,顯然,這就是在設置hidl回調到jni層的回調結構體了。

4.3、ACC/GYR回調流程范例分析

所謂ACC/GYR就是加速度/陀螺儀。

因為這個項目所帶的慣導功能需要將ACC/GYR信息回調給app(地圖軟件),所以,需要從底層回調這些信息。

這里,我們需要一段詳細的流程分析,從開始獲取數據到上報數據結束。

4.3.1、注冊gps hal層主線程

gps hal層主線程,在init函數中創建,主要功能就是監測串口是否有數據產生,當有數據到來時,就調用解析函數解析數據,然后通過回調結構體中的各個回調函數,將他們回調到hidl層,然后再在hidl層中的函數中調用jni層的回調函數,從而將數據傳遞給jni層。

int CGpsIf::init(GpsCallbacks *callbacks)
{……createGpsThread();……
}void CGpsIf::createGpsThread()
{……s_mainControlThread = s_myIf.m_callbacks.create_thread_cb("gps thread", ubx_thread, &s_controlThreadInfo);……
}

看到以上代碼,首先這個init函數就是之前setCallback所調用的init函數。然后,再看到在這個init函數中,它調用了一個名為createGpsThread的函數,在這個函數中就創建了gps的thread,并將ubx_thread這個函數注冊為了gps的thread函數。

4.3.2、注冊串口監控 — 多路復用之select

void ubx_thread(void *pThreadData)
{ControlThreadInfo *pState = (ControlThreadInfo *)pThreadData;……for(;;){fd_set rfds;int maxFd = 0;FD_ZERO(&rfds);FD_SET(pState->cmdPipes[0], &rfds); // Add cmd queue pipeif (pState->cmdPipes[0] + 1 > maxFd)maxFd = pState->cmdPipes[0] + 1;int res = s_ser.rselect(maxFd, &rfds, &tv);……}……
}

可以看到,在ubx_thread函數的死循環中,注冊了一個select多路復用(不熟悉多路復用的,可以看我另外一篇文章)。

而在上面代碼的16行,則是調用了我們自己封裝的一個select監測函數,對可讀集合進行監控。

4.3.3、讀取串口數據

void ubx_thread(void *pThreadData)
{ControlThreadInfo *pState = (ControlThreadInfo *)pThreadData;checkRecvInitReq(pState, rfds, maxFd, sinceLastNmeaMs > sinceLastUbxMs ? sinceLastNmeaMs : sinceLastUbxMs);……for(;;){int res = s_ser.rselect(maxFd, &rfds, &tv);if (res > 0){if (s_ser.fdIsSet(rfds)){unsigned char *ptr = parser.GetPointer();unsigned int space = (unsigned int)parser.GetSpace();int iSize = s_ser.readSerial(ptr, space);}}}……
}

依舊是在ubx_thread函數中,首先是第5行,這里調用了一個叫checkRecvInitReq的函數,在這個函數里,調用了openSerial,打開gps和soc傳輸數據的串口。然后我們看到第18行,當監測到集合內可讀事件的時候,就會調用readSerial去讀取對應的串口。

這里的fdIsSet由我們調用標準的FD_ISSET函數封裝而成,readSerial也是由我們調用read函數封裝而成。

4.3.4、解析數據并發出回調

void ubx_thread(void *pThreadData)
{ControlThreadInfo *pState = (ControlThreadInfo *)pThreadData;……for(;;){int res = s_ser.rselect(maxFd, &rfds, &tv);if (res > 0){if (s_ser.fdIsSet(rfds)){……while (parser.Parse(pProtocol, pMsg, iMsg)) {……pUbxGps->onNewMsg(pMsg, (unsigned int)iMsg);pProtocol->Process(pMsg, iMsg, pDatabase);……}}}}……
}

上述代碼第13行,解析數據,這個解析算法由供應商提供,不需要我們關心。不過,我們需要關心一下第15行,這里調用了一個叫做onNewMsg的函數,函數內容很多,這里就不一一展示給大家看了。在我關注的重點里,這個函數主要是配置了gps模塊輸出何種數據,沒錯,gps要輸出哪些數據是需要配置的,不配置的話就沒有數據輸出。比如acc/gry數據是屬于UBX-ESF-MEAS數據,所以必須使能它才行。

再看到第16行,這里調用了一個Process函數,在這里,我們進行了gps信息的回調。

void CProtocolUBX::Process(const unsigned char *pBuffer, int iSize, CDatabase *pDatabase)
{switch (getMessageId(pBuffer)){……case UBXID_ESF_MEAS:ProcessEsfMeas(pBuffer);processMessage<UBX_ESF_MEAS>(pBuffer, iSize, UBXID_ESF_MEAS);break;}……
}void CProtocolUBX::ProcessEsfMeas(const unsigned char* pBuffer)
{……if(CGpsIf::getInstance()->m_callbacks.acc_cb) {//UBX_LOG(LCAT_VERBOSE, "update_gps_acc");CGpsIf::getInstance()->m_callbacks.acc_cb(ACC);}……if(CGpsIf::getInstance()->m_callbacks.gyr_cb) {//UBX_LOG(LCAT_VERBOSE, "update_gps_gyr");CGpsIf::getInstance()->m_callbacks.gyr_cb(GYR);}
}

可以看到,上述代碼第18、23行調用了acc/gyr的回調函數,這里的回調函數會將數據回調給hidl層。

4.3.5、hidl hal回調

hal層發出回調之后,會來到hidl層,hidl層代碼如下:

void Gnss::gnssGyrCb(AutoNavi_Gyr* gyr){android::hardware::gnss::V1_0::IGnssCallback::AutoNaviGyr gyr_temp;if (sGnssCbIface == nullptr || gyr == nullptr) {ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);return;}//ALOGE("%s x=%f, y=%f, z=%f", __func__, gyr->x, gyr->y, gyr->z);gyr_temp.x = gyr->x;gyr_temp.y = gyr->y;gyr_temp.z = gyr->z;gyr_temp.temp = gyr->temp;gyr_temp.ticktime = gyr->ticktime;gyr_temp.axis = gyr->axis;gyr_temp.interval = gyr->interval;auto ret = sGnssCbIface->gnss_gyr_callback(gyr_temp);if (!ret.isOk()) {ALOGE("%s: Unable to invoke callback", __func__);}
}void Gnss::gnssAccCb(AutoNavi_Acc* acc){android::hardware::gnss::V1_0::IGnssCallback::AutoNaviAcc acc_temp;if (sGnssCbIface == nullptr || acc == nullptr) {ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);return;}//ALOGE("%s x=%f, y=%f, z=%f", __func__, acc->x, acc->y, acc->z);acc_temp.x = acc->x;acc_temp.y = acc->y;acc_temp.z = acc->z;acc_temp.ticktime = acc->ticktime;acc_temp.axis = acc->axis;acc_temp.interval = acc->interval;auto ret = sGnssCbIface->gnss_acc_callback(acc_temp);if (!ret.isOk()) {ALOGE("%s: Unable to invoke callback", __func__);}
}

可以看到,第19行和第42行,分別調用了jni層的回調接口,通過這個接口,就把數據給傳遞到了jni層。

五、總結

到這里,安卓平臺下的GPS架構介紹及驅動移植記錄大概就介紹完了。

實際項目中,還是要結合實際問題進行分析。

要做驅動移植,對代碼還是需要熟悉的,雖然大部分代碼都會由gps模塊供應商提供,但是在調試的時候總不能遇到問題就問gps模塊供應商,而且gps模塊供應商提供的驅動代碼也只是標準代碼,并不一定適合你的平臺,還是需要部分調整的。

另外,在調試好gps hal層驅動代碼之后,還需要對標地圖app,需要將我們上傳的數據格式和上報頻率都更改為地圖app所需要的才行。

總結

以上是生活随笔為你收集整理的安卓平台下的GPS架构介绍及驱动移植记录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

国产香蕉97碰碰久久人人 | 九色一区二区 | 国产精品久久久久高潮 | 久久久久久久久久网站 | 日韩一区二区三区高清免费看看 | 91系列在线| 国产精品6999成人免费视频 | 国产精品a久久久久 | 综合伊人久久 | 国产精品久久久久久久久久ktv | 日韩精品视频一二三 | 国产精品美女在线 | 在线成人免费电影 | 五月婷婷综合激情 | 麻豆mv在线观看 | 色偷偷88888欧美精品久久 | 国产成人一区二区精品非洲 | 欧美色噜噜 | 亚洲精品午夜久久久久久久 | 天天综合91 | 国色天香在线 | 夜夜高潮夜夜爽国产伦精品 | 久久久精品国产免费观看同学 | 亚洲精品玖玖玖av在线看 | 91精品一区国产高清在线gif | 国产亚洲精品综合一区91 | 99c视频在线 | 婷婷丁香激情网 | 久草网视频 | av网站免费线看精品 | 丁香婷婷网 | 亚洲色图色 | 国产美女精彩久久 | 热精品| 91免费视频国产 | 亚洲免费av片| 国产精品扒开做爽爽的视频 | 欧美精品乱码久久久久久按摩 | 最新中文字幕 | 日韩电影中文字幕在线观看 | 这里有精品在线视频 | 久久国产精品久久精品国产演员表 | 色综合网 | 欧美国产日韩激情 | 97超在线视频 | 激情综合网婷婷 | 热久久免费视频精品 | 深夜视频久久 | 国产精品一区二区av麻豆 | 久久久久成人精品免费播放动漫 | 一区二区三区四区五区六区 | 久久99爱视频 | 日本韩国精品一区二区在线观看 | 国产午夜精品一区二区三区四区 | 99视频久 | 中文字幕高清在线播放 | 欧美精品资源 | 日韩在线高清免费视频 | www.天天干.com | 人人超碰97| 美女视频网站久久 | 亚洲综合视频在线观看 | 日韩电影在线视频 | 日韩成人精品一区二区 | www.五月天婷婷.com | 欧美日韩精品免费观看视频 | 成人免费视频a | 国产精品大尺度 | 精品一区二区在线免费观看 | 又黄又爽又无遮挡免费的网站 | 中文字幕国产 | 天天色.com | 久久的色| 在线免费黄网站 | 国产区高清在线 | 91系列在线 | 免费a视频在线观看 | 亚洲久久视频 | 中文亚洲欧美日韩 | 伊人久久国产 | 中文永久免费观看 | 91九色综合 | 久久综合九色综合欧美就去吻 | 久久婷亚洲五月一区天天躁 | 日韩专区在线播放 | 亚洲成av人片在线观看 | 天天射综合网视频 | 国产精品国产三级国产不产一地 | 男女全黄一级一级高潮免费看 | 久久永久免费 | 精品美女视频 | 免费视频网 | 99久精品视频 | 国产成人高清 | 久草av在线播放 | 久久激情视频网 | 天天射天天艹 | 国产日韩在线播放 | 日韩欧美高清视频在线观看 | 黄色av一级 | 久久伊人色综合 | 日韩有色| 国产精品久久久久一区二区三区共 | 国产黄色免费 | 香蕉视频国产在线 | 午夜久久美女 | 天天曰视频 | www.99久久.com| 国产精品女人网站 | 中文字幕免费高清在线观看 | 2019免费中文字幕 | 最新在线你懂的 | 涩涩资源网 | 日韩精品久久久久 | 激情综合网五月婷婷 | 六月丁香在线视频 | 国产理论影院 | 91人人澡人人爽人人精品 | 麻豆国产视频下载 | 欧美激情h | 亚洲精品在线免费观看视频 | 日本韩国精品在线 | 日本黄色大片免费看 | 少妇av片 | 中文字幕亚洲综合久久五月天色无吗'' | www.伊人色.com | 99在线看| 在线激情影院一区 | 又色又爽又激情的59视频 | 国产99久久精品一区二区永久免费 | 97香蕉超级碰碰久久免费软件 | 成人国产精品电影 | 国产 中文 日韩 欧美 | 免费在线激情电影 | 日韩黄色免费 | 中文字幕在线视频免费播放 | 五月婷影院 | 99精品视频免费全部在线 | 国产高清视频网 | 黄色av成人在线 | 久久免费视频在线 | 精品久久久久_ | 97爱| 国产在线97| 揉bbb玩bbb少妇bbb | 一区二区视频网站 | 精品国产免费一区二区三区五区 | 中文字幕在线观看第一区 | 中文字幕在线观看第三页 | 在线黄色国产电影 | 亚洲资源一区 | 肉色欧美久久久久久久免费看 | 久久激情网站 | 夜夜躁日日躁 | 日本性生活免费看 | 亚洲激色| av免费在线网 | 日韩电影在线观看中文字幕 | 国产成人区 | 99热超碰在线 | 成人h视频在线播放 | 91亚·色 | 日日操天天操狠狠操 | 久久怡红院 | 1000部18岁以下禁看视频 | 国产91精品看黄网站在线观看动漫 | 亚洲天堂精品视频在线观看 | 久久黄色免费观看 | 成人91av| 成片人卡1卡2卡3手机免费看 | 国产午夜在线观看视频 | 91av九色| 天天天天色综合 | 国产精品国产自产拍高清av | 精品一区 精品二区 | 国产一级片在线播放 | 日韩在线视频一区二区三区 | 在线观看国产区 | 国产91aaa | 天天操综 | 欧美日韩中文国产一区发布 | 国产日本在线观看 | 欧美婷婷综合 | 久草视频手机在线 | 九九亚洲视频 | 高清中文字幕 | 日韩欧美视频一区二区 | 不卡的av在线播放 | 亚洲综合爱 | 中文字幕亚洲不卡 | 久久久一本精品99久久精品66 | 九九久久久久久久久激情 | 四虎永久免费 | 国产一区二区高清 | www.亚洲精品在线 | 国产最顶级的黄色片在线免费观看 | 亚洲精品高清在线 | 天天搞天天干天天色 | 在线看污网站 | 黄色大全免费网站 | 免费在线国产 | 免费看色网站 | 久草在线观看 | 欧美激情视频一区二区三区免费 | 久久草在线精品 | 成年人电影免费在线观看 | 成年人免费在线播放 | 伊人首页 | 久久免费视频2 | 国产日产精品一区二区三区四区 | 亚洲禁18久人片 | 日本黄色大片儿 | 91视频国产免费 | 免费观看www小视频的软件 | 九九精品视频在线看 | 国产精品久久精品 | 麻豆传媒电影在线观看 | 精品免费久久久久 | 亚州日韩中文字幕 | 1024手机基地在线观看 | 米奇狠狠狠888 | www.天天色.com | 久久成人精品电影 | 亚洲乱码精品久久久 | 四虎永久免费网站 | 91热视频 | 亚洲精品小视频在线观看 | 国产午夜精品一区二区三区嫩草 | 久久久久久国产精品999 | 成人四虎影院 | 日韩av资源在线观看 | 久久久www免费电影网 | 亚洲女人av | 久久精品久久99 | 在线看av的网址 | 国产精品手机视频 | 91系列在线 | 91精品国产91久久久久久三级 | 2021国产在线视频 | 91伊人| 三级黄色三级 | 91精品国产综合久久婷婷香蕉 | 91在线视频免费91 | 精品影院一区二区久久久 | 婷婷精品国产欧美精品亚洲人人爽 | 中文字幕免费高清av | 97超级碰碰碰视频在线观看 | 中午字幕在线观看 | 九九热免费视频在线观看 | 久久久久亚洲精品成人网小说 | 国产不卡毛片 | 午夜黄色影院 | 韩国av三级 | 日韩一区精品 | wwwwww国产| 国产亚洲情侣一区二区无 | 亚洲视频 中文字幕 | av看片网址 | 成人毛片在线观看视频 | 日韩三区在线 | 激情五月***国产精品 | 亚洲精品成人 | 欧美日韩99 | 成年人黄色免费网站 | 免费男女羞羞的视频网站中文字幕 | 日韩电影中文,亚洲精品乱码 | 娇妻呻吟一区二区三区 | 成人国产精品一区二区 | 日韩系列 | 日日操天天操夜夜操 | a久久久久久| 欧美日韩国产成人 | 亚洲伦理中文字幕 | 国产一区视频在线观看免费 | 国产精品久久久久久久久婷婷 | 91视频3p| 91福利社在线观看 | 不卡视频国产 | 欧美日韩3p| 成人羞羞视频在线观看免费 | 99久久精品免费看国产一区二区三区 | 国产亚洲免费的视频看 | 婷婷亚洲五月 | 色九九视频 | 天天摸天天干天天操天天射 | 欧美日韩精品免费观看视频 | 色欧美日韩 | www亚洲一区| 日韩一三区 | 91福利视频一区 | 亚洲干视频在线观看 | 国产精品毛片久久久久久 | 最近av在线 | 在线观看黄色 | 久久99国产精品二区护士 | 337p日本欧洲亚洲大胆裸体艺术 | 久久午夜国产 | 国产精品一区二区久久久 | 久久久精品国产免费观看同学 | 麻豆久久久久久久 | 玖玖玖国产精品 | 四虎5151久久欧美毛片 | 乱男乱女www7788 | 福利视频一二区 | 国产综合激情 | 午夜精品久久一牛影视 | av电影在线观看 | 在线欧美国产 | 狠狠色噜噜狠狠狠狠 | 97超碰人人澡人人爱学生 | 91麻豆精品国产91久久久使用方法 | 久艹在线免费观看 | 夜夜爽天天爽 | 五月婷婷丁香色 | 天天做天天干 | 中文在线字幕观看电影 | 欧美视频在线观看免费网址 | 成人三级网址 | 亚洲日b视频 | 日韩中文字幕国产 | 六月丁香综合 | 国内精品久久久久影院男同志 | 精品美女在线视频 | 国产高清日韩欧美 | 亚洲日本在线一区 | 激情五月网站 | 视频91在线| 成人一区二区三区在线 | 国产一级免费视频 | 久久人91精品久久久久久不卡 | av成人免费网站 | 久久精品9 | 91探花在线视频 | 久久国产a| 亚洲va欧美va人人爽 | 精品美女在线视频 | 欧美精品久久久久久久久久丰满 | 亚洲专区欧美专区 | 麻豆首页 | 久久久久久国产精品免费 | 久久久久免费精品视频 | 欧美日韩在线视频一区二区 | 天天色天天操天天爽 | 一区二区 精品 | 国产精品久久久久久电影 | 日日夜夜精品免费 | 久久精品男人的天堂 | 精品国产99 | 国产精品麻豆视频 | 久久天天操 | 九九精品在线观看 | 久久久国产精品麻豆 | 伊人成人精品 | 高清中文字幕av | 国产 日韩 在线 亚洲 字幕 中文 | 国产一在线精品一区在线观看 | 成人四虎 | 免费看的黄色的网站 | 国产精品午夜久久 | 国产精品k频道 | 午夜视频一区二区三区 | 亚洲精品一区二区网址 | 最新超碰在线 | 高清不卡毛片 | 成人毛片100免费观看 | 福利一区在线 | 欧美一级片播放 | 国产精品一区免费在线观看 | 91精品成人久久 | 亚洲视频1区2区 | 久久在现视频 | 五月婷婷综合激情 | 狠狠躁18三区二区一区ai明星 | 久草男人天堂 | 中文字幕色播 | 欧美日韩高清在线观看 | 美女福利视频在线 | 97av色| 奇米7777狠狠狠琪琪视频 | zzijzzij日本成熟少妇 | 91成人网在线观看 | 久久理伦片 | 在线视频黄 | 日韩av电影一区 | 亚洲日本三级 | 亚洲精品黄色 | 五月情婷婷 | 日韩r级电影在线观看 | 日韩av一区二区三区在线观看 | 日本在线精品视频 | 在线免费国产视频 | 丁香色婷婷 | 狠狠综合 | 99视频偷窥在线精品国自产拍 | 日本爱爱片 | 久久久久久久国产精品影院 | 久久精品精品电影网 | 狠狠色丁香婷婷综合最新地址 | 久久久久久高潮国产精品视 | 国产精品 久久 | 日韩xxxbbb | av不卡中文字幕 | 香蕉日日 | 国产成人久久精品一区二区三区 | 午夜美女福利 | 久久精品99久久久久久 | 久久久精品福利视频 | 欧美日韩精品在线观看 | 韩国三级在线一区 | 成人免费观看视频大全 | 亚洲一区二区三区在线看 | 亚洲乱码久久久 | 在线免费观看黄色 | 精品免费一区 | 不卡精品视频 | 99久久爱 | 91精品国产乱码在线观看 | 欧美午夜寂寞影院 | 国产精品一区二区三区电影 | 9在线观看免费高清完整版在线观看明 | 精品美女久久久久 | 久久视讯| 成人国产精品一区 | 欧美最猛性xxxxx免费 | 久九视频 | 91在线免费观看网站 | 免费网站在线 | 麻豆免费观看视频 | 狠狠色丁香久久婷婷综合五月 | 美女视频a美女大全免费下载蜜臀 | 国内久久久 | 伊人亚洲精品 | 超碰在线9 | 欧美日韩在线免费观看视频 | 91麻豆精品国产91 | 国产日韩欧美在线播放 | 久久天天躁狠狠躁夜夜不卡公司 | 成人黄色片在线播放 | 国模一区二区三区四区 | 国产日韩中文在线 | 97视频在线播放 | 精品久久久久久久久久岛国gif | 欧美天天综合网 | 精品久久久久久亚洲 | 日本爽妇网 | 黄色小说18 | 国产一区二区久久久 | 亚洲成av人片在线观看 | 久久看看| 久久精品这里都是精品 | 四虎永久国产精品 | 久久久久亚洲精品成人网小说 | 在线久草视频 | 在线观看黄网站 | 国产亚洲精品久久久久久 | 日韩精品一区二区三区不卡 | 国产精品视频在线看 | 久久久久久久久久伊人 | 中文字幕亚洲在线观看 | 狠狠操狠狠干天天操 | 一级做a爱片性色毛片www | 波多野结衣在线播放视频 | 午夜精品久久久久久中宇69 | 日韩欧美xxxx | av一区二区三区在线观看 | 日韩电影一区二区在线观看 | 国产一级三级 | 亚洲成人免费观看 | 怡春院av | 精品国产伦一区二区三区观看体验 | 久久中文精品视频 | 99久久久久国产精品免费 | 中文字幕在线观看视频网站 | www最近高清中文国语在线观看 | 91成人免费在线 | 婷婷综合久久 | 免费裸体视频网 | 亚洲成a人片在线观看中文 中文字幕在线视频第一页 狠狠色丁香婷婷综合 | 久久久午夜剧场 | av黄免费看 | 在线免费黄色毛片 | 麻豆国产网站 | 亚洲国产成人在线播放 | 欧美激情综合五月色丁香 | 久久99久久99免费视频 | 国产在线精品观看 | av一级片在线观看 | 色综合色综合久久综合频道88 | 欧美在线视频第一页 | 激情网五月婷婷 | 国产精品精 | 五月天天天操 | 久久久久久网 | 欧洲精品码一区二区三区免费看 | 丝袜美腿亚洲 | 青青视频一区 | 亚洲专区一二三 | 久亚洲精品 | 91夜夜夜| 日韩最新av | 国产女v资源在线观看 | 在线观看 国产 | 日韩精品欧美精品 | 在线中文字幕视频 | 国产精品久久久亚洲 | 91在线九色| 免费观看一级 | 五月天堂网 | 一级淫片在线观看 | 欧美亚洲三级 | 国产一区二区在线免费 | 久久综合久久久久88 | 亚洲精品xxx | 日韩三级视频在线观看 | 久久久久激情电影 | 国产999久久久 | 精品免费久久久久久 | 18性欧美xxxⅹ性满足 | 亚洲国产精品久久久久久 | 婷婷精品在线视频 | 黄色大片日本免费大片 | 久久精品看片 | 99精品视频在线观看播放 | 91成人在线观看高潮 | 久久香蕉影视 | 色综合天天干 | 婷婷在线免费 | 国产免费区 | 日韩欧美69 | 天天做天天看 | 欧美网址在线观看 | 免费黄色在线 | 天天干,天天草 | 182午夜在线观看 | 国产在线观看xxx | 天天综合视频在线观看 | 成人国产精品一区二区 | 日韩av一区二区在线影视 | 国产高潮久久 | 黄色av三级在线 | 国产精品精品 | 国产精品网站 | 在线观看视频99 | 久久久久一区二区三区 | 国产精彩视频 | 久久免费激情视频 | 久久久网 | 成人h动漫在线看 | 日批网站免费观看 | 97色噜噜 | 免费无遮挡动漫网站 | 超碰97国产 | 日日操天天爽 | 久久久综合电影 | 午夜久久久久久久久 | 国产免费作爱视频 | 国产精品毛片一区 | 黄色www免费 | 麻豆国产露脸在线观看 | 国产区免费在线 | 国产91精品一区二区麻豆网站 | 久久久免费 | 91成人免费看 | 欧美一级电影在线观看 | 国产在线美女 | 国产丝袜在线 | 国内精品久久久久影院日本资源 | 欧美日韩精品影院 | 激情五月婷婷综合 | 久久夜夜夜 | 99久久婷婷国产综合精品 | 黄色亚洲片 | 婷婷五月在线视频 | 久保带人| 免费色视频网址 | 日本99久久| 波多野结衣日韩 | 国产精品久久一区二区无卡 | 高清免费av在线 | 欧美日韩啪啪 | 国产精品女同一区二区三区久久夜 | 久久综合网色—综合色88 | 日韩理论影院 | 久久精品综合 | 蜜臀久久99静品久久久久久 | 色在线视频网 | 中文字幕在线播出 | 精品亚洲一区二区三区 | 91视频在线国产 | 午夜视频不卡 | 国产精品久久久久久久久久新婚 | 久久96| 在线天堂中文www视软件 | 日日夜夜干 | 国产一级片一区二区三区 | 亚洲女同videos | 色综合久久88色综合天天免费 | 欧美国产高清 | 五月婷婷中文网 | 有没有在线观看av | 91看片淫黄大片在线播放 | 国产高清专区 | 成人免费大片黄在线播放 | 日本夜夜草视频网站 | 日日草av| 日日操日日插 | 免费在线观看成年人视频 | 午夜 免费 | 亚洲va男人天堂 | 97碰碰视频 | 久草网免费 | 91久久爱热色涩涩 | www.精选视频.com| 91看片淫黄大片一级在线观看 | 日韩中文字幕视频在线观看 | 激情动态 | 国产黄色片一级三级 | 美女视频黄在线 | 人人爽人人做 | 国产乱码精品一区二区蜜臀 | 天天天色综合 | 夜添久久精品亚洲国产精品 | 欧美日韩一区二区三区在线观看视频 | 成人精品一区二区三区中文字幕 | 奇米影音四色 | 久久久久国产免费免费 | 日韩精品免费在线观看 | 免费看片在线观看 | 国产麻豆剧果冻传媒视频播放量 | 欧美a视频| 欧美999| 日本乱视频 | 五月天天色 | 免费看91的网站 | 在线观看日本高清mv视频 | 婷婷丁香六月天 | 日韩手机视频 | 久久国色夜色精品国产 | 91成年人网站 | 国产精品久久久久aaaa九色 | 99热国产在线中文 | 国产在线精 | 国产免费亚洲高清 | 久久久久97国产 | 成人在线观看免费视频 | 麻豆传媒一区二区 | 久久情侣偷拍 | 91成人网页版 | 久久伊人婷婷 | 久久免费久久 | 久久精品日产第一区二区三区乱码 | 美女啪啪图片 | 亚洲精品av中文字幕在线在线 | 在线看91| 免费毛片一区二区三区久久久 | 免费观看91视频 | 国产精品一区二区在线看 | 免费看色网站 | 久草视频网 | 国产视频午夜 | 深爱综合网 | 欧美色伊人 | 97综合网 | 中文字幕在线观看一区二区 | 99爱视频在线观看 | 亚洲综合色播 | 久久艹免费 | 欧美日韩一级在线 | 国产理论片在线观看 | 久久久久久毛片精品免费不卡 | 欧美日韩免费网站 | 中文日韩在线视频 | 日韩激情视频在线 | 91视频久久久久久 | 91在线你懂的 | 国产色小视频 | 成人福利在线播放 | 欧美日韩国产在线观看 | 四虎国产精品成人免费影视 | 超碰电影在线观看 | 欧美精品久久久久性色 | 99精品久久只有精品 | 色天天综合久久久久综合片 | 婷婷网五月天 | 一级做a爱片性色毛片www | 黄色视屏在线免费观看 | 五月天婷婷免费视频 | 精品久久久久久综合 | 波多野结衣视频在线 | 亚洲天堂网站视频 | 一区二区中文字幕在线观看 | 久久九九久久九九 | 99久久婷婷国产一区二区三区 | 婷婷色综合网 | 成人动漫一区二区三区 | 国产午夜精品一区二区三区欧美 | 成人黄色大片 | 99这里只有 | 欧美婷婷色 | 久久美女视频 | 日本成人中文字幕在线观看 | 国产品久精国精产拍 | 特级西西人体444是什么意思 | 国内精品久久久久影院一蜜桃 | 精品欧美在线视频 | 久草视频视频在线播放 | 久久国产精品区 | 2021国产在线| 最新国产精品拍自在线播放 | 国产一区二区久久精品 | 日韩一级片网址 | 国产尤物在线 | 欧美日韩一区二区在线观看 | 国产精品破处视频 | 国产精品亚洲片夜色在线 | 久久婷婷精品视频 | 成人a视频片观看免费 | 精品国产一区二区三区在线观看 | 自拍超碰在线 | 成人av高清| 国产精品成人自产拍在线观看 | 香蕉蜜桃视频 | 亚洲国产精品va在线看黑人动漫 | 欧美日韩国语 | 99视频精品 | 91.dizhi永久地址最新 | 精品一区二区影视 | 免费观看一级一片 | 永久免费毛片 | 中文字幕丝袜制服 | 国产日韩精品在线观看 | 91久久国产露脸精品国产闺蜜 | 久久精品国产一区二区电影 | 亚洲精品在 | 午夜av不卡| 又粗又长又大又爽又黄少妇毛片 | 狠狠色香婷婷久久亚洲精品 | 国产精品午夜久久久久久99热 | 奇米四色影狠狠爱7777 | 中文字幕在线观看免费 | av品善网 | 天天干天天摸 | 亚洲精品99久久久久久 | www色com | 国产视频一区二区在线观看 | 黄色日视频 | 久久网址| 日韩美女免费线视频 | 91麻豆免费看 | 天天搞天天干 | 在线免费国产 | 91在线在线观看 | 西西44人体做爰大胆视频 | 在线观看黄色 | av免费在线网站 | 探花视频在线观看免费版 | 亚洲经典精品 | 国产又粗又硬又长又爽的视频 | 国产精品久久久久久久7电影 | 最近日韩中文字幕中文 | 丁香综合激情 | 国产最新福利 | 国产亚洲精品综合一区91 | 午夜精品福利一区二区三区蜜桃 | 久久久久免费电影 | 亚洲天堂精品视频 | 免费午夜av| 欧美天天综合网 | 欧美久久久影院 | 久久久久国产精品一区二区 | 欧美福利片在线观看 | 日本黄色免费看 | 国产亚洲在线视频 | 美女免费视频一区二区 | 综合伊人av| 久久久久女教师免费一区 | 五月天久久久久久 | 色橹橹欧美在线观看视频高清 | 国产黄在线看 | 丁香婷婷色 | 婷婷精品| www.色五月.com | 国产精品免费人成网站 | 狠狠干狠狠操 | 亚洲第一香蕉视频 | 美女视频a美女大全免费下载蜜臀 | 99视频在线观看免费 | 久久国产精品系列 | 天天色.com| 亚洲免费高清视频 | 免费一级片视频 | 亚洲成人免费观看 | 91传媒免费观看 | av在线网站大全 | 久久久久免费精品视频 | 狠狠狠狠狠狠天天爱 | 97超碰在线免费 | av中文字幕网| 91成人精品一区在线播放69 | 天天操夜夜曰 | 亚洲国产经典视频 | 久久96国产精品久久99软件 | 久草在线久 | 欧美一级在线观看视频 | 欧美做受69 | 精品久久久久免费极品大片 | 中文字幕日韩免费视频 | 在线观看黄色的网站 | 一区二区三区免费在线 | www日韩视频 | 亚洲精品国产综合99久久夜夜嗨 | 在线观看视频一区二区三区 | 97碰视频| 一区二区三区手机在线观看 | 天天射天天舔天天干 | 免费看色的网站 | 国产精品自在线 | www.99av| 久久精品国产一区二区三区 | 国产精品情侣视频 | 在线免费试看 | 久草电影免费在线观看 | www.福利视频 | 亚洲成人av在线电影 | 亚洲成人频道 | 亚洲综合成人在线 | 狠狠干狠狠操 | 欧美在线1区 | 国产精品视频大全 | 在线高清一区 | 久久精品99国产精品 | av在线a | 麻豆视频一区二区 | 国产精品不卡 | 国产高清成人 | 日本韩国精品一区二区在线观看 | 狠狠干中文字幕 | 日韩精品一区二区三区高清免费 | 99热这里有 | 中文字幕一区二区在线观看 | 国产成视频在线观看 | 久久草草热国产精品直播 | 国产福利电影网址 | 99视频在线免费看 | 亚洲激情 在线 | 久久综合久久综合这里只有精品 | 亚洲国产一区二区精品专区 | 973理论片235影院9 | 精品99视频 | 91香蕉视频黄色 | 日韩不卡高清 | www夜夜操| 国产精品久久久久国产精品日日 | 久久精品79国产精品 | www.五月婷 | 国内精品久久久久影院优 | 九色视频自拍 | 超碰人人在 | 夜夜躁狠狠燥 | av电影在线免费观看 | 日韩精品一区二区三区在线视频 | 91视频免费视频 | 亚洲女人天堂成人av在线 | 日韩视频免费播放 | 国产亚洲精品xxoo | 99久高清在线观看视频99精品热在线观看视频 | 中文字幕av在线免费 | 人人躁 | 日韩精品中文字幕在线播放 | 91在线蜜桃臀 | 欧美日韩在线免费观看 | 亚洲情感电影大片 | 成人在线观看网址 | 日韩啪啪小视频 | 中文字幕文字幕一区二区 | 中文字幕在线视频一区二区 | av资源在线看 | 欧美日韩网站 | 日韩精品一区二区三区电影 | 日韩av电影手机在线观看 | 丁香色婷婷 | 日本久久久久久久久久 | 欧美精品一区在线发布 | 最近2019好看的中文字幕免费 | 国产精品自产拍在线观看 | 欧美日韩精品免费观看视频 | 超碰免费成人 | 91高清免费在线观看 | 国产成人精品久久亚洲高清不卡 | 久久精品美女视频网站 | 亚色视频在线观看 | 91免费视频黄| 九九热在线视频 | 精品国产久 | 夜夜天天干 | 97理论电影 | 青青久草在线 | 日本黄区免费视频观看 | 激情影音先锋 | 中文字幕亚洲在线观看 | 91专区在线观看 | 黄色一级动作片 | 午夜国产福利视频 | 在线a人片免费观看视频 | 国产婷婷在线观看 | 免费av网站观看 | 中文字幕在线播放第一页 | 免费看一级| 国产视频久久 | 久久人人爽av | 亚洲欧洲日韩在线观看 | 97在线观看免费观看高清 | 亚洲夜夜综合 | 久久精品视频2 | 国产第一页在线观看 | 手机av在线网站 | 久久久国产电影 | 久久久久在线观看 | 亚洲精品国产精品国自产在线 | 国产精品成人久久久久久久 | 日韩在线观看不卡 | 一区二区三区高清 | 久草在线资源观看 | 天堂在线免费视频 | 一级片黄色片网站 | 丰满少妇高潮在线观看 | 激情网在线视频 | 色婷婷激婷婷情综天天 | 天天要夜夜操 | 96精品在线 | 高清不卡免费视频 | a视频在线播放 | 免费在线播放av电影 | 久久高清av | 少妇bbbb| 色中射 | 国产一区二区精 | 国产精品国产三级国产aⅴ入口 | 国产视频欧美视频 | 中文字幕综合在线 | 激情久久综合 | 麻豆91在线 | 夜色资源网 | 成人小视频在线播放 | 日产乱码一二三区别在线 | 最新中文字幕在线观看视频 | 一区二区三区在线不卡 | 成人国产精品久久久春色 | 久久网页 | 欧美精品久久久久久久免费 | 国产资源免费在线观看 | 91麻豆产精品久久久久久 | h久久| 激情文学综合丁香 | 在线观看国产www | 国产又粗又长又硬免费视频 | 亚洲精品视频免费观看 | 久精品视频在线观看 | 精品资源在线 | 精品国产成人在线影院 | 亚洲国产最新 | 91精品夜夜| 国产成人无码AⅤ片在线观 日韩av不卡在线 | 国产成人久久精品一区二区三区 | 男女拍拍免费视频 | 成人一区不卡 | 97国产精品一区二区 | 日韩a在线看 | 国产淫片免费看 | 色吊丝在线永久观看最新版本 | 久操中文字幕在线观看 | 久久黄色成人 | 亚洲三级精品 | www.狠狠色.com | 91久久久久久国产精品 | 亚洲闷骚少妇在线观看网站 | 免费日韩一区二区 | 日韩精品一区二区三区第95 | 激情欧美一区二区免费视频 | 国产精品四虎 | av成人免费在线 | 最新久久久 | 97超碰站| 91在线日韩| 91看片网址| 国产成人99av超碰超爽 | 又黄又爽又刺激的视频 | 一区二区精品在线 | 日韩专区一区二区 | 欧美亚洲专区 | 欧美怡红院视频 | 99久久精品费精品 | 亚洲国产成人久久 | 亚洲精品国| 四虎国产永久在线精品 | 欧美综合在线观看 | av黄色免费看 | 91成年人在线观看 |