pretty code

2020年10月26日 星期一

UEFI ShellOpt 概述

最近看 Spec 看到有點乏味,突然想到之前一直想試沒試的 ShellOpt,於是便來嘗試看看。

ShellOpt 是一個特殊的 UEFI Env Variable,照 Spec 所說,設了這個環境變數後,像是 Shell 的等待使用者按鍵時間,要不要印出版本資訊等,都可以透過這個環境變數來控制,不用像我之前一樣,需要修改 Shell.c 的預設值,編譯出自己的 Shell 執行檔。

嘗試的過程中遇到了一些問題,雖然還未完全解決,還是記錄一下遇到的問題及解決方式。

01. -delay 秒數的傳遞

-delay 是控制使用者按鍵時間的參數,當 set 指令遇到 - 符號時,會誤判為 set 的使用參數,解決方式便是把它跳脫,正常是使用 ^ 符號來跳脫特殊字元,但這裡要用 set ShellOpt "^^-delay 8" 來設定才能成功。


02. Shell 解析 Argv 不成功,如何 Debug

因為 UDK 的 code 有問題,導致無法使用使用者的設定值。為了判斷問題的地方,需要印出一些訊息,我這裡是使用下面方式來除錯。

CHAR16 DebugString[128];

UnicodeSPrint(DebugString, sizeof(DebugString), L"%02d - (%s) \r\n", LoopVar, CurrentArg);

gST->ConOut->OutputString(gST->ConOut, DebugString);

測試的結果,問題是出在最後一個 gEfiShellParametersProtocol->Argv,不知為什麼會多出一個奇怪的字串,嘗試列印來看,是一個重覆的無意義字串?也許是我還沒看懂 Shell 該段 Code 的意義,仍需要繼續嘗試。

我目前暫時的解決方式是先忽略最後一個有問題的 Argv,且傳遞給 -delay 的秒數一定要有 2 位數,不足便在前面補 0,這樣便可以解決 ShellOpt 的解析問題。


最終解決方式

下午繼續奮戰這個問題,最後確定奇怪字串是因為 set command 來的,應該是過程中底層不知道那個環節出錯?目前看來只能自己寫程式來設定此變數。

一開始試著使用 ShellSetEnvironmentVariable 來設定 ShellOpt,問題還是依舊,直到使用 gRT->SetVariable 函數,ShellOpt 的值才能順利設定,不過,當下無法反映在 set command 的顯示結果,另外 GUID 需使用 gShellVariableGuid,而不是 gEfiGlobalVariableGuid。


2020/10/27 更新

今天本來想寫支程式,抓取使用者的 argv,檢查後再幫忙設定 ShellOpt 變數。由於個人習慣使用 main Entry,故所有的字串都是使用 ASCII,本想最後再使用 UnicodeSPrintAsciiFormat 函數來轉換,無意間才發現,UEFI 在這些類似的函數中,需要使用 "%a" 來表示 ASCII 字串,而不是傳統 C 語言的 "%s",這讓我不禁思考,使用 main Entry 撰寫 UEFI Application 到底是好還是不好呢?

相關 Format 選項可以參考 MdePkg\Library\BasePrintLib\PrintLibInternal.c - BasePrintLibSPrintMarker。

https://github.com/tylpk1216/ShellOpt

2020年10月15日 星期四

小程式也要講究效率

自從不用 C 寫 Parser 後,我已經習慣用 Re 來處理 Log,雖然明知道每次重覆在同一份 Log 中找尋不同資料是很愚蠢的事,應該只 parsing 一次後就把資料儲存起來!但自己寫的小程式自己用倒也還好,短短幾行 Code 看起來也比較舒服XD

後來另外一個主管看到這樣的小程式在做實驗時幫助判斷問題很方便,就延用了我的小程式做他自己想做的實驗,一直以來倒也相安無事。

直到有一天,因為他做了一些變化,導致 Log 容量膨脹許多,故開始想要節省時間,於是請我幫忙改進,我原本以為純粹是後續報表畫圖很花時間,即使我做了改進,但時間可能也節省不到 20%?不過不改不知道,單純測試 103 個單位,便少了 93% 的時間,改進後沒有再接到需求應該是有達到目標?因為不是我要用的,我也沒有繼續追問下去XD

最近都在搞 ESP8266,我發現這樣下去不行?還是來發篇文章灌個水,順便解答我心中的疑惑。

就以我原本的小程式來測試改進幅度!

改進前:13 分 33 秒。

改進後:03 分 11 秒。

計算之下,少了 76 % 的時間。

再繼續細分下去,一次的 parsing 動作可以節省 4.2 ms,只要執行次數夠多,花費時間還是很可觀的。

難怪古人說:勿以善小而不為,勿以惡小而為之。戒之戒之。

2020年10月3日 星期六

Kobo 翻頁器 DIY 最終回

將 ESP8266 (ESP-12S) 裝進 3 x AAA 電池盒中,只使用 2 x AAA 共 3V 當做輸入,原本預計要加一顆 DC-DC 0.8V ~ 3.3V to 3.3V Converter,但因賣家送錯,故直接使用 3V 的電壓驅動 ESP8266 (ESP-12S),希望可以撐到 2.7V 的最低工作電壓為止。

原則上還是要讓 ESP8266  (ESP-12S) 工作在 3.3V 才對!我這是沒辦法中的辦法,在沒有任何外加電路下,工作電壓應該也不穩定,如果還能拿到 DC Converter 再說吧。

工作影片


2020/10/05 更新

