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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux 中断实验

發布時間:2023/12/10 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 中断实验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • Linux 中斷簡介
    • Linux 中斷API 函數
    • 上半部與下半部
    • 設備樹中斷信息節點
    • 獲取中斷號
  • 硬件原理圖分析
  • 實驗程序編寫
    • 修改設備樹文件
    • 按鍵中斷驅動程序編寫
    • 編寫測試APP
  • 運行測試
    • 編譯驅動程序和測試APP
    • 運行測試

不管是裸機實驗還是Linux 下的驅動實驗,中斷都是頻繁使用的功能,關于I.MX6U 的中斷原理已經在第十七章做了詳細的講解,在裸機中使用中斷我們需要做一大堆的工作,比如配置寄存器,使能IRQ 等等。Linux 內核提供了完善的中斷框架,我們只需要申請中斷,然后注冊中斷處理函數即可,使用非常方便,不需要一系列復雜的寄存器配置。本章我們就來學習一下如何在Linux 下使用中斷。

Linux 中斷簡介

Linux 中斷API 函數

先來回顧一下裸機實驗里面中斷的處理方法:
①、使能中斷,初始化相應的寄存器。
②、注冊中斷服務函數,也就是向irqTable 數組的指定標號處寫入中斷服務函數
②、中斷發生以后進入IRQ 中斷服務函數,在IRQ 中斷服務函數在數組irqTable 里面查找具體的中斷處理函數,找到以后執行相應的中斷處理函數。
在Linux 內核中也提供了大量的中斷相關的API 函數,我們來看一下這些跟中斷有關的API 函數:

1、中斷號
每個中斷都有一個中斷號,通過中斷號即可區分不同的中斷,有的資料也把中斷號叫做中斷線。在Linux 內核中使用一個int 變量表示中斷號,關于中斷號我們已經在第十七章講解過了。
2、request_irq 函數
在Linux 內核中要想使用某個中斷是需要申請的,request_irq 函數用于申請中斷,request_irq函數可能會導致睡眠,因此不能在中斷上下文或者其他禁止睡眠的代碼段中使用request_irq 函數。request_irq 函數會激活(使能)中斷,所以不需要我們手動去使能中斷,request_irq 函數原型如下:

int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)

函數參數和返回值含義如下:
irq:要申請中斷的中斷號。
handler:中斷處理函數,當中斷發生以后就會執行此中斷處理函數。
flags:中斷標志,可以在文件include/linux/interrupt.h 里面查看所有的中斷標志,這里我們介紹幾個常用的中斷標志,如表51.1.1.1 所示:

標志描述
IRQF_SHARED多個設備共享一個中斷線,共享的所有中斷都必須指定此標志。如果使用共享中斷的話,request_irq 函數的dev 參數就是唯一區分他們的標志。
IRQF_ONESHOT單次中斷,中斷執行一次就結束。
IRQF_TRIGGER_NONE無觸發。
IRQF_TRIGGER_RISING上升沿觸發。
IRQF_TRIGGER_FALLING下降沿觸發。
IRQF_TRIGGER_HIGH高電平觸發。
IRQF_TRIGGER_LOW低電平觸發。

比如I.MX6U-ALPHA 開發板上的KEY0 使用GPIO1_IO18,按下KEY0 以后為低電平,因此可以設置為下降沿觸發,也就是將flags 設置為IRQF_TRIGGER_FALLING。表51.1.1.1 中的這些標志可以通過“|”來實現多種組合。

name:中斷名字,設置以后可以在/proc/interrupts 文件中看到對應的中斷名字。
dev:如果將flags 設置為IRQF_SHARED 的話,dev 用來區分不同的中斷,一般情況下將dev 設置為設備結構體,dev 會傳遞給中斷處理函數irq_handler_t 的第二個參數。
返回值:0 中斷申請成功,其他負值中斷申請失敗,如果返回-EBUSY 的話表示中斷已經被申請了。

3、free_irq 函數
使用中斷的時候需要通過request_irq 函數申請,使用完成以后就要通過free_irq 函數釋放掉相應的中斷。如果中斷不是共享的,那么free_irq 會刪除中斷處理函數并且禁止中斷。free_irq函數原型如下所示:

void free_irq(unsigned int irq, void *dev)

函數參數和返回值含義如下:
irq:要釋放的中斷。
dev:如果中斷設置為共享(IRQF_SHARED)的話,此參數用來區分具體的中斷。共享中斷只有在釋放最后中斷處理函數的時候才會被禁止掉。
返回值:無。

4、中斷處理函數
使用request_irq 函數申請中斷的時候需要設置中斷處理函數,中斷處理函數格式如下所示:

irqreturn_t (*irq_handler_t) (int, void *)

第一個參數是要中斷處理函數要相應的中斷號。第二個參數是一個指向void 的指針,也就是個通用指針,需要與request_irq 函數的dev 參數保持一致。用于區分共享中斷的不同設備,dev 也可以指向設備數據結構。中斷處理函數的返回值為irqreturn_t 類型,irqreturn_t 類型定義如下所示:

10 enum irqreturn { 11 IRQ_NONE = (0 << 0), 12 IRQ_HANDLED = (1 << 0), 13 IRQ_WAKE_THREAD = (1 << 1), 14 }; 15 16 typedef enum irqreturn irqreturn_t;

可以看出irqreturn_t 是個枚舉類型,一共有三種返回值。一般中斷服務函數返回值使用如下形式:

return IRQ_RETVAL(IRQ_HANDLED)

5、中斷使能與禁止函數

常用的中斷使用和禁止函數如下所示:

void enable_irq(unsigned int irq) void disable_irq(unsigned int irq)

enable_irq 和disable_irq 用于使能和禁止指定的中斷,irq 就是要禁止的中斷號。disable_irq函數要等到當前正在執行的中斷處理函數執行完才返回,因此使用者需要保證不會產生新的中斷,并且確保所有已經開始執行的中斷處理程序已經全部退出。在這種情況下,可以使用另外一個中斷禁止函數:

void disable_irq_nosync(unsigned int irq)

disable_irq_nosync 函數調用以后立即返回,不會等待當前中斷處理程序執行完畢。上面三個函數都是使能或者禁止某一個中斷,有時候我們需要關閉當前處理器的整個中斷系統,也就是在學習STM32 的時候常說的關閉全局中斷,這個時候可以使用如下兩個函數:

local_irq_enable() local_irq_disable()

local_irq_enable 用于使能當前處理器中斷系統,local_irq_disable 用于禁止當前處理器中斷系統。假如A 任務調用local_irq_disable 關閉全局中斷10S,當關閉了2S 的時候B 任務開始運行,B 任務也調用local_irq_disable 關閉全局中斷3S,3 秒以后B 任務調用local_irq_enable 函數將全局中斷打開了。此時才過去2+3=5 秒的時間,然后全局中斷就被打開了,此時A 任務要關閉10S 全局中斷的愿望就破滅了,然后A 任務就“生氣了”,結果很嚴重,可能系統都要被A 任務整崩潰。為了解決這個問題,B 任務不能直接簡單粗暴的通過local_irq_enable 函數來打開全局中斷,而是將中斷狀態恢復到以前的狀態,要考慮到別的任務的感受,此時就要用到下面兩個函數:

local_irq_save(flags) local_irq_restore(flags)

這兩個函數是一對,local_irq_save 函數用于禁止中斷,并且將中斷狀態保存在flags 中。local_irq_restore 用于恢復中斷,將中斷到flags 狀態。

上半部與下半部

在有些資料中也將上半部和下半部稱為頂半部和底半部,都是一個意思。我們在使用request_irq 申請中斷的時候注冊的中斷服務函數屬于中斷處理的上半部,只要中斷觸發,那么中斷處理函數就會執行。我們都知道中斷處理函數一定要快點執行完畢,越短越好,但是現實往往是殘酷的,有些中斷處理過程就是比較費時間,我們必須要對其進行處理,縮小中斷處理函數的執行時間。比如電容觸摸屏通過中斷通知SOC 有觸摸事件發生,SOC 響應中斷,然后通過IIC 接口讀取觸摸坐標值并將其上報給系統。但是我們都知道IIC 的速度最高也只有400Kbit/S,所以在中斷中通過IIC 讀取數據就會浪費時間。我們可以將通過IIC 讀取觸摸數據的操作暫后執行,中斷處理函數僅僅相應中斷,然后清除中斷標志位即可。這個時候中斷處理過程就分為了兩部分:

上半部:上半部就是中斷處理函數,那些處理過程比較快,不會占用很長時間的處理就可以放在上半部完成。

下半部:如果中斷處理過程比較耗時,那么就將這些比較耗時的代碼提出來,交給下半部去執行,這樣中斷處理函數就會快進快出。

因此,Linux 內核將中斷分為上半部和下半部的主要目的就是實現中斷處理函數的快進快出,那些對時間敏感、執行速度快的操作可以放到中斷處理函數中,也就是上半部。剩下的所有工作都可以放到下半部去執行,比如在上半部將數據拷貝到內存中,關于數據的具體處理就可以放到下半部去執行。至于哪些代碼屬于上半部,哪些代碼屬于下半部并沒有明確的規定,一切根據實際使用情況去判斷,這個就很考驗驅動編寫人員的功底了。這里有一些可以借鑒的參考點:

①、如果要處理的內容不希望被其他中斷打斷,那么可以放到上半部。
②、如果要處理的任務對時間敏感,可以放到上半部。
③、如果要處理的任務與硬件有關,可以放到上半部
④、除了上述三點以外的其他任務,優先考慮放到下半部。
上半部處理很簡單,直接編寫中斷處理函數就行了,關鍵是下半部該怎么做呢?Linux 內核提供了多種下半部機制,接下來我們來學習一下這些下半部機制。

