久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4638|回復: 14
打印 上一主題 下一主題
收起左側

uCOS-III學習筆記

  [復制鏈接]
跳轉到指定樓層
樓主
ID:7209 發表于 2021-2-19 20:43 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
為什么要學習這個ucos ii  
在單片機的世界里翱翔了好多年,
一直覺得無所不能、無所不會鄙視一些應用層的開發,
輕示一些軟硬都好搞一點的過去,
直到遇見你 ucosii 或你的好兄弟iii 我從沒有如此卑微的如此靠近過。
你是來團結這些”地方武裝勢力的”真真為社會主義事業而奮斗終身的。
崇拜了無數大嬸,還是俺叔給我說 “ 算法” 才是 ----葵花寶典
   但有天碰到一個“事情”需要兩個或三個或更多個家庭來合力完成一項工作的情況下;
 比如“苦逼的程序員終于要結婚了”這就需要二個最最重要的兩個高級任務你和你老婆、
 兩個稍低一點的有可能存在“翻轉任務優先級”的情況影響你和你老婆的任務執行的”任務” ,
 (其實我想說的是彩禮可能把好好的任務給攪黃,相當于最高級別的優先級丈母娘,一票否決權
  --- 如果最早你在進行任務留有debug 的話,這些都是小菜---你懂的)
 還需要一些處理各種額外的功能任務。
   如果是單片機的“世界中”這樣的情況下需要先初始化了
  老婆的“包括找到老婆+熟悉老婆各種配件+熟悉她的各種關系”,
  初始化娶老婆的各種條件”買車+買房+買家具+++++”,
  初始化婚禮的各種瑣事,初始化她父母+你父母的各種要求;
  最后的循環執行就是你和你老婆結婚+重復瑣事+賺錢+養育孩子+照顧父母+孩子結婚+自己老去,
  最后你的主函數終于運行完畢。
  這里可能有些初始化條件不合適還有可能會出現#if………#else……….   //重新選擇老婆
也可能會出現
Do{………..}while(條件) //試婚
也可能會出現
Delay(10year);  //  //延時
也可能會出現
While(各種可能情況)
{…………..};  //這里就是一個牢籠直至…………
最危險的不能進入“迭代的” 的循環中,
一旦進入后果無法設想
思想指針可以來回游走
可別忘記自己的類型和安全返回
否則很容易帶回的是錯誤的數據和丟失自己,
損壞主函數的生命周期
“忒復雜了為了結一個婚這大工程還是給了系統好把”
系統是如何來處理
建立幾個任務
任務一負責各種婚前準備
  任務二負責老婆家各種需要準備工作
  任務三負責各種意外情況處理
  任務四負責……..
  任務五負責……….
  任務六…………
這樣是不是稍微輕松一下,但是也不是最輕松的
系統給設定好了各種格式
現在的社會你只需要有錢就可以了

Ucos  ii  -----   iii    也一樣

感覺好幸福
有中馬上見到美麗賢惠聰明可愛的 新娘子
流會兒口水了

評分

參與人數 2黑幣 +62 收起 理由
gracture + 12 贊一個!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂2 踩
回復

使用道具 舉報

沙發
ID:7209 發表于 2021-2-19 21:57 | 只看該作者
首先,第一個要解決的問題是,
為什么我們需要uCos?就像最開始學C編程時,師傅告訴我們,指針很重要,那時你肯定有一個大的疑問,指針到底有什么好?
心里一直犯嘀咕著:不用指針不一樣把程序編出來了?  現在想想看c語言沒了指針,是不是寸步難行呢。回到正題,我們到底為什么需要uCos?

一般的簡單的嵌入式設備的編程思路是下面這樣的:
int  main ()
{     //初始化各種外設
    //初始化各種時鐘
    //初始化IO 口
   
  while(1)
  {
    {處理事務1};
    {處理事務2};
    {處理事務3};
        .......
    {處理事務N};
   }
}

void  shijian1 ()
{}
void shijian2()
{}
void shijian3()
{}

isr_server
{
    {處理中斷};
}

這也是我們在51、 STM32、AVR、stm8 中最常用的形式
這是最一般的思路,對于簡單的系統當然是夠用了,
但這樣的系統實時性是很差的,
比如“事務1”如果是一個用戶輸入的檢測(掃描按鍵是否有按下),
當用戶輸入時,
如果程序正在處理事務1下面的那些事務,
也就是在處理任務2 后任務3 后任務4。
那么這次用戶輸入將失效,
用戶的體驗是“這個按鍵不靈敏,
這個機器很慢”,
而我們如果把事務放到中斷里去處理(我們把按鍵掃描放在中斷函數里面),
雖然改善了實時性但會導致另外一個問題,
有可能會引發中斷丟失,
(這里我沒有想明白 按鍵掃描在中斷里丟失 是不是順序掃描0-9個按鍵
當掃描到按鍵8 ,而這個時候 我 按得失2,
如果中斷掃描足夠快的話,應該也很快就可以掃描到
)
這個后果有時候比“慢一點”更加嚴重和惡劣!
又比如事務2是一個只需要1s鐘處理一次的任務,
那么顯然事務2會白白浪費CPU的時間。
通篇想說就是 “實時性不夠好”





評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

板凳
ID:7209 發表于 2021-2-20 16:28 | 只看該作者
下面不是重點
  有些書會介紹(前后臺系統   +  實時內核)都是用于處理實際工業具體問題的軟件編程方法,
  前后臺系統結構: 就是一個死循環和若干個中斷服務程序
中斷用于處理系統的異步事件(前臺)
相應函數完成相應的操作(后臺)
這其實和我們平常寫的一樣,主函數+應用函數+中斷,只不過我們沒有給他起名字而已。
這樣做的有一個弊端也是書上說的,后來我想想也對啊
如果中斷時前臺――― 
 為了保證任務得到及時處理,
 哪些本該在任務中執行的關鍵代碼必須放在,中斷里執行。
 (就是為了得到及時的響應)
 想想中斷到可以及時處理特定的數據并且更新
