嵌入式軟件開發的設計思想非常重要,狀態機結合事件驅動

一起學嵌入式 2025-07-12 10:19

掃描關注一起學嵌入式,一起學習,一起成長

狀態機是一種思想,事件驅動也是一種思想。


事件驅動的概念

生活中有很多事件驅動的例子,上自習瞞著老師偷睡覺就是很生動的一個。

我們都是從高中時代走過來的,高中的學生苦啊,覺得睡覺是世界上最奢侈的東西, 有時候站著都能睡著啊!老師看的嚴,上課睡覺不允許 啊,要挨批啊!有木有!相比而言,晚自習是比較寬松的,老師只是不定時來巡視,還是有機會偷偷睡一會兒的。

現在的問題是,怎么睡才能既睡得好又不會讓老師發現呢? 晚自習是比較寬松的,老師只是不定時來巡視,還是有機會偷偷睡一會兒的。現在的問題是,怎么睡才能既睡得好又不會讓老師發現呢?

我們現在有三種睡覺方案:

  • 方案 A:倒頭就睡,管你三七二十一,睡夠了再說,要知道有時候老師可能一整晚上都不來的。
  • 方案 B:間歇著睡,先定上鬧鐘, 5 分鐘響一次,響了就醒,看看老師來沒來,沒來的話定上鬧鐘再睡,如此往復。
  • 方案 C:睡之前讓同桌給放哨,然后自己睡覺,什么也不用管,什么時候老師來了,就讓同桌戳醒你。

不管你們選擇的是哪種方案,我高中那會兒用的可是方案 C,安全又舒服。

方案 C 是很有特點的:本來自習課偷睡覺是你自己的事兒, 有沒有被老師抓著也是你自己的事兒,這些和同桌是毫無利害關系的,但是同桌這個環節對方案 C 的重要性是不言而喻的,他肩負著監控老師巡視和叫醒睡覺者兩項重要任務,是事件驅動機制實現的重要組成部分 。

在事件驅動機制中,對象對于外部事件總是處于“休眠” 狀態的,而把對外部事件的檢測和監控交給了第三方組件。

一旦第三方檢測到外部事件發生, 它就會啟動某種機制, 將對象從“休眠” 狀態中喚醒, 并將事件告知對象。對象接到通知后, 做出一系列動作, 完成對本次事件響應,然后再次進入“休眠” 狀態,如此周而復始。

有沒有發現,事件驅動機制和單片機的中斷原理上很相似 。
一款輕量級事件驅動型應用程序框架

事件驅動與單片機編程

在我們再回到單片機系統中來,看看事件驅動思想在單片機程序設計中的應用。當我還是一個單片機菜鳥的時候(當然,我至今也沒有成為單片機高手),網絡上的大蝦們就諄諄教導:一個好的單片機程序是要分層的。

曾經很長一段時間, 我對分層這個概念完全沒有感覺。

  • 什么是程序分層?

  • 程序為什么要分層?

  • 應該怎么給程序分層?

隨著手里的代碼量越來越多,實現的功能也越來越多,軟件分層這個概念在我腦子里逐漸地清晰起來,我越來越佩服大蝦們的高瞻遠矚。

單片機的軟件確實要分層的,最起碼要分兩層:驅動層和應用層。應用是單片機系統的核心,與應用相關的代碼擔負著系統關鍵的邏輯和運算功能,是單片機程序的靈魂。

硬件是程序感知外界并與外界打交道的物質基礎,硬件的種類是多種多樣的,各類硬件的操作方式也各不相同,這些操作要求嚴格、精確、瑣細、繁雜。

與硬件打交道的代碼只鐘情于時序和寄存器,我們可以稱之為驅動相關代碼;與應用相關的代碼卻只專注于邏輯和運算, 我們可稱之為應用相關代碼。

這種客觀存在的情況是單片機軟件分層最直接的依據,所以說,將軟件劃分為驅動層和應用層是程序功能分工的結果。那么驅動層和應用層之間是如何銜接的呢?

在單片機系統中,信息的流動是雙向的,由內向外是應用層代碼主動發起的,實現信息向外流動很簡單, 應用層代碼只需要調用驅動層代碼提供的 API 接口函數即可, 而由外向內則是外界主動發起的, 這時候應用層代碼對于外界輸入需要被動的接收, 這里就涉及到一個接收機制的問題,事件驅動機制足可勝任這個接收機制。

外界輸入可以理解為發生了事件,在單片機內部直接的表現就是硬件生成了新的數據,這些數據包含了事件的全部信息, 事件驅動機制的任務就是將這些數據初步處理(也可能不處理),然后告知應用層代碼, 應用代碼接到通知后把這些數據取走, 做最終的處理, 這樣一次事件的響應就完成了。

說到這里,可能很多人突然會發現,這種處理方法自己編程的時候早就用過了,只不過沒有使用“事件驅動” 這個文縐縐的名詞罷了。其實事件驅動機制本來就不神秘, 生活中數不勝數的例子足以說明它應用的普遍性。下面的這個小例子是事件驅動機制在單片機程序中最常見的實現方法,假設某單片機系統用到了以下資源:

  • 一個串口外設 Uart0,用來接收串口數據;
  • 一個定時器外設 Tmr0,用來提供周期性定時中斷;
  • 一個外部中斷管腳 Exi0,用來檢測某種外部突發事件;
  • 一個 I/O 端口 Port0,連接獨立式鍵盤,管理方式為定時掃描法,掛載到 Tmr0 的 ISR;

這樣,系統中可以提取出 4 類事件,分別是 UART、 TMR、 EXI、 KEY ,其中 UART 和KEY 事件發生后必須開辟緩存存儲事件相關的數據。所有事件的檢測都在各自的 ISR 中完成,然后 ISR 再通過事件驅動機制通知主函數處理。

為了實現 ISR 和主函數通信, 我們定義一個數據類型為INT8U的全局變量 g_u8EvntFlgGrp,稱為事件標志組,里面的每一個 bit 位代表一類事件,如果該 bit 值為 0,表示此類事件沒有發生,如果該 bit 值為 1,則表示發生了此類事件,主函數必須及時地處理該事件。圖 5 所示為g_u8EvntFlgGrp 各個 bit 位的作用 。

程序清單 List9 所示就是按上面的規劃寫成的示例性代碼 。

程序清單List9:

#define FLG_UART 0x01
#define FLG_TMR 0x02
#define FLG_EXI 0x04
#define FLG_KEY 0x08
volatile INT8U g_u8EvntFlgGrp = 0/*事件標志組*/
INT8U read_envt_flg_grp(void);
/***************************************
*FuncName : main
*Description : 主函數
*Arguments : void
*Return : void
*****************************************/

void main(void)
{
 INT8U u8FlgTmp = 0;
 sys_init();
while(1)
 {
  u8FlgTmp = read_envt_flg_grp(); /*讀取事件標志組*/
if(u8FlgTmp ) /*是否有事件發生? */
  {
   if(u8FlgTmp & FLG_UART)
   {
    action_uart(); /*處理串口事件*/
   }
   if(u8FlgTmp & FLG_TMR)
   {
    action_tmr(); /*處理定時中斷事件*/
   }
   if(u8FlgTmp & FLG_EXI)
   {
    action_exi(); /*處理外部中斷事件*/
   }
   if(u8FlgTmp & FLG_KEY)
   {
    action_key(); /*處理擊鍵事件*/
   }
  }
else
  {
   ;/*idle code*/
  }
 }
}
/*********************************************
*FuncName : read_envt_flg_grp
*Description : 讀取事件標志組 g_u8EvntFlgGrp ,
* 讀取完畢后將其清零。
*Arguments : void
*Return : void
*********************************************/

INT8U read_envt_flg_grp(void)
{
 INT8U u8FlgTmp = 0;
 gbl_int_disable();
 u8FlgTmp = g_u8EvntFlgGrp; /*讀取標志組*/
 g_u8EvntFlgGrp = 0/*清零標志組*/
 gbl_int_enable();
return u8FlgTmp;
}
/*********************************************
*FuncName : uart0_isr
*Description : uart0 中斷服務函數
*Arguments : void
*Return : void
*********************************************/

void uart0_isr(void)
{
 ......
 push_uart_rcv_buf(new_rcvd_byte); /*新接收的字節存入緩沖區*/
 gbl_int_disable();
 g_u8EvntFlgGrp |= FLG_UART; /*設置 UART 事件標志*/
 gbl_int_enable();
 ......
}
/*********************************************
*FuncName : tmr0_isr
*Description : timer0 中斷服務函數
*Arguments : void
*Return : void
*********************************************/

void tmr0_isr(void)
{
 INT8U u8KeyCode = 0;
 ......
 gbl_int_disable();
 g_u8EvntFlgGrp |= FLG_TMR; /*設置 TMR 事件標志*/
 gbl_int_enable();
 ......
 u8KeyCode = read_key(); /*讀鍵盤*/
if(u8KeyCode) /*有擊鍵操作? */
 {
  push_key_buf(u8KeyCode); /*新鍵值存入緩沖區*/
  gbl_int_disable();
  g_u8EvntFlgGrp |= FLG_KEY; /*設置 TMR 事件標志*/
  gbl_int_enable();
 }
 ......
}
/*********************************************
*FuncName : exit0_isr
*Description : exit0 中斷服務函數
*Arguments : void
*Return : void
*********************************************/

void exit0_isr(void)
{
 ......
 gbl_int_disable();
 g_u8EvntFlgGrp |= FLG_EXI; /*設置 EXI 事件標志*/
 gbl_int_enable();
 ......
}

看一下程序清單 List9 這樣的程序結構,是不是和自己寫過的某些程序相似?對于事件驅動機制的這種實現方式, 我們還可以做得更絕一些, 形成一個標準的代碼模板,做一個包含位段和函數指針數組的結構體,位段里的每一個元素作為圖 5 那樣的事件標志位,然后在函數指針數組中放置各個事件處理函數的函數地址, 每個處理函數對應位段里的每個標志位。

