色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

RTOS內(nèi)功修煉記(一)— 任務(wù)到底應(yīng)該怎么寫?

冬至子 ? 來(lái)源:Mculover666 ? 作者:Mculover666 ? 2023-12-01 16:36 ? 次閱讀

本篇文章講述了任務(wù)的三大元素:任務(wù)控制塊、任務(wù)棧、任務(wù)入口函數(shù),并講述了編寫RTOS任務(wù)入口函數(shù)時(shí)三個(gè)重要的注意點(diǎn)。

1. 知識(shí)點(diǎn)回顧

在正式開(kāi)始講解內(nèi)容之前,我會(huì)先回顧一下基礎(chǔ)知識(shí)點(diǎn),請(qǐng)確保你已經(jīng)了解并掌握。

1.1. 任務(wù)的創(chuàng)建方法

在用戶層調(diào)用API創(chuàng)建一個(gè)任務(wù),通常的流程如下:

① 創(chuàng)建一個(gè)數(shù)組作為任務(wù)棧:

#define TASK1_STACK_SIZE    512  
k_stack_t task1_stack[TASK1_STACK_SIZE];

② 創(chuàng)建一個(gè)任務(wù)控制塊:

k_task_t    task1;

③ 編寫任務(wù)入口函數(shù):

void task1_entry(void *arg)  
{  
    while(1)  
    {  
        printf("task1 is runningrn");  
        tos_task_delay(1000);  
    }  
}

④ 調(diào)用系統(tǒng)API創(chuàng)建任務(wù):

ret = tos_task_create(&task1,  
                      "task1",  
                      task1_entry,  
                      NULL,  
                      TASK1_PRO,  
                      task1_stack,  
                      TASK1_STACK_SIZE,  
                      10);

創(chuàng)建之后任務(wù)為就緒態(tài)(處于系統(tǒng)就緒隊(duì)列中),等待系統(tǒng)調(diào)度器調(diào)度執(zhí)行。

1.2. STM32內(nèi)存分布

閱讀之后,你應(yīng)該要知道,STM32(Cortex-M3)中Flash和SRAM的內(nèi)存空間如下:

image.png

其中Flash存儲(chǔ)空間中又分為文本段、只讀數(shù)據(jù)段、復(fù)制數(shù)據(jù)段:

image.png

其中SRAM存儲(chǔ)空間中又分為data數(shù)據(jù)段、bss數(shù)據(jù)段、堆空間、??臻g:

image.png

并且還要知道不同的變量類型,它對(duì)應(yīng)的存儲(chǔ)位置在哪里,如果沒(méi)有,一定要閱讀上文之后再回來(lái)看,這是理解之后內(nèi)容的基礎(chǔ)。

1.3. Cortex-M3/4系列內(nèi)核

CrortexM3/4系列內(nèi)核中的寄存器組都有16個(gè)寄存器,如圖所示,寄存器組通常都是CPU用于數(shù)據(jù)處理和運(yùn)行控制的,希望你可以大概知道每個(gè)寄存器的作用:

image.png

① R0-R12:通用寄存器,用于數(shù)據(jù)操作;

② R13:棧頂指針,有兩個(gè)互斥的指針MSP和PSP,在任一時(shí)刻只能使用其中一個(gè);

③ R14:連接寄存器,調(diào)用子程序時(shí)存放返回地址;

④ R15:程序計(jì)數(shù)器,PC指針指向哪里,CPU就執(zhí)行哪里的代碼;

在RTOS內(nèi)核中,這16個(gè)寄存器組的值稱之為 「上下文環(huán)境」 ,即當(dāng)前任務(wù)運(yùn)行時(shí)這16個(gè)寄存器中的值稱為上文環(huán)境,下一個(gè)任務(wù)運(yùn)行時(shí)這16個(gè)寄存器的值稱為下文環(huán)境, 「上下文切換」 就是指將這16寄存器組的值修改為下一個(gè)任務(wù)的值。

1.4. 棧

棧是一種 「只能在一端插入或者刪除元素」 的數(shù)據(jù)結(jié)構(gòu),規(guī)則為: 「先入后出」 (FILO)。

image.png

C語(yǔ)言程序運(yùn)行的時(shí)候,棧是非常非常非常重要的,在裸機(jī)程序中,棧頂指針由寄存器R13給出。