1、軟中斷
一開始Linux 內核提供了“bottom half”機制來實現下半部,簡稱“BH”。后面引入了軟中斷和tasklet 來替代“BH”機制,完全可以使用軟中斷和tasklet 來替代BH,從2.5 版本的Linux內核開始BH 已經被拋棄了。Linux 內核使用結構體softirq_action 表示軟中斷,softirq_action結構體定義在文件include/linux/interrupt.h 中,內容如下:

433 struct softirq_action 434 { 435 void (*action)(struct softirq_action *); 436 };

在kernel/softirq.c 文件中一共定義了10 個軟中斷,如下所示:

static struct softirq_action softirq_vec[NR_SOFTIRQS];

NR_SOFTIRQS 是枚舉類型,定義在文件include/linux/interrupt.h 中,定義如下:

enum { HI_SOFTIRQ=0, /* 高優先級軟中斷*/ TIMER_SOFTIRQ, /* 定時器軟中斷*/ NET_TX_SOFTIRQ, /* 網絡數據發送軟中斷*/ NET_RX_SOFTIRQ, /* 網絡數據接收軟中斷*/ BLOCK_SOFTIRQ, BLOCK_IOPOLL_SOFTIRQ, TASKLET_SOFTIRQ, /* tasklet軟中斷*/ SCHED_SOFTIRQ, /* 調度軟中斷*/ HRTIMER_SOFTIRQ, /* 高精度定時器軟中斷*/ RCU_SOFTIRQ, /* RCU軟中斷*/ NR_SOFTIRQS };

可以看出,一共有10 個軟中斷,因此NR_SOFTIRQS 為10,因此數組softirq_vec 有10 個元素。softirq_action 結構體中的action 成員變量就是軟中斷的服務函數,數組softirq_vec 是個全局數組,因此所有的CPU(對于SMP 系統而言)都可以訪問到,每個CPU 都有自己的觸發和控制機制,并且只執行自己所觸發的軟中斷。但是各個CPU 所執行的軟中斷服務函數確是相同
的,都是數組softirq_vec 中定義的action 函數。要使用軟中斷,必須先使用open_softirq 函數注冊對應的軟中斷處理函數,open_softirq 函數原型如下:

void open_softirq(int nr, void (*action)(struct softirq_action *))

函數參數和返回值含義如下:

nr:要開啟的軟中斷,在示例代碼51.1.2.3 中選擇一個。
action:軟中斷對應的處理函數。
返回值:沒有返回值。
注冊好軟中斷以后需要通過raise_softirq 函數觸發,raise_softirq 函數原型如下:

void raise_softirq(unsigned int nr)

函數參數和返回值含義如下:
nr:要觸發的軟中斷,在示例代碼51.1.2.3 中選擇一個。
返回值:沒有返回值。
軟中斷必須在編譯的時候靜態注冊!Linux 內核使用softirq_init 函數初始化軟中斷,softirq_init 函數定義在kernel/softirq.c 文件里面,函數內容如下:

634 void __init softirq_init(void) 635 { 636 int cpu; 637 638 for_each_possible_cpu(cpu) { 639 per_cpu(tasklet_vec, cpu).tail = 640 &per_cpu(tasklet_vec, cpu).head; 641 per_cpu(tasklet_hi_vec, cpu).tail = 642 &per_cpu(tasklet_hi_vec, cpu).head; 643 } 644 645 open_softirq(TASKLET_SOFTIRQ, tasklet_action); 646 open_softirq(HI_SOFTIRQ, tasklet_hi_action); 647 }

從示例代碼51.1.2.4 可以看出,softirq_init 函數默認會打開TASKLET_SOFTIRQ 和HI_SOFTIRQ。
2、tasklet
tasklet 是利用軟中斷來實現的另外一種下半部機制,在軟中斷和tasklet 之間,建議大家使用tasklet。Linux 內核使用tasklet_struct 結構體來表示tasklet:

484 struct tasklet_struct 485 { 486 struct tasklet_struct *next; /* 下一個tasklet */ 487 unsigned long state; /* tasklet狀態*/ 488 atomic_t count; /* 計數器,記錄對tasklet的引用數*/ 489 void (*func)(unsigned long); /* tasklet執行的函數*/ 490 unsigned long data; /* 函數func的參數*/ 491 };

第489 行的func 函數就是tasklet 要執行的處理函數,用戶定義函數內容,相當于中斷處理函數。如果要使用tasklet,必須先定義一個tasklet,然后使用tasklet_init 函數初始化tasklet,taskled_init 函數原型如下:

void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data);

函數參數和返回值含義如下:
t:要初始化的tasklet
func:tasklet 的處理函數。
data:要傳遞給func 函數的參數
返回值:沒有返回值。
也可以使用宏DECLARE_TASKLET 來一次性完成tasklet 的定義和初始化,
DECLARE_TASKLET 定義在include/linux/interrupt.h 文件中,定義如下:

DECLARE_TASKLET(name, func, data)

其中name 為要定義的tasklet 名字,這個名字就是一個tasklet_struct 類型的時候變量,func就是tasklet 的處理函數,data 是傳遞給func 函數的參數。
在上半部,也就是中斷處理函數中調用tasklet_schedule 函數就能使tasklet 在合適的時間運行,tasklet_schedule 函數原型如下:

void tasklet_schedule(struct tasklet_struct *t)

函數參數和返回值含義如下:
t:要調度的tasklet,也就是DECLARE_TASKLET 宏里面的name。
返回值:沒有返回值。
關于tasklet 的參考使用示例如下所示:

/* 定義taselet */ struct tasklet_struct testtasklet; /* tasklet處理函數*/ void testtasklet_func(unsigned long data) { /* tasklet具體處理內容*/ } /* 中斷處理函數*/ irqreturn_t test_handler(int irq, void *dev_id) { ...... /* 調度tasklet */ tasklet_schedule(&testtasklet); ...... } /* 驅動入口函數*/ static int __init xxxx_init(void) { ...... /* 初始化tasklet */ tasklet_init(&testtasklet, testtasklet_func, data); /* 注冊中斷處理函數*/ request_irq(xxx_irq, test_handler, 0, "xxx", &xxx_dev); ...... }

2、工作隊列
工作隊列是另外一種下半部執行方式,工作隊列在進程上下文執行,工作隊列將要推后的工作交給一個內核線程去執行,因為工作隊列工作在進程上下文,因此工作隊列允許睡眠或重新調度。因此如果你要推后的工作可以睡眠那么就可以選擇工作隊列,否則的話就只能選擇軟中斷或tasklet。

Linux 內核使用work_struct 結構體表示一個工作,內容如下(省略掉條件編譯):

struct work_struct { atomic_long_t data; struct list_head entry; work_func_t func; /* 工作隊列處理函數*/ };

這些工作組織成工作隊列,工作隊列使用workqueue_struct 結構體表示,內容如下(省略掉條件編譯):

struct workqueue_struct { struct list_head pwqs; struct list_head list; struct mutex mutex; int work_color; int flush_color; atomic_t nr_pwqs_to_flush; struct wq_flusher *first_flusher; struct list_head flusher_queue; struct list_head flusher_overflow; struct list_head maydays; struct worker *rescuer; int nr_drainers; int saved_max_active; struct workqueue_attrs *unbound_attrs; struct pool_workqueue *dfl_pwq; char name[WQ_NAME_LEN]; struct rcu_head rcu; unsigned int flags ____cacheline_aligned; struct pool_workqueue __percpu *cpu_pwqs; struct pool_workqueue __rcu *numa_pwq_tbl[]; };

Linux 內核使用工作者線程(worker thread)來處理工作隊列中的各個工作,Linux 內核使用worker 結構體表示工作者線程,worker 結構體內容如下:

struct worker { union { struct list_head entry; struct hlist_node hentry; }; struct work_struct *current_work; work_func_t current_func; struct pool_workqueue *current_pwq; bool desc_valid; struct list_head scheduled; struct task_struct *task; struct worker_pool *pool; struct list_head node; unsigned long last_active; unsigned int flags; int id; char desc[WORKER_DESC_LEN]; struct workqueue_struct *rescue_wq; };

從示例代碼51.1.2.10 可以看出,每個worker 都有一個工作隊列,工作者線程處理自己工作隊列中的所有工作。在實際的驅動開發中,我們只需要定義工作(work_struct)即可,關于工作隊列和工作者線程我們基本不用去管。簡單創建工作很簡單,直接定義一個work_struct 結構體變量即可,然后使用INIT_WORK 宏來初始化工作,INIT_WORK 宏定義如下:

#define INIT_WORK(_work, _func)

_work 表示要初始化的工作,_func 是工作對應的處理函數。
也可以使用DECLARE_WORK 宏一次性完成工作的創建和初始化,宏定義如下:

#define DECLARE_WORK(n, f)

n 表示定義的工作(work_struct),f 表示工作對應的處理函數。
和tasklet 一樣,工作也是需要調度才能運行的,工作的調度函數為schedule_work,函數原型如下所示:

bool schedule_work(struct work_struct *work)

函數參數和返回值含義如下:
work:要調度的工作。
返回值:0 成功,其他值失敗。
關于工作隊列的參考使用示例如下所示:

/* 定義工作(work) */ struct work_struct testwork; /* work處理函數*/ void testwork_func_t(struct work_struct *work); { /* work具體處理內容*/ } /* 中斷處理函數*/ irqreturn_t test_handler(int irq, void *dev_id) { ...... /* 調度work */ schedule_work(&testwork); ...... } /* 驅動入口函數*/ static int __init xxxx_init(void) { ...... /* 初始化work */ INIT_WORK(&testwork, testwork_func_t); /* 注冊中斷處理函數*/ request_irq(xxx_irq, test_handler, 0, "xxx", &xxx_dev); ...... }

設備樹中斷信息節點

如果使用設備樹的話就需要在設備樹中設置好中斷屬性信息,Linux 內核通過讀取設備樹中的中斷屬性信息來配置中斷。對于中斷控制器而言,設備樹綁定信息參考文檔
Documentation/devicetree/bindings/arm/gic.txt。打開imx6ull.dtsi 文件,其中的intc 節點就是I.MX6ULL 的中斷控制器節點,節點內容如下所示:

1 intc: interrupt-controller@00a01000 { 2 compatible = "arm,cortex-a7-gic"; 3 #interrupt-cells = <3>; 4 interrupt-controller; 5 reg = <0x00a01000 0x1000>, 6 <0x00a02000 0x100>; 7 };

第2 行,compatible 屬性值為“arm,cortex-a7-gic”在Linux 內核源碼中搜索“arm,cortex-a7-gic”即可找到GIC 中斷控制器驅動文件。
第3 行,#interrupt-cells 和#address-cells、#size-cells 一樣。表示此中斷控制器下設備的cells大小,對于設備而言,會使用interrupts 屬性描述中斷信息,#interrupt-cells 描述了interrupts 屬性的cells 大小,也就是一條信息有幾個cells。每個cells 都是32 位整形值,對于ARM 處理的GIC 來說,一共有3 個cells,這三個cells 的含義如下:

第一個cells:中斷類型,0 表示SPI 中斷,1 表示PPI 中斷。
第二個cells:中斷號,對于SPI 中斷來說中斷號的范圍為0~ 987,對于PPI 中斷來說中斷號的范圍為0~15。
第三個cells:標志,bit[3:0]表示中斷觸發類型,為1 的時候表示上升沿觸發,為2 的時候表示下降沿觸發,為4 的時候表示高電平觸發,為8 的時候表示低電平觸發。bit[15:8]為PPI 中斷的CPU 掩碼。
第4 行,interrupt-controller 節點為空,表示當前節點是中斷控制器。
對于gpio 來說,gpio 節點也可以作為中斷控制器,比如imx6ull.dtsi 文件中的gpio5 節點內容如下所示:

1 gpio5: gpio@020ac000 { 2 compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio"; 3 reg = <0x020ac000 0x4000>; 4 interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>, 5 <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; 6 gpio-controller; 7 #gpio-cells = <2>; 8 interrupt-controller; 9 #interrupt-cells = <2>; 10 };

第4 行,interrupts 描述中斷源信息,對于gpio5 來說一共有兩條信息,中斷類型都是SPI,觸發電平都是IRQ_TYPE_LEVEL_HIGH。不同之處在于中斷源,一個是74,一個是75,打開可以打開《IMX6ULL 參考手冊》的“Chapter 3 Interrupts and DMA Events”章節,找到表3-1,有如圖50.1.3.1 所示的內容:

從圖50.1.3.1 可以看出,GPIO5 一共用了2 個中斷號,一個是74,一個是75。其中74 對應GPIO5_IO00~ GPIO5_IO15 這低16 個IO,75 對應GPIO5_IO16~GPIOI5_IO31 這高16 位IO。
第8 行,interrupt-controller 表明了gpio5 節點也是個中斷控制器,用于控制gpio5 所有IO的中斷。
第9 行,將#interrupt-cells 修改為2。
打開imx6ull-alientek-emmc.dts 文件,找到如下所示內容:

1 fxls8471@1e { 2 compatible = "fsl,fxls8471"; 3 reg = <0x1e>; 4 position = <0>; 5 interrupt-parent = <&gpio5>; 6 interrupts = <0 8>; 7 };

fxls8471 是NXP 官方的6ULL 開發板上的一個磁力計芯片,fxls8471 有一個中斷引腳鏈接到了I.MX6ULL 的SNVS_TAMPER0 因腳上,這個引腳可以復用為GPIO5_IO00。
第5 行,interrupt-parent 屬性設置中斷控制器,這里使用gpio5 作為中斷控制器。
第6 行,interrupts 設置中斷信息,0 表示GPIO5_IO00,8 表示低電平觸發。
簡單總結一下與中斷有關的設備樹屬性信息:
①、#interrupt-cells,指定中斷源的信息cells 個數。
②、interrupt-controller,表示當前節點為中斷控制器。
③、interrupts,指定中斷號,觸發方式等。
④、interrupt-parent,指定父中斷,也就是中斷控制器。

獲取中斷號

編寫驅動的時候需要用到中斷號,我們用到中斷號,中斷信息已經寫到了設備樹里面,因此可以通過irq_of_parse_and_map 函數從interupts 屬性中提取到對應的設備號,函數原型如下:

unsigned int irq_of_parse_and_map(struct device_node *dev, int index)

函數參數和返回值含義如下:
dev:設備節點。
index:索引號,interrupts 屬性可能包含多條中斷信息,通過index 指定要獲取的信息。
返回值:中斷號。
如果使用GPIO 的話,可以使用gpio_to_irq 函數來獲取gpio 對應的中斷號,函數原型如下:

int gpio_to_irq(unsigned int gpio)

函數參數和返回值含義如下:
gpio:要獲取的GPIO 編號。
返回值:GPIO 對應的中斷號。

硬件原理圖分析

本章實驗硬件原理圖參考15.2 小節即可。

實驗程序編寫

本實驗對應的例程路徑為:開發板光盤-> 2、Linux 驅動例程-> 13_irq。
本章實驗我們驅動I.MX6U-ALPHA 開發板上的KEY0 按鍵,不過我們采用中斷的方式,并且采用定時器來實現按鍵消抖,應用程序讀取按鍵值并且通過終端打印出來。通過本章我們可以學習到Linux 內核中斷的使用方法,以及對Linux 內核定時器的回顧。

修改設備樹文件

本章實驗使用到了按鍵KEY0,按鍵KEY0 使用中斷模式,因此需要在“key”節點下添加中斷相關屬性,添加完成以后的“key”節點內容如下所示:

1 key { 2 #address-cells = <1>; 3 #size-cells = <1>; 4 compatible = "atkalpha-key"; 5 pinctrl-names = "default"; 6 pinctrl-0 = <&pinctrl_key>; 7 key-gpio = <&gpio1 18 GPIO_ACTIVE_LOW>; /* KEY0 */ 8 interrupt-parent = <&gpio1>; 9 interrupts = <18 IRQ_TYPE_EDGE_BOTH>; /* FALLING RISING */ 10 status = "okay"; 11 };

第8 行,設置interrupt-parent 屬性值為“gpio1”,因為KEY0 所使用的GPIO 為
GPIO1_IO18,也就是設置KEY0 的GPIO 中斷控制器為gpio1。
第9 行,設置interrupts 屬性,也就是設置中斷源,第一個cells 的18 表示GPIO1 組的18號IO。IRQ_TYPE_EDGE_BOTH 定義在文件include/linux/irq.h 中,定義如下:

76 enum { 77 IRQ_TYPE_NONE = 0x00000000, 78 IRQ_TYPE_EDGE_RISING = 0x00000001, 79 IRQ_TYPE_EDGE_FALLING = 0x00000002, 80 IRQ_TYPE_EDGE_BOTH = (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING), 81 IRQ_TYPE_LEVEL_HIGH = 0x00000004, 82 IRQ_TYPE_LEVEL_LOW = 0x00000008, 83 IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH), ...... 100 };

從示例代碼51.3.1.2 中可以看出,IRQ_TYPE_EDGE_BOTH 表示上升沿和下降沿同時有效,相當于KEY0 按下和釋放都會觸發中斷。

設備樹編寫完成以后使用“make dtbs”命令重新編譯設備樹,然后使用新編譯出來的imx6ull-alientek-emmc.dtb 文件啟動Linux 系統。

按鍵中斷驅動程序編寫

新建名為“13_irq”的文件夾,然后在13_irq 文件夾里面創建vscode 工程,工作區命名為“imx6uirq”。工程創建好以后新建imx6uirq.c 文件,在imx6uirq.c 里面輸入如下內容:

#include <linux/types.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/ide.h> #include <linux/init.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/gpio.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_gpio.h> #include <linux/semaphore.h> #include <linux/timer.h> #include <linux/of_irq.h> #include <linux/irq.h> #include <asm/mach/map.h> #include <asm/uaccess.h> #include <asm/io.h> /*************************************************************** Copyright ? ALIENTEK Co., Ltd. 1998-2029. All rights reserved. 文件名 : imx6uirq.c 作者 : 左忠凱 版本 : V1.0 描述 : Linux中斷驅動實驗 其他 : 無 論壇 : www.openedv.com 日志 : 初版V1.0 2019/7/26 左忠凱創建 ***************************************************************/ #define IMX6UIRQ_CNT 1 /* 設備號個數 */ #define IMX6UIRQ_NAME "imx6uirq" /* 名字 */ #define KEY0VALUE 0X01 /* KEY0按鍵值 */ #define INVAKEY 0XFF /* 無效的按鍵值 */ #define KEY_NUM 1 /* 按鍵數量 *//* 中斷IO描述結構體 */ struct irq_keydesc {int gpio; /* gpio */int irqnum; /* 中斷號 */unsigned char value; /* 按鍵對應的鍵值 */char name[10]; /* 名字 */irqreturn_t (*handler)(int, void *); /* 中斷服務函數 */ };/* imx6uirq設備結構體 */ struct imx6uirq_dev{dev_t devid; /* 設備號 */struct cdev cdev; /* cdev */struct class *class; /* 類 */struct device *device; /* 設備 */int major; /* 主設備號 */int minor; /* 次設備號 */struct device_node *nd; /* 設備節點 */atomic_t keyvalue; /* 有效的按鍵鍵值 */atomic_t releasekey; /* 標記是否完成一次完成的按鍵,包括按下和釋放 */struct timer_list timer;/* 定義一個定時器*/struct irq_keydesc irqkeydesc[KEY_NUM]; /* 按鍵描述數組 */unsigned char curkeynum; /* 當前的按鍵號 */ };struct imx6uirq_dev imx6uirq; /* irq設備 *//* @description : 中斷服務函數,開啟定時器,延時10ms,* 定時器用于按鍵消抖。* @param - irq : 中斷號 * @param - dev_id : 設備結構。* @return : 中斷執行結果*/ static irqreturn_t key0_handler(int irq, void *dev_id) {struct imx6uirq_dev *dev = (struct imx6uirq_dev *)dev_id;dev->curkeynum = 0;dev->timer.data = (volatile long)dev_id;mod_timer(&dev->timer, jiffies + msecs_to_jiffies(10)); /* 10ms定時 */return IRQ_RETVAL(IRQ_HANDLED); }/* @description : 定時器服務函數,用于按鍵消抖,定時器到了以后* 再次讀取按鍵值,如果按鍵還是處于按下狀態就表示按鍵有效。* @param - arg : 設備結構變量* @return : 無*/ void timer_function(unsigned long arg) {unsigned char value;unsigned char num;struct irq_keydesc *keydesc;struct imx6uirq_dev *dev = (struct imx6uirq_dev *)arg;num = dev->curkeynum;keydesc = &dev->irqkeydesc[num];value = gpio_get_value(keydesc->gpio); /* 讀取IO值 */if(value == 0){ /* 按下按鍵 */atomic_set(&dev->keyvalue, keydesc->value);}else{ /* 按鍵松開 */atomic_set(&dev->keyvalue, 0x80 | keydesc->value);atomic_set(&dev->releasekey, 1); /* 標記松開按鍵,即完成一次完整的按鍵過程 */ } }/** @description : 按鍵IO初始化* @param : 無* @return : 無*/ static int keyio_init(void) {unsigned char i = 0;int ret = 0;imx6uirq.nd = of_find_node_by_path("/key");if (imx6uirq.nd== NULL){printk("key node not find!\r\n");return -EINVAL;} /* 提取GPIO */for (i = 0; i < KEY_NUM; i++) {imx6uirq.irqkeydesc[i].gpio = of_get_named_gpio(imx6uirq.nd ,"key-gpio", i);if (imx6uirq.irqkeydesc[i].gpio < 0) {printk("can't get key%d\r\n", i);}}/* 初始化key所使用的IO,并且設置成中斷模式 */for (i = 0; i < KEY_NUM; i++) {memset(imx6uirq.irqkeydesc[i].name, 0, sizeof(name)); /* 緩沖區清零 */sprintf(imx6uirq.irqkeydesc[i].name, "KEY%d", i); /* 組合名字 */gpio_request(imx6uirq.irqkeydesc[i].gpio, imx6uirq.irqkeydesc[i].name);gpio_direction_input(imx6uirq.irqkeydesc[i].gpio); imx6uirq.irqkeydesc[i].irqnum = irq_of_parse_and_map(imx6uirq.nd, i); #if 0imx6uirq.irqkeydesc[i].irqnum = gpio_to_irq(imx6uirq.irqkeydesc[i].gpio); #endifprintk("key%d:gpio=%d, irqnum=%d\r\n",i, imx6uirq.irqkeydesc[i].gpio, imx6uirq.irqkeydesc[i].irqnum);}/* 申請中斷 */imx6uirq.irqkeydesc[0].handler = key0_handler;imx6uirq.irqkeydesc[0].value = KEY0VALUE;for (i = 0; i < KEY_NUM; i++) {ret = request_irq(imx6uirq.irqkeydesc[i].irqnum, imx6uirq.irqkeydesc[i].handler, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, imx6uirq.irqkeydesc[i].name, &imx6uirq);if(ret < 0){printk("irq %d request failed!\r\n", imx6uirq.irqkeydesc[i].irqnum);return -EFAULT;}}/* 創建定時器 */init_timer(&imx6uirq.timer);imx6uirq.timer.function = timer_function;return 0; }/** @description : 打開設備* @param - inode : 傳遞給驅動的inode* @param - filp : 設備文件,file結構體有個叫做private_data的成員變量* 一般在open的時候將private_data指向設備結構體。* @return : 0 成功;其他 失敗*/ static int imx6uirq_open(struct inode *inode, struct file *filp) {filp->private_data = &imx6uirq; /* 設置私有數據 */return 0; }/** @description : 從設備讀取數據 * @param - filp : 要打開的設備文件(文件描述符)* @param - buf : 返回給用戶空間的數據緩沖區* @param - cnt : 要讀取的數據長度* @param - offt : 相對于文件首地址的偏移* @return : 讀取的字節數,如果為負值,表示讀取失敗*/ static ssize_t imx6uirq_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt) {int ret = 0;unsigned char keyvalue = 0;unsigned char releasekey = 0;struct imx6uirq_dev *dev = (struct imx6uirq_dev *)filp->private_data;keyvalue = atomic_read(&dev->keyvalue);releasekey = atomic_read(&dev->releasekey);if (releasekey) { /* 有按鍵按下 */ if (keyvalue & 0x80) {keyvalue &= ~0x80;ret = copy_to_user(buf, &keyvalue, sizeof(keyvalue));} else {goto data_error;}atomic_set(&dev->releasekey, 0);/* 按下標志清零 */} else {goto data_error;}return 0;data_error:return -EINVAL; }/* 設備操作函數 */ static struct file_operations imx6uirq_fops = {.owner = THIS_MODULE,.open = imx6uirq_open,.read = imx6uirq_read, };/** @description : 驅動入口函數* @param : 無* @return : 無*/ static int __init imx6uirq_init(void) {/* 1、構建設備號 */if (imx6uirq.major) {imx6uirq.devid = MKDEV(imx6uirq.major, 0);register_chrdev_region(imx6uirq.devid, IMX6UIRQ_CNT, IMX6UIRQ_NAME);} else {alloc_chrdev_region(&imx6uirq.devid, 0, IMX6UIRQ_CNT, IMX6UIRQ_NAME);imx6uirq.major = MAJOR(imx6uirq.devid);imx6uirq.minor = MINOR(imx6uirq.devid);}/* 2、注冊字符設備 */cdev_init(&imx6uirq.cdev, &imx6uirq_fops);cdev_add(&imx6uirq.cdev, imx6uirq.devid, IMX6UIRQ_CNT);/* 3、創建類 */imx6uirq.class = class_create(THIS_MODULE, IMX6UIRQ_NAME);if (IS_ERR(imx6uirq.class)) {return PTR_ERR(imx6uirq.class);}/* 4、創建設備 */imx6uirq.device = device_create(imx6uirq.class, NULL, imx6uirq.devid, NULL, IMX6UIRQ_NAME);if (IS_ERR(imx6uirq.device)) {return PTR_ERR(imx6uirq.device);}/* 5、初始化按鍵 */atomic_set(&imx6uirq.keyvalue, INVAKEY);atomic_set(&imx6uirq.releasekey, 0);keyio_init();return 0; }/** @description : 驅動出口函數* @param : 無* @return : 無*/ static void __exit imx6uirq_exit(void) {unsigned int i = 0;/* 刪除定時器 */del_timer_sync(&imx6uirq.timer); /* 刪除定時器 *//* 釋放中斷 */for (i = 0; i < KEY_NUM; i++) {free_irq(imx6uirq.irqkeydesc[i].irqnum, &imx6uirq);}cdev_del(&imx6uirq.cdev);unregister_chrdev_region(imx6uirq.devid, IMX6UIRQ_CNT);device_destroy(imx6uirq.class, imx6uirq.devid);class_destroy(imx6uirq.class); }module_init(imx6uirq_init); module_exit(imx6uirq_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("zuozhongkai");

第38~43 行,結構體irq_keydesc 為按鍵的中斷描述結構體,gpio 為按鍵GPIO 編號,irqnum為按鍵IO 對應的中斷號,value 為按鍵對應的鍵值,name 為按鍵名字,handler 為按鍵中斷服務函數。使用irq_keydesc 結構體即可描述一個按鍵中斷。

第47~60 行,結構體imx6uirq_dev 為本例程設備結構體,第55 行的keyvalue 保存按鍵值,第56 行的releasekey 表示按鍵是否被釋放,如果按鍵被釋放表示發生了一次完整的按鍵過程。
第57 行的timer 為按鍵消抖定時器,使用定時器進行按鍵消抖的原理已經在19.1 小節講解過了。第58 行的數組irqkeydesc 為按鍵信息數組,數組元素個數就是開發板上的按鍵個數,I.MX6U-ALIPHA 開發板上只有一個按鍵,因此irqkeydesc 數組只有一個元素。第59 行的curkeynum 表示當前按鍵。
第62 行,定義設備結構體變量imx6uirq。
第70~78 行,key0_handler 函數,按鍵KEY0 中斷處理函數,參數dev_id 為設備結構體,也就是imx6uirq。第74 行設置curkeynum=0,表示當前按鍵為KEY0,第76 行使用mod_timer函數啟動定時器,定時器周期為10ms。

第85~103,timer_function 函數,定時器定時處理函數,參數arg 是設備結構體,也就是imx6uirq,在此函數中讀取按鍵值。第95 行通過gpio_get_value 函數讀取按鍵值。如果為0 的話就表示按鍵被按下去了,按下去的話就設置imx6uirq 結構體的keyvalue 成員變量為按鍵的鍵值,比如KEY0 按鍵的話按鍵值就是KEY0VALUE=0。如果按鍵值為1 的話表示按鍵被釋放了,按鍵釋放了的話就將imx6uirq 結構體的keyvalue 成員變量的最高位置1,表示按鍵值有效,也就是將keyvalue 與0x80 進行或運算,表示按鍵松開了,并且設置imx6uirq 結構體的releasekey成員變量為1,表示按鍵釋放,一次有效的按鍵過程發生。
第110~159 行,keyio_init 函數,按鍵IO 初始化函數,在驅動入口函數里面會調用keyio_init來初始化按鍵IO。第131~142 行輪流初始化所有的按鍵,包括申請IO、設置IO 為輸入模式、從設備樹中獲取IO 的中斷號等等。第136 行通過irq_of_parse_and_map 函數從設備樹中獲取按鍵IO 對應的中斷號。也可以使用gpio_to_irq 函數將某個IO 設置為中斷狀態,并且返回其中斷
號。第144 和145 行設置KEY0 按鍵對應的按鍵中斷處理函數為key0_handler、KEY0 的按鍵值為KEY0VALUE。第147~153 行輪流調用request_irq 函數申請中斷號,設置中斷觸發模式為IRQF_TRIGGER_FALLING 和IRQF_TRIGGER_RISING,也就是上升沿和下降沿都可以觸發中斷。最后,第156 行初始化定時器,并且設置定時器的定時處理函數。
第168~172 行,imx6uirq_open 函數,對應應用程序的open 函數。
第182~207 行,imx6uirq_read 函數,對應應用程序的read 函數。此函數向應用程序返回按鍵值。首先判斷imx6uirq 結構體的releasekey 成員變量值是否為1,如果為1 的話表示有一次有效按鍵發生,否則的話就直接返回-EINVAL。當有按鍵事件發生的話就要向應用程序發送按鍵值,首先判斷按鍵值的最高位是否為1,如果為1 的話就表示按鍵值有效。如果按鍵值有效
的話就將最高位清除,得到真實的按鍵值,然后通過copy_to_user 函數返回給應用程序。向應用程序發送按鍵值完成以后就將imx6uirq 結構體的releasekey 成員變量清零,準備下一次按鍵操作。
第210~214 行,按鍵中斷驅動操作函數集imx6uirq_fops。
第221~253 行,驅動入口函數,第250 和251 行分別初始化imx6uirq 結構體中的原子變量keyvalue 和releasekey,第252 行調用keyio_init 函數初始化按鍵所使用的IO。
第261~ 275 行,驅動出口函數,第265 行調用del_timer_sync 函數刪除定時器,第268~270行輪流釋放申請的所有按鍵中斷。

編寫測試APP

測試APP 要實現的內容很簡單,通過不斷的讀取/dev/imx6uirq 文件來獲取按鍵值,當按鍵按下以后就會將獲取到的按鍵值輸出在終端上,新建名為imx6uirqApp.c 的文件,然后輸入如下所示內容:

#include "stdio.h" #include "unistd.h" #include "sys/types.h" #include "sys/stat.h" #include "fcntl.h" #include "stdlib.h" #include "string.h" #include "linux/ioctl.h" /*************************************************************** Copyright ? ALIENTEK Co., Ltd. 1998-2029. All rights reserved. 文件名 : imx6uirqApp.c 作者 : 左忠凱 版本 : V1.0 描述 : 定時器測試應用程序 其他 : 無 使用方法 :./imx6uirqApp /dev/imx6uirq 打開測試App 論壇 : www.openedv.com 日志 : 初版V1.0 2019/7/26 左忠凱創建 ***************************************************************//** @description : main主程序* @param - argc : argv數組元素個數* @param - argv : 具體參數* @return : 0 成功;其他 失敗*/ int main(int argc, char *argv[]) {int fd;int ret = 0;int data = 0;char *filename;unsigned char data;if (argc != 2) {printf("Error Usage!\r\n");return -1;}filename = argv[1];fd = open(filename, O_RDWR);if (fd < 0) {printf("Can't open file %s\r\n", filename);return -1;}while (1) {ret = read(fd, &data, sizeof(data));if (ret < 0) { /* 數據讀取錯誤或者無效 */} else { /* 數據讀取正確 */if (data) /* 讀取到數據 */printf("key value = %#X\r\n", data);}}close(fd);return ret; }

第45~53 行的while 循環用于不斷的讀取按鍵值,如果讀取到有效的按鍵值就將其輸出到終端上。

運行測試

編譯驅動程序和測試APP

1、編譯驅動程序
編寫Makefile 文件,本章實驗的Makefile 文件和第四十章實驗基本一樣,只是將obj-m 變量的值改為imx6uirq.o,Makefile 內容如下所示:

KERNELDIR := /home/zuozhongkai/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek CURRENT_PATH := $(shell pwd)obj-m := imx6uirq.obuild: kernel_moduleskernel_modules:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modulesclean:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

第4 行,設置obj-m 變量的值為imx6uirq.o。
輸入如下命令編譯出驅動模塊文件:

make -j32

編譯成功以后就會生成一個名為“imx6uirq.ko”的驅動模塊文件。

2、編譯測試APP
輸入如下命令編譯測試imx6uirqApp.c 這個測試程序:

arm-linux-gnueabihf-gcc imx6uirqApp.c -o imx6uirqApp

編譯成功以后就會生成imx6uirqApp 這個應用程序。

運行測試

將上一小節編譯出來imx6uirq.ko 和imx6uirqApp 這兩個文件拷貝到
rootfs/lib/modules/4.1.15 目錄中,重啟開發板,進入到目錄lib/modules/4.1.15 中,輸入如下命令加載imx6uirq.ko 驅動模塊:

depmod //第一次加載驅動的時候需要運行此命令 modprobe imx6uirq.ko //加載驅動

驅動加載成功以后可以通過查看/proc/interrupts 文件來檢查一下對應的中斷有沒有被注冊上,輸入如下命令:

cat /proc/interrupts

結果如圖51.4.2.1 所示:

從圖51.4.2.1 可以看出imx6uirq.c 驅動文件里面的KEY0 中斷已經存在了,觸發方式為跳邊沿(Edge),中斷號為49。
接下來使用如下命令來測試中斷:

./imx6uirqApp /dev/imx6uirq

按下開發板上的KEY0 鍵,終端就會輸出按鍵值,如圖51.4.2.2 所示:

從圖51.4.2.2 可以看出,按鍵值獲取成功,并且不會有按鍵抖動導致的誤判發生,說明按鍵消抖工作正常。如果要卸載驅動的話輸入如下命令即可:

rmmod imx6uirq.ko

總結

以上是生活随笔為你收集整理的Linux 中断实验的全部內容,希望文章能夠幫你解決所遇到的問題。

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

毛片一区二区 | 亚洲精品乱码久久久久久蜜桃动漫 | 国产精品资源在线观看 | 国产精品网站一区二区三区 | 久草色在线观看 | 九九精品久久 | 黄色网址av| 国产伦理久久精品久久久久_ | 日本在线观看中文字幕无线观看 | 国产精品videoxxxx | 99免费看片 | 国产精品久久久毛片 | 草久视频在线 | 天天干天天做天天爱 | 麻豆视频国产精品 | 婷婷久久五月 | 在线观看国产永久免费视频 | 在线视频婷婷 | 少妇bbw揉bbb欧美 | 精品国产成人av在线免 | 久久久这里有精品 | 精品女同一区二区三区在线观看 | 国产一级免费观看视频 | 久久久久成人免费 | www.久久爱.cn | 欧美日韩高清在线 | 久久久免费网站 | a√国产免费a | 黄色成人免费电影 | 五月综合 | 成人午夜黄色影院 | 欧美一区二区三区免费看 | 精品亚洲免费视频 | 欧美日韩色婷婷 | 四川妇女搡bbbb搡bbbb搡 | 成人亚洲网 | 亚洲最新视频在线 | 久久久久日本精品一区二区三区 | 伊人五月综合 | 日韩欧美一区二区在线 | 91av播放| a天堂免费 | 成年人在线视频观看 | 在线日本看片免费人成视久网 | 欧美资源| 青青河边草免费观看完整版高清 | 激情九九 | 日韩精品免费在线观看 | 国产在线视频在线观看 | 婷婷av在线 | 国产一二三在线视频 | 亚洲日本欧美在线 | 久草视频在线看 | 精品视频在线免费 | 午夜国产福利在线观看 | 亚洲天堂网站视频 | 国产精品一区二区在线 | 亚洲精品在线视频播放 | 天天色图 | 日韩三级在线 | 91精品视频在线观看免费 | 黄色成人小视频 | 欧美一区二区三区免费观看 | 玖玖爱国产在线 | 日韩电影一区二区三区在线观看 | 国产精品自产拍在线观看网站 | 国产精品完整版 | 日韩精品一区二区三区不卡 | 免费看黄在线观看 | 久久艹在线观看 | 日本护士三级少妇三级999 | 成人99免费视频 | 久久网站最新地址 | 欧美亚洲另类在线视频 | 在线免费观看国产 | 人人干人人艹 | 美女在线免费观看视频 | 美女久久精品 | 欧美日韩免费一区二区 | 五月天久久激情 | 免费观看xxxx9999片 | 99精品免费网 | 在线v| 日韩欧美一区二区三区免费观看 | 18久久久久久| 中文字幕在线观看免费高清完整版 | 日韩精品久久一区二区三区 | 美女网站黄免费 | 亚洲人成免费 | 久久婷婷五月综合色丁香 | 久久久午夜精品理论片中文字幕 | 激情五月婷婷综合 | 在线观看中文字幕一区二区 | 日韩在线观看视频网站 | 中文字幕 影院 | 一区二区激情 | 最新精品国产 | 亚洲年轻女教师毛茸茸 | 久草免费在线观看 | 亚洲国产理论片 | 久久精品视频在线播放 | 日韩一区二区免费播放 | 在线看黄网站 | 久久久久网站 | 日韩欧美在线视频一区二区三区 | 精品在线看 | 亚洲91精品在线观看 | 日韩欧美69 | 欧美在线aaa | 久草91视频 | 国产最新福利 | 国产黑丝袜在线 | 日日夜夜精品视频天天综合网 | 极品久久久久久久 | 久久综合狠狠综合久久激情 | 操操操日日 | 久久久免费精品国产一区二区 | 在线观看爱爱视频 | av一级免费 | 国产精品久久久久久吹潮天美传媒 | 日韩精品免费一区二区在线观看 | 国产一级视频在线 | 国产视频精品免费播放 | 玖草在线观看 | 国产精品久久久久久久久久直播 | 91在线看网站 | 波多野结衣视频一区 | 日韩精品不卡在线观看 | 国产一区在线精品 | 日韩色视频在线观看 | 日韩欧美v| 91视频这里只有精品 | 国产成人区 | 欧美精品乱码久久久久 | 国产少妇在线观看 | 亚洲综合丁香 | 999久久国产精品免费观看网站 | 九九九在线 | 国产精品av一区二区 | 亚洲国产播放 | 久久久国产99久久国产一 | 久久8精品| 国内精品视频在线播放 | aaa毛片视频| 92精品国产成人观看免费 | 久久久精品国产免费观看一区二区 | 精品免费视频 | 久久久久久高清 | 又黄又爽的视频在线观看网站 | 中文字幕在线精品 | 成人精品一区二区三区电影免费 | 国产精品白丝jk白祙 | 欧美精品黑人性xxxx | 亚洲综合导航 | 日韩一级黄色片 | 色综合天天 | 久久久精品99 | 欧美性生活小视频 | 亚洲精品国产自产拍在线观看 | 欧美激情视频一区二区三区 | 日本在线视频一区二区三区 | 国产精品v欧美精品 | 青青网视频 | 亚洲国产中文字幕 | 91天天操 | 国产一级片免费视频 | 99精品久久久久久久 | 麻豆精品在线 | 久久国内免费视频 | 天天综合中文 | 久久久久国产精品厨房 | 人人草人人做 | 国内精品在线一区 | 激情自拍av | 一级黄色片在线观看 | 欧美日韩国产区 | 香蕉免费在线 | 久久久久久久av | 91完整视频 | 久久久免费国产 | 日韩中文字幕免费电影 | 91中文视频 | 超碰在线观看av.com | 日韩中文字幕免费视频 | 在线观看视频精品 | 亚洲视频精品在线 | 三级黄色网址 | 国产91国语对白在线 | www.看片网站| 亚洲色图美腿丝袜 | 97精品国产97久久久久久粉红 | 国产丝袜| 欧美精品亚洲精品 | 国产午夜剧场 | 欧美亚洲国产精品久久高清浪潮 | 东方av免费在线观看 | 日韩高清免费电影 | av网站在线免费观看 | 国产日韩欧美在线一区 | 日韩精品一区二区三区高清免费 | 日韩在线视频看看 | 国产精品高清一区二区三区 | 国产黄在线观看 | 亚洲综合最新在线 | 久久精品4 | 久草在线精品观看 | 国产精品电影一区 | 香蕉影视app| 国产一级片一区二区三区 | 日韩特级黄色片 | 久久久久久国产精品久久 | 天天天在线综合网 | 国产视频精品在线 | 最新日韩视频在线观看 | 天天干夜夜夜操天 | 久久久高清一区二区三区 | 久草网视频在线观看 | 激情影音 | 麻豆国产在线播放 | 亚洲三区在线 | 色综合天天视频在线观看 | 亚洲草视频 | 视频国产在线 | 日韩视频在线观看免费 | 一区二区三区四区五区在线视频 | 成年人黄色大片在线 | 伊人手机在线 | 91视频在线观看大全 | 国产高清免费在线观看 | 亚洲精品在线观看免费 | 国产日韩av在线 | 国产视频99 | 韩国av一区二区三区在线观看 | 久久r精品| 六月丁香综合 | 欧洲成人av | 日韩av中文字幕在线免费观看 | 久久99精品久久久久久久久久久久 | 制服丝袜成人在线 | 精品欧美小视频在线观看 | 国产精品黄色av | 91亚洲狠狠婷婷综合久久久 | 激情欧美xxxx | 青草视频在线免费 | 99亚洲国产精品 | 亚洲国产精品成人女人久久 | 91精品国产99久久久久 | 欧美综合在线视频 | 2019中文字幕第一页 | 国产精品久久久久久高潮 | 欧美巨乳波霸 | 久久不卡免费视频 | 狠狠黄| 亚洲天天综合网 | 久久精品直播 | 日日爱网址 | 久久婷婷色 | 欧美日韩免费一区二区 | 在线观看国产日韩 | 国产一级黄色片免费看 | 亚洲人视频在线 | 337p日本大胆噜噜噜噜 | 怡红院av久久久久久久 | 九九国产精品视频 | 91精品国产92久久久久 | 欧美另类交在线观看 | 精品xxx| 日韩视频在线一区 | 久久综合久色欧美综合狠狠 | 日韩午夜大片 | 人人揉人人揉人人揉人人揉97 | www.少妇| 欧美精品首页 | 欧美一区二区三区四区夜夜大片 | 日韩精品欧美一区 | 欧美巨乳网| 国产18精品乱码免费看 | 国产在线色视频 | 久久综合亚洲鲁鲁五月久久 | 国产一级在线视频 | 激情五月综合 | 天天草天天操 | 在线观看精品黄av片免费 | 91九色在线观看视频 | 综合久久久久久久 | 亚洲成av人片在线观看无 | 一区二区三区四区五区在线 | 久久精品伊人 | 在线观看日本高清mv视频 | 午夜久久久精品 | 在线观看免费中文字幕 | 蜜臀一区二区三区精品免费视频 | 久久久五月天 | 久久久久久久久久电影 | 久久久久久久久久伊人 | 91精品国产92久久久久 | 国产91丝袜在线播放动漫 | 黄色app网站在线观看 | 色婷婷国产精品 | 久热久草 | 久久少妇| 999在线观看视频 | 亚洲高清在线观看视频 | www.久久爱.cn| 国产亚洲人成网站在线观看 | 日韩欧美高清在线 | 亚洲自拍偷拍色图 | 国产又粗又猛又黄 | 激情婷婷| 五月天综合婷婷 | 婷婷激情欧美 | 97在线视频免费 | 国产精品免费大片视频 | 国产91免费在线观看 | 天堂中文在线播放 | 日本久久久精品视频 | 2023亚洲精品国偷拍自产在线 | 超碰免费成人 | 欧美精品第一 | 高清av免费观看 | 婷婷www| 久久久久夜色 | 久久精品99国产精品酒店日本 | 韩日av在线 | www.夜色.com| 日韩久久精品 | 国产成人精品一区二区三区 | 午夜精品久久 | 天天射天天操天天色 | 在线观看av片 | 国产精品久99 | 亚洲日本在线一区 | 国产原创av在线 | 久草在线综合网 | 国产青春久久久国产毛片 | 国产中文欧美日韩在线 | 超碰人人超碰 | 在线激情网 | 三级免费黄色 | 在线99视频 | 99这里只有久久精品视频 | 五月天综合色 | 人人爽人人干 | 国产小视频国产精品 | 国产精品一区二区久久精品 | av超碰在线 | 色综合久久综合中文综合网 | 91在线精品播放 | 99中文视频在线 | 18国产精品福利片久久婷 | 婷婷色网 | 亚洲免费av电影 | 久久久伊人网 | 狠狠操狠狠干天天操 | 国产精品久久av | 国产精品第三页 | 亚洲一级片免费观看 | 久久久久久不卡 | 亚洲成a人片77777kkkk1在线观看 | 国产精品久久电影网 | 亚洲人成影院在线 | 精品亚洲欧美无人区乱码 | 国产亚洲精品无 | 久久国产精品色婷婷 | 欧美日韩高清一区二区三区 | 中文字幕欧美日韩va免费视频 | 91亚洲精品视频 | 亚洲精品乱码白浆高清久久久久久 | 亚洲精品高清视频在线观看 | 日韩电影中文,亚洲精品乱码 | 亚洲v欧美v国产v在线观看 | 蜜臀av麻豆 | 麻豆综合网| 成人在线视频免费 | 成年人免费观看国产 | 美女网站视频免费黄 | 国产麻豆果冻传媒在线观看 | 欧美日韩三级 | 日韩欧美精品在线 | a√天堂资源 | 日韩在线不卡视频 | 国产精品成人一区二区 | 日韩一区二区三区高清免费看看 | 久久一区二 | av大全在线免费观看 | 亚洲涩涩涩涩涩涩 | 亚洲 成人 一区 | 又色又爽又黄高潮的免费视频 | 国产精品va最新国产精品视频 | 国产精品国产三级国产 | 午夜影院先 | 菠萝菠萝在线精品视频 | 一区二区三区电影在线播 | 精品在线观看一区二区三区 | 久久久高清 | 97av色 | 麻豆视频国产在线观看 | 五月激情婷婷丁香 | 99精品国产99久久久久久97 | 国产精品国产自产拍高清av | 国产做爰视频 | 精品亚洲成a人在线观看 | 久久精品一区二区三区四区 | 中文不卡视频在线 | 亚洲天堂免费视频 | 91大神精品视频在线观看 | 在线播放 日韩专区 | 成人夜晚看av | 中文在线www| 91久久国产自产拍夜夜嗨 | 波多野结衣电影一区二区三区 | 国产精品久久毛片 | 黄网站色成年免费观看 | 91麻豆精品国产午夜天堂 | 日韩av在线资源 | 日韩欧美xxx| 色婷婷激情四射 | 日本中文字幕在线观看 | 激情五月色播五月 | 国产精品美女免费视频 | 黄色a在线 | 青青河边草免费视频 | 国产精品理论视频 | 国产福利在线免费 | 天天干,天天操,天天射 | 久久久www成人免费毛片麻豆 | 九九免费视频 | 久久午夜电影院 | 欧美激情精品久久久久久免费印度 | 久草观看视频 | 国产婷婷一区二区 | 成人免费在线电影 | 粉嫩一区二区三区粉嫩91 | 欧美日韩亚洲在线观看 | 一区二区三区在线免费 | 黄色毛片一级 | 97超碰人人网 | 天天干天天做 | 久久久久久久久免费视频 | 国产99久久九九精品免费 | 欧美 日韩 成人 | 久久免费视频网 | 99精品久久精品一区二区 | 久久天堂亚洲 | 国产馆在线播放 | 成人在线观看日韩 | 一区二区中文字幕在线 | 美女网站久久 | 人人爽人人澡人人添人人人人 | 国产一级黄色电影 | 国产中文| 国产精品久久久久一区 | 91免费高清观看 | 激情网站五月天 | 亚洲精品自拍视频在线观看 | 成人免费毛片aaaaaa片 | 9999免费视频 | 97精品伊人| 亚洲国产精品视频 | 91少妇精拍在线播放 | 97色在线观看免费视频 | 亚洲精品国产精品久久99热 | 天天色天天 | 我要看黄色一级片 | 亚洲 欧美日韩 国产 中文 | 四虎欧美 | 中文字幕国产视频 | 免费高清影视 | 国产精品久久久久三级 | 99热国产在线 | 欧美日韩1区| 久久国产精品二国产精品中国洋人 | 激情片av | 国产免费三级在线观看 | 欧美另类高清 videos | 亚州av免费 | 久久天天综合网 | 狠狠的操狠狠的干 | 亚洲成人精品国产 | 在线观看亚洲专区 | 99高清视频有精品视频 | 在线视频久久 | 狠狠操91| 天天干,天天操,天天射 | 四虎国产精品永久在线国在线 | 丁香视频 | 国产三级午夜理伦三级 | 人人爽人人爽人人爽学生一级 | 91精品一区二区三区蜜桃 | 国产成人精品一二三区 | 在线亚洲高清视频 | 亚洲国产日韩一区 | 九九热国产视频 | 99久久久久久 | 午夜在线免费观看 | 狠狠色丁香婷婷综合久小说久 | 91av蜜桃| 国产一级电影在线 | 在线观看片 | 五月激情丁香婷婷 | 91福利视频一区 | 中文字幕永久 | 日本黄色免费在线 | 久久久久久久久久久网站 | 久久狠狠干 | 性色av免费在线观看 | 久草视频在线免费看 | 91少妇精拍在线播放 | 99免费精品 | 青青河边草免费视频 | 99久久99久久精品国产片 | 久久99国产精品二区护士 | 国产视频亚洲视频 | 欧美aⅴ在线观看 | 伊人资源视频在线 | 国产成人精品一区二 | 激情久久婷婷 | 日韩精品视频免费专区在线播放 | 99re中文字幕 | 国产成人三级三级三级97 | 91黄色视屏 | 亚洲专区欧美 | 欧美精品在线一区 | 成人9ⅰ免费影视网站 | 99精品国产在热久久 | 91亚洲激情| 区一区二区三区中文字幕 | 久草网站在线观看 | av福利在线| 免费a v网站 | 日韩在线大片 | 国产黄色片在线 | 日韩网站在线免费观看 | 在线看欧美 | 午夜成人影视 | 天天操天天射天天舔 | 久久久99精品免费观看app | 中文字幕一区二区在线播放 | 五月花丁香婷婷 | 五月婷婷综合激情 | 国产91精品高清一区二区三区 | 亚洲精品永久免费视频 | 在线观看成人小视频 | 97超视频| 精品国产理论 | 91av成人| 亚洲日本精品视频 | 国产精品久久久久久久久久久杏吧 | 久久成人亚洲欧美电影 | 欧美精品一区二区三区一线天视频 | 韩国av免费观看 | 91精品国产乱码久久桃 | 波多野结衣久久资源 | 亚洲天堂网站 | 99在线视频观看 | 国产99久久精品一区二区永久免费 | av片在线观看免费 | 成年人免费电影在线观看 | 亚洲在线日韩 | 夜夜躁狠狠躁日日躁视频黑人 | 久久国产午夜精品理论片最新版本 | 亚洲视频久久久 | 久久国产精品99久久久久 | 日韩高清免费观看 | 久久久久国产精品厨房 | 一区二区视频网站 | 精品视频在线观看 | 色综合婷婷久久 | 美女免费电影 | 欧美肥妇free | 亚洲天堂网视频 | 久久精品国产亚洲精品2020 | 亚洲精品五月天 | 人人干网站 | 久久久久久久毛片 | 福利视频在线看 | 一区二区三区久久 | 国产精品va在线播放 | 国产黄在线 | 国产精品久久电影网 | 91久久国产精品 | 在线精品视频在线观看高清 | 激情视频亚洲 | 国产a高清 | 人人干干人人 | 二区三区在线观看 | 精品国产成人在线影院 | 日韩两性视频 | 一区二区国产精品 | 99视频在线观看免费 | 中文成人字幕 | 国产精品免费不 | 国产精品1区 | 国产高清av免费在线观看 | 丁香六月激情 | 亚洲国产精品免费 | 手机av在线网站 | 免费看的黄色录像 | 精品福利视频在线 | 国产精品一区二区久久 | 九九热久久免费视频 | 特级大胆西西4444www | 欧美日韩在线播放一区 | 一区二区视频在线看 | 亚洲午夜精品久久久久久久久久久久 | 伊人国产视频 | 国产视频资源 | 六月激情婷婷 | 精品国产99 | 成人av免费在线看 | 成人一区二区三区中文字幕 | 亚洲成人av在线 | 97在线视频网站 | 久久一区二区三区超碰国产精品 | 日韩欧美在线播放 | 日韩三级.com | 国产无套精品久久久久久 | av电影中文字幕在线观看 | 91成人在线免费观看 | 午夜精品电影一区二区在线 | 国产欧美最新羞羞视频在线观看 | 日韩在线免费 | 天天操夜夜叫 | 亚洲一区网站 | 91精品视频在线 | 91免费观看国产 | 久久久99精品免费观看 | 日韩城人在线 | 日韩在线视频在线观看 | 成人影片在线免费观看 | 91视频在线观看下载 | 日韩一区二区三区免费电影 | 成年人黄色免费视频 | 久久伊人精品天天 | 九九国产精品视频 | 婷婷国产一区二区三区 | 久久国产亚洲精品 | 在线观看aaa | 欧美精品黑人性xxxx | 免费在线一区二区三区 | avv天堂| 精品久久影院 | 国产一级大片免费看 | 日韩午夜一级片 | 婷婷丁香花五月天 | 九九久久成人 | 久久免费一级片 | 黄污视频大全 | 精品免费观看 | 日韩电影在线观看一区 | 福利视频 | 色综合久久综合网 | 视频二区在线 | 黄色综合 | 一区二区在线不卡 | 99视| 成人91在线 | 色综合久久中文综合久久牛 | 色大片免费看 | 欧美一级视频免费看 | 国产成人高清在线 | 欧美少妇18p | 亚洲清纯国产 | 中文字幕视频播放 | 狠狠狠色丁香婷婷综合激情 | 免费高清无人区完整版 | 国产99久久久精品 | 日韩在线观看视频在线 | 在线观看免费国产小视频 | 色噜噜狠狠狠狠色综合 | 91在线蜜桃臀 | 亚洲视频久久久 | 日本久久中文字幕 | 夜色资源站国产www在线视频 | 日韩精品极品视频 | 欧美日韩高清在线一区 | 99久久99视频只有精品 | 日韩免费中文字幕 | 国产色视频一区二区三区qq号 | 国产精品24小时在线观看 | 欧美日韩不卡在线 | 国产又粗又硬又爽的视频 | 亚洲欧洲精品一区二区精品久久久 | 国产精品中文字幕在线 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产精品国产三级国产aⅴ入口 | 激情久久小说 | 国产一区二区在线视频观看 | 三级大片网站 | av超碰免费在线 | 四虎5151久久欧美毛片 | 国产精品久久久久久久久久免费看 | 黄色精品一区二区 | 久久精品国产一区二区 | 人人添人人澡人人澡人人人爽 | 久久久天天操 | 99精品视频中文字幕 | 日韩av视屏 | 日韩欧美大片免费观看 | 波多野结衣资源 | 国产精品理论在线观看 | 天天射天天舔天天干 | 五月婷香蕉久色在线看 | 女人18精品一区二区三区 | 国产免费黄色 | 精品久久网 | 96视频在线| 欧美另类v | 天天色天天操综合网 | 天堂在线视频免费观看 | 国产精品久久一区二区无卡 | 国产精品一区在线观看 | 99自拍视频在线观看 | 免费黄色特级片 | 黄色软件网站在线观看 | 午夜私人影院久久久久 | 五月婷婷免费 | 日韩欧美在线一区二区 | 精品视频免费看 | 波多野结衣在线观看视频 | 六月丁香婷婷久久 | 色资源网免费观看视频 | 国语精品免费视频 | 激情av在线资源 | 国产亚洲一级高清 | 丁香激情综合久久伊人久久 | 日韩av成人 | 国产日韩av在线 | 亚洲日韩中文字幕在线播放 | 欧美成人h版电影 | 美女露久久 | 九九在线免费视频 | 国内外成人免费在线视频 | 天天爽天天摸 | 爱爱av在线 | 99久久久国产精品美女 | 在线看福利av| 99热日本 | 99在线播放| 超碰在线亚洲 | 日本论理电影 | 久久怡红院 | 天天躁日日躁狠狠躁av中文 | 国内外成人免费在线视频 | 日韩精品久久久久久久电影竹菊 | 国产精品一区二区av影院萌芽 | 一区二区三区视频网站 | 免费人做人爱www的视 | 中文字幕在线播放一区二区 | 日韩电影中文字幕在线观看 | 国产精品久久久久久久久岛 | 国产不卡免费av | 国产精品女同一区二区三区久久夜 | 午夜精品一区二区国产 | 国产视频一区在线免费观看 | 国产一区在线视频 | 欧美小视频在线观看 | 97视频在线观看成人 | 欧美日韩高清在线观看 | 91亚洲综合| 国内精品在线看 | 啪啪凸凸| 成人午夜精品久久久久久久3d | 国产精品久久久久aaaa九色 | 人人玩人人弄 | a成人v在线 | 96久久精品| 国产探花在线看 | 日韩精品偷拍 | 中文字幕乱在线伦视频中文字幕乱码在线 | 国产黄色电影 | 99久久夜色精品国产亚洲96 | 18久久久久久 | 国产精品99久久久 | 国产精品av免费在线观看 | 欧美一级视频在线观看 | 女人18片毛片90分钟 | 成人av免费在线看 | 久草视频看看 | 国产69精品久久99不卡的观看体验 | 伊人天天操 | 成年人看片网站 | 久久久久久久久久久久久国产精品 | 中文字幕xxxx | 久久久www| 日韩在线观看高清 | 日韩中文字幕亚洲一区二区va在线 | 91在线视频在线观看 | 久久久综合 | 天天爽天天摸 | 成人黄色av免费在线观看 | 久久99久国产精品黄毛片入口 | 亚洲涩涩涩 | 99热在线精品观看 | 国产精品theporn | 国产不卡在线 | 国产精品嫩草影视久久久 | 日本视频网 | 欧美 日韩 成人 | 日韩精品久久久免费观看夜色 | 999成人 | 久久伊人国产精品 | 在线蜜桃视频 | 国产精品电影一区二区 | 国产视频在线观看免费 | 久久爱992xxoo| 色爱区综合激月婷婷 | 亚洲综合最新在线 | 日韩免费成人 | 久久久久久久久毛片 | 国产精品久久影院 | 日日夜夜网站 | 国产成人精品综合久久久久99 | 国产一级电影免费观看 | 在线看欧美 | 国产区网址 | 国产色久 | 91精品亚洲影视在线观看 | 色综合久久五月天 | 伊人网av | 国产精品乱码久久久久久1区2区 | 国产精品免费不卡 | .精品久久久麻豆国产精品 亚洲va欧美 | 亚洲日本在线一区 | 国产精品欧美久久久久三级 | 中文字幕在线视频一区 | 亚州人成在线播放 | 在线观看视频中文字幕 | 黄色网在线播放 | 少妇bbr搡bbb搡bbb | 天天做日日做天天爽视频免费 | 亚洲播放一区 | 久久九精品 | 九九九九九精品 | 色综久久 | 在线观看网站你懂的 | 亚洲免费视频在线观看 | 成人免费视频在线观看 | 青春草免费在线视频 | 69久久99精品久久久久婷婷 | 久久久久久激情 | 午夜av在线 | 日韩成片| 欧美日韩a视频 | 亚洲精品美女久久 | 国产精品午夜久久久久久99热 | 亚洲国产精品日韩 | 伊人天天狠天天添日日拍 | 鲁一鲁影院 | 国产日韩在线观看一区 | 天天玩天天干天天操 | 国产精品18久久久久久不卡孕妇 | 成年人免费在线观看网站 | 日日操夜 | 一区二区三区精品在线视频 | 97激情影院 | 成人a视频片观看免费 | 日本黄色片一区二区 | 激情电影影院 | 日韩av电影国产 | 日韩精品中文字幕在线 | 美女福利视频在线 | 黄色成人av在线 | 国产美女精品久久久 | 中文字幕亚洲欧美日韩 | av一级在线 | 久久久天天操 | 欧美精彩视频在线观看 | 五月婷丁香 | 色播亚洲婷婷 | 视频国产在线观看18 | 碰超人人 | 国产伦精品一区二区三区高清 | 午夜12点 | 久久精品中文字幕一区二区三区 | 国产韩国精品一区二区三区 | 一级片视频免费观看 | 色欧美88888久久久久久影院 | 欧美精品二区 | 国产三级午夜理伦三级 | a级免费观看 | 成人在线视| 在线黄色av | 日日干干夜夜 | 午夜精品久久久久久99热明星 | 久草视频国产 | 欧美在线1 | 性色大片在线观看 | 中文字幕 国产视频 | av在线电影网站 | 在线黄色av电影 | 99自拍视频在线观看 | 日韩色av色资源 | 成人一级片免费看 | 成人av电影免费在线观看 | 亚洲激情综合 | 国产二区视频在线 | jizzjizzjizz亚洲 | 国产黄色精品视频 | 麻豆传媒一区二区 | 国产区精品视频 | 激情www| 欧美日韩高清一区 | 免费欧美高清视频 | 国产免费一区二区三区最新 | 九九99 | 天天爽天天爽 | 国产97视频在线 | 夜夜看av | 最新中文字幕视频 | 日韩一区二区三区高清在线观看 | 免费精品在线 | 日韩成人欧美 | 色爱成人网 | 欧美日本国产在线观看 | 三级黄色a | 国产夫妻自拍av | 国产精品久久久久久久久久久久久 | 97视频免费在线观看 | 欧美成人在线免费观看 | 精品亚洲欧美一区 | 超碰97中文| 青青啪| 九九热免费视频在线观看 | av免费电影在线 | 天天爱综合 | 日韩一区二区免费视频 | 天天干天天玩天天操 | 久久久久久久免费 | 成人精品亚洲 | 久久久免费观看 | 狠狠色伊人亚洲综合网站色 | 久久久久国产精品免费免费搜索 | 久久久久久久久久伊人 | 在线观看91精品视频 | 欧美日韩精品免费观看视频 | 最新国产精品拍自在线播放 | 99精品在线免费在线观看 | 一区二区视频在线播放 | 日韩 精品 一区 国产 麻豆 | 欧美人牲 | 中文字幕在线字幕中文 | 精品91久久久久 | 中文字幕观看av | 亚洲视频免费 | 91九色精品女同系列 | 伊色综合久久之综合久久 | 超碰97免费观看 | 国产精品久久久久永久免费观看 | 91成人精品一区在线播放 | 日韩av片无码一区二区不卡电影 | 久久伊99综合婷婷久久伊 | 97爱爱爱| 中文在线8资源库 | 色综合天天做天天爱 | 久久精品成人热国产成 | 麻豆传媒视频在线 | 亚洲精品乱码久久久久久 | 欧美精品v国产精品v日韩精品 | 久久久久免费精品视频 | 在线观看韩日电影免费 | 97影视| 97人人看| 国产麻豆电影在线观看 | 98精品国产自产在线观看 | 天天人人综合 | 成人亚洲免费 | 久久久久久久久网站 | 911国产| 亚洲爽爽网| 久草久草视频 | 国产精品精品久久久久久 | 久久精品美女视频 | 亚洲精品在线资源 | 中文字幕有码在线播放 | 国产精品1区2区 | 国产一级片不卡 | 精品国产伦一区二区三区观看说明 | 国产精品精品久久久 | 欧美亚洲一级片 | 高清视频一区 | 欧美日韩网址 | 免费看的黄色小视频 | 欧美孕妇与黑人孕交 | 国产美女精品视频 | 国产v在线| 亚洲国产手机在线 | 韩国精品视频在线观看 | 五月天激情综合 | 免费a现在观看 | 日韩精品一二三 | 91精品国产高清自在线观看 | 国产一级二级av | 国产精品精品久久久久久 | 国产精品久久久久久久毛片 | 久久久久色 | av网站手机在线观看 | 又黄又爽的免费高潮视频 |