Một số mẹo cho việc phát triển ứng dụng hệ thống nhúng

Bài viết được sự cho phép của tác giả Nguyễn Hồng Quân

1. Chia sẻ Internet từ laptop cho máy tính nhúng

Đây là tình huống mà bạn đang phát triển ứng dụng cho máy tính mini (NUC, Raspberry Pi, Beagle Bone…) và chủ yếu dùng mạng dây (chưa setup wifi hoặc máy đó không có card wifi). Đôi lúc bạn cần phải xách nó đi đâu đó (để trình diễn demo, để cài đặt lại chẳng hạn) mà chỗ đó không có router để cấp mạng, bạn có thể chia sẻ Internet từ laptop (laptop đang kết nối Internet qua wifi) cho nó. Để cho ngắn gọn, mình sẽ gọi máy tính nhúng là RPi trong bài này.

Nguyên lý của việc này là biến laptop của bạn thành một thiết bị router mạng đơn sơ, tạo một mạng con với RPi, do laptop của bạn quản lý.

Với Ubuntu 20.04+ thì việc này rất đơn giản. Sau khi dùng dây LAN nối giữa RPi với laptop, bạn chỉ việc mở phần mềm tên là “Settings”, tìm đến mục “Network”, bấm vào nút “chỉnh sửa” (có hình bánh răng) cho mạng dây (Wired):

Ở màn hình kế tiếp, chọn tab “IPv4” rồi chọn “Shared to other computers”.

Sau khi lưu lại cấu hình này, bấm vào tab “Details”, bạn sẽ thấy địa chỉ IP của laptop trong mạng con mới tạo này. Thông thường là 10.42.0.1. Tuy nhiên, đó chỉ là địa chỉ của laptop, còn địa chỉ của RPi là gì, làm sao truy cập đến nó? Có các cách sau đây:

a) Dùng mDNS

Cách này áp dụng khi cả laptop và RPi của bạn đều đã cài đặt phần mềm avahi-daemon và bạn nhớ tên hostname của RPi. Khi đó địa chỉ của RPi sẽ có dạng [hostname].local, ví dụ raspberrypi.local. Thử ping vào địa chỉ đó, bạn sẽ thấy RPi trả lời:

$ ping raspberrypi.local
PING raspberrypi.local 

(

10

.42.0.95

)

56

(

84

)

bytes of data.

64

bytes from

10

.42.0.95

(

10

.42.0.95

)

:

icmp_seq

=

1

ttl

=

64

time

=

1

.05 ms

64

bytes from

10

.42.0.95

(

10

.42.0.95

)

:

icmp_seq

=

2

ttl

=

64

time

=

0

.844 ms

64

bytes from

10

.42.0.95

(

10

.42.0.95

)

:

icmp_seq

=

3

ttl

=

64

time

=

1

.21 ms

Với mDNS thì thật ra bạn không cần dùng đến địa IP nữa, có thể dùng địa chỉ “*.local” này để truy cập bằng bất cứ phương thức nào, như SSH, FTP, HTTP:

b) Dùng nmap để quét

Nếu lỡ quên cài avahi-daemon cho RPi thì ta dùng nmap để quét trong mạng con:

$ sudo nmap -sn 

10

.42.0.0/24 [

sudo

] password

for

quan: Nmap scan report

for

10

.42.0.95 Host is up

(

0

.0011s latency

)

. MAC Address: B8:27:EB:D1:AB:91

(

Raspberry Pi Foundation

)

Nmap scan report

for

Fossa

(

10

.42.0.1

)

Host is up. Nmap

done

:

256

IP addresses

(

2

hosts up

)

scanned in

3

.89 seconds

nmap không được cài sẵn trong Ubuntu, bạn phải cài bằng cách:

sudo apt install nmap

c) Xem trong danh sách địa chỉ IP đã cấp

Tìm trong thư mục /var/lib/NetworkManager/ (cần quyền sudo), coi có file nào có tên dạng dnsmasq-[ifname].leases, ví dụ, vì card mạng của tôi có tên enp2s0 nên sẽ có file dnsmasq-enp2s0.leases. Mở nội dung file đó sẽ thấy địa chỉ nào được cấp cho RPi:

$ sudo cat /var/lib/NetworkManager/dnsmasq-enp2s0.leases

1596695111

b8:27:eb:d1:ab:91

10

.42.0.95 raspberrypi

01

:b8:27:eb:d1:ab:91

Giải thích thêm, NetworkManager là chương trình quản lý mạng phổ biến trên hệ điều hành Linux dành cho desktop (và smartphone) (còn có các chương trình khác dành cho bối cảnh sử dụng khác). Khi dùng nó để tạo mạng con, nó sẽ gọi thêm một chương trình tên là dnsmasq lên để đảm nhiệm chức năng DHCP server và DNS server cho mạng con đó.