棧的作用,一方面是局部變量的存儲(chǔ),局部變量的定義會(huì)被匯編為PUSH 指令,將局部變量中的內(nèi)容壓入棧中,在函數(shù)執(zhí)行完畢之后出棧,該局部變量被銷毀;另一方面是函數(shù)調(diào)用時(shí)的參數(shù)傳遞,也會(huì)被壓入棧中,在函數(shù)執(zhí)行完畢后出棧。

2. 任務(wù)控制塊長(zhǎng)啥樣

任務(wù)控制塊是一個(gè)任務(wù)的核心,廣義的講: 「內(nèi)核所有對(duì)任務(wù)的操作,其實(shí)都是在操作任務(wù)控制塊」 。

任務(wù)控制塊類型k_task_t是一個(gè)結(jié)構(gòu)體類型:

typedef struct k_task_st    k_task_t;

當(dāng)定義了一個(gè)任務(wù)控制塊時(shí),該結(jié)構(gòu)體變量沒(méi)有初始值,所以 「存儲(chǔ)位置在STM32內(nèi)部SRAM中的bss段內(nèi)」 。

任務(wù)控制塊的結(jié)構(gòu)體類型定義如下:

/**  
 * task control block  
 */  
struct k_task_st {  
    k_stack_t          *sp;                     /**< task stack pointer. This lady always comes first, we count on her in port_s.S for context switch. */  
  
    knl_obj_t           knl_obj;                /**< just for verification, test whether current object is really a task. */  
  
    char                name[K_TASK_NAME_MAX];  /**< task name */  
    k_task_entry_t      entry;                  /**< task entry */  
    void               *arg;                    /**< argument for task entry */  
    k_task_state_t      state;                  /**< just state */  
    k_prio_t            prio;                   /**< just priority */  
  
    k_stack_t          *stk_base;               /**< task stack base address */  
    size_t              stk_size;               /**< stack size of the task */  
  
  
  
    k_list_t            stat_list;              /**< list for hooking us to the k_stat_list */  
  
    k_tick_t            tick_expires;           /**< if we are in k_tick_list, how much time will we wait for? */  
  
    k_list_t            tick_list;              /**< list for hooking us to the k_tick_list */  
    k_list_t            pend_list;              /**< when we are ready, our pend_list is in readyqueue; when pend, in a certain pend object's list. */  
      
  
    pend_obj_t         *pending_obj;            /**< if we are pending, which pend object's list we are in? */  
    pend_state_t        pend_state;             /**< why we wakeup from a pend */  
};

此處引用的源碼 「不完整」 ,方便閱讀起見(jiàn),所有使用宏開(kāi)關(guān)配置的定義全部省略。

任務(wù)控制塊中的內(nèi)容主要分為三部分:

① 任務(wù)棧棧頂指針sp:接下來(lái)會(huì)重點(diǎn)講解;

② 任務(wù)的全部信息:任務(wù)名稱、任務(wù)狀態(tài)、任務(wù)優(yōu)先級(jí)、任務(wù)入口函數(shù)及參數(shù)、任務(wù)棧地址和大??;

③ 任務(wù)的鏈表:后續(xù)文章中重點(diǎn)講解。

3. 任務(wù)棧

3.1. 任務(wù)棧是什么

任務(wù)棧類型 k_stack_t 是一個(gè) uint8_t 類型:

typedef uint8_t             k_stack_t;

當(dāng)定義了一個(gè)任務(wù)棧數(shù)組時(shí):

#define TASK1_STACK_SIZE    512  
k_stack_t task1_stack[TASK1_STACK_SIZE];

本質(zhì)上還是一個(gè)uint8_t類型的全局變量數(shù)組,該全局變量數(shù)組沒(méi)有初始值,所以 「存儲(chǔ)位置仍在STM32內(nèi)部SRAM中的bss段內(nèi)」 。

在使用該數(shù)組的時(shí)候,只通過(guò)指針sp訪問(wèn),假裝它是一個(gè)棧,在使用上和棧的使用方式一模一樣,所以稱之為任務(wù)棧。

3.2. 任務(wù)棧中有什么(作用)

在創(chuàng)建任務(wù)的API中,有這樣一句代碼來(lái)初始化任務(wù)棧,并且返回任務(wù)棧的棧頂指針sp:

task- >sp = cpu_task_stk_init((void *)entry, arg, (void *)task_exit, stk_base, stk_size);

查看cpu_task_stk_init函數(shù)的定義,會(huì)發(fā)現(xiàn) 「不同的CPU結(jié)構(gòu),該函數(shù)的實(shí)現(xiàn)不同」 。

image.png

為什么不同的CPU結(jié)構(gòu),會(huì)導(dǎo)致任務(wù)棧的初始化代碼實(shí)現(xiàn)不同呢?

不急,讓我們先來(lái)看看如何來(lái)初始化任務(wù)棧, 「Cortex-M系列芯片的內(nèi)核對(duì)應(yīng)的都是ARM v7m架構(gòu)」 ,選取此架構(gòu)中的 cpu_task_stk_init 函數(shù)實(shí)現(xiàn)來(lái)探索問(wèn)題的答案。

① 獲取任務(wù)棧棧頂指針的地址并對(duì)齊:

cpu_data_t *sp;  
  
sp = (cpu_data_t *)&stk_base[stk_size];  
sp = (cpu_data_t *)((cpu_addr_t)sp & 0xFFFFFFF8);

② PendSV異常發(fā)生時(shí)自動(dòng)保存的寄存器:

/* auto-saved on exception(pendSV) by hardware */  
*--sp = (cpu_data_t)0x01000000u;    /* xPSR     */  
*--sp = (cpu_data_t)entry;          /* entry    */  
*--sp = (cpu_data_t)exit;           /* R14 (LR) */  
*--sp = (cpu_data_t)0x12121212u;    /* R12      */  
*--sp = (cpu_data_t)0x03030303u;    /* R3       */  
*--sp = (cpu_data_t)0x02020202u;    /* R2       */  
*--sp = (cpu_data_t)0x01010101u;    /* R1       */  
*--sp = (cpu_data_t)arg;            /* R0: arg  */

③ 手動(dòng)保存/加載的寄存器:

*--sp = (cpu_data_t)0x11111111u;    /* R11      */  
*--sp = (cpu_data_t)0x10101010u;    /* R10      */  
*--sp = (cpu_data_t)0x09090909u;    /* R9       */  
*--sp = (cpu_data_t)0x08080808u;    /* R8       */  
*--sp = (cpu_data_t)0x07070707u;    /* R7       */  
*--sp = (cpu_data_t)0x06060606u;    /* R6       */  
*--sp = (cpu_data_t)0x05050505u;    /* R5       */  
*--sp = (cpu_data_t)0x04040404u;    /* R4       */

④ 返回當(dāng)前棧頂指針:

return (k_stack_t *)sp;

初始化后任務(wù)棧中的內(nèi)容如下:

image.png

任務(wù)切換的大致流程是觸發(fā)PendSV異常,在異常處理函數(shù)中使用匯編語(yǔ)言實(shí)現(xiàn)任務(wù)切換,也就是 「上下文切換」 ,在接下來(lái)的文章中會(huì)專門講述任務(wù)切換。

當(dāng)該任務(wù)被調(diào)度執(zhí)行時(shí),CPU會(huì)自動(dòng)將任務(wù)棧中最前面的8個(gè)寄存器值加載到CPU寄存器中,完成 「下文環(huán)境切換」 ,此時(shí):

  • 棧頂指針寄存器R13中的值是該任務(wù)的任務(wù)棧的sp指針;
  • 程序計(jì)數(shù)器指針PC指向的是該任務(wù)的入口函數(shù)entry;

接下來(lái)CPU中的環(huán)境就是該任務(wù)的環(huán)境,該任務(wù)開(kāi)始運(yùn)行。

因?yàn)闂m斨羔樦赶虻氖窃撊蝿?wù)的任務(wù)棧,所以此時(shí)若在任務(wù)的入口函數(shù)中傳遞參數(shù),調(diào)用函數(shù),創(chuàng)建局部變量, 「所有數(shù)據(jù)都被壓入到該任務(wù)的任務(wù)棧中」 ,與STM32內(nèi)部的棧空間毫無(wú)關(guān)系。