這樣, main()函數中的事件處理代碼就可以做成標準的框架代碼。應該說,這樣的實現方式是很好的,足以輕松地應對實際應用中絕大多數的情況。

但是,事件驅動機制用這樣的方式實現真的是完美的么?在我看來,這種實現方式至少存在兩個問題:

  • 不同事件集中爆發時,無法記錄事件發生的前后順序。
  • 同一事件集中爆發時,容易遺漏后面發生的那次事件。

圖 6 所示為某一時段單片機程序的執行情況,某些特殊情況下,會出現上面提到的兩個問題。

圖中, f1 為某事件的處理函數, f2 為另一事件的處理函數, I1、 I2、 I3 為 3 個不同事件觸發的 ISR,假定 I1、 I2、 I3 分別對應事件 E1、 E2、 E3。從圖中可以看出,主函數在調用事件處理函數 f1 的時候,發生了 2 次事件,主函數被 I1和 I2 中斷了 2 次, I1 和 I2 執行的時候各自置位了相應的事件標志位。

函數 f1 返回后, 主函數又調用了另一個事件處理函數 f2, f2 執行期間先后發生了 2 次同樣的事件, f2 被 I3 中斷了 2次,對應的事件標志位被連續置位了 2 次。

在圖 6 中我們當然可以看出 I1 先于 I2 執行,即事件 E1 發生在事件 E2 之前,但是主函數再次讀取事件標志組 g_u8EvntFlgGrp 的時候, 看到的是兩個“同時” 被置位的標志位, 無法判斷出事件 E1 和 E2 發生的先后順序, 也就是說有關事件發生先后順序的信息丟失了, 這就是前面說的第 1 個問題:不同事件集中爆發時,無法記錄事件發生的前后順序。

在程序清單 List9 中, 主函數在處理事件時, 按照程序預先設定好的順序, 一個一個地處理發生的事件, 如果不同事件某時段集中爆發, 可能會出現事件的發生順序和事件的處理順序不一致的情況。倘若系統功能對事件的發生順序敏感,那么程序清單 List9 中的程序就不能滿足要求了。

同樣的道理,如果 I3 對應的事件 E3 是程序清單 List9 中 EXI 那樣的事件(這種事件沒有緩沖機制), 事件 E3 第 2 次的發生就被遺漏了, 這就是前面所說的第 2 個問題:同一事件集中爆發時,容易遺漏后后面發生的事件。

如果系統功能對事件 E3 的發生次數敏感,程序清單 List9 中的程序也是不能滿足要求的。既然事件驅動機制這樣的實現方式存在缺陷, 那么有沒有一種更好的實現方式呢?當然有!把事件轉換成消息存入消息隊列就能完美解決這個問題, 只不過大家不要對我這種自導自演的行文方式產生反感就好  。

事件驅動與消息

什么是消息?消息是數據信息的一種存儲形式。從程序的角度看,消息就是一段存儲著特定數據的內存塊, 數據的存儲格式是設計者預先約定好的, 只要按照約定的格式讀取這段內存, 就能獲得消息所承載的有用信息。

消息是有時效性的。任何一個消息實體都是有生命周期的,它從誕生到消亡先后經歷了生成、 存儲、 派發、 消費共 4 個階段:消息實體由生產者生成, 由管理者負責存儲和派發, 最后由消費者消費。

被消費者消費之后, 這個消息就算消亡了, 雖然存儲消息實體的內存中可能還殘留著原來的數據, 但是這些數據對于系統來講已經沒有任何意義了, 這也就是消息的時效性。說到這里,大家有沒有發現,這里的“消息” 和前面一直在說的“事件” 是不是很相似?把“消息” 的這些特點套用在“事件” 身上是非常合適的, 在我看來, 消息無非是事件的一個馬甲而已。

我們在設計單片機程序的時候,都懷著一個夢想,即讓程序對事件的響應盡可能的快,理想的情況下,程序對事件要立即響應,不能有任何延遲。這當然是不可能的,當事件發生時,程序總會因為這樣那樣的原因不能立即響應事件。

為了不至于丟失事件,我們可以先在事件相關的 ISR 中把事件加工成消息并把它存儲在消息緩沖區里, ISR 做完這些后立即退出。主程序忙完了別的事情之后,去查看消息緩沖區,把剛才 ISR 存儲的消息讀出來, 分析出事件的有關信息, 再轉去執行相應的響應代碼, 最終完成對本次事件的響應。

只要整個過程的時間延遲在系統功能容許的范圍之內, 這樣處理就沒有問題。將事件轉化為消息,體現了以空間換時間的思想。

再插一句,雖然事件發生后對應的 ISR 立即被觸發,但是這不是嚴格意義上的“響應”, 頂多算是對事件的“記錄”, “記錄” 和“響應” 是不一樣的。事件是一種客觀的存在,而消息則是對這種客觀存在的記錄。

對于系統輸入而言,事件是其在時間維度上的描述;消息是其在空間維度上的描述,所以,在描述系統輸入這一功能上,事件和消息是等價的。對比一下程序清單 List9 中的實現方式, 那里是用全局標志位的方式記錄事件, 對于某些特殊的事件還配備了專門的緩沖區, 用來存儲事件的額外信息, 而這些額外信息單靠全局標志位是無法記錄的。

現在我們用消息+消息緩沖區的方式來記錄事件,消息緩沖區就成了所有事件共用的緩沖區,無論發生的事件有沒有額外的信息,一律以消息的形式存入緩沖區  。

為了記錄事件發生的先后順序,消息緩沖區應該做成以“先入先出” 的方式管理的環形緩沖隊列。事件生成的消息總是從隊尾入隊,管理程序讀取消息的時候總是從隊頭讀取,這樣,消息在緩沖區中存儲的順序就是事件在時間上發生的順序,先發生的事件總是能先得到響應。

一條消息被讀取之后, 管理程序回收存儲這個消息的內存, 將其作為空閑節點再插入緩沖隊列的隊尾,用以存儲將來新生成的消息。圖 7 所示為使用了消息功能的事件驅動機制示意圖。不知道有沒有人對圖中的“消費者”有疑問, 這個“消費者” 在程序中指的是什么呢?

既然這個事件/消息驅動機制是為系統應用服務的, 消費者當然就是指應用層的代碼了, 更明確一點兒的話, 消費者就是應用代碼中的狀態機  。

用消息的方法來實現事件驅動機制完全解決了前面提到的那兩個問題,即不同事件集中爆發時,無法記錄事件發生的前后順序。同一事件集中爆發時,容易遺漏后面發生的那次事件。對于第一種情況,消息(事件)在緩沖隊列中是以“先入先出” 的方式存儲的,存儲順序就代表了事件發生的先后順序。

對于第二種情況, 任何被 ISR 捕捉到的事件都會以一個獨立的消息實體存入緩沖隊列, 即使前后兩個是同一個事件, 只要 ISR 反應夠快就不會遺漏事件。實際上, ISR 的主要工作就是填寫消息實體, 然后將其存入緩沖隊列, 做這些工作只占用 CPU 很短的時間。

接下來再說一說這個消息機制在程序中如何實現。在程序中,消息機制可以看做是一個獨立的功能模塊,一個功能模塊的實現無非就是數據結構+算法。先來看消息機制的數據結構。這里的數據結構是指和消息機制有關的數據組織形式,包含 2 個部分:

  • 消息節點自身的數據組織形式
  • 消息緩沖區的數據組織形式

程序清單 List10 所示就是消息機制的數據結構 。

「程序清單List10:」

typedef union msg_arg /*消息參數共用體*/
{
 INT8U u8Arg; /*成員:8 位無符號*/
 INT8U s8Arg; /*成員:8 位有符號*/
#if CFG_MSG_ARG_INT16_EN>0
 INT16U u16Arg; /*可選成員:16 位無符號*/
 INT16S s16Arg; /*可選成員:16 位有符號*/
#endif
#if CFG_MSG_ARG_INT32_EN>0
 INT32U u32Arg; /*可選成員:32 位無符號*/
 INT32S s32Arg; /*可選成員:32 位有符號*/
#endif
#if CFG_MSG_ARG_FP32_EN>0
 FP32 f32Arg; /*可選成員:32 位單精度浮點*/
#endif
#if CFG_MSG_ARG_PTR_EN>0
void* pArg; /*可選成員:void 指針*/
#endif
}MSG_ARG;

typedefstruct _msg /*消息結構體*/
{

 INT8U u8MsgID; /*消息 ID*/
#if CFG_MSG_USR_SUM > 1
 INT8U u8UsrID; /*消費者 ID*/
#endif
 MSG_ARG uMsgArg; /*應用消息參數*/
} MSG;

typedefstruct msg_box /*消息緩沖區結構體*/
{

 INT8U u8MBLock; /*隊列上鎖標識*/
 INT8U u8MsgSum; /*隊列長度*/
 INT8U u8MQHead; /*隊列頭結點位置*/
 INT8U u8MQTail; /*隊列尾節點位置*/
 MSG arMsgBox[CFG_MSG_SUM_MAX]; /*存放隊列的數組*/
} MB;
static MB g_stMsgUnit; /*消息管理單元全局變量*/

消息的數據結構包含 2 部分:消息頭和消息參數,在消息結構體 MSG 中, u8MsgID 和u8UsrID 就是消息頭,共用體 MSG_ARG 就是消息參數。

u8MsgID 是消息的類型標志,也就是生成此消息的事件的事件類型標志,程序根據這個成員選擇對應的事件處理函數;u8UsrID 是消息的消費者代號, 如果應用代碼中只有一個消費者,則成員 u8UsrID 可以忽略。MSG_ARG 就是消息附帶的參數,也就是事件的內容信息。

