# 發哥實習準備
- WiFi
- GNSS driver
- Network Protocol
- Linux/OpenWRT/Uboot upstream
- [OpenWrt](https://zh.wikipedia.org/zh-tw/OpenWrt)
- [Das U-Boot](https://zh.wikipedia.org/zh-tw/Das_U-Boot)
- [如何Upstream kernel和U-boot](http://rockchip.wikidot.com/upstream-kernel-u-boot)
- Serdes
- [SerDes 的基礎](https://www.ctimes.com.tw/DispArt/tw/1107261455DR.shtml)
- [化繁為簡談虛擬區域網路 在Cisco交換器設定VLAN及Trunk](https://www.netadmin.com.tw/netadmin/zh-tw/feature/0C1A2DDB3CF94296864832049D8897A4)
## 影像辨識
利用 HSV 將背景濾掉深色背景 (cv2.bgr2hsv)
- Hue 色相
- Saturation 飽和度
- Value 明度
找尋大於特定面積的 contour
- cv2.findcontours
- cv2.contourArea
轉正
- cv2.warpAffine
校正
- 拍照儲存
特徵變識
- sift.detectAndCompute()
## 畢業專題
一般用 Halmilton-Jacobi-Bellman 方程式來求解
不過會推到 PDE 很難解!
ode45.m 用 runge-kutta 四階解
判斷是否正定 -> Cholesky decomposition
P(x) = $LL^{T}$
- $L$ 是一個下三角矩陣且所有對角元素均為正實數
## NLP
- Batch normalization

使用 GPU 加速運算時,假設我們的 Batch = 3
x1, x2, x3 這三筆資料會是平行運算的,我們把 x1, x2, x3 排在一起變成一個 input matrix X
對 weight matrix W 運算,得到一個 output matrix Z
Adam
- Adam Optimizer 其實可以說就是把前面介紹的Momentum 跟 AdaGrad這二種Optimizer做結合
- adagrad -> learning rate 會調整
- momentum -> 動量的概念
- 如果這次的更新和上一次同方向,梯度就會變大 (慣性)
- 如果這次的更新和上一次不同方向,梯度就會變小 (像是摩擦力)
- Weight decay
損失函數為 loss(w, b),我們在這個損失函數後加上一個帶有 L2 范數的懲罰項,其中 λ 是懲罰項的倍率,當 λ=0 時,則權重衰減不會發生;當 λ 越大時,懲罰的比率較高,權重衰減的程度也就跟著變大。

我們使用梯度下降更新權重,會得到以下式子。你會發現與沒有加上懲罰項的差別在於 w 多了 (1- λ) 這個係數,其主要的思想在於強制約束權重,不讓模型擬合時過度依賴某一些權重,進而達到正則化的效果。

[L1 , L2 Regularization 到底正則化了什麼 ?](https://allen108108.github.io/blog/2019/10/22/L1%20,%20L2%20Regularization%20%E5%88%B0%E5%BA%95%E6%AD%A3%E5%89%87%E5%8C%96%E4%BA%86%E4%BB%80%E9%BA%BC%20_/)
## 3D Print PSS
使用 process 類別
```csharp=
public void RunPythonScript(string sArgName, string args = "", params string[] teps)
{
count = 0; // initialize
Process p = new Process();
string path = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + sArgName;// 獲得python檔案的絕對路徑(將檔案放在c#的debug資料夾中可以這樣操作)
path = @"C:\Users\chiangkd\Desktop\Parameter-Suggestion-System\" + sArgName;//(因為我沒放debug下,所以直接寫的絕對路徑,替換掉上面的路徑了)
p.StartInfo.FileName = @"python.exe";//沒有配環境變數的話,可以像我這樣寫python.exe的絕對路徑。如果配了,直接寫"python.exe"即可
string sArguments = path;
foreach (string sigstr in teps)
{
sArguments += " " + sigstr;//傳遞引數
}
sArguments += " " + args;
p.StartInfo.Arguments = sArguments;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.BeginOutputReadLine();
p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
Console.ReadLine();
p.WaitForExit();
}
```
[Process.OutputDataReceived 事件](https://docs.microsoft.com/zh-tw/dotnet/api/system.diagnostics.process.outputdatareceived?view=net-6.0)
先宣告一個 `Process` 類變數
- `StartInfo` 獲取或設置要傳遞給 `Process` 的 `Start` 方法的屬性
- `Arguments` open 程式的命令列引數
- `UseShellExecute` 取得或設定,是否要使用作業系統 Shell 來啟動 `process`
- 如果在啟動處理序時使用 `Shell`,則為 `true`,如果處理序應直接從可執行檔建立,則為 `false`。 預設值是 `true`
- `RedirectStandard` 、 `RedirectStandardInput` 、 `RedirectStandardError`
- 取得或設定,輸入輸出錯誤是否應該要從資料流讀取/寫入
- `CreateNoWindow` 如果應該啟動處理序而不建立要包含處理序的新視窗,則為 `true`,否則為 `false`。 預設為 `false`。
**==通過 standard IO 進行通訊==**
### GBDT

- CatBoost
- auto-encoder
- symmetric(oblivious) trees
- 最大的特點對類別特徵的直接支援,甚至允許字串類型的特徵進行模型訓練。
- XGBoost
- 預分類 (presorted)
- 對於每個節點,列舉所有的特徵
- 對於每個特徵,按特徵值對例項進行分類
- 使用線性掃描根據該特徵基礎資訊增益的程度確定最佳分割
- 以最佳的分割解決方案來處理所有的特徵
- LightGBM
- Leaf-wise
- 單側取樣技術 (GOSS)
- 保留所有具有大梯度的例項,並在具有小梯度例項上執行隨機取樣
- 假設我有50萬行資料,1萬行有更高的梯度。所以我的演算法會選擇(更高梯度的1萬行 剩餘49萬行隨機選擇的x%)。假設x是10%,那麼在發現的分割值的基礎上,選擇的全部行數是50萬中的5萬9千。
- 這裡的基本假設是,具有小梯度訓練例項的樣本訓練誤差較小,並且已經訓練得很好。
- 為了保持相同的資料分佈,當計算資訊增益時,GOSS為小梯度的資料例項引入了一個常數乘數。因此,GOSS在減少資料例項的數量和保持學習決策樹的精確性之間取得了良好的平衡。
:::info
個人理解 : 針對梯度較大的點給他較大的權重,因為較大的梯度有更高的誤差,利於我們找到最優的分割點,較小的梯度則隨機抽取一定的百分比,計算時會更加快速,缺點容易過度擬合。
:::
[CatBoost、LightGBM、XGBoost](https://hackmd.io/@LBear/Sk83b33kL)
### Cross Entropy
## CCPNS
**Get Average Price**
```python
price = requests.get(url + 'api/v3/avgPrice', params={'symbol': symbol}).json()['price']
```
[IFTTT](https://zh.wikipedia.org/zh-tw/IFTTT)
## VLAN
- 靜態 VLAN
- Port-based
- 動態 VLAN
- MAC-based
- 這種方式會使用 VMPS (VLAN Management Policy Server) 這種額外設備來協助達成動態 VLAN 的設定,而 VMPS 可以用 Catalyst 5000 系列的 Switch 設備或是其他的伺服器來架設,不過一般最常用的 Cisco Catalyst 2950 不能用來架設 VMPS
### 使用 Trunk 來傳遞多個 VLAN 間的資料,(==只有 FastEthernet 等級以上才可以做 Trunk==)
Trunk 主要分成兩種協定: 802.1q 協定和 ISL 協定。
- 簡單來說,Trunk 會在資料內增加一個標籤 (Tag),用來表示目前這份資料是屬於哪一個 VLAN,貼上標籤後再把這分資料傳到另一台設備。另一台設備收到之後,再根據這個標籤得知這份資料是屬於哪一個 VLAN ,然後把這份資料送往所屬的 VLAN。
- 802.1Q 協定
IEEE 802.1Q 協定在 VLAN 中通常用來連接多個 Switch 和 Router 設備,而 Cisco 的設備在 Fast Ethernet 和 Gigabit Ethernet 介面上都支援 IEEE 802.1Q 協定。基本上每一個套用 802.1Q 協定的 port 都會被指定成 Trunk 類型,而所有 Trunk 上 的 port 都隸屬於 Native VLAN
- Native VLAN 是設備上預設的 VLAN , Native VLAN 有一個作用是,所有沒有被貼上標籤的資料都會被送往這個 Native VLAN,每個 VLAN 都會有一個 ID 用來區分 VLAN , 而 Native VLAN 的預設 ID 就是 VLAN 1
- ISL 協定
Inter-Switch 運作於, OSI 網路的第二層 (Data Link Layer) ,做法就是在前面增加一段表頭,並在最後增加一段 CRC ,由於 ISL 協定與任何協定無關,因此 ISL 能夠封裝任何種類的上層資料
- 802.1Q 與 ISL 協定比較
ISL 協定是用硬體來時做,因此所能支援的 VLAN 個數依照硬體的好壞而定,速度也是依照硬體的好壞來決定,而 802.1Q 協定是在軟體上做處理,所以速度想必比較慢。
[L2 Switch 與 L3 Switch 差別](https://bubble727.pixnet.net/blog/post/24850127)
- Sub Interface
[[筆記]Cisco基本指令-分割子介面(Sub-Interface)](https://david50.pixnet.net/blog/post/45271917-%5B%E7%AD%86%E8%A8%98%5Dcisco%E5%9F%BA%E6%9C%AC%E6%8C%87%E4%BB%A4-%E5%88%86%E5%89%B2%E5%AD%90%E4%BB%8B%E9%9D%A2(sub-interface))
## Core register

- R0 to R12 register are for general purpose
- 用於一般用途,例如數據操作,儲存數據,儲存地址
- All the core register are 32 bit wide.
- R13 is called as SP (stack pointer)
- 該 register 實際上用於跟蹤 stack memory
- Stack pointer 主要分為 PSP, MSP
- PSP : Process Stack Pointer
- MSP : Main Stack Pointer
- 這些 register 被稱為 Banked version of SP
- R14 is call link register (LR)
- 紀錄函式呼叫結束時,要回傳到 caller 的實際位址
```c
08000213: bl 0x80001d4 <generate_interrupt>
```
- `bl` 代表具有鏈結的分支,當你對鏈結只用分支時,鏈接 register 將更新為寄信人地址。
- 使用 `bx` `lr`
- `bx` means branch indirect (間接分支)
```c
080001fd: bx lr
```
- LR 的值會被複製到 PC 中,這就是執行控制回復調用方的方式。
- R15 Program Counter(PC)
- 包含當前程式地址(當前要執行的指令), reset 時,處理器將 [reset vector](https://en.wikipedia.org/wiki/Reset_vector) 的值載入 PC
:::info
在計算中,重置向量是中央處理單元在重置後查找它將執行的第一條指令的默認位置。重置向量是指針或地址,只要CPU能夠執行指令,它就應該始終從該指針或地址開始。該地址位於非易失性內存的一部分中,該部分已初始化為包含啟動CPU操作的指令,這是引導包含CPU的系統過程中的第一步。
:::

---

- Program Status Register (PSR)
- 代表程式當前執行的狀態
- 32 bits wide
- 實際上是 三個不同 register 的集和
- Application PSR (APSR)
- Interrupt PSR (IPSR)
- Execution PSR (EPSR)

- APSR
- 包含所有 condition flags (Negative flag, zero flag...) 以便檢測結果為負或結果為零或任何進位 (carry) 或借位 (borrow)
- 如果當前指令在 ALU 中導致任何的負值, 則 negative flag 會被設置
- 如果當前指令在 ALU 中導致任何的零值, 則 zero flag 會被設置
- 如此一來就可以知道 assembly programming 的 decision (當在寫 assembly 的時候,使用這個條件標誌很有用,根據結果進行分之,對零做出其他決定...)
- IPSR
- 包含當前中斷服務程序的 IRQ 編號
- EPSR
- 注意 EPSR 的 bit 的位置 (T bit is important!)
- T bit -> Thumb state bit
- T bit
- T bit 設定為 `1` ,處理器則會認為他的下一條指令是來自 Thumb ISA
- 如果 T bit 設定為 `0` 則即將執行的下一條指令是來自 ARM ISA
- ARM Cortex Mx 僅支持 Thumb state , T-bit 須保持為 `1`
## Reset sequence of the processor
一旦將 Reset 訊號發送給微控制器的處理器,如何 Reset 處理器或微控制器?
1. 將 PC 加載為 0
2. 將 `0x0000_0000` 的值讀入 MSP
- `0x0000_0000` 屬於 flash memory 或 ROM
- MSP = value @ `0x0000_0000`
3. 將 `0x0000_0004` 的值讀入 PC
- `0x0000_0004` 的值是 reset handler 的地址
4. PC jumps to the reset handler
5. 從 reset handler 中調用 `main()` function
## Importance of T bit of the EPSR
1. 各種 ARM processors 支持 ARM-Thumb 互通,可以在 ARM-Thumb 狀態之間切換,
2. 處理器必須處於 ARM 狀態才能執行 ARM ISA(instruction set architecture) 的指令,處理器必須處於 Thumb 狀態才能執行 Thumb ISA
3. 如果 ESPR 的 ‘T’ bit 為 set(1) ,則處理器認為下一條指令即將執行的操作來自 Thumb ISA
4. 如果 ESPR 的 ‘T’ bit 為 reset(0) ,則處理器認為下一條指令即將執行的操作來自 ARM ISA
5. Cortex Mx processor 不支持 “ARM” state ,因此 ‘T’ bit 的值必須始終為 1
- Failing to maintain this is illegal and this will result in the “Usage fault” exception.
6. PC(program counter) 的 LSB (bit 0) 連結到 ‘T’ bit 。當將值或地址加載到 PC 時, bit[0] 的值會被加載到 ‘T-bit’ 。因此在 PC 中放置的任何地址的第 0 位都必須為 1
- 通常編譯器就會注意這一點, programmers 不用擔心
- 當在 PC 中放入一些原始值或原始地址時才需要特別小心,應確保原始值應該是奇數(bit[0] 才會是 1)
7. **==所以在 vector table 中所看到的 vector address 都會增加 1==** 如果僅查看 vector table ,所有的地址都是奇數 -> 就是因為 T - bit
## bit banding
**==General formula:==**
$Alias\ address = alias\_base + (32 * (bit\_band\_memory\_addr - bit\_band\_base)) + bit * 4$
**計算 SRAM `0x20000200` 的第 7 bit**
- $alias\_ base$ : `0x22000000`
- $bit\_band\_memory\_addr$ : `0x20000200`
- $bit\_band\_base$ : `0x20000000`
$0x22000000 + (32 * (0x20000200 - 0x20000000)) + 7 * 4$
## Stack memory and allocation


- ==**ARM Cortex Mx Processor 都是使用 Full descending stack (無法更改!)**==
:::info
為什麼要 MSP 和 PSP?
方便管理,例如 MSP 跑 handler mode , PSP 跑 user task
:::
## Change SP to PSP for thread mode


- 在 Reset 後, MSP 會做為 current stack pointer ,也就是說 SP 會複製 MSP 的內容
- Thread mode 可以改變 SP 為 PSP ,透過 CONTROL register 的 **SPSEL** bit
- `SPSEL` = `0` : MSP is the current stack pointer (default)
- `SPSEL` = `1` : PSP is the current stack pointer

- Handler mode 的 code execution 永遠是用 MSP 作為 current stack pointer ,這代表在 Handler mode 中更改 CONTROL register 的 SPSEL 的值沒有意義,會被忽略
- To access MSP and PSP in assembly code, you can use the **MSR** and **MRS** instructions.


- 在 `fun_x` 中, 4 個參數傳遞給 `fun_y` 將這 4 個變數作為 local variable ,根據規範,這 4 個 register 用於將參數從一個函數傳遞給另一個函數。
- 在函數調用期間, `fun_x` 的功能是,將這些值複製到其內部 registers 中,然後 `fun_y` 複製 register 內容到 local variable
- 當 `fun_y` 想要返回結果,則將使終使用 R0 register ,如果結果是 64 bit ,則使用兩個 register , R0 和 R1 (**All the core register are 32 bit wide.**)
- 如果輸入的參數大於 4 個,會使用 R0, R1, R2, R3 **然後剩下的用 STACK 存!**
- **根據此標準,將不會使用 R4 傳遞輸入參數**

## Open-Drain and Push-Pull