同理,當(dāng)任務(wù)執(zhí)行完畢時(shí)(不一定是程序結(jié)束,而是調(diào)度器需要去調(diào)度執(zhí)行別的任務(wù)了),因?yàn)闂>哂?「后入先出」 的規(guī)則,CPU再將當(dāng)前寄存器組的值壓入到棧中,完成 「上文環(huán)境保存」 ,下次再需要被加載時(shí),這些寄存器組的值將首先出棧。

最后揭曉問(wèn)題答案,因?yàn)?「不同的CPU架構(gòu),CPU寄存器組的數(shù)量、功能都不同」 ,所以需要針對(duì)每種CPU架構(gòu)都要有一個(gè)實(shí)現(xiàn)。

4. 任務(wù)到底應(yīng)該怎么寫

在學(xué)習(xí)RTOS的時(shí)候,我們的關(guān)注點(diǎn)都是“如何創(chuàng)建任務(wù)”,將重點(diǎn)放在了創(chuàng)建任務(wù)的API上,而忽略了一些最重要的問(wèn)題。

重點(diǎn)①: 「任務(wù)入口函數(shù),并不是一個(gè)普通的函數(shù)」

任務(wù)入口函數(shù),通常它都偽裝成了一個(gè)普通函數(shù),不像main函數(shù)那樣鶴立雞群,所以很多時(shí)候我們覺(jué)得它就是一個(gè)普通函數(shù)調(diào)用,實(shí)則不然。

「每一個(gè)任務(wù)的entry,首先應(yīng)該是一個(gè)獨(dú)立的裸機(jī)程序。」

為什么這么說(shuō)?因?yàn)槎嗳蝿?wù)操作系統(tǒng)的機(jī)制是搶占式調(diào)度和時(shí)間片輪轉(zhuǎn),無(wú)論再怎么牛逼,也無(wú)法改變CPU中只有一個(gè)CPU的事實(shí),所以無(wú)論在任何一個(gè)時(shí)刻,系統(tǒng)中都只有唯一一個(gè)任務(wù)在運(yùn)行。

重點(diǎn)②: 「每寫一行代碼,都要思考任務(wù)棧是否足夠」

在任務(wù)入口函數(shù)中創(chuàng)建的局部變量,函數(shù)調(diào)用,函數(shù)傳參,都使用的是該任務(wù)的任務(wù)棧,和STM32內(nèi)部棧空間沒(méi)有任何關(guān)系,所以在編寫的時(shí)候一定要時(shí)刻思考自己指定的任務(wù)棧大小是否足夠,特別是在開(kāi)辟局部變量數(shù)組的時(shí)候,調(diào)用一些庫(kù)的API的時(shí)候。

而在任務(wù)入口函數(shù)中,如果定義的是static變量,則不會(huì)存放到任務(wù)棧中,存放位置在STM32內(nèi)部SRAM中的bss區(qū)域內(nèi)。

除此之外,其余代碼都屬于可執(zhí)行代碼,存放在Flash中Text區(qū)域中的Executable Code段,大可不必太在意。

重點(diǎn)③: 「盡量盡量要主動(dòng)釋放CPU,切忌浪費(fèi)CPU」 。

在裸機(jī)程序中,如果你動(dòng)不動(dòng)喜歡寫個(gè)死循環(huán)延時(shí),尚可原諒,但是在RTOS系統(tǒng)中,如果一個(gè)任務(wù)在死循環(huán)做無(wú)用功,而導(dǎo)致其它任務(wù)得不到調(diào)度執(zhí)行,將是不可饒恕的。

在編寫任務(wù)入口函數(shù)的時(shí)候,一定要遵循“不使用,就讓出”的原則,做一個(gè)高素質(zhì)的任務(wù),最普遍的做法是使用系統(tǒng)提供的delay函數(shù)來(lái)延時(shí)。