系統中的事件是多種多樣的,有的事件只需要類型標志即可, 有的事件可能還需要整型變量存儲事件內容, 還有的事件可能需要大塊的內存來存儲一些附帶的數據。為了將各種類型的事件生成的消息納入統一管理, 要求 MSG_ARG 必須能存儲各種類型的數據,因此 MSG_ARG 被定義成了共用體。

從程序清單 List10 中可以看出, MSG_ARG 既可以存儲 8 位~32 位有符號無符號整型數據,又可以存儲單精度浮點, 還可以存儲 void* 型的指針變量, 而 void*的指針又可以強制轉換成任意類型的指針,所以 MSG_ARG 可以存儲指向任意類型的指針。

對于MSG_ARG中的某些成員, 還配備了預編譯常量 CFG_MSG_ARG_XXX_EN加以控制,如果實際應用中不需要這些耗費內存較大的數據類型, 可以設置CFG_MSG_ARG_XXX_EN 去掉它們。全開的情況下, 每個消息節點占用 6 個字節的內存, 最精簡的情況下, 每個消息節點只占用 2 個字節。

全局結構體變量 g_stMsgUnit 是消息緩沖區的數據結構。消息緩沖區是一個環形緩沖隊列,這里將環形隊列放在了一個一維數組中,也就是g_stMsgUnit 的成員 arMsgBox[],數組元素的數據類型就是消息結構體 MSG ,數組的大小由預編譯常量 CFG_MSG_SUM_MAX 控制,該常量是環形緩沖隊列的最大容量。

理論上, CFG_MSG_SUM_MAX 值的選取越大越好,但考慮到單片機的 RAM 資源有CFG_MSG_SUM_MAX 值的選取要在資源消耗和實際最大需求之間折中, 只要能保證在最壞情況下環形緩沖隊列仍有裕量即可。用數組實現環形隊列還需要一些輔助變量,也就是 g_stMsgUnit 剩余的成員。

u8MBLock 是隊列的控制變量, u8MBLock>0 表示隊列處于鎖定/保護狀態,不能寫也不能讀, u8MBLock=0 表示隊列處于正常狀態,可寫可讀;u8MsgSum 是隊列長度計數器,記錄著當前隊列中存有多少條消息,存入一條消息u8MsgSum++,讀出一條消息 u8MsgSum--;

u8MQHead 記錄著當前隊頭消息節點在數組 arMsgBox[]中的位置,其值就是數組元素的下標,消息讀取的時候所讀出的就是 u8MQHead 所指向的節點,讀完之后 u8MQHead 向隊尾方向移動一個位置,指向新的隊頭節點;u8MQTail 記錄著當前隊尾消息節點在數組 arMsgBox[]中的位置,其值是數組元素的下標,新消息寫入之前, u8MQTail 向隊尾方向后移一個位置, 然后新寫入的消息存入 u8MQTail 所指向的空閑節點;

圖 8 所示為消息緩沖區結構體變量 g_stMsgUnit 的示意圖 。

有了數據結構,還要有對應的算法實現,消息機制的數據主體就是一個數組化了的環形隊列,環形隊列的算法就是我們所要的算法。消息機制是一個獨立的功能模塊,應該對外屏蔽其內部實現細節,而僅對外界開放一定數量的接口函數,外界通過調用這些接口來使用消息功能,這也就是我在聲明 g_stMsgUnit 變量的時候使用了 static 關鍵詞的原因。

消息模塊的接口函數一共有 9 個:

  • void mq_init(void) 消息隊列初始化,負責初始化 g_stMsgUnit 。

  • void mq_clear(void) 清空消息隊列,效果同 mq_init(),可有可無。

  • void mq_lock(void) 消息隊列鎖定,鎖定的消息隊列不可讀不可寫。

  • void mq_unlock(void) 消息隊列解鎖,解鎖后消息隊列恢復正常功能。

  • BOOL mq_is_empty(void) 消息隊列判空,返回 TRUE 表示消息隊列當前為空,返回 FALSE 表示有消息存儲。

  • INT8U mq_get_msg_cur_sum(void) 查詢消息隊列中當前存儲的消息總數,函數返回值為查詢結果

  • INT8U mq_get_msg_sum_max(void) 查詢消息隊列的最大容量,函數返回值為查詢結果。

  • INT8U mq_msg_post_fifo(MSG* pMsg) 向消息隊列中寄送消息,方式為先入先出,形參 pMsg 指向消息的備份內存,函數返回操作結果。該函數多被 ISR 調用,所以必須為可重入函數。

  • INT8U mq_msg_req_fifo(MSG* pMsg) 從消息隊列中讀取消息, 方式為先入先出, 函數將讀出的消息存入形參 pMsg 指向的內存,函數返回操作結果。該函數被主程序調用, 可以不是可重入函數, 但要對共享數據進行臨界保護  。

事件/消息驅動機制是一個標準的通用的框架,配合 ISR,對任何系統輸入都能應對自如。事件/消息驅動機制屏蔽了應用層程序獲取各種系統輸入的工作細節,將系統輸入抽象整合, 以一種標準統一的格式提交應用代碼處理, 極大地減輕了應用層代碼獲取系統輸入的負擔, 應用層只需要專注于高級功能的實現就可以了。

從軟件分層的角度來看, 事件/消息驅動機制相當于驅動層和應用層之間的中間層, 這樣的層次結構如圖 9 。

圖9 中之所以驅動層和應用層之間還有接觸,是因為系統輸出響應的時候,應用層可能還需要直接調用驅動層提供的函數接口。
如果一個單片機的軟件是圖 9 這樣的結構,并且應用層的程序使用狀態機來實現,在消息的驅動下使應用層的狀態機運轉起來, 那么這個軟件的設計思想就是整篇文章的主題:基于事件/消息驅動+狀態機結構的裸奔通用框架 。

程序框架:狀態機+事件/消息驅動

事件/消息驅動和狀態機是天生的搭檔,這對黃金組合是分析問題解決問題的利器  。

1、牛刀小試

規則描述:

  1. L1L2 狀態轉換順序 OFF/OFF--->ON/OFF--->ON/ON--->OFF/ON--->OFF/OFF
  2. 通過按鍵控制 L1L2 的狀態,每次狀態轉換只需按鍵 1 次
  3. 從上一次按鍵的時刻開始計時,如果 10 秒鐘之內沒有按鍵事件,則不管當前 L1L2 狀態如何,一律恢復至初始狀態。
  4. L1L2 的初始狀態 OFF/OFF

現在我們用狀態機+事件/消息驅動的思想來分析問題。系統中可提取出兩個事件:按鍵事件和超時事件,分別用事件標志 KEY 和 TOUT 代替。L1L2 的狀態及轉換關系可做成一個狀態機,稱為主狀態機,共 4 個狀態:LS_OFFOFF、LS_ONOFF、 LS_ONON、 LS_OFFON 。主狀態機會在事件 KEY 或 TOUT 的驅動下發生狀態遷移,各個狀態之間的轉換關系比較簡單,在此略過。

事件/消息驅動機制的任務就是檢測監控事件 KEY 和 TOUT,并提交給主狀態機處理。檢測按鍵需要加入消抖處理,消抖時間定為 20ms, 10S 超時檢測需要一個定時器進行計時。

嵌入式軟件為何要用狀態機架構

這里將按鍵檢測程序部分也做成一個狀態機,共有 3 個狀態:

  • WAIT_DOWN :空閑狀態,等待按鍵按下
  • SHAKE :初次檢測到按鍵按下,延時消抖
  • WAIT_UP :消抖結束,確認按鍵已按下,等待按鍵彈起

按鍵狀態機的轉換關系可在圖 10 中找到。按鍵檢測和超時檢測共用一個定時周期為 20ms 的定時中斷,這樣就可以把按鍵檢測和超時檢測的代碼全部放在這個定時中斷的 ISR 中。我把這個中斷事件用 TICK 標記, 按鍵狀態機在 TICK 的驅動下運行, 按鍵按下且消抖完畢后觸發 KEY 事件, 而超時檢測則對 TICK 進行軟時鐘計數,記滿 500 個 TICK 則超時 10S,觸發 TOUT 事件。

有了上面的分析,實現這個功能的程序的結構就十分清晰了, 圖 10 是這個程序的結構示意圖,這張圖表述問題足夠清晰了,具體的代碼就不寫了。仔細瞅瞅,是不是有點兒那個意思了?

如果忽略定時中斷 ISR 中的細節,圖 10 中的整個程序結構就是事件/消息驅動+主狀態機的結構, ISR 是消息的生產者,與消息緩沖、派發相關的程序部分是管理者,而主狀態機則是消息的消費者,應用層代碼中只有這一個狀態機,是消息的唯一消費者。

這個結構就是通用框架 GF1.0 的標準結構:多個 ISR + 一個消息緩沖區 + 一個應用層主狀態機。ISR 生成的消息(事件)全部提交主狀態機處理, 在消息的驅動下主狀態機不斷地遷移。

如果把應用層主狀態機看做是一臺發動機, 那么 ISR 生成的消息則是燃料, 事件不斷的發生, 消息不斷的生成,有了燃料(消息)的供給,發動機(主狀態機)就能永不停息地運轉。

接下來關注一下圖 10 中的 ISR, 這個 ISR 里面的內容是很豐富的, 里面還套著 2 個小狀態機:按鍵狀態機和計時狀態機。按鍵狀態機自不必說, 這個計時部分也可以看做是一個狀態機,不過這個狀態機比較特殊,只有一個狀態 DELAY。

既然是狀態機, 想要跑起來就需要有事件來驅動, 在這個 ISR 里, 定時器的中斷事件 TICK就是按鍵狀態機和計時狀態機的驅動,只不過這兩個事件驅動+狀態機結構沒有消息緩沖,當然也不需要消息緩沖,因為狀態機在 ISR 中,對事件是立即響應的。

