2017年8月31日 星期四

USB port randomly stop working

最近發生一個問題是 PC 會隨機發生認不到 usb 網卡,出現機率不高,但是發生後該 usb port 就突然認不到卡,連 usb 裝置無法辨識的提示都沒有,像是該 port 根本不知道有裝置連上來

網路上有人說是 usb selective suspend 造成的問題,並且看起來遇到這個問題的人還蠻多的,這個問題微軟自己也有官方的說明,但最後卻沒發現真正的 root cause,因為還牽涉到許多硬體製造商的 driver,所以太難找到原因

這裡這裡也有人在討論

後來實際重現問題後,把 usb selective suspend 關掉馬上就認到卡了,看起來的確是這個問題,只能先把 usb selective suspend 關掉再看會不會發生

2017年8月25日 星期五

寫 ACM 的時候最好少用 C++ std

寫了一題用到 STL map 怎樣都過不了,拿掉 map 用其他方法後就過了,兩個用的是一樣的演算法,實在看不出來 map 版本哪邊有問題,也許 C++ 有太多隱藏地雷,不熟的人踩到都不知道怎麼死的

2017年8月15日 星期二

GPS C/N 與 SNR

markdown GPS 常會聽到 C/N 與 SNR value,這兩個東西都是用來表達 GPS 訊號強度,常常會在同樣的場景中互用 ## C/N(carrier-to-noise density) 每單位 bandwidth 的 carrier power 和 noise power 的比率 ## SNR(signal-to-noise ratio) 表示一個給定 bandwidth 的 signal power 與 noise power 的比率 這兩個值可以用公式互相換算 C/N0 (dB-Hz) = C – (N – BW) = C – N0 = SNR + BW C is the carrier power in dBm or dBW; N is the noise power in dBm or dBW; N0 is the noise power density in dBm-Hz or dBW-Hz; BW is the bandwidth of observation, which is usually the noise equivalent bandwidth of the last filter stage in a receiver’s RF front-end. Reference * [Measuring GNSS Signal Strength](https://insidegnss.com/measuring-gnss-signal-strength/)

2017年8月14日 星期一

GPIO type -- open drain

open drain 類型的 GPIO 如果沒有接上拉電阻則就只會有 pull low 跟 floating 的狀態,因為它 pull high 的能力需要由上拉電組提供

如下圖,當 Q1 導通,則電路跟接地連接,輸出為 0V,當 Q1 斷開,輸出為上拉電阻的 VCC 值

2017年8月9日 星期三

Windows Native API -- Zw and Nt

Windows 的 native API 都有兩種 prefix 的開頭,Zw 和 Nt,例如 ZwCreateFile 和 NtCreateFile

user mode 的 native API 在 ntdll.dll 裡面,在 ntdll.dll 裡面實際上 Zw 開頭的 API 跟 Nt 開頭的 API 指向完全一樣的位置,user code 的 code 呼叫 Zw 或 Nt API 事實上是沒有分別的

kernel mode 的 native API 在 ntoskrnl.exe 裡面,在 kernel mode 中 Zw 跟 Nt API 就有分別了

先說 kernel mode 的 Zw API,例如 ZwCreateFile,它會先做一些事前準備,然後才呼叫到真正的 system service routine

它會把參數在 kernel stack 中的位置放到 EDX 暫存器,把 NtCreateFile system service 的 index value 放到 EAX 暫存器,然後透過 KiSystemService 來呼叫位於 KiServiceTable[EAX] 的 function,這個動作跟 user code 呼叫 system service 有點像

在這之中 previous mode 會被設定為 kernel mode

而 kernel mode 的 Nt API,則會直接呼叫該 system service routine,不會透過 KiSystemService 來呼叫,也不會設定 previous mode

看起來在 kernel mode 中 Zw 跟 Nt API 最大的差別就是有沒有去設定 previous mode,假設 previous mode 設定為 user mode 的話,system service routine 會對參數做嚴格的檢查,但是 kernel 基本上相信任何其他的 kernel component,所以 previous mode 為 kernel mode 的話,system service routine 就不會對參數做任何檢查

所以在 kernel 中建議是呼叫 Zw API,因為它會將 previous mode 設定為 kernel mode,若是呼叫 Nt API 的話,因為 kernel code 可能會執行在任意的 user mode stack 中,導致 previous mode 為 user mode,這可能會導致一些非預期的錯誤

2017年8月1日 星期二

Serial Communication -- UART

UART(Universal Asynchronous Receiver/Transmitter)是一種實作序列傳輸介面的硬體積體電路,實際上 UART 是序列介面與並列介面的中間者,UART 的一端為並列資料存取,另一端為序列資料存取,也就是靠 2 wire TX and RX 做傳輸



非同步的序列傳輸介面有很多,例如 RS232、RS422 和 RS485,因為本質上都都是序列非同步收發,所以廠商將收發獨立出來,不同的介面用不同的外部電路與軟體來實現,所以一個 UART 根據實際的需求,可以設定成後面接 RS232 或是 RS422 等等介面,這也是它 Universal 名稱的由來

UART 通常都是在電腦邏輯電壓中運作,例如 3.3V,這不是 RS232 這類序列介面工作的電壓,UART 將這轉換的動作讓另外的 line driver/receiver 去做,例如 MAX232 就是一個 RS232 line driver



Reference:
https://www.crifan.com/files/doc/docbook/rs232_serial_intro/release/htmls/rs232_vs_uart.html
http://makerpro.cc/2016/04/understand-what-is-uart/
https://learn.sparkfun.com/tutorials/serial-communication/uarts
http://yehnan.blogspot.tw/2013/01/arduinoterms.html

USBXpress -- USB to Uart programming SDK

USBXpress 是 Silicon Labs 這家公司提供的一包 SDK,讓開發者可以用它來控制 Silicon Labs 出品的 USB 轉 UART 的晶片,像是 CP210x USB to UART bridge 系列晶片


Silicon Labs 有將 programming guide 放在網路上自由下載,API 不多,而且看起來設計的蠻簡單的