這樣做有非常多的優(yōu)點(diǎn),一方面是防止系統(tǒng)發(fā)生堵塞,導(dǎo)致其它任務(wù)得不到運(yùn)行;另一方面是使系統(tǒng)中的空閑任務(wù)可以在空閑的時(shí)候回收系統(tǒng)內(nèi)存資源,進(jìn)入低功耗模式等騷操作。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5357

    瀏覽量

    120720
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10910

    瀏覽量

    356651
  • RTOS
    +關(guān)注

    關(guān)注

    22

    文章

    817

    瀏覽量

    119735
  • Cortex-M3
    +關(guān)注

    關(guān)注

    9

    文章

    270

    瀏覽量

    59513
  • SRAM控制器
    +關(guān)注

    關(guān)注

    0

    文章

    11

    瀏覽量

    5908
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    CTO到底應(yīng)不應(yīng)該代碼?聽(tīng)聽(tīng)硅谷大神們?cè)趺凑f(shuō)

    醫(yī)療社區(qū)丁香園的 CTO 馮大輝離職了,炸出了科技行業(yè)里的個(gè)大問(wèn)題:CTO到底應(yīng)不應(yīng)該代碼?
    發(fā)表于 08-29 10:07 ?1571次閱讀

    電子工程師應(yīng)該修煉的九大內(nèi)功

    ,平均年齡在29歲,美國(guó)電子工程師的年齡平均在40歲左右。在這個(gè)朝氣蓬勃的年齡,電子工程師如何實(shí)現(xiàn)快速個(gè)人成長(zhǎng)呢?本文作者結(jié)合網(wǎng)上的資源,整理了下就大內(nèi)功修養(yǎng)路徑,和電子工程師們分享。
    發(fā)表于 11-03 10:31 ?3399次閱讀

    RTOS信號(hào)量、隊(duì)列通信原理

    有深入理解RTOS原理,或閱讀過(guò)RTOS源碼的同學(xué)應(yīng)該知道:RTOS實(shí)現(xiàn)任務(wù)間通信通常是由系列
    發(fā)表于 08-16 10:07 ?1691次閱讀

    嵌入式軟件工程師的內(nèi)功修煉

    嵌入式軟件的內(nèi)功,21ic家也曾經(jīng)多次強(qiáng)調(diào)。相信大家都看過(guò)武俠小說(shuō)或電視,金老前輩的甚是出名,里面有“天下武功出少林”說(shuō),為什么呢?就是因?yàn)樯倭钟?b class='flag-5'>一本《易筋經(jīng)》,“掃地僧”也就是當(dāng)時(shí)江湖的大神,學(xué)了
    發(fā)表于 11-03 15:33

    RTOS中的多任務(wù)切換的相關(guān)資料分享

    淺談RTOS中的多任務(wù)切換(基于UC/OS iii)文章目錄淺談RTOS中的多任務(wù)切換(基于UC/OS iii). 簡(jiǎn)介二.主要變量1.全
    發(fā)表于 12-06 07:08

    RTOS任務(wù)性能分析實(shí)現(xiàn)經(jīng)驗(yàn)分享

    1、如何利用公式評(píng)估RTOS個(gè)任務(wù)的系統(tǒng)資源占用呢在實(shí)踐中,我們應(yīng)該如何利用上述公式評(píng)估 RTOS
    發(fā)表于 04-15 18:16

    到底該不該用RTOS?看完你就有答案了

    到底該不該用RTOS,看完你就有答案了
    的頭像 發(fā)表于 02-25 16:17 ?3394次閱讀

    LEDs狀態(tài)燈任務(wù)(線程)設(shè)計(jì) (基于RTOS

    LEDs狀態(tài)燈任務(wù)(線程)設(shè)計(jì)(基于RTOS
    的頭像 發(fā)表于 03-12 11:30 ?2376次閱讀

    如何讓RTOS任務(wù)訪問(wèn)同個(gè)UART?

    RTOS任務(wù)編程的時(shí)候,同個(gè)硬件(比如UART、I2C等)被多個(gè)任務(wù)訪問(wèn)的情況比較多,如果不合理處理,就會(huì)導(dǎo)致“混亂”的局面。 處理“混亂”局面的方法比較多,下面基于FreeRT
    的頭像 發(fā)表于 03-12 17:18 ?2105次閱讀

    淺析OS中的線程、進(jìn)程和協(xié)程與RTOS任務(wù)屬于那種

    今天為大家講解講解OS中的線程、進(jìn)程和協(xié)程的這幾個(gè)概念,同時(shí)起看看RTOS中的任務(wù)到底屬于哪種。
    的頭像 發(fā)表于 04-19 10:06 ?3235次閱讀
    淺析OS中的線程、進(jìn)程和協(xié)程與<b class='flag-5'>RTOS</b><b class='flag-5'>任務(wù)</b>屬于那種

    RTOS任務(wù)的堆棧大小與代碼量有啥關(guān)系嗎?

    最近有小伙伴問(wèn)了這樣個(gè)問(wèn)題:我有個(gè)任務(wù)中的代碼量很多,是不是這個(gè)任務(wù)的堆棧需要分配很大才行? 下面就圍繞任務(wù)代碼量,以及堆棧進(jìn)行描述相關(guān)內(nèi)容。 1
    的頭像 發(fā)表于 05-26 09:34 ?2164次閱讀

    分析RTOS實(shí)現(xiàn)多任務(wù)調(diào)度的基本原理

    概念,相信大部分初學(xué)者都是懵的。 不太懂這些概念很正常,下子懂了,我倒反而覺(jué)得不正常。 1什么是多任務(wù) 這里大部分人應(yīng)該都是從裸機(jī)階段過(guò)來(lái)的,裸機(jī)系統(tǒng)般也稱之為單
    的頭像 發(fā)表于 07-27 15:59 ?5449次閱讀
    分析<b class='flag-5'>RTOS</b>實(shí)現(xiàn)多<b class='flag-5'>任務(wù)</b>調(diào)度的基本原理

    電池制造內(nèi)功修煉法打開(kāi)產(chǎn)線智識(shí)之窗

    制造能力是制造業(yè)永恒修煉的“內(nèi)功”。電池制造的要求正從ppm向ppb演進(jìn),對(duì)良率的追求近乎極限,數(shù)字化技術(shù)成為伸向極限的觸手,新技術(shù)的應(yīng)用正助力電池制造成本、效率、體系邁向新階段,推動(dòng)極限制造變革。
    的頭像 發(fā)表于 04-03 11:05 ?850次閱讀

    RTOS中的任務(wù)是線程?進(jìn)程?還是協(xié)程?

    今天為大家講解講解OS中的線程、進(jìn)程和協(xié)程的這幾個(gè)概念,同時(shí)起看看RTOS中的任務(wù)到底屬于哪種。
    的頭像 發(fā)表于 06-04 17:19 ?1733次閱讀
    <b class='flag-5'>RTOS</b>中的<b class='flag-5'>任務(wù)</b>是線程?進(jìn)程?還是協(xié)程?

    使用任務(wù)通知提高RTOS應(yīng)用的效率

    在實(shí)時(shí)嵌入式系統(tǒng)中,性能和資源效率是決定設(shè)計(jì)成敗的關(guān)鍵因素。傳統(tǒng)的實(shí)時(shí)操作系統(tǒng)(RTOS)提供了如隊(duì)列、信號(hào)量和事件組機(jī)制,實(shí)現(xiàn)任務(wù)之間的同步和通信。FreeRTOS/SAFERTOS還提供種方法可以使這些過(guò)程更快、更輕量化,
    的頭像 發(fā)表于 12-27 14:54 ?249次閱讀
    主站蜘蛛池模板: 色狠狠婷婷97| 国产短视频精品区| 成 人 动漫3d 在线看| 国产精品久久高潮呻吟无码| 狠狠啪 日日啪| 免费精品国偷自产在线在线| 视频一区视频二区在线观看| 亚洲欧美一级久久精品| 99re28久久热在线观看| 国产精品无码久久久久不卡| 久久在精品线影院| 日韩AV片无码一区二区三区不卡 | 国内精品久久人妻无码HD浪潮| 老阿姨才是最有V味的直播| 色播播电影| 中国少妇内射XXXHD免费| 俄罗斯aaaaa一级毛片| 久久电影午夜| 日韩亚洲人成在线| 伊人草久久| 国产成年网站v片在线观看| 久久影院一区| 武侠古典久久亚洲精品| 99国产精品综合AV无码| 国产在线播放91| 且试天下芒果免费观看| 亚洲 色 欧美 爱 视频 日韩| 99精品AV无码一区二区| 国语自产一区第二页| 人妻夜夜爽99麻豆AV| 伊人热人久久中文字幕| 国产精品99久久久久久AV蜜臀| 免费可以看黄的视频s色| 亚州视频一区| 凹凸精品视频分类视频| 久久久无码精品亚洲欧美| 我的奶头被客人吸的又肿又红| 99久久热视频只有精品| 九色终合九色综合88| 午夜伦yy44880影院| 成年黄网站免费大全毛片|