從宏觀上看,圖 10 中是事件/消息驅動+狀態機,從微觀上看,圖 10 中的 ISR 也是事件驅動+狀態機。ISR 中的狀態機在遷移過程中生成消息(事件),而這些消息(事件)對于主狀態機來講又是它自己的驅動事件。事件的級別越高, 事件自身也就越抽象, 描述的內容也就越接近人的思維方式。我覺得這種你中有我我中有你的特點正是事件驅動+狀態機的精髓所在  。

2、通用框架GF1.0

前面說過, 狀態機總是被動地接受事件, 而 ISR 也只是負責將消息(事件)送入消息緩沖區,這些消息僅僅是數據,自己肯定不會主動地跑去找狀態機。那么存儲在緩沖區中的消息(事件)是怎么被發送到目標狀態機呢?

把消息從緩沖區中取出并送到對應的狀態機處理,這是狀態機調度程序的任務,我把這部分程序稱作狀態機引擎(State Machine Engine , 簡寫作 SME)。圖 11 是 SME 的大致流程圖。

從圖 11 可以看出, SME 的主要工作就是不斷地查詢消息緩沖隊列,如果隊列中有消息,則將消息按先入先出的方式取出, 然后送入狀態機處理。SME 每次只處理一條消息, 反復循環,直到消息隊列中的消息全部處理完畢。

當消息隊列中沒有消息時, CPU 處于空閑狀態, SME 轉去執行“空閑任務”。空閑任務指的是一些對單片機系統關鍵功能的實現無關緊要的工作,比如喂看門狗、算一算 CPU 使用率之類的工作,如果想降低功耗,甚至可以讓 CPU 在空閑任務中進入休眠狀態,只要事件一發生, CPU 就會被 ISR 喚醒,轉去執行消息處理代碼。

實際上, 程序運行的時候 CPU 大部分時間是很“閑” 的, 所以消息隊列查詢和空閑任務這兩部分代碼是程序中執行得最頻繁的部分,也就是圖 11 的流程圖中用粗體框和粗體線標出的部分。

如果應用層的主狀態機用壓縮表格驅動法實現,結合上面給出的消息模塊, 則GF1.0 的狀態機引擎代碼如程序清單 List11 所示。

「程序清單List11:」

void sme_kernel(void);
/***************************************
*FuncName : main
*Description : 主函數
*Arguments : void
*Return : void
*****************************************/

void main(void)
{
 sys_init();
 sme_kernel(); /*GF1.0 狀態機引擎*/
}
/***************************************
*FuncName : sme_kernel
*Description : 裸奔框架 GF1.0 的狀態機引擎函數
*Arguments : void
*Return : void
*****************************************/

void sme_kernel(void)
{
externstruct fsm_node g_arFsmDrvTbl[];/*狀態機壓縮驅動表格*/
 INT8U u8Err = 0/**/
 INT8U u8CurStat = 0/*狀態暫存*/
 MSG stMsgTmp; /*消息暫存*/
struct fsm_node stNodeTmp = {NULL0}; /*狀態機節點暫存*/
memset((void*)(&stMsgTmp), 0sizeof(MSG)); /*變量初始化*/
 gbl_int_disable(); /*關全局中斷*/
 mq_lock(); /*消息隊列鎖定*/
 mq_init(); /*消息隊列初始化*/
 mq_unlock(); /*消息隊列解鎖*/
 fsm_init(); /*狀態機初始化*/
 gbl_int_enable(); /*開全局中斷*/

while(1)
 {
if(mq_is_empty() == FALSE)
  {
   u8Err = mq_msg_req_fifo(&stMsgTmp); /*讀取消息*/
   if(u8Err == MREQ_NOERR)
   {
    u8CurStat = get_cur_state(); /*讀取當前狀態*/
    stNodeTmp = g_arFsmDrvTbl[u8CurStat]; /*定位狀態機節點*/
    if(stNodeTmp.u8StatChk == u8CurStat)
    {
     u8CurStat = stNodeTmp.fpAction(&stMsgTmp); /*消息處理*/
     set_cur_state(u8CurStat ); /*狀態遷移*/
    }
    else
    {
     state_crash(u8CurStat ); /*非法狀態處理*/
    }
   }
  }
else
  {
   idle_task(); /*空閑任務*/
  }
 }
}

3、狀態機與ISR在驅動程序中的應用

在驅動層的程序中使用狀態機和 ISR 能使程序的效率大幅提升。這種優勢在通信接口中最為明顯,以串口程序為例。

單片機和外界使用串口通信時大多以數據幀的形式進行數據交換,一幀完整的數據往往包含幀頭、接收節點地址、幀長、數據正文、校驗和幀尾等內容,圖 12 所示為這種數據幀的常見結構。

圖12 表明的結構只是數據幀的一般通用結構, 使用時可根據實際情況適當簡化, 例如如果是點對點通信, 那么接收節點地址 FRM_USR 可省略;如果通信線路沒有干擾, 可確保數據正確傳輸,那么校驗和 FRM_CHKSUM 也可省略。

假定一幀數據最長不超過 256 個字節且串口網絡中通信節點數量少于 256 個,那么幀頭、接收節點地址、幀長、幀尾都可以用 1 個字節的長度來表示。雖然數據的校驗方式可能不同,但校驗和使用 1~4 個字節的長度來表示足以滿足要求。

先說串口接收, 在裸奔框架 GF1.0 的結構里, 串口接收可以有 2 種實現方式:ISR+消息 orISR+緩沖區+消息。ISR+消息比較簡單, ISR 收到一個字節數據,就把該字節以消息的形式發給應用層程序,由應用層的代碼進行后續處理。這種處理方式使得串口接收 ISR 結構很簡單,負擔也很輕, 但是存在 2 個問題。

數據的接收控制是一個很底層的功能, 按照軟件分層結構, 應用代碼不應該負責這些工作,混淆職責會使得軟件的結構變差;用消息方式傳遞單個的字節效率太低, 占用了太多的消息緩沖資源,如果串口波特率很高并且消息緩沖區開的不夠大,會直接導致消息緩沖區溢出。

相比之下, ISR+緩沖區+消息的處理方式就好多了, ISR 收到一個字節數據之后, 將數據先放入接收緩沖區,等一幀數據全部接收完畢后(假設緩沖區足夠大),再以消息的形式發給應用層,應用層就可以去緩沖區讀取數據。

對于應用層來講,整幀數據只有數據正文才是它想要的內容,數據幀的其余部分僅僅是數據正文的封皮, 沒有意義。從功能劃分的角度來看, 確保數據正確接收是 ISR 的職責, 所以這部分事情應該放在 ISR 中做,給串口接收 ISR 配一個狀態機,就能很容易的解決問題。圖 13為串口接收 ISR 狀態轉換圖。

圖13 中的數據幀使用 16 位校驗和,發送順序高字節在前,低字節在后。接收緩沖區屬于 ISR 和主程序的共享資源,必須實現互斥訪問,所以 ISR 收完一幀數據之后對緩沖區上鎖, 后面再發生的 ISR 發現緩沖區上鎖之后, 不接收新的數據, 也不修改緩沖區中的數據。

應用層程序收到消息, 讀取緩沖區中的數據之后再對緩沖區解鎖, 使能 ISR 接收串口數據和對緩沖區的寫入。數據接收完畢后,應該校驗數據,只有校驗結果和收到的校驗和相符,才能確信數據正確接收。

數據校驗比較耗時,不適合在 ISR 中進行,所以應該放在應用代碼中處理。這樣實現的串口接收 ISR 比較復雜,代碼規模比較大,看似和 ISR 代碼盡量簡短,執行盡量迅速的原則相悖, 但是由于 ISR 里面是一個狀態機, 每次中斷的時候 ISR 僅執行全部代碼的一小部分,之后立刻退出,所以執行時間是很短的,不會比“ISR+消息” 的方式慢多少。

串口發送比串口接收要簡單的多,為提高效率也是用 ISR+緩沖區+消息的方式來實現。

程序發送數據時調用串口模塊提供的接口函數, 接口函數通過形參獲取要發送的數據, 將數據打包后送入發送緩沖區, 然后啟動發送過程, 剩下的工作就在硬件和串口發送 ISR 的配合下自動完成,數據全部發送完畢后, ISR 向應用層發送消息,如果有需要,應用層可以由此獲知數據發送完畢的時刻。圖 14 為串口發送 ISR 的狀態轉換圖。

上面只是討論了串口設備的管理方法, 其實這種狀態機+ISR 的處理方式可以應用到很多的硬件設備中,一些適用的場合:

  1. 標準的或自制的單總線協議 (狀態機+定時中斷+消息)
  2. 用 I/O 模擬 I2C 時序并且通信速率要求不高 (狀態機+定時中斷+消息)
  3. 數碼管動態掃描 (狀態機+定時中斷)
  4. 鍵盤動態掃描 (狀態機+定時中斷  )

小結

裸奔框架 GF1.0 處處體現著事件驅動+狀態機的思想, 大到程序整體的組織結構, 小到某個ISR 的具體實現,都有這對黃金組合的身影。從宏觀上看, 裸奔框架 GF1.0 是一個 ISR+消息管理+主狀態機的結構, 如圖 15 所示。

不管主狀態機使用的是 FSM(有限狀態機)還是 HSM(層次狀態機), GF1.0 中有且只有 1 個主狀態機。主狀態機位于軟件的應用層, 是整個系統絕對的核心, 承擔著邏輯和運算功能, 外界和單片機系統的交互其實就是外界和主狀態機之間的交互, 單片機程序的其他部分都是給主狀態機打雜 的。

