顯示具有 Embedded 標籤的文章。 顯示所有文章
顯示具有 Embedded 標籤的文章。 顯示所有文章

2024年10月2日 星期三

From120s to 0.5s Programming Optimization

程式算法本身的複雜度

CPU的速度和設計架構

CPU的位元帶寬

自己的程式的寫法




將一個照片RGB格式的彩色圖像轉換成黑白照片。

轉換的公式如下:
  Y = 0.299 * R + 0.587 * G + 0.114 * B; 

圖像尺寸640*480*24bit,RGB圖像已經按照RGBRGB順序排列的格式了。


以下是輸入和輸出的定義:

已經完成了第一個最佳化
看得出來最佳化在哪裡嗎?


優化原則: 圖像是一個2D資料,我用一個1維陣列來存儲。 編譯器處理1維陣列的效率高過2維陣列

這大概是能想得出來的最簡單的寫法了,實在看不出有什麼毛病,好了,編譯一下跑一跑吧。

這個代碼分別用VC6.0和GCC編譯,產生2個版本,分別在PC上和embedded system上面跑。

速度多少?說出來嚇死你!


第一次試跑的成績

在PC上,因為有硬體浮點運算處理器,CPU頻率也夠高,計算速度為20秒

embedded system ,沒有以上2個優勢,浮點操作被編譯器分解成了整數運算,運算速度為120秒左右
這只是一副圖像的運算速度!!

上面這個代碼還沒有跑,就已經知道會很慢了,因為這其中有大量 的浮點運算。只要能不用浮點運算,一定能快很多。

那這個公式怎麼能用定點的整數運算替代呢?

可以如何化簡?
我們就先簡化算式D吧!

RGB的取值範圍都是0~255,都是整數,只是這個係數比較麻煩, 不過這個係數可以表示為:
這一下,能快多少呢?

化簡後的成績


PC上的速度2秒

Embedded system
上的速度45秒


這個代碼編譯後,又快了20%
還是太慢!

雖然快了不少,還是太慢了一些,
20秒處理一幅圖像,地球人都不能 接受!

仔細看一下這個式子!

RGB的取值有文章可做,RGB的取值永遠都大於等於0,小於等於
255,我們能不能將D,E,F都預先計算好呢?然後用查表算法計 算呢?
我們使用3個數組分別存放DEF的256種可能的取值,然後。。。


查表數組初始化



突破音障!
這一次的成績把我嚇出一身冷汗,執行時間居然從30秒一下提高到 了2秒!在PC上測試這段代碼,眼皮還沒眨一下,代碼就執行完了。

一下提高15倍,爽不爽?
下一程,幾 秒?

120秒 ->45秒 -> 30秒 -> 2秒
還能再 快嗎?

很多embedded sysytem 的32bitCPU,都至少有2個ALU,能不能讓2個ALU都跑起來?

2個ALU處理的數據不能有數據依賴,也就是說:
某個ALU的輸入條件不能是別的ALU的輸出,這樣
才可以並行
到這裡,似乎已經足夠快了,但是我們反覆實驗,發現,還有辦法再快!

Int D[256],E[256],F[256]; //查表數組 更改為:
Unsigned short D[256],E[256],F[256]; //查表數組

這是因為編譯器處理int類型和處理unsigned short類型的效率不一樣
將函數聲明為inline,這樣編譯器就會將其
嵌入到母函數中,可以減少CPU調用子函 數所產生的開銷
這2個小小的改進帶來的效益!


一次的成績是: 0.5秒

現在,我們已經達到了客戶的要求!

如果加上以下措施,應該還可以更快:

把查表的數據放置在CPU的高速數據CACHE
裡面

把函數calc_lum()用組合語言來寫

同樣的需求,寫法不一樣,速度可以從120秒 變化為0.5秒,說明CPU的潛能是很大的!看你 如何去挖掘。










2021年2月24日 星期三

使用Samba在linux建立Windows網路芳鄰的分享資料夾-區分唯讀用戶與可寫入用戶的案例