Với một số phiên bản Ubuntu cũ hơn (khoảng 18.10 đến 19.10), bạn sẽ không thấy lựa chọn “Shared to other computers”. Đó chỉ là thiếu sót của giao diện “Settings”, bạn vẫn có thể cấu hình chia sẻ mạng trong một ứng dụng khác, tên là “Advanced Network Configuration”. Ứng dụng này có thể tìm thấy trong màn hình Dash (ấn phím Super/Windows để mở). Với Ubuntu 19.04 và 19.10 thì ứng dụng này bị giấu khỏi Dash, bạn phải mở bằng dòng lệnh:

nm-connection-editor

Sau khi mở “Advanced Network Configuration”, bạn có thể chọn để sửa một cấu hình mạng dây đang có, tương tự với chương trình “Settings” phía trên.

Mẹo nhỏ:

Để đưa “Advanced Network Configuration” trở lại màn hình Dash thì sửa file /usr/share/applications/nm-connection-editor.desktop và xóa dòng “NotShowIn=GNOME;” đi.

[Desktop Entry]

Name

=

Advanced Network Configuration

Comment

=

Manage and change your network connection settings

Icon

=

preferences-system-network

Exec

=

nm-connection-editor

Terminal

=

false

StartupNotify

=

true

Type

=

Application

X-GNOME-Bugzilla-Bugzilla

=

GNOME

X-GNOME-Bugzilla-Product

=

NetworkManager

X-GNOME-Bugzilla-Component

=

nm-connection-editor

Categories

=

GNOME;GTK;Settings;X-GNOME-NetworkSettings;X-GNOME-Utilities;

X-Ubuntu-Gettext-Domain

=

nm-applet

2. Tạo cổng serial ảo

Để tạo cổng serial ảo thì mình dùng socat. Cách tạo như sau:

Mở một tab của Terminal, gõ lệnh:

socat -d -d PTY,link

=

writer PTY,link

=

reader

Khi đó, socat sẽ tạo ra hai file, writer và reader. Hai tên này thích đặt sao cũng được, không nhất thiết phải là writer và reader.

Trong lúc vẫn giữ socat chạy, mở một tab khác của Terminal lên, chạy phần mềm mô phỏng, truyền tên của một trong hai file kia vào, giống với cách bạn truyền tên cổng serial thật vào, ví dụ:

./device-emulator writer

Và ở một Terminal khác thì bạn cấu hình cho phần mềm server truy cập vào file còn lại, thay cho cổng serial thật.

Lưu ý là tên file đặt là gì không quan trọng, nên tại đầu “reader” bạn vẫn có thể ghi, để đầu “writer” đọc được.

Bạn cũng có thể bỏ tham số “link” khỏi socat, ví dụ:

socat -d -d PTY PTY

Nhìn vào thông báo của socat để lấy tên file tương ứng với cổng serial ảo, ví dụ:

2017

/10/06

17

:09:49 socat[

6828

] N PTY is /dev/pts/5

2017

/10/06

17

:09:49 socat[

6828

] N PTY is /dev/pts/6

2017

/10/06

17

:09:49 socat[

6828

] N starting data transfer loop with FDs [

5

,5

] and [

7

,7

]

Tuy nhiên, đây là cách rất không được khuyến khích, vì mỗi lần tắt socat mở lại, socat sẽ phải tạo file mới với con số mới (để tránh đụng với các file pseudo-terminal sinh ra mỗi khi bạn mở một tab Terminal mới), ứng dụng của bạn sẽ phải cấu hình lại, nếu không sẽ vô tình ghi vào file pts của một Terminal nào đó.

Với cổng serial ảo tạo bởi socat, bạn có thể truy cập, theo dõi bằng hầu hết các phần mềm giao tiếp serial, ngoại trừ các phần mềm viết bằng Qt như CuteCom. Cụ thể, nếu cần phần mềm có giao diện đồ họa thì nên dùng GtkTerm:

Nếu thấy thoải mái với dòng lệnh thì bạn nên dùng thư viện PySerial của Python, khởi chạy công cụ dòng lệnh của nó bằng cách:

$ python3 -m serial.tools.miniterm /tên/port

PySerial cũng là thư viện đảm nhiệm tính năng truy cập serial trong các bộ công cụ lập trình nhúng sau:

  • IDF của Espressif (tương tác với ESP32/8266)
  • PlatformIO (tương tác với tất cả các loại board mà PlatformIO hỗ trợ).

(và tất nhiên, cùng với các thư viện Python khác, đã đóng góp phần rất lớn trong các sản phẩm của AgriConnect).

Đừng bỏ lỡ tin tuyển dụng IT mới nhất trên TopDev