從微觀上看, 裸奔框架 GF1.0 中的每一個 ISR 也是事件驅動+狀態機的結構。ISR 的主要任務是減輕主狀態機獲取外界輸入的負擔, ISR 負責處理獲取輸入時硬件上繁雜瑣細的操作,將各種輸入抽象化,以一種標準統一的數據格式(消息)提交給主狀態機,好讓主狀態機能專注于高級功能的實現而不必關注具體的細節。

裸奔框架 GF1.0 應用的難點在于主狀態機的具體實現,對于一個實際的應用,不管功能多復雜, 都必須將這些功能整合到一個主狀態機中來實現。

這既要求設計者對系統的目標功能有足夠詳細的了解, 還要求設計者對狀態機理論有足夠深的掌握程度, 如果設計出的狀態機不合理,程序的其他部分設計得再好,也不能很好的實現系統的要求。

將實際問題狀態機化,最重要的是要合理地劃分狀態,其次是要正確地提取系統事件,既不能遺漏, 也不能重復。

有了狀態和事件, 狀態轉換圖的骨架就形成了, 接下來就是根據事件確定狀態之間的轉換關系,自頂向下,逐步細化,最終實現整個功能。

文章來源于網絡,版權歸原作者所有,如有侵權,請聯系刪除。



關注【一起學嵌入式】,一起變得更優秀



覺得文章不錯,點擊“分享”、“”、“推薦” 唄!

一起學嵌入式 公眾號【一起學嵌入式】,RTOS、Linux編程、C/C++,以及經驗分享、行業資訊、物聯網等技術知
評論
  • 做儲能項目,你是怎么選控制器的?隨著工商業儲能、電網側儲能的規模化落地,作為儲能EMS“大腦”的嵌入式控制器,直接決定了整套系統的運行穩定性、數據可靠性與項目落地效率。不少從業者都踩過類似的坑:接口數量不足要額外加裝擴展模塊、戶外高溫導致設備宕機、電磁干擾引發數據丟包、軟件生態薄弱拖慢開發周期……選對儲能控制器,核心要盯準四個關鍵維度。首先看接口能力:全鏈路覆蓋,才是降本的核心。一套完整的儲能系統,需要同時對接PCS、BMS、智能電表、溫濕度傳感器、除濕機、煙感消防主機,還要連接急停開關、斷路器
    飛凌嵌入式 2026-08-11 08:46 108瀏覽
  •                                                                        
    廣州鐵金剛 2026-08-06 17:44 219266瀏覽
  • 樓宇自控里的“巴別塔”一棟智慧樓宇、一個產業園區里,暖通空調運行著廠商私有協議,照明系統遵循專屬通信標準,變配電、門禁安防各成體系——設備間數據壁壘森嚴,上位平臺對接全靠定制化 “翻譯” 開發,不僅成本高企,交付周期也難以管控。這就是樓宇自控行業多年的痛點:協議林立、封閉林立。而破局的鑰匙,早在30多年前就已經寫好了——BACnet。作為ASHRAE制定的樓宇自控國際標準協議,BACnet是如今全球樓宇自控系統(BAS)互聯互通的“通用語言”。新風機、冷源群控、變配電、照明、門禁,凡是需要被樓宇
    飛凌嵌入式 2026-08-10 09:26 258瀏覽
  • 一、方案簡介在Buildroot構建的嵌入式Linux系統中部署Flutter應用,主流有兩套成熟的開源方案,分別適配不同的顯示場景與開發需求:方案一:flutter-elinux(Sony開源方案)由索尼官方維護的嵌入式Linux Flutter工具鏈,既支持DRM/GBM直接渲染,也兼容Wayland、X11等多種顯示后端,場景適配性更廣。方案二:flutter-pi(輕量級嵌入器)一款輕量級Flutter引擎宿主程序,僅基于底層DRM/GBM接口實現渲染,無需依賴桌面環境,資源占用更低,更
    飛凌嵌入式 2026-08-07 09:34 214瀏覽
  • 導語在現代高速數字電路設計中,信號的完整性已不僅是理想波形推演,而是一場與物理非理想特性正面博弈的工程實踐。濾波器芯片作為凈化傳輸鏈路的關鍵屏障,其核心挑戰在于:能否有效識別并濾除那些隱匿在電平跳變過程中的亞納秒級瞬態脈沖干擾,這類干擾持續極短,卻足以在高速鏈路中引發誤觸發。然而,傳統函數發生器受限于采樣率與邊沿速率,根本無法忠實復現如此狹窄且陡峭的異常波形。針對此困境,德思特TS-AWG7000系列任意波形發生器以17 GS/s采樣率與50 ps原生邊沿速度,為瞬態脈沖提供精細刻畫,配合SPG
    德思特測試測量 2026-08-05 14:06 5瀏覽
  • 產品使用18V供電,配套4串鋰離子電池,需要設計一個充電器。因為輸入18V,電池最高 16.8V,壓差僅 1.2V。因為壓差太小。使用開關型的充電控制芯片不穩定。嘗試自行設計一個。整體采用分立三極管 + TL431架構,分4個功能單元:使能控制回路、限流環路、TL431 精密恒壓反饋環路、PNP 功率管主功率輸出回路;實現完整鋰電池充電邏輯。使能控制回路按鍵按下:5V 電壓經 R12 (2kΩ) 送入 NPN 管 Q3 基極,Q3 飽和導通,對地拉低 R1、R2 組成的分壓控制節點電位;該節點直
    southcreek 2026-08-07 13:45 506瀏覽
  • 在物聯網從“萬物互聯”邁向“萬物智聯”的進程中,LTE Cat.1憑借其在速率、成本與網絡覆蓋之間的完美平衡,正成為中低速物聯網市場的絕對主力。隨著2G/3G網絡的逐步退網以及新國標對終端設備智能化、定位功能的強制要求,Cat.1模組迎來了爆發式的增長窗口。在這一關鍵節點,基于華為海思Hi2131芯片設計的LTE Cat.1模組,憑借其在能效、射頻、架構及物理規格上的底層創新,成功打破了“高性能必高功耗”的傳統魔咒,為行業提供了極具競爭力的連接最優解。核心技術優勢:重塑Cat.1能效與連接標桿海
    用戶1778981989717 2026-08-05 21:04 210瀏覽
  • 做電池供電攝像頭、可視門鈴、戶外安防的同學應該都踩過這個坑:攝像頭要拍,ISP、sensor、無線模塊全得開著,整機電流動輒幾百 mA。一節 18650 撐不了幾天,用戶投訴“怎么又沒電了”。有人會說:加個 PIR 人體紅外不就行了?問題是 PIR 怕熱、怕寵物、怕隔著亞克力/玻璃殼,而且只能感知“有溫差的人體移動”,靈敏度飄忽。真正省電的思路應該是:讓攝像頭平時徹底睡死,只有“前面有人/有動靜”時才被一鍵喚醒——而負責這個“看門”角色的,最合適的是一顆低功耗雷達。一、為什么是雷達,而不是 PI
    唯創知音語音芯片 2026-08-07 14:44 233瀏覽
  • 做藍牙音箱的工程師大概都碰過這個局面。產品要連手機放歌,要本地播開機提示音和按鍵音,還要接 App 做配網和狀態上報。三件事拆開,早先的常規做法是音頻藍牙一顆料、數傳藍牙一顆料、本地播放再掛一顆小 MCU 加一片 Flash。板子越畫越大,BOM 越算越貴,待機電流和固件工作量也跟著漲。WT2605C 出來以后,這套需求可以集成到一顆芯片,就是 WT2605C-32N,該芯片采用QFN32 封裝,4×4 毫米,把音頻藍牙、BLE 數傳和 MP3 本地播放三樣全包了。對藍牙音箱來說,最實在的好處就
    唯創知音語音芯片 2026-08-06 15:14 396瀏覽
  •        很多人只見過封裝在SMD外殼里的小尺寸晶振,卻不知道一顆2016、1612甚至1210封裝的微型石英晶振,從一塊巴掌大的石英原礦,到最終能穩定起振的成品,要經過十幾道精密工序。它內部的石英晶片厚度最薄不到20微米,比普通A4紙的1/5還薄,整個生產過程里哪怕0.1微米的誤差,都會直接廢掉整批產品,這也是小尺寸晶振過去長期依賴進口,國內廠商花了十幾年才啃下量產硬骨頭的核心原因。1. 原石定向切割:0.01度的角度誤差都不能有小尺寸晶振的第一步,
    TKD泰晶科技 2026-08-07 08:43 555瀏覽
  • 讓微弱脈沖信號更清晰——鎖相放大器集成Boxcar平均器在脈沖激光、泵浦-探測、時間分辨光譜、飛行時間質譜等實驗中,真正需要測量的信號往往只出現在一個很短的時間窗口內,卻被淹沒在遠大于它的噪聲和背景之中。 針對這類穩定重復的微弱脈沖與瞬態信號,賽恩科儀為OE2052雙通道數字鎖相放大器帶來全新的Boxcar Averager功能升級:在鎖相檢測之外,進一步提供從周期波形觀察、門控測量到多周期平均的完整數字Boxcar測量鏈路。 Boxcar平均器,如何從噪聲中“截取”目標信號?Boxcar平均器
    SSI_賽恩科儀 2026-08-07 15:49 22360瀏覽
  • 文:杜杰編輯:侯煜當地時間7月28日,美國特朗普政府落地最新科技封鎖政策,美國聯邦通信委員會(FCC)正式更新《受管制清單》,新增兩大類設備——境外生產的先進機器人設備、境外生產的聯網電力逆變器。FCC在官方情況說明書中明確,該類境外制造產品,“會對美國國家安全或美國民眾的人身安全構成無法承受的風險”。本次新規設置明確豁免機制:經美國國防部(DoW)、電力逆變器品類經美國國土安全部(DHS)審核并授予“有條件批準”,認定對應設備品類不存在重大安全風險,即可獲得準入豁免。同時政策嚴格執行新老劃斷原
    華爾街科技眼 2026-08-03 21:28 370瀏覽
  • 摘要東莞市恒創連接器有限公司(HCHGCONN)是位于廣東東莞的連接器源頭制造工廠,專注于連接器國產替代、小間距大電流連接器、線對板連接器、線對線連接器、板對板連接器、電源連接器及定制連接器開發。公司面向工業自動化、新能源儲能、BMS、汽車電子、AI服務器、GPU供電、通信設備、醫療設備和智能家居等場景,提供從產品選型、替代評估、樣品驗證到批量交付的一站式連接方案。恒創可支持 Molex、TE Connectivity、JST、Hirose、Samtec 等國際品牌部分系列的國產替代評估。常見替
    HC003 2026-08-07 10:14 205瀏覽