而任務或應用程序是不是能立刻更新吶???
這個真未必能夠及時執行。
比如:
一個項目是這樣的定時開燈或關燈+WIFI 通信 + 時間屏幕顯示
更新時間功能我們放在中斷里
當進行WIFI 通訊 時
即時我讀取到了時間改變了,但是現在沒有切換到
屏幕時間顯示,是不是也不會更新顯示時間數組
(這個說法有些澀)
生活的例子:
現在需要燒水(設定一個時間)+看閨女
看閨女就是中斷里的代碼
燒水開了沒有開,只有看2分閨女――― 去看看時間或水―――
燒水時間是一值在走并且水一直在升溫
而作為主循環中每走幾分鐘才查看一回,而且這個查看時間還不固定
閨女哭了、閨女不讓走、閨女要吃奶粉
這些在中斷中都需要立即執行的
中斷里――只有聽見水壺鳴叫或時間到
才去處理燒開水灌進水壺里的動作
有個說法 “任務級響應延遲”
實時內核:(ucos)
用于管理控制器、微處理器的時間及硬件資源的軟件代碼。
忒重要了這句話,就是通過管理控制器的時間來控制硬件資源的軟件代碼;
通過把一個大的項目分解成為幾個小的任務或叫線程
分配單片機的時間來間隔運行任務 1、2、3、4、5
每個任務都是的
while(1) { ;;;}這樣的死循環
實時內核--- 相當于家長來負責管理這些任務的運行時間、運行順序;

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

地板
ID:7209 發表于 2021-2-20 16:54 | 只看該作者
重點一句話:    ucos是用約70多個新函數形式為應用程序代碼提供服務的。   這句話也是書上的,相當于學習“c 語言中的 頭文件函數”;   我們想 用 vc6.0  在屏幕上輸出 字符 是不是要用到printf() ,   而用到這個函數是不是需要 #include <stdio.h>   想輸出時間 是不是需要 #include <ctime.h>   學習細節---( 時刻把握整體  我們 wifi.c + LED.C + KEY.C               都寫好了,并且放在一個工程中了, 調用一下系統函數              來協調外設給我老實工作否則,              在現在的 while(1) {} 死循環中,一樣也能干掉你這個線程)   不畏懼困難。 還有這個線程就是任務就是一個函數實現一個功能。

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

5#
ID:7209 發表于 2021-2-25 16:23 | 只看該作者
從總體上理解一個事物
從總體上看待一個人
從總體上學習一個技能
這個總體很重要,比如學習ucos  iii 或 ii
其實如果從總體上說沒啥大的區別
可也不能說沒有區別  
先學會一個在說 III 和 II 都是個浮云
先白話幾句  下面都是聊天
如果計劃作一件事情是不是先在腦子里思考一下這個事情的大概,
如果有老婆的話是不是需要和老婆商量一下,如果商量好了或自己決定了這件事情;
就相當于 建立了 “任務” 現在建立了任務
    這個任務可能是一個 “看電視的閑任務”
也可能會遇到更緊急的任務 “只好刪除這個任務” ( 更緊急的任務是優先級)
還有可能 “在開始操作這個任務的時候先掛起這個任務”(就是先記下來不執行)
頂下來的無論學習任務還是找老婆的任務一旦定下來就必須要有回應
哪怕是 個“空任務”什么也不做; 也要對他有定義有設置。

人生就和這個很類似
china main()  //中國出生  也就是建立了任務
{
   father_init(); // 父親初始化
   mother_init(); // 母親初始化
   house_init();  //房子初始化
   while(1)
   {
     幼兒() ;  //
     小學 ();  //
     中學 ();  //
     高中 () ; //
     大學 ();  //
     工作 ();  //
     組合家庭 () ; //
     生活 ();  //
     孕育新生命 ();  //  ------------------   china main()
     50_year(); //                            {  ;;;;;;;;
     60_year(); //                              }
     70_year(); //
     80_year(); //
     90_year(); //
     over_game(); //      
    // 刪除任務本身 (); //
     // 每個人沒有 return
     //
   }
}
-----------------------------------------------
china main()
{
   //
   OSInit(&err);    //  各種適齡婚前的必要條件

   OSTaskCreate("new_family");  // 創建一個新任務 創建新的家庭

   OSStart(&err);   //這個開始任務有些 “農村分家的意思”   

  }

static void new_family()
  {
      //各種初始化兩個人新家的準備
     //各種初始化條件

     OS_CPU_SystickInit();   //時鐘 控制一個家庭的節奏
     Mem_Init();    //初始化家庭的內存空間

    CPU_IntDisMeasMaxCurReset();  //復位清 零當前最大 夫妻吵架互相不搭理的 最大隔閡時間
    //其實這里 不寫函數名字好一些
    //提前給大家提高了  困難  指數

// ( 只看注釋也可以)

     OSTaskCreate( " father_taks");    //

     OSTaskCreate( " mother_task");    //

     OSTaskCreate("  girl_task");     //

     OSTaskCreate("  son_task");      //


     OSTaskDel("&newfamily ,&err");  //刪除開始任務
   }



void father_task1()
  {          }
void mother_task2()
  {          }
void girl_task()
   {              }
void son_task()
  {                }

主要任務就是這四個方面還有別的比如 :

  給父母養老_task ();   // 其實這個也是應該添加在任務里的
在往后的 幾十年里 這四個任務會 按照一定的 "cnts" 或 Systick  系統時鐘穩定運行

  我們是生活在一個連環的任務中,我們是父母的任務也是自己的孩子的任務,
  這要在C++ 上是繼承和被繼承的關系是類和派生類的關系
  在 代碼中我們就是一個任務,一個家庭是一個大任務;
  丈夫_apptask();
  妻子_apptask();
  孩子_apptask();
  閨女_apptask();
  分工不同,需要完成的任務也不同
  但是在 社會這個大循環中個體所賦予的任務大同小異
  分工不同造成實際需要完成的工作也不同
  比如:father_init() ; 這個初始化函數中就必須表現出掙錢的特征,
     或者說以這個為主要任務
  //其實也就是下面的 括號里的 具體名字 ,叫法不同 我覺得來表示人生還是很像的