雖然拜讀了鳥哥對Samba伺服器詳細的解說,但是在實務上,如果建立的分享資料夾,需指定部分用戶能讀寫,部分用戶只能讀取,未指定的用戶則完全無權限,要怎樣設定呢? 還是看得霧煞煞的,自己嚐試做不同的設定終於成功了,如果有此類需求,可以按照下面步驟試試看:

1. 更改/etc/samba/smb.conf
[project]                                                  # 顯示在Windows網路芳鄰的目錄名稱
       comment =Project Group
       path = /data/project                         # 在linux中的路徑,在步驟3建立此目錄
       browseable=yes                             # 大家都可以看到,但是只有valid users才能進入
       public=no
       writable = yes
       write list=@prjwriters                              # 寫入的群組
       valid users=@prjreaders,@prjwriters  # 可連入的群組
       create mask = 0664                       # 注意權限的設定
       directory mask = 0775

2. 更改/etc/group,指定寫入群組的帳號與唯讀群組的帳號
prjreaders:x:10003:user1,user2,user3
prjwriters:x:10004:user4,user5,user6

3. 建立分享目錄,並設定目錄權限
     mkdir /data/project
     chmod 2775 project               # 注意權限的設定

4. 要重開Samba service
     /etc/init.d/smb restart

上面步驟不含Samba Server架設與Samba帳號建立,還是請大家拜讀鳥哥的書籍。

參考資料

1.鳥哥私房菜 第十六章、檔案伺服器之二: SAMBA 伺服器 http://linux.vbird.org/linux_server/0370samba.php#theory_source 

資料來源: https://fredwang.blogspot.com/2013/05/sambalinuxwindows.html


Linux mount the samba disk

mount -t cifs -o username=guest,password="" //192.168.1.183/share /home/usb

2021年2月18日 星期四

Linux 匹配文字 grep 指令用法教學與範例

本篇介紹如何使用 Linux 的 grep 指令,根據關鍵字或正規表示法找出想要的資料。

Linux 的 grep 是一個很好用的指令,可以從串流資料或檔案中,使用關鍵字或正規表示法(regular expression)篩選出想要尋找的資料,並且顯示出來,以下是 grep 的用法教學以及實際範例。

grep 這個指令名稱其實是來自於正規表示法的 g/RE/p,其意義是代表以正規表示法全域搜尋並列印出來(globally search for RE and print it)。

搜尋關鍵字

grep 最基本的用法就是以普通的關鍵字來搜尋,其基本語法如下:

grep 關鍵字 檔案1 檔案2 ...

例如在 /etc/os-release 檔案中搜尋 Ubuntu 關鍵字:

grep Ubuntu /etc/os-release
NAME="Ubuntu"
PRETTY_NAME="Ubuntu 18.04.3 LTS"

執行的結果會列出所有含有關鍵字的整行文字。

grep 亦可搭配萬用字元(*)同時搜尋多個檔案,例如在 /etc/ 目錄之下所有 *.conf 檔案中,尋找 network 這個字眼:

grep network /etc/*.conf
ltrace.conf:hex(uint) inet_network(string);
nsswitch.conf:networks:       files
sysctl.conf:# Additional settings - these settings can improve the network
sysctl.conf:# security of the host and prevent against some network attacks
sysctl.conf:# redirection. Some network environments, however, require that these

搜尋多個檔案時,在輸出中會標示資料來源是哪一個檔案。

除了搜尋檔案內容之外,亦可搭配管線(pipe)篩選串流資料,例如篩選出含有 network 關鍵字的檔案名稱:

ls /etc/ | grep network
network
networkd-dispatcher
networks

不分大小寫

grep 預設會區分字母的大小寫,如果希望以不分大小寫的方式搜尋,可以加上 -i 參數:

grep -i Ubuntu /etc/os-release

標示行號

若要標示匹配文字的行號,可以加上 -n 參數:

grep -n Ubuntu /etc/os-release
1:NAME="Ubuntu"
5:PRETTY_NAME="Ubuntu 18.04.3 LTS"

反向匹配

若想要將匹配的資料排除,只顯示出沒有關鍵字的那幾行資料,可以加上 -v 參數。例如顯示不包含 Ubuntu 關鍵字的那幾行:

grep -v Ubuntu /etc/os-release

遞迴搜尋檔案

如果想要在指定目錄與其子目錄下所有的檔案中,搜尋指定的關鍵字,可以加上 -r 參數:

grep -r ubuntu /etc/

如果只想要從特定的檔案中尋找關鍵字,可以使用 -r 搭配 --include 指定檔案類型:

grep -r --include="*.conf" ubuntu /etc/

如果自己的權限沒辦法讀取所有的檔案,就會出現某些檔案無法讀取的錯誤訊息,這時候可以將這種錯誤訊息導向 /dev/null,只看正常訊息就好:

grep -r ubuntu /etc/ 2>/dev/null

顯示前後幾行

有時候只顯示匹配成功那一行,不容易看出是否是我們想要找的資料,這時候可以加上 -A(After)、-B(Before)或-C(Context),指定要顯示的前後行數:

grep -A 1 Ubuntu /etc/os-release


grep -B 1 Ubuntu /etc/os-release


grep -C 1 Ubuntu /etc/os-release

顏色標示

grep 可以使用顏色標示的方式,將成功匹配的部分文字標示出來,方便使用者閱讀。顏色標示功能可以透過 --color=never--color=always--color=auto 這幾種參數來關閉、開啟或設為自動。開啟顏色標示的輸出會像這樣:

grep 顏色標示

grep 顏色標示

正規表示法

grep 在搜尋關鍵字時,其實是以正規表示法的方式匹配文字的,所以一般的正規表示法都可以直接使用,以下是一些常用的範例。開頭與結尾是最常用的:

ls | grep "^a"


ls | grep "b$"


ls | grep "^[ab]"


ls | grep "[ab]$"

各種出現次數的指定:

ls | grep "^ab*"


ls | grep "^ab?"


ls | grep "^ab+"

多種字眼的組合,也很常用:

ls | grep "ab|cd"


ls | grep -E "ab|cd"

如果只想要精準篩選出 net 這個單字,可以這樣寫:

ls | grep "<net>"
issue.net

這樣就只會出現含有 net 這一個單字的結果,像是 network 這樣的字眼就會被排除。

參考資料:鳥哥的 Linux 私房菜Carlos-StudioLinux 命令大全 

資料來源: https://blog.gtwang.org/linux/linux-grep-command-tutorial-examples/

Linux udev usb 插入自訂執行 script

 在這個單元,我們要開始運用 udev 呼叫 my_script 的時候,所傳過來的環境變數(environment variables)。其中最重要,而且每次都一定會設定的變數就是:SUBSYSTEM 及 ACTION。其他的許多變數常因 SUBSYSTEM 而異。

第一個單元裡,我們曾寫了一個範例程式,叫做 my_script,讓 Linux 系統每次發生 udev 事件時,都會發出一次聲響(sound effect)。以一個 USB thumb drive 做實驗,插入(insert)或拔除(unplug)時分別都會聽見約 6、7 次,以及 3 次聲響。也就是說,插入一個 USB 隨身碟時,系統上會產生許多次的 uevents。拔除時亦然。我們再複習一下這個簡單的掛勾機制(hook):

$ cat /etc/udev/rules.d/z99_test.rules
RUN+="/home/nobody/my_script"
$ ls -l ~/my_script
-rwxr-xr-x 1 nobody nobody 1056 Nov 22 03:04 /home/nobody/my_script

為了篩選出(match)方便與之掛勾的特定事件(uevent),我們必須更進一步追蹤這些事件的內幕。首先,把 my_script 改寫為以下 3 行:

#!/bin/sh
echo $SEQNUM $SUBSYSTEM $ACTION $DEVNAME >> /tmp/my_script.log
exit $?

先以 root 的權限把 logfile /tmp/my_script.log 的內容清空,再插入,或拔除手邊任何一個 USB 隨身碟。然後再看看在 /tmp/my_script.log 這個檔案裡面,我們到底收集到了那些情資。結果大概會很接近如下所示的內容:

2124 usb add /dev/1-6
2125 usb add
2126 scsi_host add
2127 usb_device add /dev/bus/usb/001/007
2134 bdi add
2128 scsi add
2129 scsi_disk add
2131 scsi change
2130 scsi_device add
2132 block add /dev/sda
2133 block add /dev/sda1
2136 scsi_disk remove
2135 scsi_device remove
2137 block remove /dev/sda1
2140 scsi remove
2143 usb_device remove /dev/bus/usb/001/007
2138 bdi remove
2141 scsi_host remove
2142 usb remove
2139 block remove /dev/sda
2144 usb remove /dev/1-6

其中第一個 field 是環境變數 SEQNUM 的值,可用來判別事件發生的先後順序,第二個是 SUBSYSTEM,第三個是 ACTION,第四個則為 DEVNAME 的值,其中,DEVNAME 有時候並未設定。細數後可知,插入 USB 的動作導致系統上一共產生了 11 次的 uevents,拔除時,則產生了 10 次的 uevents。在這眾多的 uevents 當中,特別適合用來唯一識別 USB 裝置插入(insert)及拔除(remove)動作的事件,也就是只發生過一次的事件可說是:

SUBSYSTEM==usb_device
ACTION==add

以及

SUBSYSTEM==usb_device
ACTION==remove

以下這個 my_script 示範如何限縮這個 script 的反應,只在插入或移除一個 USB device 時發出聲響,而且分別只響一次:

#!/bin/sh
# my_script example 3-1
LOGFILE=/tmp/my_script.log # 定義變數 LOGFILE
exec 3>> $LOGFILE && exec >& 3 && exec 2>&1 # 把 stdout/stderr 導入 $LOGFILE
SND_USB_INSERT="/xp/WINDOWS/Media/Windows XP Pop-up Blocked.wav" # 定義聲音檔
SND_USB_REMOVE="/xp/WINDOWS/Media/chimes.wav" # 定義聲音檔

if [ "$SUBSYSTEM" = "usb_device" -a "$ACTION" = "add" ]
then
    echo ""
    echo "=============================="
    date "+%G-%m-%dT%H:%M:%S %z"
    echo "$SUBSYSTEM $ACTION"
    echo "aplay -q \"$SND_USB_INSERT\""
    aplay -q "$SND_USB_INSERT"
elif [ "$SUBSYSTEM" = "usb_device" -a "$ACTION" = "remove" ]
then
    echo ""
    echo "=============================="
    date "+%G-%m-%dT%H:%M:%S %z"
    echo "$SUBSYSTEM $ACTION"
    echo "aplay -q \"$SND_USB_REMOVE\""
    aplay -q "$SND_USB_REMOVE"
fi
exit $?

編輯 my_script 的時候,要確認聲音檔是不是存在。編輯完畢之後,要記得做

$ chmod 755 ~/my_script

以上的 script 是說,當(if) SUBSYSTEM 這個變數的值等於(=)usb_device,而且(-a)當 變數 ACTION 的值為 add 的時候,就(then)執行一些 echo(1), date(1), aplay(1) 的指令;要不然的話當(elif)變數 SUBSYSTEM 的值為(=) usb_device,而且(-a)變數 ACTION 的值為(=)remove 時,就(then)執行另一批指令。請注意,方括號 [ 及 ] 跟 = 的前後,要有空白(space),變數(variable)的前後,也必須加上雙引號(double quotation marks),因為變數值可能會包含空白字元(embedded spaces)。

最後一個指令 "exit $?",是要結束這個 script 並把當時的執行結果傳回(return)給呼叫這個 script 的任何程式。想要省略掉的話,也沒什麼問題,然而我們必須平時就養成撰寫程式的正確習慣,在 UNIX 系統上,任何程式、函式都必須要有傳回值,就算是不知道有誰會去用它。我們不希望看到那一天,當有人突然去用它的時候,就必須面對噩運。這看似小事一件,然而缺乏持續性對小節的正確習慣或態度,我們對核四的運轉,為了自己的生存,必須反對到底。

做完以上的 script,只要隨手找個 USB 設備插入,或拔出,就都會聽到變數 $SND_USB_INSERT 或是 $SND_USB_REMOVE 所設定的聲效檔(sound file)。這是採用正面表列只當變數 SUBSYSTEM 內傳過來的值為 usb_device 時,才依變數 ACTION 的值是 add 或是 remove 來採取行動。

如果我們也希望這個程式對記憶卡以及 PCMCIA、CF 以及 SD 插槽也有所反應的話,則可修改程式,也檢查變數 SUBSYSTEM 是否為 "mmc" 或是 "pcmcia"。以同樣的方法可以得知,SD 卡插槽,以及 PCMCIA 插槽的插入與拔除動作可以:

SUBSYSTEM==mmc
ACTION==add

SUBSYSTEM==mmc
ACTION==remove

SUBSYSTEM==pcmcia
ACTION==add

SUBSYSTEM==pcmcia
ACTION==remove

可靠地識別。以下的另一個 my_script 範例則示範採用負面表列的邏輯結構,檢查變數 SUBSYSTEM 如果不是 "usb_device"、"mmc"、"pcmcia" 其中之一的話,即立刻結束程式(terminate),不然,則印出訊息,再判斷變數 ACTION 為 "add" 或 "remove" 分別作出對應的音效:

#!/bin/sh
# my_script example 3-2
LOGFILE=/tmp/my_script.log # 定義變數 LOGFILE
exec 3>> $LOGFILE && exec >& 3 && exec 2>&1 # redirect stdout/stderr 到 LOGFILE
SND_INSERT="/xp/WINDOWS/Media/Windows XP Pop-up Blocked.wav" # 定義聲音檔
SND_REMOVE="/xp/WINDOWS/Media/chimes.wav" # 定義聲音檔

if [ "$SUBSYSTEM" != "usb_device" -a "$SUBSYSTEM" != "pcmcia" -a "$SUBSYSTEM" != "mmc" ]
then
    exit 0
fi

echo ""
echo "=============================="
date "+%G-%m-%dT%H:%M:%S %z"
echo "$SUBSYSTEM $ACTION"

if [ "$ACTION" = "add" ]
then
    echo "aplay -q \"$SND_INSERT\""
    aplay -q "$SND_INSERT"

elif [ "$ACTION" = "remove" ]
then
    echo "aplay -q \"$SND_REMOVE\""
    aplay -q "$SND_REMOVE"
fi
exit $?

編輯完畢、儲存檔案後,程式會立即生效。這時,無論是在 PCMCIA 插槽、CF 插槽、SD 插槽,還是 USB 插座插入或拔除週邊設備,電腦都會發出預設的音效,而且每個動作只會發出一次聲音,不像在第一單元那樣發出 6、7 次的聲響。

變數 ACTION 除了 "add" 跟 "remove" 兩個可能的值以外,還可能會是 "change"。這例如可能會發生於以下的情況:如果你使用的是一台含有內建電池的筆記型電腦(notebooks),那麼,在插上或拔掉外接電源線(AC power cord)時,udev 系統分別會產生兩種 uevents:

SUBSYSTEM=power_supply
ACTION=change
POWER_SUPPLY_ONLINE=1

以及

SUBSYSTEM=power_supply
ACTION=change
POWER_SUPPLY_ONLINE=0

我們現在就繼續改良以上的 my_script,讓它在插入跟拔掉電源線時,也會發出聲音信號:

#!/bin/sh
# my_script example 3-3
LOGFILE=/tmp/my_script.log # 定義變數 LOGFILE
exec 3>> $LOGFILE && exec >& 3 && exec 2>&1 # redirect stdout/stderr 到 LOGFILE
SND_INSERT="/xp/WINDOWS/Media/Windows XP Pop-up Blocked.wav" # 定義聲音檔
SND_REMOVE="/xp/WINDOWS/Media/chimes.wav" # 定義聲音檔

PRINT_DATE()
{
    echo ""
    echo "=============================="
    date "+%G-%m-%dT%H:%M:%S %z"
}

if [ "$SUBSYSTEM" != "usb_device" -a "$SUBSYSTEM" != "pcmcia" -a "$SUBSYSTEM" != "mmc" -a "$SUBSYSTEM" != "power_supply" ]
then
    exit 0
fi
if [ "$SUBSYSTEM" = "power_supply" -a "$ACTION" = "change" ]
then
    if [ "$POWER_SUPPLY_ONLINE" = "0" ]
    then
        PRINT_DATE
        echo "$SUBSYSTEM $ACTION OFFLINE"
        echo "aplay -q \"$SND_REMOVE\""
        aplay -q "$SND_REMOVE"
    elif  [ "$POWER_SUPPLY_ONLINE" = "1" ]
    then
        PRINT_DATE
        echo "$SUBSYSTEM $ACTION ONLINE"
        echo "aplay -q \"$SND_INSERT\""
        aplay -q "$SND_INSERT"
    fi
else
    if [ "$ACTION" = "add" ]
    then
        PRINT_DATE
        echo "$SUBSYSTEM $ACTION"
        echo "aplay -q \"$SND_INSERT\""
        aplay -q "$SND_INSERT"
    elif [ "$ACTION" = "remove" ]
    then
        PRINT_DATE
        echo "$SUBSYSTEM $ACTION"
        echo "aplay -q \"$SND_REMOVE\""
        aplay -q "$SND_REMOVE"
    fi
fi
exit $?

這個第三個版本,我們在程式的前面,定義了一個函數叫做 "PRINT_DATE ()",它是用來避免重複的程式碼(repeated codes),使得程式比較簡短易讀(readability)。

還記得我們把這個程式的所有 stdout 以及 stderr 都導向 $LOGFILE 了嗎?在指令行打:

$ less /tmp/my_script.log 

則會看到類似以下的文字紀錄(logs):

==============================
2011-11-11T05:02:52 +0800
pcmcia add
aplay -q "/xp/WINDOWS/Media/Windows XP Pop-up Blocked.wav"

==============================
2011-11-11T05:03:01 +0800
pcmcia remove
aplay -q "/xp/WINDOWS/Media/chimes.wav"

==============================
2011-11-11T05:03:16 +0800
mmc add
aplay -q "/xp/WINDOWS/Media/Windows XP Pop-up Blocked.wav"

==============================
2011-11-11T05:03:23 +0800
mmc remove
aplay -q "/xp/WINDOWS/Media/chimes.wav"

==============================
2011-11-11T07:24:26 +0800
power_supply change OFFLINE
aplay -q "/xp/WINDOWS/Media/chimes.wav"

==============================
2011-11-11T07:24:29 +0800
power_supply change ONLINE
aplay -q "/xp/WINDOWS/Media/Windows XP Pop-up Blocked.wav"

==============================
2011-11-11T05:05:18 +0800
usb_device add
aplay -q "/xp/WINDOWS/Media/Windows XP Pop-up Blocked.wav"

==============================
2011-11-11T05:05:46 +0800
usb_device remove
aplay -q "/xp/WINDOWS/Media/chimes.wav"

資料來源: http://kolmogolovi.blogspot.com/2011/11/linux-udev-3.html

2021年1月27日 星期三

mdadm軟RAID的刪除方法和注意事項

刪除整個RAID:


mdadm / dev / md0–fail / dev / sdb–remove / dev / sdb
mdadm / dev / md0–fail / dev / sdc–remove / dev / sdc
mdadm / dev / md0–fail / dev / sdc–remove / dev / sdd
mdadm / dev / md0–失敗/ dev / sde–刪除/ dev / sde
mdadm / dev / md0–失敗/ dev / sdf–刪除/ dev / sdf


mdadm–stop / dev / md0
mdadm–remove / dev / md0


mdadm–misc–zero-superblock / dev / sdb
mdadm–misc–zero-superblock / dev / sdc
mdadm–misc–zero-superblock / dev / sdd
mdadm–misc–zero-superblock / dev / sde
mdadm–misc–zero-超級塊/ dev / sdf


即:先刪除RAID中的所有設備,然後停止該RAID即可

為了防止系統啟動時候啟動raid
rm-f/etc/mdadm.conf
rm-f/etc/raidtab

檢查系統啟動文件中是否還有其他mdad啟動方式

vi/etc/rc.sysinit+/raid\c 

資料來源: http://www.4u.idv.tw/2018/09/14/mdadm%E8%BD%AFraid%E7%9A%84%E5%88%A0%E9%99%A4%E6%96%B9%E6%B3%95%E5%92%8C%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/

2020年12月18日 星期五

Yocto WiFi configuration for automatic connection at boot

Objective: This writeup will cover WiFi configuration on Raspberry Pi using the Yocto tool. The goal is to have an automatic WiFi connection on boot-up

Recommended prerequisite articles to read:

  1. Custom Raspberry Pi Image Build with Yocto

In the previous article, we built a console-only image for the Raspberry Pi 4. For such a headless set up, we need a smooth way to interact with the device. One of the most convenient way is the use of the SSH protocol that can allow us to remotely access the raspberry pi and even transfer files to it via scp. However, to use these tools the board and the host machine need to be connected in a way such as being in the same local network or connected to the internet. Hence to connect the Pi to the internet, we need to enable the WiFi.

We don’t want to be manually configuring the WiFi every time a reboot occurs. At the time being, we can assign a static IP address to our board since this is for in-house development. We will also hard code the router/network SSID and our password. All these can be performed after bootup but we want to have all the network configurations performed automatically at boot up.

1. Configure SSID and passphrase

Edit the wpa_supplicant.conf-sane in the following path … /meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/wpa_supplicant.conf-sane

ctrl_interface = /var/run/wpa_supplicant
ctrl_interface_group = 0
update_config = 1
 
Network = {
               ssid = "SSID"
               psk = "PASSWD"
}

2 . Script to initialize the wpa_supplicant and configure WiFi at boot up

Create a custom script “setup-wifi.sh” at the following path …/meta/recipes-core/initscripts/initscripts-1.0/setup-wifi.sh

#!/bin/sh
ifconfig wlan0 10.233.174.16   #Set the static IP address, should be unique
wpa_passphrase SSID  PASSWD> /etc/wpa_supplicant.conf
route add default gw 10.233.174.254  #Router IP address
wpa_supplicant -B -i   wlan0    -c    /etc/wpa_supplicant.conf
echo “nameserver 8.8.8.8” >> /etc/resolv.conf
echo “nameserver 10.233.174.254” >> /etc/resolv.conf
: exit 0

3. Edit initscript recipe to enable WiFi configuration at boot up

Edit the initscript bitbake recipe at … /meta/recipes-core/initscripts/initscripts-1.0.bb that incorporates the “setup-wifi.sh” and installs it in /etc/initscripts directory after build.

SRC_URI = "
file://setup-wifi.sh \
"
do_install () {
install -m 0755    ${WORKDIR}/setup-wifi.sh     ${D}${sysconfdir}/init.d
  
update-rc.d -r ${D} setup-wifi.sh start 99 2 3 4 5 .
}
  
MASKED_SCRIPTS = " \
setup-wifi \
"

SSH

With the above configurations, rebuild the core-image as explained in the previous article. On bootup, you can test the WiFi configuration by issuing the commands:

ifconfig            //should show the IP address of the Pi as hard coded in the Yocto image
ping google.com        //shows that the DNS server(s) hardcoded are working

With the above network configurations, we can access the board remotely via ssh and transfer files via scp from a Linux machine.

On the Linux machine, we enter the IP address we assigned to the board as below:

ssh root@10.233.174.16

This opens a terminal console of the board remotely and we can access all the files remotely.

 

資料來源: https://reiwaembedded.com/raspberry-pi-yocto-wifi-configuration-for-automatic-connection-at-boot/