2018年3月21日 星期三

在 Nuvoton NUC131 上執行 FreeRTOS 8.2.3


因為一些因素在比較 RTOS, 然後就順手做了這個
玩法不難, 就是從 FreeRTOS 裡面那一堆 demo 中翻出同為 Cortex-M0 的 MCU
然後從它的編譯腳本反推關聯檔案, 改寫到我的 makefile 中即可
這次使用的版本是 8.2.3, 因為比較需要才選這, 目前最新版為 9.0.0 目前最新版為 10.0.0
我只把它裝起來, 然後簡單驗證一下確定可以多工, 如果對 RTOS 設計有興趣請另尋文章
這 OS 很多人用, 網路上文章多到爆!

FreeRTOS 的硬體依賴蠻小的, 如果不是太奇怪的改造版核心應該都可以用內建 demo 去改
它只需要 timer, 如果像 Cortex-M 系列 MCU 在 CPU 那裡就已經有 timer
那幾乎啥也不用改, 只要編譯上去就會動, 而 STM32Cube 則提供選項讓用戶可以選
看是要用 CPU 自帶的 timer, 還是 STM32 週邊提供的 timer
接著在 FreeRTOSConfig.h 裡把 FreeRTOS 的函數名稱定義給中斷向量就打完收工
這裡先提供源碼:

FreeRTOSV8.2.3.zip 官方原版, 未修改的

CORTEX_M0_NUC131.zip NUC131 demo, 複製到官方版的 FreeRTOS/Demo 目錄下即可

nuc131-freertos.zip 把 FreeRTOS 需要的部份抽出來獨立使用


官方版的複製目錄後進到該目錄下 make 即可編譯
編譯依賴和燒錄方法請參考前篇:用 MCP2515 和 NUC131 進行 CAN bus 通訊
用 Arduino 的 gcc 編譯, OpenOCD 燒錄
修改 OpenOCD 新增 flash ID, 然後用 st-link-v2 燒錄和除錯


如同別的 MCU 的 demo, 上面運行了幾個 task, 還有 timer
LED 部份由於這張板上只有三顆, 第四顆是固定恆亮的電源 LED
因此 vParTestToggleLED() 裡只做了 3 LED, 其他的就無法觀看
不過 LED 3 (即是板上標示 I/O 的那顆) 在出錯時會閃的比較快
所以還是可以看出有無異常, 正常應該是三秒變一次 (toggle, 點亮或熄滅)
我的板子上方接了藍色模組板, 那只是提供 5V 電源輸入, 做別的實驗用的

接著是 nuc131-freertos.zip 這包, 把 FreeRTOS 抽出
只留下 OS 本體和 Cortex-M0 會用到的部份, 其他都移除, 然後寫兩個測試
freertos-test 和 freertos-isr
freertos-test 是用 FreeRTOS 的 timer 去開關 LED
留下幾個可能會用到的函數和其註解, 剩下不需要的都刪除, 算是最精簡的測試
freertos-isr 則是測試按鈕反應時間, 測試硬體如下

把一個按鈕接在 LED 1 (即是板上標示 RX 的那顆), 然後設定為會發中斷的 GPIO
按鈕另一端接地, 按下後觸發中斷, 中斷內容寫在 GPAB_IRQHandler()
程式開始先創一個 binary semaphore, 在 FreeRTOS 中它就是一個貯列 (queue)
接著創三個 task, Task1 是死迴圈, 不斷浪費力氣幹沒意義的事
Task2 定時去開關 LED 2 (即是板上標示 TX 的那顆)
Task3 則是盯著 binary semaphore, 有東西出來就去開關 LED 3
優先權定為 Task3 > Task2 > Task1

當按鈕按下後, 中斷觸發, GPAB_IRQHandler() 被呼叫
確認是按鈕觸發的就呼叫 xSemaphoreGiveFromISR(), 放個東西進貯列, 例如放隻烤雞(?)
然後離開中斷, 接著工作切換, Task3 盯著貯列, 發現有隻烤雞, 大吉大利, 今晚吃雞
於是就把烤雞拿去吃了, 然後改變 LED 3 狀態, 接著繼續盯著貯列等下一隻烤雞
我們把示波器接在 LED 1 和 LED 3 上, 看看按下按鈕後多久 LED 3 會變
結果時間落在約 50~1000uS 之間, 非常亂數, 時快時慢, 但不會超過 1000uS 太多