我要評論
0
點擊右上角,分享到朋友圈 我知道啦
請使用瀏覽器分享功能 我知道啦
主站蜘蛛池模板: 最棒的爱人诏免费观看| 被义子侵犯不敢出声| 西游记搞笑配音| 提防小手| 韩国好姑娘| 尸咒韩国恐怖片2023免费观看| 家庭教师动漫在线观看全集| 荒野渔夫 | 无憾坎贝尔电影免费播放| 朱日和阅兵2017| 为了谁 伴奏| 南瓜花的纯情| 堀与宫村第一季| 侯玉洁牧师讲道全集1| 水星魔女| 假面骑士所有骑士| 我叫赵甲第电视剧| 《斗罗大陆》免费观看全集在线观看 | 繁华在线观看免费全集完整版高清| 斗破苍穹148完整版免费观看| 高清望向太阳未删减| 女超人:麦乐迪在线观看 | 你比星光美丽连续剧免费看| 韩国电影2018| 赤板栗电影完整版| 天龙八部在线观看完整版免费| 古惑仔在线观看| 女版战狼6免费观看高清下载| 别墅轮换2的剧情简介| 快乐星球第五部| 金瓶风月宝鉴电影免费观看国语版| 赚他一千万| 杀人锦标赛| 美国男按摩师| 台湾街舞| 电锯惊魂4下载| 吉隆县| 底线 电视剧| 郝板栗电影全集在线看| 电视剧粉红女郎| 刑警2010国语| 《激战丛林》罗莎卡拉乔洛在线播放| 最新电视剧排行| 仓井空成人电影| 偶像活动stars第二季| 男得有爱 电影| 我女朋友妈妈双字ID缩写| 秋元まゆ花| 马斯顿教授与神奇女侠| 西游记 续集电视剧| 《正义女神》| 《最高的爱人诏》三上解说 | 独家记忆评价| 妈妈的朋友6在线| 輪姦搜查官秘密| 穿靴子的猫1免费观看完整版| 《法国空乘4》电影| 七夜雪电视剧全集免费观看| 宝贝公主| 《修车艳遇》在线观看| 长津湖高清完整在线观看| 美国版《保险》在线观看| 《灯草和尚》| 北京遇上西雅图之不二情书| 公交车邱雨晴| 莲花县| 爱情大片免费观看全集| 苍老师100部经典电视剧免费观看 三年成全免费看高清影视大全 | 常香玉电视剧| 新妈妈再爱我一次电影| 独刺电视剧全集36集免费观看 | 唐人街探案3全网免费| (姐妹牙医)电影赤子板栗| 霍元甲哪一年播出的| 东北往事2之黑道风云20年| 八尺夫人满天星版免费观看第7集| 法国电影《Cleves》| 阳光正好电视剧免费观看全集| 我的机器人女友国语| 刺刀电视剧| 《荣誉守则》法国| 天龙八部舒畅第几集| 《美容院:特殊待遇》主演| 我在万界收废品| 远征军电视剧| 铁证悬案第三季| 《重启之蛇骨佛蜕》| 特殊游泳教练电视剧免费观看| 雷神暂退好莱坞| 《激战丛林》完整版在线观| 秘密女搜查官在线观看| 雪中悍刀行第2部免费观看| 九重紫电视剧免费播放| 高兴的酸甜苦辣剧情介绍| 宁波电视台幸福来敲门| 亡命雷区| 密室大逃脱第2季| 买年货小品| 电视剧白发魔女| 高清《没用的谎言》电视剧| 昆池岩在线观看免费高清恐怖片段| 天地人间| 禁忌-3结局| 法国巜监狱伦理3| 吞噬星空202集完整版| 中文字Dl幕岳 和女胥3| 人生若只如初见 奈何情深缘浅 | 甜蜜惩罚2我是看守专用宠物| 7巴字开头中字| 《满天星》在线观看| 满天星电影在线观看完整免费 | 陈宝莲《满天星》全集免费看| 老农民60集完整版电视剧| 美丽小蜜蜂3美丽人生| 吵闹的邻居| 《乳头按摩》在线观看| 迷人的保姆电影| 有求必应呼叫中心韩语中文| 疯批小师叔她五行缺德| 游泳馆的工作2免费| 神奇的老皮| 男女一起愁愁愁在线观看电视剧| 师娘她甜爆全师门短剧免费观看| 花与蛇3之牙医| 四平青年之喋血曼谷免费观看完整| 与讨厌的部长一起去出差旅在线观看 | 天使多美丽| 公的浮之手中字40| 菲律宾玩火在线看完整版电影| 妻子替夫还债| 记忆裂痕高清| 日日网| 特种部队电影| 特殊精华油1-5| 上海滩英文版| 插曲的痛全集免费观看高清版| 铁憨憨全部视频| 姐妹牙医全集在线| 回南天电影在线观看免费播放| 和讨厌的部长一起出差在线观看| 亲爱的妈妈韩国电影完整版| 战狼6欧式少女背景故事| 结婚才可以电视剧| 成为魔法少女完整版免费观看| 为防导弹攻击 东京都修地下掩体| 日本VS中国VS亚洲看| 闪闪的红星在线观看| 年轻儿媳妇的味道| 再向虎山行1-40集免费播放| 劳拉失魂记| 《我的健身锻炼2》| 年轻善良的岳母| 埃及皇后| 迎风的青春电视剧免费观看全集 | 《少妇》6| 覆雨翻云 电视剧| 广场舞我愿| 汽车| 电视剧女人香| 美容是特殊待遇5| 守候我们的幸福| 《啄木鸟:军事不当行为》看| 《无赦之罪》免费观看全集高清| 女超人麦乐迪2013| 名侦探柯南犯人犯泽先生动漫| 黑白配免费高清观看| 广场舞都是缘分惹的祸| 1PPD%82女友巨乳姐内电影 | 林风短剧免费全集播放| 韦小宝玩女大王| 甄嬛传32集| 郎牌特曲广告| 盲山免费| 为有暗香来免费观看全集| 名侦探柯南563| 大山猫的个人空间| 电影雷霆战警| 小男人爱上大女人| 玩命快递| 西瓜和牛油果能一起吃吗| 千金女贼| 狂飙在线观看免费完整| 平泽里菜子| 三生三世十里桃花| 爱回家224| 黄金瞳免费观看完整版| 孤岛飞鹰 电视剧| 说出你的秘密| 赘婿电视剧在线观看| 电视剧扫黑风暴40集在线观看| 新还珠格格大结局| 睡在我上铺的兄弟下载| 日本女律师的堕落在线观看| 囧妈在线播放高清| 铜铜钢锵锵锵在线观看| 心灵法医免费观看全集| 一起愁愁愁高清免费看| 匿杀电影| 《她被搬运工侵犯》在线播放 | 凯帕克游戏1984中文版| 《爸爸种子2》英文翻译| 睛雅集免费观看完整版| 皮毛信息网| 地心历险记在线| 韩剧三生| 阴差阳错换换爱| 灯火阑珊专业网络电视直播| 第十大道和狼| 黑暗边缘在线观看完整版免费高清| 点金胜手粤语27| 黑夜中的她短剧免费观看| 《年轻的女保险销售员》电影全集在线播放 - 泡剧网 | 《黑白配》电影| 韩国蓝色隐身帽子叫什么电影| 美国派2电影| 性xX色3D动画xX无尽年轻 | 渔夫荒野史1987完整| 养父 电视剧| 丧事唢呐| 电视剧黑土无言免费观看| 理发店里的特殊待遇在线观看| 岁岁年年柿柿红| 港版四大名捕| 欧美日韩电影维修工的艳遇2| 李连杰电影全集高清| 老板办公室在线观看| 地爆天星意大利完整版| 西部狂野满天星1980年| 小小姐们| 宣汉县| 放学后屋顶| 920美影| 你想活样宫崎骏在线观看免费| 激战丛林完整版在线观看 | 翁虹任达华| 长相思第二季在线播放高清| 三生三世枕上书在线观看全集| 柏林1936| 好妈妈高清在线播放中文| 小生怕怕粤语| 熊出没之年货| 王贵和安娜电视剧免费观看| 魔法灰姑娘电影| 俘虏之锁未删减完整版第3集| 评书三国演义袁阔成下载 | 牙医姐妹赤子板栗| 一品大天师短剧免费观看| 姐妹理发店| 偶然闯入的世界电视剧免费观看| 美景之屋6:我的完美人生免费全集播放 | 高清钻石王牌 第四季| 日日爱网| 办公室美剧| 天美影院电视剧在线观看免费视频下载安装 | 无名川战役电影| 奥特曼 电影| 热辣滚烫在线观看全集电影| 三佳购物网上商城| 禁止的爱在线观看 国语版| 牧原美奈| 我的瘦子女朋友2上映时间| 《黑土无言》电影免费观看| 怒放之青春再见| 自由的她们免费观看全集高清| 非凡医者| 周弘电影在线观看免费| 哦吼小闪电的真名叫什么| 栋仁的时光| 双龙出手| 千金赤子板栗1985日本| sdde-403| 仙逆73| 妻子6免费完整版| 北非谍影免费| 哇嘎视频在线观看| 伸冤人3 在线观看| 美乃雀在线看| 江照黎明| 陪部长出差| 国王在冬眠在线观看全集电影| 牙医姊妹电影完整版| 非诚勿扰2电影下载| 公之浮手中字40| 亮剑3gp下载| 特殊治疗室6| 高清《年轻朋友的妻子3》| 电视剧说谎的爱人| 启航当风起时电视剧全集免费观看| 李昊石被立案调查| 法国护士长无删减版观看| 朝鲜美女bbwbbw撒尿| xl司令在线观看完整版动漫免费| 古董局中局第一部免费观看| 吴尊演的电视剧| 被义子侵犯BD中文字幕| 建党伟业在线观看完整版| 荣誉电视剧| 战狼6双人免费高清完整版视频下载| 满清十大刑酷翁虹版| 鬼吹灯之天星术国语版| 求求鬼别吃我| 新神榜 杨戬| 她的盛焰未删减| 我才是真豪门:身份互换全集免费 | 人民的名义2在线观看免费完整版| 塔日酒店电影在线观看| 幸福归来电视剧免费观看完整版| 比思论坛东方美人| 我的男人| 义姐不是良妈动漫在线观看| 流浪的青春| 高清杀手记忆 第一季| 上瘾12集未删减| 男生女生一起努力愁愁电视剧免费 | 一波拉病毒2在线播放高清免费| 鬼片电影林正英| 《小叔叔来家做客》电影| 一颗红豆| 《妽妽的丰满大胸》2| 英姿飒爽是什么意思| 《房屋销售员》免费观看| 我只喜欢你电视剧免费观看全集| 凌云志志(法国)满天星 | 钢铁侠3开场音乐| 医武弃少短剧全集| 孟羽童疑似成立个人工作室| 名侦探柯南剧场版国语版全集| 小张帝现场搞笑| 从你的指尖传出的热情| 国乒女团丢冠后马琳缺席颁奖仪式| 《误杀3》电影超清免费观看| 银行家的妻子中语| 电视剧五号特工组第一部| 罗莉星克菜尔电影在线观看| 上甘岭 电视剧| 丈夫的上司来家拜访日剧免费观看全集| 声生不息港乐季免费观看完整版| 《overflower》真人版| 《疯狂农场3》免费观看中文版| 《美丽妻子替丈夫还债》 | 黛比浪漫女教师在线| 女皇之刃| 美国开放酒店2| 密绝1950| 奥林匹克星传| 瓢虫贝贝| 马龙被疑打假球| 中国双航母首同框| 年轻的母亲1观看在线| 法国护士长无删减版观看 | 不良义姐彭禺厶 雷濛| 武动乾坤 电视剧| the亲子伦| 问心电视剧免费观看完整版| 新巴尔虎左旗| 按摩天堂| 天龙八部在线观看完整版免费| 真假学园第二部| 女教师被入侵电影| 和女部长一起出差 电影在线观看| 野兽刑警| 美容院的待遇服务在线观看| 我在开会他在下添好爽在线视频| 公的孚之手中文| 食物链电影完整在线观线| 盲女72小时迅雷下载| 女超人第一季| 余秋雨经典语录| 我的后半生一共多少集| 韩国n房| 郝板丽电影| 小蜜蜂电影| 《激战丛林》电影在线观看意大利| 饥饿游戏2:星火燎原 | 我知道你去年夏天干了什么| 蛇蝎美人百度影音| 初体验2电视剧| 特种使命| 女版战狼10高清免费播放| 高清以猫饲爱未删减| 电影《穿睡衣下楼取快递》| 降头在线观看| 沈丘县| 古川穗香| 谢娜唱哭了| 女销售卖房子视频| 他偏爱我短剧免费观看全集| 雪花红梅飘| 电视诗歌散文| 咱们结婚吧1—6| 《凶器》| 成全高清完整版免费动漫| 天地情缘之绝世天魔| 楼外楼电视剧| 家族荣誉4| 女房客在线观看| 以你的心诠释我的爱有车吗| 我们恋爱吧第6季| 高清《人世间》免费全集 | 巜性刑房3捆绑凌虐免费在线观看| 权力的游戏第一季未删减| 秋瓷炫《生死决断》在线播放| 冰激凌怎么画最好看| 漂亮的女朋友5| 新梁山泊与祝英台| 天堂计划| 天剑绝刀电视剧| 骄阳似我赵今麦电视剧第7集 | 高清《几度夕阳红》| 插曲的痛60全集免费观看高清版校园青春| 变形计他乡有爱| 涩屋屋| 终极证据电视剧| 月光光心慌慌7| 色既时空| 世界大战100年全程实录| 《家庭矛盾》melody电影免费观看| 神断狄仁杰第二部| 命中注定我爱你免费观看| 李梦:张隆每个月都有按时付钱| 需要爸爸来播种免费观看| 国王的勇士3| 《性解密》电影完整版 -免费国语手机在线观看 -将军影院 | 西游记大闹天宫电影| 需要爸爸播种在线观看免费| 侠盗飞车圣安地列斯热咖啡| 战狼9免费高清版999| 范冰冰 电影| 会说话的安娜| 电影美容院的特别待遇| 与外婆同行| 四个男人要轮流练瑜伽是什么电影 | 秦腔戏mp3下载| 豪门弃妇:翻身成商业女王全集免费| 高清《借钱》韩剧| 韩国电影 好姑娘干 在线观看 | 金惠秀老千| 女虐女胯下变态调教| 济公之神龙再现| 波野多结衣种子下载| 新年歌曲dj| 《需要爸爸播种子2》演员全名 | 朴雅珍演过的蓝色帽子| 朋友的妈妈1| 三年国语版高清在线观看| 女大学沙龙| 信仰1—42集免费观看视频播放| 酒店1—60集全集免费观看高清| 日本电影部长来做客中字| 美食的俘虏146| 《卖房子的女销售》台湾| 奔跑吧玫瑰韩剧国语版免费观看 | 越战先锋在线完整版观看| 电视剧火蝴蝶| 女按摩师3| 向幸福出发主持人刘心悦| 北京高院工作报告点名吴亦凡案| 电影《小王子》中文版| 黑白配HD中文版在线观看| 丫丫预计今日返京| 想爱就爱2.5| 《maruzzella》完整版在线观看| 世界奇闻怪事图片| 文豪野犬第五季免费观看| 长津湖之水门桥| 巴啦啦小魔仙之彩虹心石11| 女超人麦乐迪无删减版在线| 很想很想你| 机动奥特曼 第三季| 坎贝奇在线| 最后的99天在线观看| 模特参赛宣言| 一个妈妈的女儿第二集| 灿烂的花园综艺免费观看高清| 《法国空乘5》电影免费观看| 电影十日谈| 家教高级| 赤子板栗牙医姐妹日本电影| 龙三和他的七人党| 蜀山奇侠之仙侣奇缘全集免费观看| 赤身跳舞全集免费观看| 《斗罗大陆》免费观看在线观看高清| 《花子vs倔强驱魔师》第1集| 斗罗大陆第二季全集免费观看完整版 | 镜双城电视剧在线观看网站| 特殊的治疗室| 爱很美在线观看完整版| 六人行中英文字幕| 爸爸的种子高清免费版| 黑暗荣耀2无删减韩剧在线播放| 宛如我心| 圣特罗佩1982完整版| 赵本山相亲2下载| 钻石王老五的爱情| 刚结婚陪部长出差在线观看| 迷人的保姆高清线观看| 甜蜜惩罚 我是看守专用宠物第3 | 李卫当官第二部高清| 我想和你好好| 女搜查官穿皮衣天海翼| 绝对权力电视剧全集完整版观看| 危情少女| 《性的暴行》在线观看| 陪安东尼度过漫长岁月百度云| 李梦出轨| 炸天小姐电影星辰影院| 超级碗中场秀| 家门的荣光分集介绍| 白峰601在线观看免费版电视剧大全| 中业岛地图| 《水润人生》刘智贤| 年轻的保姆5线观高清多鱼| 安姨《房屋售楼员》播放| 文章孙兴最新电影| 魔术奇缘电视剧| 电影《觉醒年代》| 我爱张宝利国语版全集| 将界2第5酒店真人| 半妖的夜叉姬在线观看| 小学生高清电影免费观看| 徐少强新版金银瓶2008第2集 | 二十一世纪爱情指南电影| 人生没有原谅短剧免费观看| 河南电视台法制频道今天7:50| 姐妹医生在线观看| 电影心灵奇旅| 朋友的姐姐4线在完整中字| 怦然心动20岁第三季| 哈尔的移动城堡免费完整版| 丁巴度电影在线免费观看| 苏文茂相声全集| 二次曝光迅雷下载| 女保险公司推销员8| 无影灯下连续剧全集免费播放| 弃女归来:家产我来拿短剧全集| 甄嬛传免费版| 手足兄弟短剧| 木下檩檩子电影免费观看中| 水咲萝拉白妖精| 归棹电视剧| 台湾版《棘手狂情》香港电影| 姐妹牙医赤板栗完整版在线播放免费| 西游记 续集电视剧| 金瓶爱的奴隶| 天使多美丽| 谎言与间谍啄木鸟2剧情简介| 喜来乐传奇| 比利·林恩的中场战事| 年轻的保险销售员8| 无贼剧情介绍| 回旋蛇球| 黑巨痉大战饿罗斯美女| 八戒满十八全集免费看| 招摇电视剧免费观看全集完整版| 解冻韩国电影| 韩国好姑娘免费视屏播放| 洛城疑云| 钦州市| 封神榜电视剧免费观看完整版| 寒战2电影| 美容店的特别待遇5中字主演| 甄嬛传第57集| 花与蛇全集| 斗罗大陆2在线观看免费高清| 《替夫还债》高清完整版| 法医宋慈 电视剧| 秦总夫人| 倔强的驱魔师无删减在线观看 | 梅花三弄水云间| 圣特罗佩姑娘们免费观看| 法国空乘2019满天星法版完整版| 财阀家的小儿子11| 葵花宝典未满年龄确认请离开司马光| 楚乔传第一部免费观看全集完整版| 八妻子影秋在线| 战狼9欧式少女办| 女老师2| 猫鼠游戏电影| 美容院的待遇8免费观看 | 《外卖员的特殊待遇》演员 | 幸福的出租车| 张警官第一集在线观看 | 97影院在线观看免费播放电视剧大全 | 和喜玉兰完整版| 妈妈的职业免费电影| 高清《葬送的芙莉莲》| 丫头5| 巴基斯坦电影| 歌手在线观看免费完整版| 搜神记动漫免费观看完整版国语| 武驰人生萧战短剧免费观看高清| 斗破苍穹缘起在线观看| 我的漂亮妈妈8中字开头7个字答案 | 喜盈门电影| 还珠格格第一部1一24集| 我的好兄弟的女朋友| 《有翡》全集在线观看| 西藏锅庄| 《罗丽星克迷宫》免费观看| 化骨龙与千年虫粤语| 老电影歌曲| 《玛丽玛丽》满天星| 古惑仔4下载| 小姨多鹤| 菲律宾电影《兽行》的剧情简介| 县委大院电视剧免费播放| 花木兰电影| 电视剧第二十二条婚规| 一愁愁电视剧免费观看完整版| 美国式禁忌19| 金银瓶1-5hd普通话水蜜桃2 布隆迪| 六盘水最高峰| 善良的老师3完有限中字木瓜| 白夜破晓全集免费播放| 坏性:被强奸的妻子2| 金瓶梅全集观看完整版| 最新港剧| 女职员的付出5中字在线| 白月梵星全40集免费观看完整版| 盲爱千金短剧全集免费播放| 超级教师3免费观看全部电视剧| 《家庭矛盾》完整版麦乐迪| 先生我可以上你吗2高能片段| 动感之星之妖精168集全集| 水落石出第一部| 生死线电视剧全集免费观看完整版| 坎贝尔《人生无憾》在线播放 | 越狱第三季| 午夜十二点高清完整版免费观看| 地铁迷情| 独家记忆评价| 牙医赤子板栗完整版在线观看 | 胡慧中电影| 英雄本色免费| 伦理我的厨房岳母在线观看| 红场特警| 索多玛的120天| 特殊保险推销员中字8| 老友记第九季| 高清聊斋:兰若寺未删减| 高压监狱2无删减1080P| 短剧在线观看免费全集| 冰冷长街| 永兴县| 怪奇物语第一季免费观看| 加勒比海盗5 死无对证| 阿尔涅的事件簿全集观看| 俘虏之锁未删减版在线观看| 难寻电视剧免费观看全集完整版| 查泰莱夫人的情人电影| 三级片替夫还债的家庖妇女| 邻居的老婆在线| 新版金瓶梅在线观看| SSSxxxx美国666| 朴妮唛迅雷种子| 不再说分手| 卢旺达的玫瑰电影在线播放 | 一九四二年电影完整版免费| 日本金银1—6| 玉蒲团视频在线观看免费视频| 动漫烟花| 粉色大白菜法国原版| 两个女人喜欢我韩剧在线播放| 保罗1一4| 一起长大 电视剧| 寻龙诀电影完整版下载| 紫川之光明王免费观看| 2008金瓶梅在线观看| 滚蛋吧肿瘤君| 也曾迷茫也曾彷徨是什么歌| 双人高潮按摩在线观看免费高清版| 七日情电影| 大小谎言第一季完整版在线观看 | 你好树先生| 某科学超电磁炮s| 韩剧结婚是疯狂的| 魔道祖师第三季在线观看完整版| 刘浮生全集免费观看| 内衣销售员的秘密| 龙争虎斗| 灵魂之音| 女飞行员(法国)满天星女版2011在线观看 | 绿草地电影| 黑衣人小方| 女版西游记大波唐三藏| 有效期限爱上你| 人民公社大食堂| 3对1初次体检4| 又见一帘幽梦优酷| 危情在线播放| 婚纱 韩国电影| xl司令第一季全集在线观看无马赛克影视 | 17·3电影高清在线观看| 黑玫瑰 电视剧| 狂飙电视剧免费完整版| 异族通婚| 美国式禁忌1~4伦理灭火宝贝 | 电影《便利店相泽南》免费观看 | 出差遇见渣男前任完整版| 功夫梦:融合之道未删减| 宝洁回应香皂嵌刀片| 《黑暗森林》莉娜安德森| 减肥工具| 《功夫熊猫2》| 敌人英语| 四大名妓三意影院需要爸爸播种| 世上只有妈妈好电视剧全集免费| 少帅传奇48集电视剧| 麦乐迪马克斯女超人免费观看| 飘雪网在线观看免费完整版| 斯诺克虎牙4| 麻豆《维修艳遇》在线| 天魔异种| 明月照我心电视剧免费观看| 圣特罗佩姑娘们完整版在线观看 | 电影《渔夫的妻子》赛纶| 僵尸世界大战超清版| 七号房的礼物在线观看| 客户名单电影| 麦乐迪家庭矛盾是哪部电影 | xl司令在线观看全集免费| 武驰人生萧战短剧免费观看高清| 鹰眼黑寡妇| 3d肉下载| 成全动漫免费完整版高清| 我和僵尸有个约会1粤语在线观看 回复术士的重来人生在线观看 | 女人的战争 卑劣的交易| 乌云之上电视剧全集剧情| 五感图下载| 插曲的痛30全集| 替天行道之杀兄电影高清完整 | 中餐吃什么好| 新三国全部95集免费| 天涯女人心电视剧| 不良义姐免费看真人版| 赛车总动员1 QVOD| 反恐电影《沙漠》| 《维修人员的培训》| 初恋限定第二季| 美猴王动画片免费观看完整版| 《似火流年》| 色情电影瓜达卢佩的玫瑰| 林志玲坠马碎胸| 限制别人网速| 娜娜米什么梗| 死神来了8在线观看完| 晚娘罪色| 迷人的保姆| 祁阳县| 2019商务旅行女老板戴的帽子经典电影| 高清沧元图 前传:东宁府的夏天 狂飙电视剧全集免费在线观看 | 孽海花传奇| 草灯和灯电影完整版| 黑发尤物舞蹈教学| 花的勇气ppt| 同学的母亲中字ID英文| 隋唐英雄3全集66集| 小炸jackson| 美式禁忌保罗1982| 哇嘎电影高清完整版免费看| 陆贞传奇7| 爱我几何电影完整版高清免费观看| 变形金刚4绝迹重生完整版| 数字追凶第一季| 维生素love水香| 妻子替夫还债| 非诚勿扰 小德| 欢乐白领夫妻| go电影免费观看国语高清| 麦乐迪和父亲的电影名字 | 老婆6免费完整高清电视剧| 再见爱人第四期在线观看| 黑白森林国语| 薛刚反唐电视剧全集65集| 哇嘎哇嘎高清在线观看| 夫妻成长日记下载| 韩版花样男子国语版| 暴躁46集在线观看电视剧免费全集| 史上最窝囊丈夫| 情欲电影| 黑暗荣耀第二季在线观看免费 | 卓君最新机械舞| 白蛇传说粤语| 让儿媳妇变成花痴第二季剧情简介| 无法忍受的日子| 老电影庐山恋| 华夏人寿怎么样| 法国空姐第五季国语版免费观看 | 《法国空乘2》免费观看全集 | 漂亮瑜伽4在线观看| 丈夫的陷阱| 《斯巴达2帝国女版》在线| 做aj的电视剧大全国语竖版 | 木下檀檩子电影在线观看2023年上映时 | 三上悠亚《最高の爱人诏》| 妖精的尾巴02| 魔幻情劫| 中华之剑电视剧全集免费观看| 无憾坎贝奇观看电影| 大侠黄飞鸿| 决不饶恕| 勿忘仇敌| 《她被搬运工侵犯》在线播放| 谁能百里挑一20130427| 一路向西 百度影音| 《唐诡奇谭之九重楼》| 甜蜜惩罚第二季台词无马赛| 英格兰VS伊朗直播| 家国两难全| 白发皇妃电视剧| 丈夫上司装饰品的妻子演员表| 白魔女学园| 花田喜事2010粤语版| 美丽的桃子美国版5娃娃脸 | 做aj的电视剧免费观看大陆 | 二婶电视剧全集| 哇嘎嘎电影免费播放 | 《特殊的房租》中文| 涂了春药被一群人轮爽翻天视频| 亲爱的热爱的第二季| 法国空乘4不乘空雅| 年轻的姐夫免费看| 照亮你电视剧免费观看星辰影视 | 梨花似雪| 360天爱上我| 说英雄谁是英雄免费观看| 远离人群的地方| 甜蜜再恋第二部全集| 替夫还债的电影完整版中文字幕| 电视剧乌云之上在线观看| 触及真心| 满天星版风女管家2008| 火龙对决| flypaper百度影音| 宜昌保卫战电视剧| 哇嘎全集免费看| 口红森林| 谢娜官方工作室发文道歉| 爱情公寓1 下载| 《她被搬运工侵犯在线观看| 朋友的姐姐在线观看| 镜双城电视剧免费观看全集完整版| 甄嬛传高清在线观看免费完整版| 法国《古墓丽影》在线观看| 小时代3在线观看| 湘北曾姨百家号| 酋长之女2:狂飙2| 法版《执行秘书》在线观看| 美国派1电影| 小黄飞斯卡拉| 不离婚的男人完整版|