contributed by < liangchingyun
>
vwifi 是一個具體而微的 WiFi 裝置驅動程式,採用 cfg80211 框架,目前支援掃描、連接等 cfg80211 的介面操作,並得以正確處理 Tx/Rx 封包。
Problem:
cfg80211_inform_bss
中的 scan_width
在 v.6.7 以後的版本已被移除,原因是掃描頻寬目前都是以 20MHz 為主,因此不需要另外描述掃描頻寬。
Solution:
確保程式碼中有用到 scan_width
的部份只在 v.6.7 前做運用。
Problem:
cfg80211_beacon_data
在 v.6.7 以後的版本以後被加到 cfg80211_ap_settings
中。
Solution:
加入 cfg80211_ap_update
,其中包含更動的兩個參數及 cfg80211_beacon_data
。 回呼函式中有用到 cfg80211_beacon_data
的部份也進行調整。
有一些回呼函式還沒有被實作,例如 station dump (顯示與 Wi-Fi AP 連接的 station 的相關資訊,包括資料傳輸率和 MCS )。
Modulation 可以控制資源單位可以攜帶幾個 symbol (bits) ,因此會影響資料傳輸率。
採用 802.11n (HT) 做為 PHY,設置如下 :
Modulation : 64-QAM
Data Bandwidth : 20MHz
Number of Spatial Streams : 4
參照 802.11n (HT) 調變對照表可得:
Number of Data Subcarriers : 52
Number of Coded Bits per Subcarrier per Stream : 6
Coding : 5/6
OFDM Symbol Duration : 3.2 us
Guard Interval Duration : 0.8 us
代入上方計算資料傳輸率的公式可得 data rate = 260 Mbps ,藉此驗證程式所計算出來的結果是否相符。
在結構體 vwifi_vif
上新增 tx_power
以描述裝置的傳輸功率。
在 cfg80211_ops
的架構上新增實作 vwifi_set_tx_power
及 vwifi_get_tx_power
兩個回呼函式,則使用者可以透過 iw dev [interface] set txpower [auto/limit/fixed] [transmit power (mBm)] 設定裝置傳輸功率。
Problem:
在使用 iw
指令時,會導致 et_tx_power
的輸入參數 wdev
為 NULL,詳見 cfg80211: allow per interface TX power setting 。
Solution:
新增函式 wiphy_get_vwifi_vif
改以利用參數 wiphy
取得裝置的 virtual interface,而非 wdev
。
改進方向
加上距離位置設定,就可以推得 station 所收到 Wi-fi AP 的訊號。
實作輕量化的傳輸行為模式
當一個裝置被設定為 Ad-hoc mode ,就可以跟其他處在同一個 Ad-hoc 網路的裝置任意傳輸,而不用直接連線。
在 wiphy
上新增 NL80211_IFTYPE_ADHOC
interface type,使 Linux 系統能知道此裝置已成為 Ad-hoc (IBSS) 模式(透過 vwifi_change_iface
的 operation 切換)。使用者可透過命令 iw dev [interface] set type ibss 將裝置切換成 IBSS 模式。
加入、離開特定頻段的 IBSS 網路。
ibss_list
以便快速找到所有的 IBSS 裝置。在轉送前要確認 source 和 destination 是否處於相同 IBSS cell,以及確認是否在該 IBSS cell 的同個 BSS 中。
測試:
ah_inform_bss(vif)
執行 scan 可發現該 bss 資訊
Linux 下關於視訊設備的驅動框架,支援的設備有:
兩種角度來看 V4L2 框架
Frambuffer: RAM 中的一段連續記憶體,CPU 或 GPU 會把要顯示的影像放到 Framebuffer 中,讓 Display 裝置顯示。
Problem:
在其版本上無法成功編譯
Solution:
class_create(owner, name)
–> class_create(name)
struct vb2_queue
的 member 名稱: min_buffers_needed
–> min_queued_buffers
struct fb_info
的方式: info->flags = FBINFO_FLAG_DEFAULT;
–> fb_data->info = framebuffer_alloc(0, &dev->vdev.dev);
Problem:
有多個載入模組時所配置的記憶體位置在卸載時沒有被釋放,導致 memory leak。
Solution:
使用 rcu_varrier()
來解決來不及釋放的記憶體問題。
LKMPG (Linux Kernel Module Programming Guide)
Problem:
tasklet 在運作時是 non-blocking 的,因此一定會讓 tasklet_fn
全部完成後才會繼續做其他事,且在 tasklet 中不宜使用 delay 或 sleep 等操作。
Solution:
將範例中的 delay 時間做調整。
simrupt 是一個 Linux 核心模組,用於展示延遲工作 (deferred work) 和以下核心概念實作:
tasklet
是 Linux kernel 中的一中軟中斷機制,用於中斷上下文中處理較長時間的任務,相關的定義及函式都存在 linux/interrupt.h 中。
process 使用 mutex 時,必須先持有 mutex 才得以進入 CS (critical section) 存取資源,
結束後再釋放 mutex 讓其他 process 使用。
若無使用 mutex 確保 critical section 的單一存取,有可能會發生 race condition。
Rhashtable (Relativistic hash tables)
在過去的 hash tables 中,若需要進行同步的存取,會需要 mutex locks 來做存取的控制。但在多核處理器的環境底下, mutex locks 導致使執行序相互等待,效率下降。
Problem:
Bucket 數量太少,每個 bucket 後面接的鏈結串列很長,節點讀取很花時間
–> 擴張 hash table 使 bucket 增加
–> 要做 resizing ,影響讀取效率
縮小 hash table,減少 bucket 數量。
Step 0: 原本的 hash table 有奇數、偶數的 bucket:
Step 1: 建立新的 hash table 指標,指向目前 hash table 第一個 bucket 的第一個節點:
Step 2: 把奇數 bucket 的最後一個節點連接到偶數 bucket 的第一個節點:
Step 3: 把原始 hash table 的指標刪除
注意:可能還有 readers 在查找資料,因此須等一段時間,確保所有 readers 皆已查找完畢,再進行刪除。
Step 4: 發布新的 hash table ,確認接下來的 readers 都讀到最新的內容
Step 1: 新的 hash table ,奇數 bucket 連接到舊有的奇數節點,偶數 bucket 連接到舊有的偶數節點
Step 2: 將舊有的 hash table 指標指向新的 hash table
Step 3: 等 readers 全部讀取完,刪除舊的指標
Step 4: 做指標的修改 (unzip),第一個節點會往下尋找在新的 hash table 與它在相同 bucket 中的節點
Step 5: 持續上個步驟直到所有節點都指向新的 hash table
比較 RP, DDDS, rwlock 在兩種情況下效能的差異。
在過去的版本的 rhashtable 結構體中,若要插入、刪除或 resize 的操作,需要使用 mutex lock 來保護 hash table ,防止操作被同步。而最新版本的中則使用 per-bucket spinlocks ,只鎖定正在被修改的 bucket 而非整個 hash table ,使其他的 bucket 則可以繼續進行原本的操作。