最短:


最長:


看這延遲時間第一個就想到這是 OS tick 的間隔, 接著修改 FreeRTOSConfig.h
把這個:
#define configTICK_RATE_HZ ((TickType_t) 1000)
改成:
#define configTICK_RATE_HZ ((TickType_t) 100000)
結果變這樣:

最短:


最長:


注意示波器時間軸修改為一格 5uS
反應速度落在 30~40uS 之間, 依然非常亂數, 時快時慢
就算把 Task1 裡的死迴圈填入 vTaskDelay() 結果還是一樣, 只能等下一個 tick 才做事
而且還要優先權夠, 如果把死迴圈優先權放最高, 那麼 Task 2,3 永遠排不到, LED 完全不變
除非把死迴圈改成 vTaskDelay() 才會切換

這裡我只看現象, 並沒有花太多時間進去仔細研究, 雖然真的硬下去啃應該也不會花太多時間
核心檔案不到 10 個, 而且包含大量註解, 不過興趣不大, 目前是需要多少情報就啃多少
目前工作上主要都是用 OS 而不是做 OS, 因為要做產品賣的, 自己搞的土砲長官不放心XD
特別是像車用的, 有規範在的, 已經不是做不做的出來的問題, 而是要有認證, 還要有成功案例才行
雖然我們也知道某些設備明明一個死迴圈就可以打理一切, 裝個 OS 根本多餘
就算要 RT, 那些死迴圈的不見得反應就比較慢
FreeRTOS 已經很小, 但基礎仍然要一定量的儲存空間, 以我做的來說就是 15K
如果遇到那些變態高手把規範研究清楚了, 用死迴圈硬幹, 15K 搞不好可以做出全部功能
他的產品就可以用更便宜的 MCU, 成本更低, 把那些砸錢買商業 OS 的對手踩腳下, 對岸很多這種的XD
但死迴圈也不是完全無敵, 特別是要解複雜協議時, 那種需要等, 需要重試的協議特別麻煩
所以還是要評估整體專案的複雜程度來做決定, 沒有哪種就一定好, 這樣的議題電腦上特別多
像是 USB3 比 USB2 快, 可是若後面接的是低轉速磁盤硬碟, 加錢買 USB3 版的就是蠢逼XD
不過當市場上的蠢逼多到一定程度時又會變成不做 USB3 賣不掉的情況, 這又是另外的故事了
我能想到的折衷方案大概就是把 USB2 接頭塗成藍色, 反正傳輸速度一樣不是嗎?XD

