在 宣告 regmap_config 時,會又 reg_defaults 這個欄位。
這是說明 chip reset 後的 register default value。
並不是要 regmap 做初始話時,寫入的 value。
所以修改 reg_default[] 內的值,並不會跟心的 真正的 chip 上。
保險的作法是在 driver probe 時,把 default register 全部寫一次。
2020/11/25
dreamsourcelab LA on WM8974 I2C decode
dreamsourcelab 的 LA 很有趣。
PC 端的軟體是 opensource 的。
所以在 linux 上使用的話,要clone github project,然後 configure, make ...
有 LA 的 decode 功能,幫你 decode 。
向上面就是 I2C 的波型。
decode 完可以 log。
上面就是做 WM8974 的 I2C log。
wm8974 因為只能 write,不能 read,所以沒變法確認write OK
用 LA log,然後寫一個程式update 每個 register 的 final value:
memo 一下 DSView 的操作:
PC 端的軟體是 opensource 的。
所以在 linux 上使用的話,要clone github project,然後 configure, make ...
有 LA 的 decode 功能,幫你 decode 。
向上面就是 I2C 的波型。
decode 完可以 log。
上面就是做 WM8974 的 I2C log。
wm8974 因為只能 write,不能 read,所以沒變法確認write OK
用 LA log,然後寫一個程式update 每個 register 的 final value:
memo 一下 DSView 的操作:
- 可以指定 log 的時間 (10sec),然後安下 play 開始 log
- 滾輪是 zomm in/out
- decode 出現的 dialog,指出要 decode 的 probe data (SDA, SCL)
- decode 的 save 圖示,把 decode 完的結果 log 成 file
2020/11/20
wpa_supplicant & wpa_cli
ref:
wpa_supplicant
network 設定中:
wpa_supplicant 的 config 檔,其中的 network { }區段。對應的就是 wpa_cli 的 add_network , set_network
所以 config 的內容,都可以用 wpa_cli 設定。
wpa_supplicant
network 設定中:
mode 0 : infrastructure,預設值,會嘗試連結AP 1 : IBSS,ad-hoc, peer to peer 2 : AP另外,
ap_scan: 0 : scan, 不connect 1 : scan, 找不道的話,舊自己當 AP 2 : scan, and connect
wpa_supplicant 的 config 檔,其中的 network { }區段。對應的就是 wpa_cli 的 add_network , set_network
所以 config 的內容,都可以用 wpa_cli 設定。
sendmail - 送不出..
phabricator 用 sendmail 寄公司內部信。
然後錢一陣子轉 vm 後,有人收不到 phabricator 的通知了。(據說是所有人都收步道..)
先看一下 /var/log/syslog...
看一下sensmail 狀況..
看一下 phabricator: ref:testing outbound:
測試一下 sendmail 吧。(ref:how to test sendmail)
轉到 vm 時,dns 沒設定,所以沒動作,test ping google 也 fail
所以把 dns 設好後用 sendmail 測試 OK
然後錢一陣子轉 vm 後,有人收不到 phabricator 的通知了。(據說是所有人都收步道..)
先看一下 /var/log/syslog...
... Nov 20 11:20:01 franxx sm-msp-queue[9753]: My unqualified host name (franxx) unknown; sleeping for retry Nov 20 11:21:01 franxx sm-msp-queue[9753]: unable to qualify my own domain name (franxx) -- using short name Nov 20 11:24:34 franxx systemd[1]: Started Session 3645 of user darling. Nov 20 11:39:01 franxx CRON[11008]: (root) CMD ( [ -x /usr/lib/php/sessionclean ] && if [ ! -d /run/systemd/system ]; then /usr/lib/php/sessionclean; fi) Nov 20 11:39:01 franxx systemd[1]: Starting Clean php session files... Nov 20 11:39:01 franxx systemd[1]: Started Clean php session files. Nov 20 11:39:23 franxx sendmail[11087]: My unqualified host name (franxx) unknown; sleeping for retry ...但是這個好像不影響,只是會慢一點。..
看一下sensmail 狀況..
$ sudo systemctl status sendmail ● sendmail.service - LSB: powerful, efficient, and scalable Mail Transport Agent Loaded: loaded (/etc/init.d/sendmail; bad; vendor preset: enabled) Active: active (running) since Mon 2020-10-26 14:14:32 CST; 3 weeks 3 days ago Docs: man:systemd-sysv-generator(8) Process: 1223 ExecStart=/etc/init.d/sendmail start (code=exited, status=0/SUCCESS) Tasks: 1 Memory: 4.4M CPU: 53.028s CGroup: /system.slice/sendmail.service └─1615 sendmail: MTA: accepting connections ov 18 15:24:34 franxx sm-mta[2047]: 0AD7L1bD018430: 0AI7OYgC002047: postmaster notify: User unknown Nov 18 15:24:34 franxx sm-mta[2047]: 0AI7OYgC002047: to=MAILER-DAEMON, delay=00:00:00, mailer=local, pri=0, dsn=5.1.1, stat=User unknown Nov 18 15:24:34 franxx sm-mta[2047]: 0AI7OYgC002047: to=postmaster, delay=00:00:00, mailer=local, pri=0, dsn=5.1.1, stat=User unknown Nov 18 15:24:34 franxx sm-mta[2047]: 0AI7OYgC002047: 0AI7OYgD002047: return to sender: User unknown Nov 18 15:24:34 franxx sm-mta[2047]: 0AI7OYgD002047: to=MAILER-DAEMON, delay=00:00:00, mailer=local, pri=0, dsn=5.1.1, stat=User unknown Nov 18 15:24:34 franxx sm-mta[2047]: 0AI7OYgC002047: Saved message in /var/lib/sendmail/dead.letter Nov 18 16:21:01 franxx sm-mta[3039]: 0AI8L1XF003039: from=<>, size=2253, class=0, nrcpts=1, msgid=<202011180821.0AI8L1I1003037@franxx>, pr Nov 18 16:21:01 franxx sm-mta[3039]: 0AI8L1XF003039: to=狀態正常,但是都記不出去。, delay=00:00:00, mailer=local, pri=32253, dsn=4.4.3, stat=queued Nov 18 16:21:01 franxx sm-mta[3039]: 0AI8L1XH003039: from=<>, size=2259, class=0, nrcpts=1, msgid=<202011180821.0AI8L1I2003037@franxx>, pr Nov 18 16:21:01 franxx sm-mta[3039]: 0AI8L1XH003039: to= , delay=00:00:00, mailer=local, pri=32259, dsn=4.4.3, stat=queued
看一下 phabricator: ref:testing outbound:
phabricator/ $ ./bin/mail list-outbound # List outbound mail. phabricator/ $ ./bin/mail show-outbound # Show details about messages. phabricator/ $ ./bin/mail send-test # Send test messages.看一下out-bound...
XXX:/opt/phabricator$ ./bin/mail list-outbound 263 Sent D163: Fix: If low battery, the alert sound keep ringing in security screen after PND resume. 264 Sent D162: Fix 2 issues. 265 Sent D162: Fix 2 issues. 266 Sent D164: Fix: If low battery, the alert sound keep ringing in security screen after PND resume. 267 Sent D164: Fix: If low battery, the alert sound keep ringing in security screen after PND resume. 268 Sent D164: Fix: If low battery, the alert sound keep ringing in security screen after PND resume. 269 Sent D164: Fix: If low battery, the alert sound keep ringing in security screen after PND resume. 270 Sent D164: Fix: If low battery, the alert sound keep ringing in security screen after PND resume. 271 Sent D164: Fix: If low battery, the alert sound keep ringing in security screen after PND resume. ... 284 Sent D167: Fix 3 suspend/wakeup issues. 285 Sent D167: Fix 3 suspend/wakeup issues. 286 Sent D168: Fix 3 suspend/wakeup issues. 287 Sent D168: Fix 3 suspend/wakeup issues. 288 Sent D167: Fix 3 suspend/wakeup issues. 289 Sent D167: Fix 3 suspend/wakeup issues. 290 Sent D168: Fix 3 suspend/wakeup issues. 291 Sent D168: Fix 3 suspend/wakeup issues. 292 Sent D168: Fix 3 suspend/wakeup issues. 293 Sent D168: Fix 3 suspend/wakeup issues. 294 Sent D167: Fix 3 suspend/wakeup issues. 295 Sent D167: Fix 3 suspend/wakeup issues.果然queue住一堆..
測試一下 sendmail 吧。(ref:how to test sendmail)
$ echo "from franzz" | sendmail -v charles.chang@localtek.com WARNING: local host name (franxx) is not qualified; see cf/README: WHO AM I? localtek.com: Name server timeout charles.chang@localtek.com... Transient parse error -- message queued for future delivery charles.chang@localtek.com... queued果然,是 dns 的問題。
轉到 vm 時,dns 沒設定,所以沒動作,test ping google 也 fail
所以把 dns 設好後用 sendmail 測試 OK
2020/11/17
regmap, 有關沒對齊的 reg, value bits 的 i2c transfer function.
regmap.c 中有...
所以wm8974 的 code:
switch (config->reg_bits + map->reg_shift) { ... case 7: switch (config->val_bits) { case 9: map->format.format_write = regmap_format_7_9_write; break;然後
static void regmap_format_7_9_write(struct regmap *map, unsigned int reg, unsigned int val) { __be16 *out = map->work_buf; *out = cpu_to_be16((reg << 9) | val); }
所以wm8974 的 code:
static const struct regmap_config wm8974_regmap = { .reg_bits = 7, .val_bits = 9,的確可以送出 follow wm8974 奇怪 protocol 的格式。
2020/11/14
ubuntu - unattended-upgrade, 有點煩
太煩了。把 unattended-upgrade 移除了,
如果不是每天開機,用這格反而麻煩。
偶額開機要用,要安裝 package,他卻卡住dpkg lock 好久...
每天開機的機器可能比較適合,他會自動安排更新時間。
如果不是每天開機,用這格反而麻煩。
偶額開機要用,要安裝 package,他卻卡住dpkg lock 好久...
每天開機的機器可能比較適合,他會自動安排更新時間。
2020/11/13
inode and partition space
在disk partition 中要能create 新檔,除了要有剩餘空間外,還有有inode 剩下才行。
一般用 df
touch 66 個 file 後,inode 剩下 0
這時候,就算是 df 中 /dev/root 還有 50M 的空間,也沒辦法再 create 新檔了。
另外,..
其中根目錄會列出subfolder 的inode 用量總和。
如果是慢慢漲起來的..可以用 find . 然後依照 file time sorting,找出新增的檔案...
一般embedded system 是在 rootfs 遭遇這個問題,rootfs 又是一個 block device,用 loopback 做出來。
可以用tune2fs 來看,不用真的 mount 起來..
ref:
一般用 df
# df -i Filesystem Inodes Used Available Use% Mounted on /dev/root 3.6K 3.5K 66 98% / devtmpfs 23.6K 353 23.2K 1% /dev tmpfs 124.6K 1 124.6K 0% /dev/shm tmpfs 124.6K 384 124.2K 0% /run tmpfs 124.6K 6 124.6K 0% /sys/fs/cgroup tmpfs 124.6K 8 124.6K 0% /tmp tmpfs 124.6K 5 124.6K 0% /var/tmp /dev/mmcblk0p8 0 0 0 0% /data tmpfs 124.6K 4 124.6K 0% /run/user/0 # df Filesystem Size Used Available Use% Mounted on /dev/root 504.4M 422.5M 51.8M 89% / devtmpfs 94.2M 0 94.2M 0% /dev tmpfs 498.4M 0 498.4M 0% /dev/shm tmpfs 498.4M 268.0K 498.1M 0% /run tmpfs 498.4M 0 498.4M 0% /sys/fs/cgroup tmpfs 498.4M 4.0K 498.4M 0% /tmp tmpfs 498.4M 0 498.4M 0% /var/tmp /dev/mmcblk0p8 6.6G 1.0M 6.6G 0% /data tmpfs 99.7M 0 99.7M 0% /run/user/0像 df -i 中,/dev/root 已經用掉 98%,剩下 66 個 inode。
touch 66 個 file 後,inode 剩下 0
這時候,就算是 df 中 /dev/root 還有 50M 的空間,也沒辦法再 create 新檔了。
另外,..
du --inode folder也會列出 folder 內的inode 用量。
其中根目錄會列出subfolder 的inode 用量總和。
如果是慢慢漲起來的..可以用 find . 然後依照 file time sorting,找出新增的檔案...
find . -type f -name '*.kk' -printf "%T+ %p\n" | sort
一般embedded system 是在 rootfs 遭遇這個問題,rootfs 又是一個 block device,用 loopback 做出來。
可以用tune2fs 來看,不用真的 mount 起來..
$ tune2fs -l ext4 tune2fs 1.44.1 (24-Mar-2018) Filesystem volume name:Last mounted on: Filesystem UUID: a34e7a5d-cb27-4f62-bdce-3d68b3e55537 Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: has_journal dir_index extent Filesystem flags: signed_directory_hash Default mount options: (none) Filesystem state: clean Errors behavior: Unknown (continue) Filesystem OS type: Linux Inode count: 3712 Block count: 468226 Reserved block count: 23411 Free blocks: 29952 Free inodes: 129 First block: 1 Block size: 1024 Fragment size: 1024 Blocks per group: 8080 Fragments per group: 8080 Inodes per group: 64 Inode blocks per group: 8 Last mount time: n/a Last write time: Thu Oct 29 11:30:35 2020 Mount count: 0 Maximum mount count: -1 Last checked: Thu Oct 29 11:30:19 2020 Check interval: 0 ( ) Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 128 Journal inode: 8 Default directory hash: half_md4 Directory Hash Seed: 0e89286e-5c9d-4f0c-9aad-37b2cd127b29 Journal backup: inode blocks
ref:
- How to Find and Sort Files Based on Modification Date and Time in Linux
- How can I use `find` and sort the results by mtime? [duplicate]
- NO SPACE LEFT ON DEVICE – RUNNING OUT OF INODES
- df與du輸出結果不同的原因研究
- Linux / Unix: Find Inode Of a File Command
- Detailed Understanding of Linux Inodes with Example
- How to find the inode size of an ext2/ext3/ext4 filesystem?
2020/11/12
紀錄 make, linking with libnl-3...
fatal error: netlink/genl/genl.h: No such file or directory #include <netlink/genl/genl.h>找一下..因為已經有 install lib-nl-3-dev 了...
apt-file search genl.h .. libnl-3-dev: /usr/include/libnl3/netlink/genl/genl所以修改 Makefile..
加入
CFLAGS += -I/usr/include/libnl3
然後出現..
/usr/bin/ld: cannot find -lnl-genl-3然後一樣用 apt-file
apt-file search libnl-genl libnl-genl-3-dev: /lib/aarch64-linux-gnu/libnl-genl-3.a libnl-genl-3-dev: /lib/aarch64-linux-gnu/libnl-genl-3.so但是用 find ..
$ sudo find . -name libnl-genl* ./lib/aarch64-linux-gnu/libnl-genl-3.so.200.24.0 ./lib/aarch64-linux-gnu/libnl-genl-3.so.200 ./var/lib/dpkg/info/libnl-genl-3-200:arm64.symbols ./var/lib/dpkg/info/libnl-genl-3-200:arm64.triggers ./var/lib/dpkg/info/libnl-genl-3-200:arm64.list ./var/lib/dpkg/info/libnl-genl-3-200:arm64.md5sums ./var/lib/dpkg/info/libnl-genl-3-200:arm64.shlibs ./usr/share/doc/libnl-genl-3-200所以.. 自己建 link ?:
姊果一直說 fail,沒版法建,只好直接 copy, rename..
cp libnl-genl-3.so.200.24.0 libnl-genl-3.so之後再 make 舊 OK
WM8974 , 奇怪的 audio codec..
在linux kernel 中,很久以前,就有 wm8974 的 driver 了。
datasheet 看到這個不叫 i2c,叫 2 wire。
從 2 wire command diagram 來看.. 的確很奇怪:
address 部份跟一般 i2c 一樣,前 7 個是 address,最後一個 bit 是 read/write bit
接著是 reg , 只有 7 bit,所以最後一個 bit 是 data 的 highest bit
wm8974 的 reg 只有 7 bit,data 有 9 bit
register value 說明也真的有定義第9bit..
所以 i2c protocl:
因為這樣,wm8974 沒有 read 動作。
也就是說,不能 read register。 --- 不然 protocol 要怎樣....
Linux driver 的部份:
古老的 wm8974 driver 使用自己提供的 i2c_read, i2c_write,看得出這個奇怪的動作:
然後沒有提供 i2c_read
然後 driver 註冊時...
然後新版的kernel (3.1 以上),新增加了 regmap 這個 結構,
就是把 register map cache 起來,write 時同時更新 cache,
read 時就拿 cache 值,不用真的去 read。
-- 當然也可以真的去 read
同時 regmap 也增加了 reg_bits, val_bits 這兩個 properties。
所以新版的 wm8974 driver,已經有:
用了 regmap,cache type 用 FLAT,就會 使用 cache,這樣,read 就會從 cache 做,
這時候,要 dump register 舊只能用 regmap support 的地方:
datasheet 看到這個不叫 i2c,叫 2 wire。
從 2 wire command diagram 來看.. 的確很奇怪:
address 部份跟一般 i2c 一樣,前 7 個是 address,最後一個 bit 是 read/write bit
接著是 reg , 只有 7 bit,所以最後一個 bit 是 data 的 highest bit
wm8974 的 reg 只有 7 bit,data 有 9 bit
register value 說明也真的有定義第9bit..
所以 i2c protocl:
1: chip address(7)+R/W(1) 2: reg index(7) + Data 8th bit(1) 3: Data 7-0 bit (8)跟一般 I2C 裝置不一樣。
因為這樣,wm8974 沒有 read 動作。
也就是說,不能 read register。 --- 不然 protocol 要怎樣....
Linux driver 的部份:
古老的 wm8974 driver 使用自己提供的 i2c_read, i2c_write,看得出這個奇怪的動作:
static inline unsigned int wm8974_read_reg_cache(struct snd_soc_codec * codec, unsigned int reg) { u16 *cache = codec->reg_cache; if (reg == WM8974_RESET) return 0; if (reg >= WM8974_CACHEREGNUM) return -1; return cache[reg]; } /* * write wm8974 register cache */ static inline void wm8974_write_reg_cache(struct snd_soc_codec *codec, u16 reg, unsigned int value) { u16 *cache = codec->reg_cache; if (reg >= WM8974_CACHEREGNUM) return; cache[reg] = value; } /* * write to the WM8974 register space */ static int wm8974_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u8 data[2]; /* data is * D15..D9 WM8974 register offset * D8...D0 register data */ data[0] = (reg << 1) | ((value >> 8) & 0x0001); data[1] = value & 0x00ff; wm8974_write_reg_cache (codec, reg, value); if (codec->hw_write(codec->control_data, data, 2) == 2) return 0; else return -EIO; }i2c_write 內容有看到把 data shift 到 reg 一個bit
然後沒有提供 i2c_read
然後 driver 註冊時...
static int wm8974_init(struct snd_soc_device *socdev) { struct snd_soc_codec *codec = socdev->codec; int ret = 0; codec->name = "WM8974"; codec->owner = THIS_MODULE; codec->read = wm8974_read_reg_cache; codec->write = wm8974_write; ..read 用的是 read_reg_cache
然後新版的kernel (3.1 以上),新增加了 regmap 這個 結構,
就是把 register map cache 起來,write 時同時更新 cache,
read 時就拿 cache 值,不用真的去 read。
-- 當然也可以真的去 read
同時 regmap 也增加了 reg_bits, val_bits 這兩個 properties。
所以新版的 wm8974 driver,已經有:
static const struct regmap_config wm8974_regmap = { .reg_bits = 7, .val_bits = 9, .max_register = WM8974_MONOMIX, .reg_defaults = wm8974_reg_defaults, .num_reg_defaults = ARRAY_SIZE(wm8974_reg_defaults), .cache_type = REGCACHE_FLAT, };比較漂亮的寫法就是用regmap : regmap, 有關沒對齊的 reg, value bits 的 i2c transfer function.
用了 regmap,cache type 用 FLAT,就會 使用 cache,這樣,read 就會從 cache 做,
這時候,要 dump register 舊只能用 regmap support 的地方:
# cat /sys/kernel/debug/regmap/2-001a/registers 00: 0000 01: 002e 02: 0000 03: 0000 04: 0010 05: 0001 06: 0120 07: 0000 08: 0000 09: 0000 0a: 0041 0b: 00d7 0c: 0000 0d: 0000 0e: 0100 0f: 00ff 10: 0000 11: 0000 12: 012c 13: 002c 14: 002c 15: 002c 16: 002c 17: 0000 18: 0032 19: 0000 1a: 0000 1b: 0000 1c: 0000 1d: 0000 1e: 0000 1f: 0000 20: 0038 21: 000b 22: 0032 23: 0000 24: 001b 25: 0001 26: 0133 27: 0066 28: 0000 29: 0000 2a: 0000 2b: 0000 2c: 0003 2d: 0010 2e: 0000 2f: 0000 30: 0000 31: 0002 32: 0000 33: 0000 34: 0000 35: 0000 36: 0025 37: 0000 38: 0001
2020/11/11
Face Recognition : FAR and FRR
ref:
和 data base 中每個人的 參數比較,計算出"引力"(距離平方反比),跟誰引力最大,就是誰。
但是也有 "不認識","不屬於 database 中" 的情況出現。
這時候,就要把 "距離" 加上一個 threshold,要引力大於這個值才算,否則就是 "不認識" 的人。
而這個 threshold 舊決定了 FAR 跟 FRR。
FAR 隨著threshold 增加而降低。
FRR 隨著threshold 增加而增加。
兩個剛好在左右兩端達到最大。
所以最佳 threshold 的值就是 FAR, FRR 都最小的中間數值。
感想:看完上面ref 的內容,感覺 face recognition 蠻不准的....
- False Acceptance Rate (FAR) and False Recognition Rate (FRR) in Biometrics
- Face recognition system and calculating FRR, FAR and EER for Biometric system evaluation + code
- The Secret to Better Face Recognition Accuracy: Thresholds
- FAR : False Acceptance Rate
- FRR : False Rejection Rate
和 data base 中每個人的 參數比較,計算出"引力"(距離平方反比),跟誰引力最大,就是誰。
但是也有 "不認識","不屬於 database 中" 的情況出現。
這時候,就要把 "距離" 加上一個 threshold,要引力大於這個值才算,否則就是 "不認識" 的人。
而這個 threshold 舊決定了 FAR 跟 FRR。
FAR 隨著threshold 增加而降低。
FRR 隨著threshold 增加而增加。
兩個剛好在左右兩端達到最大。
所以最佳 threshold 的值就是 FAR, FRR 都最小的中間數值。
感想:看完上面ref 的內容,感覺 face recognition 蠻不准的....
2020/11/10
bookmark : CRA (Chief Ray Angle)
Image Sensor 用的參數。
Image Sensor 的每個 pixel 上都會有一個 micro-lens。
micro-lens 用來聚焦光線到 pixel 上。
lens 有 FOV (field of view),所以必須要和外接的鏡頭搭配,讓經由鏡頭篇折的光線,進入 micro-lense 後,能夠正確的落在 pixel 上。
如果沒有批配的話,光線進入 micro-lense 後,就會落掉旁邊的 pixel ,造成雜訊點或是影像失真。
所以 sensor 的 CRA 必須要和鏡頭設計一起考慮。
實際測試的姊果,lens fov 與 CRA 符合的 camera,影像較 CRV 0 的清楚很多,相較起來,CRV0 的影像好像是對焦沒對好。
Image Sensor 的每個 pixel 上都會有一個 micro-lens。
micro-lens 用來聚焦光線到 pixel 上。
lens 有 FOV (field of view),所以必須要和外接的鏡頭搭配,讓經由鏡頭篇折的光線,進入 micro-lense 後,能夠正確的落在 pixel 上。
如果沒有批配的話,光線進入 micro-lense 後,就會落掉旁邊的 pixel ,造成雜訊點或是影像失真。
所以 sensor 的 CRA 必須要和鏡頭設計一起考慮。
- 淺談影像CRAM: 基本,概略的說明
- Camera 模组之 Micro Lens 篇: 詳細的說明,從 micro lens 到 sensor 有詳細的圖,說明 CRA 與 色差的關係
- The Fundamentals of Camera and Image Sensor Technology: 說明有關 sensor , micro lens 和 lens 的構造
實際測試的姊果,lens fov 與 CRA 符合的 camera,影像較 CRV 0 的清楚很多,相較起來,CRV0 的影像好像是對焦沒對好。
2020/11/8
opencv document: cross build
這篇很詳細講opencv cross build for arm 的方法,基本上和上次寫的cmake cross build 的方法一樣。
opencv 寫好了platform,XXX.cmake。
所以只要準備好要的cross-tool,然後用opencv 的 toolchain cmake 就可以。
其他如果有需要的library,可以參考上次寫的。放在set_ 裡面。
其實embeddes system opencv port,比較重要的是 bsp 有沒有hardware support,還有opencv 要怎麼link 到 bsp 的hardware 加速library。
另外,還要build 出 python support module,放在target system 得 python class loading path 中,這樣 target system 的 python 才能 import。
opencv 寫好了platform,XXX.cmake。
所以只要準備好要的cross-tool,然後用opencv 的 toolchain cmake 就可以。
其他如果有需要的library,可以參考上次寫的。放在set_ 裡面。
其實embeddes system opencv port,比較重要的是 bsp 有沒有hardware support,還有opencv 要怎麼link 到 bsp 的hardware 加速library。
另外,還要build 出 python support module,放在target system 得 python class loading path 中,這樣 target system 的 python 才能 import。
python 3 and opencv3.4.2 ..imshow fail. --- centor of contours
一個 imshow 就 fail 掉:
結果follow 這一個:
haha 6 月的時後,已經發生過了...
另外,很有趣,python 因為可以return tuple type,所以function 把 rc code(success, fail) 和 process result 包成一個 tuple 傳回來。
所以,以 opencv 的 threshold( ) function:
如果要直接拿結果,不管成功失敗,可以直接取 tuple 的 elememt:
依照這篇文章,利用findContour找出輪廓,再用moments 找出輪廓中心座標的 code,在: 加上了最小面積偵測,如果太小就不採用。(實際上是遭遇到雜訊點面積為0的錯誤)
另外,為了考慮能porting 到 embedd system,所以拿掉而外的 module。
參考文章說的,findcontours 的傳回格式跟opencv 版本有關。
這一篇是同樣方法的中文版本,說得更清楚,也有用實際照片做例子
-- 看起來這是標準的方法...
這一篇是用C++的example,如果python porting 不上去,或是 bsp 的 opencv port 沒有support python時,可以用C++做。
-- 參考他的作法,改成跟python 版 一樣的 algorithm 版本的 C++ code,一樣在 github project 中。
沒用用到什模特殊的,最後一個 commit,把 show image 的部份刪除就可以在 target board 上 run 了,用存檔來檢查每一個 process 的結果。
cv2.error: OpenCV(3.4.2) /tmp/build/80754af9/opencv-suite_1535558553474/work/modules/highgui/src/window.cpp:632: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'
結果follow 這一個:
conda remove opencv conda install -c conda-forge opencv=4.1.0..意思是說..3.4.2 板的沒有enable WITH_GTK=ON ?
haha 6 月的時後,已經發生過了...
另外,很有趣,python 因為可以return tuple type,所以function 把 rc code(success, fail) 和 process result 包成一個 tuple 傳回來。
所以,以 opencv 的 threshold( ) function:
rc, out = cv2.threshold(blurred,60,255,cv2.THRESH_BINARY)rc 是 成功或失敗,out 是 threshold 處理以後的結果。
如果要直接拿結果,不管成功失敗,可以直接取 tuple 的 elememt:
out = cv2.threshold(blurred,60,255,cv2.THRESH_BINARY)[1]
依照這篇文章,利用findContour找出輪廓,再用moments 找出輪廓中心座標的 code,在: 加上了最小面積偵測,如果太小就不採用。(實際上是遭遇到雜訊點面積為0的錯誤)
另外,為了考慮能porting 到 embedd system,所以拿掉而外的 module。
參考文章說的,findcontours 的傳回格式跟opencv 版本有關。
這一篇是同樣方法的中文版本,說得更清楚,也有用實際照片做例子
-- 看起來這是標準的方法...
這一篇是用C++的example,如果python porting 不上去,或是 bsp 的 opencv port 沒有support python時,可以用C++做。
-- 參考他的作法,改成跟python 版 一樣的 algorithm 版本的 C++ code,一樣在 github project 中。
沒用用到什模特殊的,最後一個 commit,把 show image 的部份刪除就可以在 target board 上 run 了,用存檔來檢查每一個 process 的結果。
2020/11/6
pthread return value
pthread 可以 return value 給 parent process (who create it)
用 這個 方法:
要測試 一下..
等等... 感覺怪怪的...
因為 return 一個 cast 成 (void*) 的 scalar value
...
要是看這一篇的話,thread要為return value alloc一塊記憶體,不能隨thread 退出兒消失。
經由把指標return 給 creator 後,creator 負責 free 掉。
有關 return 跟 exit() :
這一篇說明看起來好可怕...
對C++來說,return 會 call 所有 local scope 物件的 destructor,一一release 完再結束,而exit( )不會這樣做,它直接結束。
-- 可以寫sample code 試試,看看 1.不寫 2.return 3.exit( ) 對於 local 物件有蛇麼差別。
實際上用 g++ -S main.cpp 產生 assembly file 來看有 return 跟沒 return 的差別。
只插在 有return 的,多一個 intruction 把 return value 放到 eax,沒return 的,就放一個 nop (為什麼要放?)
用 這個 方法:
#include <pthread.> #include <stdio.h> void *myThread() { printf("in thread now\n"); return (void *) 42; } int main() { pthread_t tid; int status; pthread_create(&tid, NULL, myThread, NULL); pthread_join(tid, (void*)&status); printf("%d\n",status); return 0; }.. 這個 status 的宣告...
要測試 一下..
等等... 感覺怪怪的...
因為 return 一個 cast 成 (void*) 的 scalar value
...
要是看這一篇的話,thread要為return value alloc一塊記憶體,不能隨thread 退出兒消失。
經由把指標return 給 creator 後,creator 負責 free 掉。
有關 return 跟 exit() :
這一篇說明看起來好可怕...
對C++來說,return 會 call 所有 local scope 物件的 destructor,一一release 完再結束,而exit( )不會這樣做,它直接結束。
-- 可以寫sample code 試試,看看 1.不寫 2.return 3.exit( ) 對於 local 物件有蛇麼差別。
實際上用 g++ -S main.cpp 產生 assembly file 來看有 return 跟沒 return 的差別。
只插在 有return 的,多一個 intruction 把 return value 放到 eax,沒return 的,就放一個 nop (為什麼要放?)
add read/write function in i2c_client driver function
snd_soc_codec_driver裡面有:
- write : i2c_write
- read : i2c_read
所以如果想要 debug snd_soc_code driver,知道該 driver 對 i2c 的動作。
可以自己寫 i2c_read, i2c_write 放進去。
static unsigned int my_i2c_read(struct snd_soc_codec *codec, unsigned int reg) { struct my_priv *mypriv = snd_soc_codec_get_drvdata(codec); int ret = -1; unsigned char tx[1], rx[1]; struct i2c_msg xfer[2]; struct i2c_client *client = mypriv->i2c; tx[0] = reg; rx[0] = 0; /* Write register */ xfer[0].addr = client->addr; xfer[0].flags = 0; xfer[0].len = 1; xfer[0].buf = tx; /* Read data */ xfer[1].addr = client->addr; xfer[1].flags = I2C_M_RD; xfer[1].len = 1; xfer[1].buf = rx; ret = i2c_transfer(client->adapter, xfer, 2); if (ret != 2) printk("\t%s error ret = %d\n", __func__, ret); return (unsigned int)rx[0]; } static int my_i2c_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { struct my_priv *mypriv = snd_soc_codec_get_drvdata(codec); int ret = -1; unsigned char tx[2]; size_t len = 2; if(reg==1) value |= 0x02; // don't power off spk tx[0] = reg; tx[1] = value; printk("\t %s: (addr,data)=(%x, %x)\n", __func__, reg, value); ret = i2c_master_send(mypriv->i2c, tx, len); if (ret != len) return -EIO; return 0; }但是要struct my_priv 要把 probe 時,register 的 i2c client 田進變數
struct my_priv { struct i2c_client *i2c; ...然後 module probe function...
static int my_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct my_priv *mypriv; mypriv = devm_kzalloc(&i2c->dev. sizeof(struct my_priv), GFP_KERNEL); i2c_set_client_data(i2c, mypriv); mypriv->i2c = i2c; ...這樣,這個 driver call snd_soc_read/write 時,就會 call 到 自己的 i2c_read/write function.
然後舊可以加 debug message...
但是這樣舊沒用到 regmap,所以 sys/kernel/debug/regmap/XXXX/registers 的內容不會顯示。
2020/11/5
nginx : get auth failcount behind proxy
2020/11/3
記 一下 i2c tool 的動作, i2cget , i2cset
其實單獨執行。不加 argument 的時候,都會有 help.
# i2cdetect BusyBox v1.31.1 (2020-02-18 12:01:00 CST) multi-call binary. Usage: i2cdetect -l | -F I2CBUS | [-ya] [-q|-r] I2CBUS [FIRST LAST] Detect I2C chips -l List installed buses -F BUS# List functionalities on this bus -y Disable interactive mode -a Force scanning of non-regular addresses -q Use smbus quick write commands for probing (default) -r Use smbus read byte commands for probing FIRST and LAST limit probing range # i2cdetect -y -a 2 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- UU -- -- -- -- -- UU -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- # i2cdump BusyBox v1.31.1 (2020-02-18 12:01:00 CST) multi-call binary. Usage: i2cdump [-fy] [-r FIRST-LAST] BUS ADDR [MODE] Examine I2C registers I2CBUS I2C bus number ADDRESS 0x03-0x77 MODE is: b Byte (default) w Word W Word on even register addresses i I2C block s SMBus block c Consecutive byte Append p for SMBus PEC -f Force access -y Disable interactive mode -r Limit the number of registers being accessed # i2cdump -fy 2 0x12 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 00: c9 06 48 01 60 50 0b 23 00 00 60 00 e1 e1 f0 00 ??H?`P?#..`.???. 10: 18 1e fc fc fc fc 07 03 03 d0 1f 60 20 00 10 00 ???????????` .?. 20: 00 0f 33 05 10 29 22 f6 bd 00 73 3e 79 e1 1d 03 .?3??)"??.s>y??? 30: 92 39 3a e6 00 10 f1 1d 00 00 00 00 00 00 00 00 ?9:?.???........ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ # i2cget BusyBox v1.31.1 (2020-02-18 12:01:00 CST) multi-call binary. Usage: i2cget [-fy] BUS CHIP-ADDRESS [DATA-ADDRESS [MODE]] Read from I2C/SMBus chip registers I2CBUS I2C bus number ADDRESS 0x03-0x77 MODE is: b Read byte data (default) w Read word data c Write byte/read byte Append p for SMBus PEC -f Force access -y Disable interactive mode # i2cget -fy 2 0x12 0 0xc9 # i2cget -fy 2 0x12 1 0x06 # i2cset BusyBox v1.31.1 (2020-02-18 12:01:00 CST) multi-call binary. Usage: i2cset [-fy] [-m MASK] BUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE] Set I2C registers I2CBUS I2C bus number ADDRESS 0x03-0x77 MODE is: c Byte, no value b Byte data (default) w Word data i I2C block data s SMBus block data Append p for SMBus PEC -f Force access -y Disable interactive mode -r Read back and compare the result -m MASK Mask specifying which bits to write # i2cset -fy 2 0x12 0 0xc8 # i2cget -fy 2 0x12 0 0xc8
clang, disable optimize for latter pass
這一篇,用 llvm-11 的話,opt 的指令沒有效。
stack overflow 有說。
在 compile 時,如果沒有加上 -O,在產生的 ll file, function 錢會有 optnone,避免 reg2mem 做 optimization:
如果不要他先 optimize,又要加
最後,用 as 和 ld link 出 exeutable file,
要指定 crt1.o, crti.o,但是最終還是無法執行。
可能是 default library 的關係。
用 gcc assembly front-end 舊可以..
或許照著寫舊可以用 ld 成功 link..
這一篇 就是這樣做
依照 error mesaage,最後。minimum:
這一篇 的回答好像才是重點,interpreter 的問題。
用 gcc compile 的 a.out 和 ld link 出來的 a.out,用 readelf -l 看, interpreter 不一樣。
用 patchelf 的話..
實際上沒有 /lib/ld64.so.1
所以 Error message 是 'No sunch file or directory'
用 patchelf 設定正確的 interpreter;
這一篇 有詳細講crtX.o 和 interpreter 之間的關係和實驗。
stack overflow 有說。
在 compile 時,如果沒有加上 -O,在產生的 ll file, function 錢會有 optnone,避免 reg2mem 做 optimization:
; Function Attrs: noinline nounwind optnone uwtable define i32 @add(i32, i32) #0 { %3 = alloca i32, align 4 %4 = alloca i32, align 4 store i32 %0, i32* %3, align 4所以 compile 時要加場上 -O
clang -S -emit-llvm -O main.c這樣就不會有 optnone 的標記:
; Function Attrs: norecurse nounwind readnone uwtable define i32 @add(i32, i32) local_unnamed_addr #0 { %3 = add nsw i32 %1, %0 ret i32 %3 }但是也optimize 過了...
如果不要他先 optimize,又要加
clang -S -emit-llvm -O -Xclang -disable-llvm-passes main.c這樣才能完成跟街學文章一樣的code
; Function Attrs: nounwind uwtable define i32 @add(i32, i32) #0 { %3 = alloca i32, align 4 %4 = alloca i32, align 4 store i32 %0, i32* %3, align 4, !tbaa !2 store i32 %1, i32* %4, align 4, !tbaa !2 %5 = load i32, i32* %3, align 4, !tbaa !2
最後,用 as 和 ld link 出 exeutable file,
要指定 crt1.o, crti.o,但是最終還是無法執行。
可能是 default library 的關係。
用 gcc assembly front-end 舊可以..
gcc main.s -no-pie -o main用 -v 可以看一下 gcc ld 的 default crt.o 和 library
或許照著寫舊可以用 ld 成功 link..
這一篇 就是這樣做
ld -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 test.o /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/gcc/x86_64-linux/4.3/crtbegin.o -lc /usr/lib64/gcc/x86_64-linux/4.3/crtend.o /usr/lib64/crtn.o用了 ld-linux-x86-64.so crti.o crtbegin.o
依照 error mesaage,最後。minimum:
ld main.o /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o -lc但是link 出來的 a.out 執行出現 'No such file or directory'
這一篇 的回答好像才是重點,interpreter 的問題。
用 gcc compile 的 a.out 和 ld link 出來的 a.out,用 readelf -l 看, interpreter 不一樣。
用 patchelf 的話..
$ patchelf --print-interpreter a.out /lib/ld64.so.1 $ patchelf --print-interpreter gmain /lib64/ld-linux-x86-64.so.2不一樣。
實際上沒有 /lib/ld64.so.1
所以 Error message 是 'No sunch file or directory'
用 patchelf 設定正確的 interpreter;
patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 a.out所以。最後,正確 ld 的 command 是:
ld -o a.out -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o -lc /usr/lib/x86_64-linux-gnu/crtn.o main.
這一篇 有詳細講crtX.o 和 interpreter 之間的關係和實驗。
2020/11/2
https 基本原理
Browser, Server 都先準備好自己的 private/public key pair
兩人用對方的 public 加密送資料給對方。
對方就可以用自己的 private key 解開。
- Browser 透過 https 向 Server 發出 request
- Server 把自己經過 CA 認證的 site.crt 送給 browser,(crt 裡面有 server 的 public key 和 CA 的 sign
- Browser 收到 crt, 先用 CA 的 public key 確認 crt 裡,CA 的 sign 是正確的,還有 checksum 正確,代表 crt 沒被竄改
- Browser 把 crt 裡的 public 拿出來,加密自己的 public key,送給 Server
- Server 收到 Browser 的 public key 了
兩人用對方的 public 加密送資料給對方。
對方就可以用自己的 private key 解開。
用 tls 通訊 Boost 的 example
boost asio 有 ssl 的 programming example:
但是沒有操作說明。
這一篇是 操作說明,可惜是以 windows 為 platform
.. 現在在 linux 上試試看。
這一篇 也有產生 key, crt 和example 修改的範例
這一篇用 boost asio ssl 模擬 browser 對 https 的 request 動作。
先亂寫一下...,不知道政不正確...
SSL certication
然後這個 certication 是經果某個機構認證的。
機構:Cerfitication Authority (CA)
把自己的 public key 和自己的 location, domain name 包成 CSR (Certificate Signing Request) 格式,交給 CA
CA 會去檢查你是不是就是這個 CSR 內的 domain owner
-- 會要求你提供一堆資料。
CA 確認的話,CA 就會寄一份 SSL certification 給你,內容包含你的機構名稱,public key。
然後你就可以把這個SSL certication 放在你的 server 中。
CA 寄給你的 SSL certification 會包另一個 " trust root" 的 certification。
Browser 都會內建一堆 CA 機構的的 Root certification。
這樣舊知道你的 SSL certification 是不是真的。
browser 收到你用 private 加密的內容。
browser 有你的 SSL 憑證,包含一個CA root 的認證。好確保這個憑證是真的。
裡面有你的 public key,可以用來解開你用 private key 加密的內容。
CSR 送給 CA 機構,他確認正確後,就會把CSR 的資料斷做 checksum,然後用CA 自己的 private key 加密後,附在你的 CSR 後面。t
這就是CRT 了。
CA 會把 CRT 寄給你。
browser 都有內建一堆 CA 的 public key.
所以收到某網站的 CRT,他先用 CA 的 public key 確認這格 CRT 真的是 CA 認可(sign) 過得。
然後因為 checksum 的關係,。同時確認這格 CRT 沒有被修改。
這樣他就可以相信這個 CRT 裡的 public key 跟 domain 資料。
舊可以用 public key 來解開/確認這格 domain 用 private key 加密過後的資料。
openssl 可以作到所有的事,也可以用來列出 CSR, CRT, Key 的內容。
產生 private key
這一篇 使用 openssl 產生 private/public key pair。
然後各自加密檔案,再用對方解密。
同時還說明 crt 中用來 verify signature 的方法(command)
這一篇直接寫出command.
這一篇是 操作說明,可惜是以 windows 為 platform
.. 現在在 linux 上試試看。
這一篇 也有產生 key, crt 和example 修改的範例
這一篇用 boost asio ssl 模擬 browser 對 https 的 request 動作。
先亂寫一下...,不知道政不正確...
SSL certication
- Cryptographic Key
- server/domain , organization name
然後這個 certication 是經果某個機構認證的。
機構:Cerfitication Authority (CA)
把自己的 public key 和自己的 location, domain name 包成 CSR (Certificate Signing Request) 格式,交給 CA
CA 會去檢查你是不是就是這個 CSR 內的 domain owner
-- 會要求你提供一堆資料。
CA 確認的話,CA 就會寄一份 SSL certification 給你,內容包含你的機構名稱,public key。
然後你就可以把這個SSL certication 放在你的 server 中。
CA 寄給你的 SSL certification 會包另一個 " trust root" 的 certification。
Browser 都會內建一堆 CA 機構的的 Root certification。
這樣舊知道你的 SSL certification 是不是真的。
browser 收到你用 private 加密的內容。
browser 有你的 SSL 憑證,包含一個CA root 的認證。好確保這個憑證是真的。
裡面有你的 public key,可以用來解開你用 private key 加密的內容。
CSR 送給 CA 機構,他確認正確後,就會把CSR 的資料斷做 checksum,然後用CA 自己的 private key 加密後,附在你的 CSR 後面。t
這就是CRT 了。
CA 會把 CRT 寄給你。
browser 都有內建一堆 CA 的 public key.
所以收到某網站的 CRT,他先用 CA 的 public key 確認這格 CRT 真的是 CA 認可(sign) 過得。
然後因為 checksum 的關係,。同時確認這格 CRT 沒有被修改。
這樣他就可以相信這個 CRT 裡的 public key 跟 domain 資料。
舊可以用 public key 來解開/確認這格 domain 用 private key 加密過後的資料。
openssl 可以作到所有的事,也可以用來列出 CSR, CRT, Key 的內容。
產生 private key
openssl genesa -out mypriv.key 4096用private key 做出 CSR
openssl req -out mysite.csr -key mypriv.key -new
這一篇 使用 openssl 產生 private/public key pair。
然後各自加密檔案,再用對方解密。
同時還說明 crt 中用來 verify signature 的方法(command)
這一篇直接寫出command.
# Generate keys openssl genrsa -out key.pem openssl rsa -in key.pem -out key.pub -pubout # Encrypt and Decrypt a file (using public key to encrypt) echo --pass-- >> pass.txt openssl rsautl -in pass.txt -out pass.enc -pubin -inkey key.pub -encrypt openssl rsautl -in pass.enc -out pass.dec -inkey key.pem -decrypt cat pass.dec
訂閱:
文章 (Atom)