星期三, 2月 28, 2024

入手了 Raspberry Pi 5 8GB

前陣子一時興起訂了 Raspberry Pi 5 8GB,想作一個常開的小 Server 來使用。 在 台灣樹莓派 - Raspberry Pi Taiwan 上買了 8GB 套裝

與 10 元硬幣比較,Pi 5 體積真的很小

把 Pi 5 裝進選購附風扇的外殼中

機器裝好後要安裝系統了,這邊我選擇使用習慣的 Gentoo 系統。

按照以下網頁的步驟安裝進 SD 卡。

How to install Gentoo on Raspberry Pi 5

在安裝過程中的一些設定的詳細說明,可以到官方網站上觀看

Raspberry Pi Documentation - Raspberry Pi 5

另外與文件不同的是
  • 在這裡我選用了專門針對 Raspberry Pi 5 的 kernel_2712.img 而不是 Gentoo 文件中較為標準的 kernel8.img
  • 選擇用了比較習慣的 systemd init system, 而非 openrc

設定完畢,螢幕線,鍵盤線,電源線,網路線插好後,就可以開機了。

除了沒有網路...

新增 /etc/systemd/network/50-dhcp.network

[Match]
Name=en*

[Network]
DHCP=yes
然後執行
systemctl start systemd-networkd

除此整個過程除了插拔鍵盤 USB 外,就沒有什麼困難的地方了。使用安裝套件需要編譯的 Gentoo,體感上覺得速度還可以。風扇的聲音也完全聽不到

另外跑了 GeekBench 6 來比對以下與我桌機的性能差異。

Name Platform Architecture Single-core Multi-core Score
AMD Ryzen 7 2700X 3700 MHz (8 cores) Linux x64 1285 6317
Raspberry Pi 5 Model B Rev 1.0
ARM ARMv8 2400 MHz (1 cores) )
Linux AArch64 547 1342
以這麼小台且安靜的機器來說,這個性能可以接受了。

星期日, 2月 11, 2024

Rust Trait 系統在 Module 中一直不習慣的一點

在 Rust 中,Trait 定義了一個我們可以對一個型別作什麼事情。 比如以下定義了一個 trait Walk, 若一個型別有 Walk 的 trait, 那其必有 walk 這個 function 可呼叫。
pub trait Walk {
   fn walk(&self);
}
底下則定義了一個 struct 並實做了 Walk trait。
use crate::action::Walk;

pub struct Robot {
}

impl Walk for Robot {
   fn walk(&self) {
      println!("Walk");
   }  
}
程式的組成結構為
  • Cargo.toml
  • src/
    • main.rs
    • robot/
      • mod.rs (定義了 struct Robot, 並實做 Walk)
    • action/
      • mod.rs (定義了 Trait Walk)
在 main.rs 中使用 Walk。
mod robot;
mod action;

use crate::robot::Robot;

fn main() {
   let robot = Robot {
   }; 

   robot.walk();
}
雖然 struct Robot 與 Walk 的實做在同一個 rs 檔案中。 但編譯卻會出現以下錯誤。
   Compiling rust_trait v0.1.0 (/tmp/rust_trait)
error[E0599]: no method named `walk` found for struct `Robot` in the current scope
  --> src/main.rs:10:10
   |
10 |    robot.walk();
   |          ^^^^ method not found in `Robot`
   |
  ::: src/robot/mod.rs:3:1
   |
3  | pub struct Robot {
   | ---------------- method `walk` not found for this struct
   |
  ::: src/action/mod.rs:2:7
   |
2  |    fn walk(&self);
   |       ---- the method is available for `Robot` here
   |
   = help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
   |
1  + use crate::action::Walk;
   |

For more information about this error, try `rustc --explain E0599`.
error: could not compile `rust_trait` (bin "rust_trait") due to previous error
錯誤訊息說明說雖然 Robot 有實做了 Walk Trait, 但 main 本身沒有引入 Walk trait, 因此無法使用。需要將程式改為
mod robot;
mod action;

use crate::robot::Robot;
use crate::action::Walk;

fn main() {
   let robot = Robot {
   }; 

   robot.walk();
}

這邊在 main 中引入了 Walk Trait 後,在 Robot 中實做的 walk 才能正確使用。 也就是說如果一個 struct 實做了 20 個 trait,那麼想完整使用每個 trait 的 function,需要額外再引入 20 個 trait...。

會這麼設計的理由可能是希望寫的人能夠清楚知道自己在作什麼,需要什麼東西。若編譯器沒有提示功能,使用起來感覺蠻痛苦的...。