36 則留言:

  1. FreeRTOS已前進到10.0.0。前進的原因是,因為它被Amazon併了。變成Amazon用的IOT作業系統。所以又新加了網路功能。
    新的FreeRTOS也改名,變成a:FreeRTOS。這次進版,網頁就支援繁中了。

    回覆刪除
    回覆
    1. 蝦密!多謝情報!
      查了一下好像是去年底的事情
      這舊版 OS 稍微看一下是沒有發現驅動層
      10.0.0 就有了, 還是超麻煩的網路驅動, 看起來十分頭痛!

      刪除
  2. https://play.google.com/store/apps/details?id=ru.zdevs.zflasherstm32
    可以用手機做燒錄。但要付一美元解鎖。

    回覆刪除
    回覆
    1. 多謝情報!
      戰鬥民族做的麼, 若再加上 toolchain
      http://kevinboone.net/android_native.html
      (我沒試過, 看起來好像可以)
      這樣就可以走到哪工作到哪囉, 真夭壽XD

      刪除
    2. 有在規劃。其實現在NB很普遍,也會帶debugger。
      只是萬一debugger掛了,還有手機燒錄做備援。
      萬一NB掛了,剩下手機,還有遠端桌面。可以利用WOL去叫PC開機,再用VPN連回去,用遠端桌面登入PC,可以做一點簡單操作。
      萬一手機也掛了,那就沒有辦法了。正在考慮辦個備用門號,用二支手機來防止這件事發生。

      刪除
    3. 這種等級的備援是要戰爭用的嗎?XD
      用手機敲程式很彆扭的, 這可能不會是我的選項, 而且網路門號貴
      若我來搞大概就筆電加上保護措施或是買 windows 平板來用

      刪除
  3. https://devanlai.github.io/webdfu/dfu-util/
    MCU更新燒錄網頁。只有chrome瀏覽器可以用。PC及手機試過可以動作。

    回覆刪除
    回覆
    1. 補充:MCU USB燒錄功能,叫DFU。再來是chrome具有抓USB裝置的能力,叫WebUSB功能。
      於是就有人寫網頁,具有WebUSB驅動能力,取得USB控制權,再將DFU檔送到USB裝置上,完成燒錄動作。
      也就是網頁可以開USB並下載燒錄檔,所以前面提的,被時代超車了。

      刪除
    2. chrome 可以控制 USB 喔, 多謝情報, 開眼界了!
      那個大概是 Android 那裡來的, usb manager 那套
      可以讓軟體自帶 USB 驅動, 不過最近有個議題:bad power 漏洞
      那就是用手機控制充電器, 可能利用了某些充電晶片的除錯功能, 送訊息設定讓它只送高壓
      導致下一個用這充電器設備若無法承受高壓就燒毀, 這些惡黨真是什麼招式都有
      這方法雖然方便, 但直接的操作硬體還是要小心, 有些時候還是傳統的好XD

      刪除
    3. Chrome也可以直接驅動bluetooth。今年也完成NFC驅動。Audio/Camera已行之有年。
      驅動加速開發有二個原因,1. WebAssemble興起,效能不輸Java,但可以自由分配在使用者或是在伺服器中執行,加速移動式應用程式發展。
      2. 5G通信的應用。 因為使用者開網頁同時下載好Webassemble的時間變得無感,就不用使用者安裝任何程式,就可以執行。

      5G的商機會如此大,就是軟體架構轉變中。現在應用程式可以在伺服器-使用者中自由分配。chrome則想將作業系統完全通透。變成伺服器-使用者-裝置 三者直通(作業系統消失其角色)。

      刪除
    4. 看過一張圖, 細節忘了, 內容大致上是說 javascript 繼續下挖 asm
      只會讓坑越來越深無法解決問題, 但是為了讓網頁更豐富, 除了往下挖似乎也別無他法
      我整理一些老舊庫存時就發現許多已經存下的網頁無法正常顯示
      小遊戲類的可以直接用 flash player 的問題不大, 用 wine 完美運行
      但是 flash 裡面會往外調用 javascript 的就幾乎都殘了, 顯示不正確或是不顯示
      而那些微軟帝國時代的 vb script 就直接全滅, 因為帝國垮了XD
      網頁這東西成本很高, 因為它一直改變, 或許幾年後這 asm 又會被換成什麼鬼不知道
      常常要修改, 如果是像網路遊戲類的可能還好, 反正本來就要維護
      而且伺服器關了遊戲就不能玩, 本地程式留著也沒用, 所以放上網沒差
      但是燒錄工具這種東西十年二十年後再拖出來用都是家常便飯, 總不能每次都要重寫吧
      這問題雖然同樣會發生在其他直譯或編譯語言, 但是各家語言至少有個中心規格
      而不像瀏覽器, 表面上是統一, 但是實際上各家又有大量差異很大的實作
      所以我絕對不會拿瀏覽器去做一些可能會長期使用的東西, 已經吃過虧了
      另外, 這種一路通看似很方便, 實際上就是要套牢用戶, 吃夠了甜頭
      接著就是使用者付費囉XD 維護伺服器和其運行的程式, 都是要人力的
      當然不會免費囉, 就像網盤那種套路一樣, 先拉客, 然後漲價, 爽!XD
      確實是商機, 但吃的到這肥肉的往往是那些巨頭, 因為這成本非常高, 小廠玩不起

      刪除
    5. 網盤?我是覺得未來軟體公司的明燈,沒有就糟了。這也是我很不看好apple的原因,它是最大的不自己發展網盤的公司。
      5G時代,網盤可以隨時取用,手機已是個人用電腦,但能源限制了它的計算力,個人要大型計算力,必然要租用伺服器。
      但現在已有無伺服器技術,只要程式碼就可以形成網站,它以執行次數來收費。
      個人是覺得無伺服器技術遲早會走入個人化,最後只要在個人網盤放好程式及資料放特定資料夾內,再設成以此資料夾為無伺服器執行,就可以有個人伺服器功能。
      網盤不是只是存放資料的地方,會如此想會我們自我的限制。

      相同的網頁上的執行程式,從java走到javascript再走到webAssemble都代表一種新的進步,但二次再進市場,大多會成功。若遇以第一次失敗的理由去看,會錯失不少東西。

      刪除
    6. 這得看你的使用情境了, 所謂無伺服器技術應是指網路 api 吧
      像 google 以及亞馬遜兩巨頭提供的服務
      確實, 統計資料不同於一些靜態資料, 可以獲取一些動態資訊
      我也知道有些網盤和這些 api 公司也 "有一腿" XD
      可以實行動態串接, 但別忘了, 這些資料在網路上串過多家公司, 雖然都加密
      但進到一家公司經手後就解密處理, 意思就是你的資料很多家公司都看過
      對於許多商業公司來說這是無法被接受的, 於是又落到個人用戶手中
      個人用戶資料相對不敏感, 可是有多少人願意在家裡架這種?
      除非像小米這類巨頭幫你架好, 你只要買他們家產品登入帳號就可以看資料
      這樣一般用戶才會接受, 願意投注時間干程式的人並不多
      而且這群干程式的裡面也有人是不接受資訊全上網的, 例如我XD
      至少現在看到仍是如此, 我沒有看到 "大多會成功" 的結果, 掛逼的依然一堆
      例如一兩年前剛收一波走的○○共享系列, 共享硬體就是典型的線上串接應用, 死一堆走了
      會成功的仍然只有那些巨頭, 而且這些運算計價還持續漲價!XD

      刪除
    7. 不是API。因為連伺服器也不用租,看不到OS也看不到CPU,但可以執行。
      https://aws.amazon.com/tw/lambda/serverless-architectures-learn-more/
      https://ithelp.ithome.com.tw/articles/10213431

      刪除
    8. 我是不知道你有無玩網路遊戲,以軟體工程的角度看過去,遊戲一定有升級問題。
      早期伺服器軟體升級,一定要使用者全退出才能升級(廢話,不給資料等同斷線)。
      現在手遊,你有看到要大家退出升級伺服器? 不是沒有,很少。
      主要就是在發展線上升級,且使用者不必退出的技術,其中成熟的就是server less技術。
      它讓主機近似於消失(其實是分散執行),架站只要專注在網頁呈現。
      手遊開發公司大部分都會用,因為不用離線升級,就可以保障一直有收入。
      只是這個技術和傳統不同,你才會誤認成API。但它給使用者就是可以執行,不知作業系統,也不用理解CPU或是主機。因為主機完全消失,故名為無伺服器。

      刪除
    9. https://denny.qollie.com/2016/05/22/serverless-simple-crud/
      這是完全無背景的人可以看的。

      刪除
    10. 我之所以知道可以做到線上更新,主要是有發現Erlang語言有此能力。在一般PC就可以安裝。但它不是常用語言。
      後來網路伺服器發展,這種技術移轉到javascript及python上。最後成就了serverless
      javascript現在不是只有網頁在用,伺服器也用,無伺服也用。變成程式看你要放在使用者端或是伺服器端都可以,程式碼不太需要修改。
      現在又可以用webAssemble加速,後又有chrome支援硬體。
      差不多用javascript可以從伺服器到瀏覽器再到硬體都可以控制到。

      刪除
    11. 想了一下,我想可能有觀念要重新說明:程式熱抽換

      serverless的主要功能是程式熱抽換,也就是一邊執行,一邊做程式更新。
      在PC上很少會用到,但在伺服器上,一直都有需求。
      其中最大的問題是變數寫回。因為一般程式都是使用變數寫回的描述所以無法做。
      Erlang是一種只可讀出變數語言,所以可以做到,其實它就是為了程式熱抽換而生。

      後來Java成為伺服器語言,還是沒有解決熱抽換問題。所以就有另一個語言去做,只要可以跑JVM就可以了,它就是Scala。

      現在AWS想要推廣,就把這個方法移轉去javascript上,就生成serverless。

      刪除
    12. 這就是 API 啊老哥!沒發現這些網頁點開裡面都有 api 字眼嗎XD
      不是不用租伺服器, 而是錢算在一起, 就像債務整合一樣
      當然, 因為全包給同一家, 確實可以得到一些優惠
      但你該繳的錢一毛也沒少, 只是整合一次付, 帳單明細變少了而已
      手遊我是沒玩, 但我認為那和軟體架構有關, 不會因為什麼 serverless 才無敵
      就像 Arduino 的 api, GPIO 裡你不用知道填哪個暫存器, 只要知道腳代號
      所以 Arduino 就不用填暫存器了嗎? 當然不是啊, 只是這些活別人幫你干了而已
      這 serverless 依然是對某個網址送訊息, 然後就回結果, 和以前的 AJAX 一樣
      一種穿過網路的 RPC (remote procedure call)
      只是格式換成 json, 然後一群全職工程師幫你調度後台, 這些工程師的薪水誰付?
      當然是偉大的客人買單囉XD
      伺服器從來就沒有消失, 費用也沒少, 換個名字告訴你這是統包服務, 就這樣
      我不否認這東西的價值, 統包也是有優勢, 得看應用場景
      但我必須說該干的活都沒少, 只是差在誰去做

      刪除
    13. 如果API可以做到程式不用離線就更新,為何現在才出?
      基本問題不是API可以解的。
      因為開伺服器一定要先用API,API算是入口省不掉,但API不是serverless重點。

      刪除
    14. AJAX更新的是使用者端,不是伺服器端,你弄錯了。AJAX沒有解決伺服器端程式更新問題。

      刪除
    15. 本地程式發現 api 沒回應可以等一下再重試
      發現 api 換了可以先要求用戶更新本地軟體
      也可以像多數軟體直接說:服務暫停, 抱歉
      同樣的 api 端也是如此, 可以做備援服務切換
      能否不離線更新只是程式架構設計的問題
      你也可以做無痛更新, 但就要投注人力和加購備援機器, 如此而已
      我們以前用 php 寫服務直接檔案貼進去就更新, 伺服器也不用重開啊
      要離線更新什麼的沒聽說過

      刪除
    16. 因為PHP是檔案管理,和網盤一樣,更新確實是只要檔案更新,使用者重刷就可以了。
      若是聊天機器人的伺服器系統就不是了,使用者輸入,要跑文字解析,語法解析,然後比對Q&A資料庫,找出相似度最高的回答。每個使用者還有前後文要記錄下來。單人聊天問題還小,多人含機器人互動的世界,程式更新要怎辦?

      所以沒有在玩game的人很難去理解為何伺服器要執行程式,且程式又要如何更新。

      刪除
    17. php 不是檔案管理, 它接收輸入, 運算, 回傳結果, 它就是一隻程式
      你說的資料庫存取, 語法解析, php 都能做
      php 除了自己程式運算, 也可以調用外部程式協助, 以前還有人調用 python 做過人工智慧應用

      刪除
    18. https://www.zhihu.com/question/29216344
      原來有分,game server是有互動型式的。它有合適的條件。
      確實大部分應用是web server就足用。

      刪除
  4. https://home.gamer.com.tw/creationDetail.php?sn=3053560
    這是game server的知識。不過server也有可能以web server實現,就看互動性如何。

    回覆刪除
    回覆
    1. 這是多人合作的線上遊戲...
      上面你貼的:https://denny.qollie.com/2016/05/22/serverless-simple-crud/
      裡面:timeout
      目前最多只能運算 300 秒,就會被強制結束掉

      所以, serverless 一樣不能解決你的問題, 因為無法持續執行
      至於為什麼設這限制, 我猜就是熱抽換, 也是要暫停的
      撇開 serverless 不談, 就看看 update 的部份
      我沒有玩過現代的新網遊, 但十多年前的仙境傳說我有玩過
      也自架私服, 在私服資料庫裡亂搞了一陣子, 若是說當年那種形式的遊戲
      差不多就是你這篇文說的樣子, 當時的私服是分三台伺服器, 具體內容忘了
      要做熱抽換仍然取決於軟體架構, 當時的私服肯定不行
      現在新遊戲若可以, 那也要付出很高的代價, 同時取決於更新的項目
      如果只是改改掉寶率, 改遊戲副本內容, 那種熱抽換很容易, 就是改資料庫然後更新 cache
      但如果要改通訊加密方式, 改地圖內容, 要熱抽換代價會很高
      以舊遊戲來說, 當時地圖訊息是客戶一份, 伺服器一份, 印象中是以伺服器為準
      所以你能不能移動到哪是伺服器決定, 若用戶端沒更新, 他可能就會看到明明有路卻不能走
      那麼, 需要把所有人踢出去嗎? 如果是更新加密協議當然要踢啊不然怎麼加入執行中程式
      若是地圖的話就可能有討論空間, 可以先禁止進入, 等用戶都離開這區後更新, 其他區不受影響
      完成後檢查登入的客戶端, 已經更新地圖的用戶才放行, 這也是個方案
      有多種解法, 取決於架構和預算, 沒有一定要什麼方案才可以

      幾年前分散式伺服器出來時大家也是一窩蜂, 關鍵詞:大數據, 啥不相關的都要扯大數據
      結果炒了一陣子就消失了, 因為很多情境下, 傳統的單一伺服器資料庫仍然是無法取代的
      而有必要且玩得起大數據的, 仍然只有那些巨頭, 小廠商跟人家玩什麼大數據啊XD

      刪除
  5. STM32系列目前有一套free C,官方叫STM32CubeIDE,已確認它是eclipse編輯器+GCC內裝。前幾個版本還不太好用,現在IDE1.4看來已經穩定了。再加上很便宜的ST-link除錯器(買一把平均一個不到百元)。
    個人認為ST將原始碼弄到這地步,其它單晶片會被比下去。

    回覆刪除
    回覆
    1. 放心, 不會!
      ST 的軟體在簡易應用沒什麼問題, 但是當你拿到一些奇怪需求的專案時
      就會想把它全部砍掉自己重寫, 因為 MCU 的應用本來就是壓榨硬體極限
      那樣一層轉一層的軟體根本是浪費資源, 而且當遇到問題時難以除錯
      特別是有用到中斷的, 可以去翻一下 ST 提供的源碼的中斷處理
      沒有人 MCU 中斷寫的那麼一大坨的, 完全就是為了應付 CubeMX 程式產生器而設
      MCU 的軟體不該這樣寫的, 給學生玩玩或是新手入門也就算了
      真正會企業開專案的幾乎都是非常難搞的需求, 畢竟如果隨便兜一兜就能上線使用
      企業自己找個工讀生拼一拼不就行了, 哪需要花大筆 NRE 開案?
      而那些需要穩定又高效的韌體的應用, 寫起來需要仔細了解硬體特性
      對於這類開發人員來說, 有沒有 CubeMX 並不重要
      只要能夠完成任務並且能從客戶那裡收到錢的就是好硬體!

      刪除
    2. 那是HAL函式庫,高階MCU用。低階用的是LL函式庫。我是可以自由調度,高低階會評估使用那些工具就不會有問題了。

      刪除
    3. 好吧, 你習慣就好
      對我來說那都叫 HAL, 應用處理器才需要這樣設計

      刪除
    4. 工具統一有個好處,可以整個專案傳給別人改。我已幫FB朋造可以除錯的專案,和另一個朋友共同開發。因為安裝方便,這些事變得可以實行,用雲端碟分享,用通信軟體就可以抓到專案。
      等於實作雲端共同開發很方便。

      刪除
    5. 幫FB友除錯時,因為打字太慢,他直接錄影片送過來,同時看到電腦及板子的工作狀態。可以這樣除錯也是新奇的經驗。

      刪除
    6. 那也要你有工具 "選擇權" 才行啊, 那種和協議綁一起賣的軟體可沒法隨便改啊
      例如 cc2540 那套, STM32 本身軟體都是免費, 但是當和特殊硬體綁時就不是這樣了
      方便從來就不是免費的, 是要犧牲運算資源的, 如同前面寫的, 只是簡易應用沒問題
      特殊應用, 特別是高速反應的, 用這種就是提高成本, 說是 ST 坑你買高階版 MCU 都不過份啊XD

      刪除
    7. 想也知,有特殊硬體出現時,自然是人家寄來模組,以及demo板子來。我這裏接好線,手機錄影,再寄回專案。
      軟體? 函式庫都是硬體附的。目前沒有遇到要錢的。
      以前有這樣接到外包,但工具不同,只能寄燒錄檔,來來回回的時間多很多。

      刪除
    8. 時代不同了, 以前是什麼都要錢, 現在則是 M 化
      要麼不用錢且開源, 要麼好幾萬還要簽保密, 兩極化

      刪除

注意:只有此網誌的成員可以留言。