(  III 將學習 任務 --- 任務時間片運行 --- 閑任務和阻塞延時 --- 時間戳 --- 臨界段
  --- 就緒列表 --- 優先級 --- 時基列表 --- 時間片 --- 任務掛起和恢復 --- 任務刪除



評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

6#
ID:7209 發表于 2021-3-1 21:40 | 只看該作者
下面繼續閑聊,
  經過幾個片斷聊天理解ucos  也是不現實的。
  如果是趙大爺的話就是 “話療”,
  通過談話的 方式來理解明白我們需要掌握的東西.

  剛開始學習ucos 時也是膽戰心驚苦悶無比,
  搞不懂為什么有些通俗易懂的知識非要寫的那么高大上
  難以理解。
  現實社會這個大循環中,人們是圍繞 “錢” 在轉,
  無論多少個家庭、個人都無法離開這個 最基本的 生存需求,
  不圍繞錢來 轉的 我只能想到 “佛” “道” 界,
  這些如果在 ucos 系統中,我理解應該就屬于 "空閑任務" 沒有這些任務是不行的。
  ( 社會需要這些精神上的知識)

  既然 社會 是圍繞 "錢" 這個最基本的目標在運作,
  那么 在ucos 中 有沒有 也有一個也圍繞 “靶點”而運行?
  通過學習 知道是有的;
  這個 點就是 “時鐘”--- Systick --- 類似---心跳--
  在ucos 系統中也是圍繞這個和錢類似的  "點" ,
  讓任務來有條不紊的運行,  沒有他行不行,萬萬不行。
  在學習單片機的時候也有 51、avr 、stm8、stm32、PIC。
  這些都是需要時鐘的;
  現在32 特別火 就已32 來說吧!

下面不是閑聊需要理解的  
  stm32 中有一個SysTick定時器 他是一個24位倒計定時器,當計數到 0 時,
  則從reload 寄存器中自動重新裝載定時器的初值,并開始新一輪的計數。
  這個定時器是24位
  這個定時器是倒計時(比如 從1000減到0 , 1000 就是初值 )
  當遞減到0 時就有從 reload 寄存器中重新加載初值
  這個初值最大是多少 24位 = 0xffffff = 0b1111 1111 1111 1111 1111 1111
  2^24 = 等于多大的數值 =  16777215
  一般我們也沒有用這么大的,這是可以加載的最大數值
  也就是數 數字來 cpu 也要倒序 減 - - ;
  在 ucos 中使用systick 來計數,作為 “系統時鐘節拍”
  一般這個節拍是固定的用 OS_TICKS_PER_SEC 這個標志來定義了
  OS_TICKS_PER_SEC = 200 也有的 = 500
  理解大概意思就行,知道有這個標志
  為什么 ???


  下面是 delay_init();
         delay_ms();
   兩個函數 ,第一個初始化 系統時鐘 開啟SYSTICK
   第二就是在有個別任務中需要用到的延時函數


//初始化延遲函數
//當使用OS的時候,此函數會初始化OS的時鐘節拍
//SYSTICK的時鐘固定為HCLK時鐘的1/8
//SYSCLK:系統時鐘



/***********************
要說清楚還需要進入這個延時函數初始化中來
這個函數最重要的功能是給
fac_ms fac_us賦值
如果是ucos 話進入這個函數
而且這個函數還必須在沒有進入中斷中來初始化
void delay_init()
{
#if SYSTEM_SUPPORT_OS                                                          //如果需要支持OS.
        u32 reload;
#endif
                //選擇外部時鐘  HCLK/8
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
//這里選擇外部時鐘原 也就是外部的 8Mhz
//經過倍頻后 時鐘 = 72mhz = 72000 000

        fac_us=SystemCoreClock/8000000;       
//這里計算 出 延時 微秒的倍乘數值
        //為系統時鐘的1/8  
// fac_us = 72000 000 /8000 000
        //fac_us = 9       
        #if SYSTEM_SUPPORT_OS                                                          //如果需要支持OS.
        //72000000/8000000 = 9
        reload=SystemCoreClock/8000000;                                //每秒鐘的計數次數 單位為K          
        //      = 72000 000 /8000 000
        //  reload = 9;
        //--------------------------------------------
       
        //      = 1000 000 /200
        //      = 1000 0 /2 =5000
        reload*=1000000/delay_ostickspersec;                //根據delay_ostickspersec設定溢出時間
        //reload = reload * 1000 000 /200
        // reload = 9 * 5000
        // reload = 45000     
        // 設定LOAD 寄存器的最大值
        //就是從45000 開始遞減
       
        //reload為24位寄存器,最大值:16777216,在72M下,約合1.86s左右       
       
        //--------------------------------------------------------
       
        fac_ms=1000/delay_ostickspersec;                        //代表OS可以延時的最少單位          
  // fac_ms = 1000 /200
  // fac_ms = 5       
        //設定 延時毫秒 倍 乘值
       
        //+++++++++++++++++++++++++++++++++++++++++++++++
       
        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;           //開啟SYSTICK中斷
        SysTick->LOAD=reload;                                                 //每1/delay_ostickspersec秒中斷一次       
        //這里 LOAD = 45000
       

       
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;           //開啟SYSTICK   
          // 啟動嘀嗒定時器

#else
       
        fac_ms=(u16)fac_us*1000;                                        //非OS下,代表每個ms需要的systick時鐘數   
         // 9*1000 = 9000

#endif
}                                                                    

********************/


我貼過來這個delay_Init(); 延時函數初始化是因為在有些任務中,
需要用到 delay_ms(); delay_us();
//延時nus
//nus為要延時的us數.
//比如                                                                                       
void delay_us(u32 nus)
{               
        int ticks;
        int told,tnow,tcnt=0;
        int reload=SysTick->LOAD;                                        //LOAD的值                     
        // reload = 45000
       
        ticks=nus*fac_us;                                                         //需要的節拍數                           
    //這里假設 nus = 10
        //ticks = 10*9
        //這就是需要減 90 次
        //也就是 要從45000減到
        //        44910 就到了延時時間
        // 90 = 0x5A;
        // 90 就是 從 45000 減 到 44910

       
        tcnt=0;
        delay_osschedlock();                                                //阻止OS調度,防止打斷us延時
        told=SysTick->VAL;                                                //剛進入時的計數器值
        // 這是剛進入ucos 的最大值
        //
        while(1)
        {
                tnow=SysTick->VAL;       
                //得到現在的的嘀嗒時鐘的計數 值
                //如果現在的值不等于 最初進入的計數值
                //
               
                if(tnow!=told)   //進行比較
                {            
                        //這里注意一下SYSTICK是一個遞減的計數器就可以了.
                        if(tnow<told)   
                                //如果現在的計數值 < 剛進入的計數值
                                  tcnt+=told-tnow;  //微秒延時使用這個來計數判斷
                          //tcnt = tcnt+told-tnow
                          // 1000 = 1000 +2000-2000
                          // 7998 < 8000
                          // 0 = 0 + 8000 - 7998
                          
                        else
                                tcnt+=reload-tnow+told;          //ms 延時使用這個來計數
     // tcnt = tcnt +(reload-tnow+told)
     // 0 = 0 + ( 45000 - 1000 +2000 )
     told=tnow;
                        if(tcnt>=ticks)break;                                //時間超過/等于要延遲的時間,則退出.
                }  
        };
        //這個 while(); 等待函數
        //就是經過 不停的
        //tnow = tnow -0x14
        //每次循環一次就減20 個計數
        //直道tcnt = 6D
        //這個時候 大于 6D> 5A
        //就直接退出了定時
        //這里還有個發現就是 實際上定時 us= 10
        //多計數了 19 個計數
        delay_osschedunlock();                                                //恢復OS調度                                                                            
}
//通過不斷的循環仿真還是有好處的
//特別對初始化函數 ucos 啟動可以很好的理解
//啟動是如何運行的
//這個是有些復雜的啟動嘀嗒時鐘情況
//在有的代碼中只是啟動了 systicks 使能了一下
//這里復雜就是有 延時函數 并且是不允許中斷的延時
//還有就是 延時是有范圍
//以前可能沒有注意到這些
//在就是 野火的代碼在 啟動嘀嗒定時器的函數中是有錯誤的
//SystICK->CTRL| = 0X07; 在實際代碼中不是這樣寫的
//但是 他計算后的情況和上面類似
//這就造成有些位設置不對
//會出現設置過后不能起到作用
//我也是看到有網友碰到了這種情況
//



評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

7#
ID:839835 發表于 2021-3-2 15:22 | 只看該作者
很好的文章
回復

使用道具 舉報

8#
ID:7209 發表于 2021-3-4 20:21 | 只看該作者

謝謝鼓勵
  delay_ms();
   delay_us();
  delay_Init();
  這三個函數 感覺沒有 說明白
  這幾天一直在 想如何在 補充一下
  我的想說的 是
  1  ucos  中的時鐘節拍 是如何 算出來的
  2  在任務中如果要使用 delay_ms(); 是如何使用的 他是如何工作的
      2 -1   還有就是 本來 備案中有 程序一步一步是如何 運行的  可 想 不好 最好的表達方式
  
回復

使用道具 舉報

9#
ID:7209 發表于 2021-3-16 21:22 | 只看該作者
ucos 的任務想了好幾天
   也寫了些稿子,總覺的都不夠能清楚簡單明了的說明這個任務
   任務在書上說了很多,包括一些視頻分了好幾段來說明
   而我又想不依靠書上了語言來說書上的知識
   這就造成好些“歪理邪說”很有可能誤導一些知識點的解釋
   
還是開始吧
   任務可以理解 --- 生活中的一項任務比如燒水
                                    比如洗菜
                   比如 炒菜、比如洗衣服、比如吃飯、比如收拾屋子都是在家庭內
                   圍繞特定固定地址 的活動
   這些活動 可以允許 顛倒 順序
   
   這些活動 也可以 根據需要切換 先后
   
   這些活動 也 有 必須立即執行的 中斷任務  
     比如 水開了
     比如 12點了 必須中斷一切別的活動 先 吃飯在說
         
   
   這些活動也 可以 同步一起做
       比如洗衣機洗衣服的時間內可以做飯
       洗衣服的時間內可以拖地
       這好像任務同步了是不是???

   這些活動是誰來安排先后順序?
    一般有一個當家的老婆媳婦女朋友來安排
    如果是一個沒有返回的單身漢就好比一個
    一家總要有一個說話算數的
    一家總要有一個來協調安排先做啥在做啥的
    一家總要有一個 “總管” 的
    void main("有繼承沒有子類的函數")
     {
      //0
      //1
      //20
      ......
      //110
      ......
     //活夠了                        
     }                                       

    //想想就悲哀
   這些活動 還有一些 比如需要燒水 但是現在水瓶內還是滿的
                     比如每天需要拖地 但是現在地板還很干凈
                     比如需要做飯 但是你或你和媳婦都不餓
                     這是不是就相當于 有需求 但是先掛了起來不執行

  先說 一家的 “ 總管” 吧!
  她   --- 是如何管理你和你的家的
  她   --- 是如何給你分配干活的工具的
  她   --- 是如何給你分配先干啥后干啥的
  她   --- 是如何給你劃的道道的

  在實際應用程序設計中,通常需要把握完成的工作分成多個任務
  每個任務只負責一項工作
  一個任務是一個 “線程”(計算機離不開叫線程的)
  實際上早期只有一個CPU
  某刻只能做一個任務
  ucos 支持多任務管理
  允許有無數個任務
  但是一般受限CPu 和存儲器的容量
  
  多任務其實就是多個任務間的切換和調度
  在任務相繼執行過程中
  CPU 的使用權在任務間切換
  
  創建后的任務函數是這樣的
  
  void Task_task1(void* p_arg)
  這里我想說的是
  void *p_arg
  這和在普通函數的形參一樣
  這個參數是 void 型指針
  該指針是一個通用的指針變量
  可以向任務傳遞一個 “變量地址”
  傳遞一個結構體
  甚至 傳遞一個函數入口地址


   生活中我們處理一個大問題的時候通常都是將這個問題“分而治之”,
   把大問題分成多個小問題,
   小問題被逐步的解決掉,
   大問題也就隨之解決了。
   那么這些小問題就可以看成是很多個小任務。
   
   在我們設計復雜、大型程序的時候也是一樣的,
   將這些負責的程序分割成許多個簡單的小程序,
   這些小程序就是單個的任務,
   所有的小任務融洽的工作,
   最終完成復雜的功能。
   在操作系統中這些小任務可以并發執行,
   從而提高CPU的使用效率。
   
   UCOSIII就是一個可剝奪的多任務系統,
   我們使用UCOSIII的一個重要 的原因就是它的多任務處理能力。  

(
任務說白了就是一個大的工作分若干個人來共同完成
每個人就相當于與一個獨立的任務
最后在系統的協調下
共同完成這項工作
)

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

10#
ID:86450 發表于 2021-3-17 08:40 | 只看該作者
這么好的文章 。。
回復

使用道具 舉報

11#
ID:7209 發表于 2021-3-18 20:15 | 只看該作者
/***********************************************
感謝版主不辭辛苦的給予的“黑幣”獎金鼓勵
感謝各位老師給予的夸獎評價
在學習的路上不敢驕傲
在項目的路上老板
表揚的好似只有 0 回和 1回
更多的是

來 小X 這個需求在改改
   小X 這個功能能不能在添加一個新的創意
   小X 這個邏輯有些菜
   小X 這個項目進展有些慢
   小X 這個設備怎么設計的有bug
   ...........
   ...........
   第一年我羨慕大佬
   第二年我羨慕老板
   第三年我羨慕搬磚
   第四年 ......搬磚
  ........     搬磚
  ........搬磚
  ........ 搬磚
  .........搬磚
  (還想寫,但是咱是來學習的)

后來想想就是個菜鳥
適合搬磚
其實想想
無論多么牛逼
都是個打工的
在別人眼里都是個工具

除非達到前幾年
航天行業的那個兄弟
自己走了
那幫人玩不轉
************************************/
//一直想從整體上說任務
//分開了說
//老忘記前面學的啥 (比較笨)
  
   任務是以何種面貌存在的呢?
   在UCOSIII中任務就是程序實體,
   每個任務就是一個 void main(); 函數
   UCOSIII能夠管理和調度這些小任務(程序)。
   任務的設計也是整個軟件代碼的基礎
   其他設計工作都是圍繞一個個小任務來展開的
   
   在不看書本的知識情況下想一想
   做飯吃飯這類任務
   是不是 ----是個重復的或說周期類執行的任務
   
下館子這類任務
是不是 ----是個事件觸發類事物
   {
    //女朋友生日、老婆生日、朋友想你了陪他喝會兒
    //都是在受到外部刺激了
    //或受到外部觸發了
    //才產生一次)  
   }



老婆給你買衣服這類任務
   是不是 ----是不是個單次執行類任務
   {
     //小姑娘可以一月買兩件或三件衣服
     //大老爺們你一月買三件試試
     //大部分是一對鞋破了直接扔掉買對新的
     //衣服爛了小了在買一套替換
    }  

   
周期類或重復任務---- 比如做飯
   {
   準備好菜
   洗好米
   和好面
   --------這都是準備的 狀態
   炒菜、蒸米、下面
   ------- 這是執行的狀態
   蒸米需要10分鐘
   炒菜需要5分鐘
   面熟需要8分鐘
   --------這是等待狀態
   
  (這里一定別小看 等待的 狀態這個狀態忒有必要了)
   /***
   為什么這里等待很有必要
   其實等待的時間就是讓CPU來
   切換不同的任務
   否則 一個任務寫個 while(1) {   ......}
   一直運行不出來?
   咋運行別的任務
   這里也是系統的最好的地方
   系統內怎么切換的
   暫時不管它
   ****/
   }   
   
//下面繼續偽代碼
  
/**單次執行類任務-----就是女朋友給你買衣服******/
  
   鞋破了衣服爛了
   給當家的匯報---------這是創建任務

   通過了同意了
   給錢了,并且買到了----這是運行了任務
   {
    這也有可能
    給錢了同意了
    但是現在不同意去購買去執行
   }
   
   買到了試試合適
   還想要一個“機械鍵盤”的可愛要求
        ---- 直接刪除這個任務3
  

   void my_Task_clothing(void *pdata)
   {
    //進行準備工作 定義和初始化變量
    //任務實體 完成衣服具體購買
    //任務刪除 將這月買衣服的任務刪除
   
    }   


/***周期類任務 做飯吃飯************************/   


   void my_Task_have_a_meal(void *pdata)
   {
    //進行準備工作
    //食材
    while(1)
     {
      //做飯
      //吃飯
      //等待延時 沒到飯點,沒有餓的需求。
      }
   }

/***觸發類任務 有約去外吃飯**********************/

  void my_Task_eat(void *pdata)
  {
    //進行準備工作
    //準備穿的衣服
    //準備好酒
    //化妝
   while(1)
    {
      //等待朋友發的位置
      //或給朋友發吃飯的位置
      //也就是獲取別人的請求
      //接受到消息后
      //開始一起吃飯
      //聊天
      //等待下一次彼此聚餐
    }
   }



評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

12#
ID:7209 發表于 2021-3-19 17:48 | 只看該作者
繼續說說和書上沒有關系的白話
  這么多任務
  有是單任務、
  有是觸發類任務、
  又是周期類或重復類任務
  
  又是出外吃飯、又是買衣服、又是在家做飯吃飯
  
  這些任務應該怎么安排?
  安排不好就是-----生活的雞飛狗跳
  這就出現一個問題----先后順序
  那個任務應該安排在最靠前?
  那個任務可以安排的次一些?
  那個任務可以安排的靠后一些?
  哪些任務可以協調為有需求在執行的觸發性任務?
  哪些任務可以安排為臨時性或突發性任務?
  
  如何安排先后順序--- 優先級 ----???
  無論幾個任務這個中心非常重要
  如果不能安排好就會造成系統不能協調工作
  
  1---首先要滿足這個項目對"實時性"的要求,這也是ucos吹的地方。
  2---在就是多少個任務系統協調起來最合適,想想是不是任務
      數目越少越好,要是就兩個或三個四個任務
      系統跑起來都不是事
  3---在就是適當簡化或屏蔽掉一些系統的多余的用不到的功能   
      這個暫時理解即可,知道在ucos中可以屏蔽一些功能
  4---任務和中斷、任務和任務、重復類和單次任務之間
      聯系適當或合理簡化數據的同步和通信需求
      從而降低或減少對系統資源的時間上的影響
  當然,合適不合適跑跑就知道了
  實踐--- 實踐 ----- 實踐
  

  缺一不可類任務或關鍵類任務
             任務優先級安排越高越好,必須保障其執行機會

  周期性頻繁類任務
             任務優先級安排也要高,一般這類任務都執行時間都不會長
                 在寫的時也要保證這類任務盡量簡短

  快速響應類實際環境中的傳感器更新數據類任務
             任務優先級安排也要高,以確保數據的實時性

  ---交換性或上下任務通信數據傳遞、信號數據處理類
             任務優先級安排低于快速響應類
  
  致命性危險性緊迫性破壞性非常嚴重性任務
             任務一般采用與中斷有聯系
  
  這么多都要求優先級高
  確實不好處理
  舉一個例子吧
  
   中國保護動物共分為三個級別。

   一級保護動物:金絲猴、雪豹、中華白海豚、西藏野驢、梅花鹿、野牦牛藏羚羊等。

   二級保護動物:短尾猴、獼猴、藏酋猴、穿山甲、豺、黑熊、棕熊、石貂、水獺等。

   三級保護動物:黃鼬、青鼬、中華竹鼠、銀星竹鼠等。

   這雖然不是一個行業的
   但是動物保護分級能很好說明就是這樣的一個意思
   在國家保護動物中分1、2、3的優先性
   這也是在任務分配中各個任務的優先級   
     
前面蒸米煮面條需要等待為什么很有必要???
   答: 這是因為ucos 是完全基于優先級的操作系統
        所以一定條件下必須出讓cpu占有權以便比自己優先級更低的任務
        能夠運行
        這是通過調用部分系統函數來實現的
        這些函數如下表---
        一般的任務必須調用至少一個表里的函數
        只有一種情況除外
        就是單次執行的任務
        因為任務刪除后肯定出讓CPU
        所以可以不調用表中的函數
  
  (看看就行不用記住)
  OSFlagPend   --- 等待事件標志組的事件標志位
               (類似手機里APP的屏幕通知)
  OSQPend      --- 等待消息隊列中的消息
               (類似 QQ 中別人給你打字你看到別人正在輸入)
  OSSemPend    --- 等待一個信號量
               (類似摩斯密碼
                 等待前線發送過來,
                 指揮所根據發送的字符
                 了解前線情況
                 還有些信號量有廣播的功能)
  OSTimeDly    --- 延時
  OSMutexPend  --- 等待一個互斥信號量
                (類似對講機 每次只能一個人說話另外一個人聽)
  這些只是生活中的比喻,有些不恰當
  
  OSQPend      --- 等待消息隊列中的消息
  OSTaskSuspend -- 掛起任務
  OSTimeDlyHMSM -- 延時

  上面這幾個函數都能引起任務函數的時間等待

   任務由三部分組成:
   任務堆棧、任務控制塊、任務函數。

任務由這三部分組成都是啥意思啊?
  答:任務堆棧 --- 理解為倉庫
      任務控制塊 - 理解為倉庫管理員
      任務函數 --- 理解為物流司機
      現在網絡購物方便實惠
      我們下單子后是給商家---這就是發送了一個請求信號量 (這里注意了)
      
      商家接收到下的單子也就是信號量開始對單子處理
      或對你購買的東西進行確認
      (商家需要和賣家知道彼此說的是啥)
     
      開始備貨  (這是不是就是創建了一個任務)
      
      開始對任務進行具體操作
      貨物現在需要在倉庫里有個存儲空間 (這就是任務堆棧了)
      貨物在倉庫中有進出關系
      ucos 系統在處理任務堆棧也有進出關系
      (這個和實際ucos 中一樣也有先進先出或后進先出規則)
      別管是啥進出規則

      這個堆棧里或倉庫里保存了這件商品的基本信息
      
      倉庫管理員來管理這個商品是發給誰 (這就是任務控制塊)
      倉庫管理員好牛啊
      控制管理層大小是個領導
      
      庫管決定后通知任務函數
      任務函數來規劃是發到北京還是宇宙
      是走路地還是航空
      (這就是憑本事吃飯了自己發揮了只要能完成給客戶的商品發送)
      任務其實就是個干具體工作的
      完成具體任務
      是個苦逼的打工仔
   

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

13#
ID:7209 發表于 2021-3-21 22:07 | 只看該作者
下面這幾句話也是在網絡上看到,感覺寫的很通俗易懂供參考:

  任務狀態
簡單分為運行態,就緒態,阻塞態。


運行態:萬事俱備,不欠東風(獲得CPU控制權);

就緒態:萬事俱備,只欠東風(缺少CPU控制權);

阻塞態:萬事不俱備(等事件或信號),還欠東風(缺少CPU控制權);

  (運行態:老板簽過字、銀行正常上班有錢------可以正常發薪水)
  (就緒態:老板沒簽字、銀行正常上班有錢 ----- 還需要等待)
  (阻塞態:老板沒簽字、銀行正常上班沒錢 ----- 還需要等待)



每個任務基本上都會游離于這三種狀態。

運行到阻塞,就緒到運行稱為任務切換過程。


從用戶的角度看,UCOSIII的任務一共有5種狀態:
    1、休眠態:
       任務已經在CPU的flash中了,
       但是還不受UCOSIII管理。

    2、就緒態:
       系統為任務分配了任務控制塊,
       并且任務已經在就緒表中登記,
       這時這個任務就具有了運行的條件,
       但是沒有獲得CPU 的使用權
       此時任務的狀態就是就緒態。

    3、運行態:
       任務獲得CPU的使用權,正在運行。

    4、等待態:
       正在運行的任務需要等待一段時間,
       或者等待某個事件,
       這個任務就進入了等待態,
       此時系統就會把CPU使用權轉交給別的任務。


    5、中斷服務態:
       當發送中斷,
       當前正在運行的任務會被掛起,
       CPU轉而去執行中斷服務函數,此時任務的任務狀態叫做中斷服務態。


白話任務堆棧、任務控制塊、任務函數



  在多任務操作系統中創建任務時,都需要指定該任務的堆棧大小,
  那么這個堆棧的作用時什么呢?
  什么情況下需要用到堆棧,以及大小不夠時會產生什么異常呢?



任務堆棧的作用:


1 任務處于運行狀態:
當任務在運行時,
   一般都會調用各式各樣的函數,
   而函數的局部變量,參數,返回值是存在于函數棧幀里的,
   每個函數都擁有獨立的棧幀,
   各個棧幀使用的空間就是任務堆棧的空間。
   所以任務堆棧的作用是用于保存函數在運行/調用過程中的參數/局部變量。

   (理解堆棧就是個倉庫倉庫里各種各樣的商品也就是各種功能不同函數)




2 任務處于切換
當運行的任務被切換時,需要保護現場(CPU中寄存器的值),
   以便于下次恢復數據。
   所以任務堆棧的作用是用于保存CPU中寄存器的值。

3

任務(低優先級的)在運行過程中,
   隨時可能被切換,
   所以CPU中寄存器的值入棧的棧位置是不確定的,
   這取決于當前任務的執行情況。



4 堆棧溢出
若堆棧的空間設置太大,會浪費內存資源。
   而設置得太小,則會出現堆棧溢出,在沒有MMU功能的操作系統中,
   可能會導致系統奔潰。
所以,
   需要根據任務的情況設置合適的堆棧大小。
   同時,應避免使用遞歸調用函數,
   函數中局部變量的分配空間不能太大。


   任務堆棧是任務的重要部分,
   堆棧是在RAM中按照“先進先出(FIFO)”的原則   
   組織的一塊連續的存儲空間。

   為了滿足任務切換和響應中斷時保存CPU寄存器中的內容及
   任務調用其它函數時的需要,
   每個任務都應該有自己的堆棧。

   一般是這樣定義的
   #define START_STK_SIZE  512        //堆棧大小
   CPU_STK START_TASK_STK[START_STK_SIZE];//定義一個數組來作為任務堆棧

   一般就是這樣定義的,
   明白就行不能有壓力。

  任務堆棧的大小是多少呢?

  CPU_STK為 CPU_INT32U類型,
  也就是  unsigned int類型,
  為4字節的,
  那么任務堆棧
  START_TASK_STK的大小就為:512 X 4=2048字節!




  任務如何才能切換回上一個任務
  并且還能接著從上次被中斷的地方開始運行?

  這一點很重要系統是如何來切換任務的?
  它是怎么知道某一個任務運行到了那里?
  它是怎么來記錄任務運行過程中產生的數據?

    這就是任務堆棧初始化的工作
    這里是不是和剛學習單片機c51有些類似

    org 0x0300
    ljmp main
main: mov r0,r1
     .....
     .....
     .....
     .....
     ajmp main

     道理是一樣的
     只不過在C 中我們直接定義了幾個大的ROM
     每個ROM有是連續的存儲空間
     好似這樣的結構



     ................
     .   c51        .     
     .              .     
     .              .     
     .  void main() .     
     .              .     
     .              .         
     .              .     
     ................

     ........................................................
     .   stm32      .                                       .
     .        ucos - iii       .                            .
     ........................................................     
     .  void main() .            .            .             .
     .              .void main() .            .             .
     .              .            .void main() .             .
     .              .            .            . void main() .
     ........................................................   


     51 的ROM 空間有過2K 、16K、64K 的
     STM32 的空間就大的多了
     這樣利用ucos iii 的組織能力就能在其內部分割出來
     相同或不相同的 void main(); 來
     這其實就是任務堆棧的原型了。
     至于在單片機內部是如何分配的就不知道了。




    知道堆棧的大概了那么
    恢復現場就是重新讀取保存下來的CPU的內部各個寄存器數據。


    因此在創建一個新任務時,
    必須把系統啟動這個任務時所需的CPU各個寄存器初始值事先存放在任務堆棧中。

    這樣當任務獲得CPU使用權時,

    就把任務堆棧的內容復制到CPU的各個寄存器,
    從而可以任務順利地啟動并運行。


    把任務初始數據存放到任務堆棧的工作就叫做任務堆棧的初始化,
    UCOSIII  提供了完成堆棧初始化的函數:
    OSTaskStkInit()。

    CPU_STK  *OSTaskStkInit (OS_TASK_PTR    p_task,
                             void          *p_arg,
                             CPU_STK       *p_stk_base,
                             CPU_STK       *p_stk_limit,
                             CPU_STK_SIZE   stk_size,
                             OS_OPT         opt)


   用戶一般不會直接操作堆棧初始化函數,
   任務堆棧初始化函數由任務創建函數OSTaskCreate()調用。
   不同的CPU對于的寄存器和對堆棧的操作方式不同,
   因此在移植UCOSIII的時候需要              
   用戶根據各自所選的CPU來編寫任務堆棧初始化函數。



前面我們創建了一個任務堆棧,怎么使用這個任務堆棧?

作為任務創建函數OSTaskCreate()的參數,
               函數OSTaskCreate()如下:

void  OSTaskCreate (OS_TCB        *p_tcb,
                    CPU_CHAR      *p_name,
                    OS_TASK_PTR    p_task,
                    void          *p_arg,
                    OS_PRIO        prio,
                    CPU_STK       *p_stk_base,         //任務堆棧基地址
                    CPU_STK_SIZE   stk_limit,        //任務堆棧棧深
                    CPU_STK_SIZE   stk_size,        //任務堆棧大小
                    OS_MSG_QTY     q_size,
                    OS_TICK        time_quanta,
                    void          *p_ext,
                    OS_OPT         opt,
                    OS_ERR        *p_err)

    其實看著有些復雜,其實很多參數都是一定的;
    學習過后就理解
    基礎東西很重要
    特別是C 語言的基礎知識和算法
    因為基礎的都是實際來處理具體問題的
    即便上了系統
    系統也只是起到一個調度的作用
    平衡各個任務之間的運行

函數OSTaskCreate()中的參數p_stk_base如何確定?

   根據堆棧的增長方式,
   堆棧有兩種增長方式:
   向上增長:堆棧的增長方向從低地址向高地址增長。
   向下增長:堆棧的增長方向從高地址向低地址增長

   函數OSTaskCreate()中的參數p_stk_base是任務堆棧基地址,
   那么如果CPU的堆棧是向上增長的話
   那么基地址就&START_TASK_STK[0],
   如果CPU堆棧是向下增長的話
   基地址就是&START_TASK_STK[START_STK_SIZE-1]
   STM32的堆棧是向下增長的!

  寫了很多廢話,只是 為了了解任務堆棧
  也寫的沒有趣味性了
  失敗




評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

14#
ID:7209 發表于 2021-3-24 13:35 | 只看該作者
任務堆棧: 就是上下文切換的時候用來保存任務的工作環境,
           若是使用STM32的話用來保存內部寄存器值,
           無論是中斷還是任務切換都要產生需要保存的
           能維持任務中斷或任務切換過后的正常運行的數據。
   

2 任務控制塊
是任務的抽象類型,用于描述其屬性和方法

     任務控制塊好似讓做飯這項任務的基礎包
     做啥飯
     都有啥蔬菜
     油鹽醬醋
     包括盛菜的盤子
     這就是任務的基礎包
     里面有完成任務的必要材料
     以及去倉庫拿這些食材
     廚師好似任務控制塊,控制做出的飯菜味道營養
     (那么做出的菜就好比任務函數,送到不同的餐桌,起不同的功能)
   
     用來記錄任務的堆棧指針、任務的當前狀態、任務的優先級別
     等一些與任務管理有關的屬性的表稱為任務控制塊
   
     用來記錄倉庫里商品的存放位置、倉庫有多少商品、商品的價格
     等一些商品的屬性就是任務控制塊也就是 庫管。
     而且在倉庫里任務控制塊制作一個excel表就是一個表格
     
     一般倉庫都是一格一格這樣擺放的
     也就是說只要使用這個倉庫
     這樣的空格子就是連續的
     對應ucos就是一條空任務鏈表
     既然有空的肯定有實的任務列表
     實的就是我們實際創建任務產生的任務控制塊
     也就是在倉庫里擺放了 100件
     實際存在的商品
     (在ucos III中規定了47個這樣的參數來說明內部的消息)
   
  
      
     任務控制塊是用來記錄與任務相關的信息的數據結構,
     每個任務都要有自己的任務控制塊。     
     任務控制塊由用戶自行創建,
     如下代碼為創建一個任務控制塊:
   
     
     
     OS_TCB StartTaskTCB;  //創建一個任務控制塊

     OS_TCB為一個結構體,
     描述了任務控制塊,
     任務控制塊中的成員變量用戶不能直接訪問,
     更不可能改變他們。

     OS_TCB為一個結構體,其中有些成員采用了條件編譯的方式來確定


     任務控制塊初始化函數:
     OSTCBInit()
      
     下面是ucos ii中的任務控制塊初始化函數
     INT8U OSTCBInit(
       INT8U prio,   //任務的優先級別
       OS_STK  *ptos,  //任務堆棧棧頂指針
       OS_STK  *pbos,  //任務堆棧低指針
       INT16U id,      //任務的標識符
       INT16U stk_size, //任務堆棧的長度
       void *pext,     //任務控制塊的擴展指針
       INT16U opt);    //任務控制塊的選擇項
    (這里III 對任務控制塊參數達到47個忒復雜了怕一下嚇懵了,
     知道大概有哪些東西就行)
    INT8U OSTCBInit(
         //商品的價格
         //商品的最多的數目
         //商品最少的數目
         //商品的標志
         //倉庫對該商品分配的存儲空間大小
         //該商品如果在規定存儲空間放不下如何在新空間來標志
         //商品的其他選擇項目
         );
    該函數啥作用?
      -- 對創建該商品放入整個倉庫的商品目錄中
      -- 為商品進行說明
      -- 為該商品在倉庫存放(堆棧內)指定位置


   
   II 和 III 任務控制塊里所包含的參數不一樣
   III 的參數多多了
回復

使用道具 舉報

15#
ID:901261 發表于 2021-4-6 12:50 | 只看該作者
謝謝樓主的發帖,我正在學習ucosII  ,感覺你讓我受到了很大的啟發
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 美女黄网 | 亚洲天天干 | 国产精品久久久久久久久污网站 | 美女视频黄的 | 视频一区二区中文字幕 | 欧美一级黄色免费看 | 免费久| 欧美freesex黑人又粗又大 | 亚洲自拍偷拍免费视频 | 欧美日韩国产中文 | 涩涩视频在线看 | 999观看免费高清www | 国产精品久久影院 | 国产精品性做久久久久久 | 91精品国产美女在线观看 | 色婷婷精品久久二区二区蜜臂av | 亚洲性人人天天夜夜摸 | 在线一区| 国产婷婷 | 国产精品国产精品国产专区不片 | 国产精品久久久久久久久久久久冷 | 亚洲欧美一区二区三区1000 | 九九热精品视频在线观看 | 综合色站导航 | 日韩中文久久 | 一区二区在线免费观看 | 免费一区 | 国产精品亚洲一区二区三区在线 | 欧美一区二区视频 | 婷婷综合色| 亚洲一区综合 | 手机在线一区二区三区 | 免费a级毛片在线播放 | 精品欧美一区二区中文字幕视频 | 国产精品久久久久久久久动漫 | 国产成人综合一区二区三区 | 成人天堂 | 精品视频一区二区三区 | 丁香五月缴情综合网 | 在线观看日本高清二区 | 午夜激情国产 |