無意間在 YouTube 看到,有一種 LiFePO4 電池,其工作電壓為 3.2V,在到低電量前,都維持一個很穩定的電壓,如果可以買到 AAA 規格的電池,應該就可以省略 DC Converter,還可以用並聯增加電池容量,可惜的是,不容易買到 AAA 規格的電池,選擇還不多,目前市面上看到的都是大陸製的產品,且容量在 280 ~ 350 mAh。

另外,昨天實測的結果,使用兩顆新的乾電池看了一個多小時的書,翻頁都還正常。但我猜應該是沒辦法撐過 3 小時,因為乾電池的放電電壓下降的很快。

2020/10/07 更新

根據 Kobo 閱讀器自己的閱讀統計,累計閱讀了約 2 小時又 24 分鐘後,翻頁器已經無法工作,斷電再開也無法開機,兩顆全新的乾電池使用電表量測的結果,電壓都約在 1.24V 左右,離最低 2.7V 的工作電壓已有一段距離。不過,這兩顆電池只是無法再提供 ESP-12S 需要的工作電壓,拿去裝在手電筒上還是可以用的。

2020/10/08 更新

還有一種鎳鋅充電電池,其電壓為 1.6V,其放電電壓也很穩定,故也是一種替代方案,但跟 LiFePO4 一樣,沒有大廠的產品可購買。

另外,今天又跟另外一個賣家購入了 DC Converter,這個東西在市面上不太好找,希望這次賣家不要再標示錯誤了。

好奇統計了一下,截至目前為止,為了這個硬體翻頁器共花了 NT $8,592 元,都可以再買一台電子書閱讀器了!但是跟學習到的東西比起來,還是很划算。

烙鐵及排風扇等:約 3,300 元。
硬體開發板相關:約 1,200 元。
其他零件及收納:約 4,100 元。

2020/10/12 更新

新的賣家出貨速度很快,給個讚!這次學乖了,焊接前,先量測一下電壓,2.86V 左右的電壓轉完後約為 3.44V,比號稱的 3.3V 高出了些許,使用電表看不出是否真的恆定在 3.44V?但應該是有符合我的需求,等到原本用過的電池沒電後,再拿全新的電池記錄數據。

另外,這次的 Converter 比上次賣家送錯的還大了些,雖然只是公釐的差異,放進電池盒就得喬一下位置。還有這次的焊接技術又更差了,不小心傷到外盒好幾處,焊好的線我也覺得搖搖欲墜,哪一天線突然斷掉我也不意外XD

2020/10/15 更新

事情果然沒有那麼順利,反正我也習慣了XD

使用新的乾電池測試時,約 40 分後翻頁器便無法工作,比不使用 DC Converter 的 2 小時半還差?量測輸入電壓約 1.6V,輸出電壓約 2.5V,而我的 Convert 規格為 DC - DC 0.8 ~ 3.3V To 3.3V。

懷疑是下面幾個原因:

01. ESP-12S 使用了第一個賣家標示錯的 5V Converter 造成的內傷。
02. 被第一個賣家標示誤導,使用 4.3V 測試第二個賣家的真 3.3V Converter,導致 3.3V Converter 內傷。
03. 焊接技術差,沒有完全接好,電流過不去,造成異常耗電。
04. 要如原廠建議,供電電流 > 500 mA。
05. GPIO 當輸入時,還是要接個電阻限流?CHIP 內部電阻阻值不夠,導致 CHIP 內傷。

後續待我好好想想 ~

2020/10/16 更新

從官方討論區看到的討論,看起來 internal pull-up resistor 應該不是問題。


2020/10/19 更新

除了在按鍵上的焊點貼上絕緣膠帶外,並未做其他改進。由於家裡只剩鹼性電池,故改用鹼性電池測試,陸續分別使用了 4 次,資料如下:

21:40 ~ 23:40 (120)
10:40 ~ 11:20 (040)
11:30 ~ 12:20 (050)
17:40 ~ 18:35 (055)

總共看了 265 分鐘,第 5 次想要繼續使用,翻頁器便無法開機,拿去手電筒仍然可以使用。

好像在 Youtube 上曾看過,鹼性電池的使用時間約略是普通乾電池的 2 倍?如果是這樣我會認為,雖然電池應該也還有電,但因為 DC Converter 會隨著輸入電壓的下降,提供的電流也隨之下降,故這時候的工作電流已經無法讓 ESP8266 正常開機。假設我調整使用時間,也許可以得到更漂亮的數據。

另外,Kobo Clara HD 在搭配我的自製翻頁器時,1 個小時約掉 5% 電。

如果想要讓翻頁器更持久,也許還可以朝下面幾點改進:

01. 按鍵從 polling 改 interrupt。
02. 使用官方 SDK 寫程式,減少不必要的執行程式碼。

這篇文章描述了一些關於啟動時的注意事項,還提到如果因為電源的關係導致 ESP8266 進入了故障模式,則有可能因為溫度一直上升而讓 ESP8266 死掉。

2020/10/22 更新

昨天趁休假時,又試了一次鹼性電池,總共看了 3 次,分別是 01:30、01:00、0200,累積看到 270 分鐘後,翻頁器便無法作用,關掉電源再開也無法正常開機。一樣把電池拿去手電筒還是可以使用。

看來在接了 DC Converter 後,使用鹼性電池就是可以使用約 4 小時半,暫時就先這樣吧。

2020/10/30 更新

上個星期買了Energizer Max AAA battery,測試看看是否可以撐比較久?陸續使用了 5 ~ 6 次,每次至少 30 分鐘以上,最後共可看 5 小時又 20 分鐘,好像也沒有比原本的鹼性電池好多少?此電池一顆價錢為 NT $12.4。