1. Giới thiệu

OpenThread do nhóm Google Nest phát hành là một cách triển khai mã nguồn mở của giao thức mạng Thread®. Giao thức này được thiết kế để đẩy nhanh quá trình phát triển các sản phẩm cho nhà thông minh. Quy cách Thread xác định một giao thức giao tiếp không dây đáng tin cậy, an toàn và tiêu thụ ít điện năng giữa các thiết bị dựa trên IPv6 cho các ứng dụng nhà ở và toà nhà thương mại.
Espressif đã chuyển ngăn xếp OpenThread dựa trên FreeRTOS và LwIP, cho phép nhà phát triển nhanh chóng xây dựng các mạng Thread. Bạn có thể lấy mã nguồn liên quan trên GitHub. Đồng thời, Espressif cũng đã triển khai một Bộ định tuyến biên sử dụng giao thức Thread dựa trên RTOS.
Trong Lớp học lập trình này, bạn sẽ lập trình OpenThread trên phần cứng thực, tạo và quản lý một mạng Thread, đồng thời truyền thông báo giữa các nút.

Kiến thức bạn sẽ học được
- Tạo và flash các tệp nhị phân OpenThread CLI vào các bảng ESP.
- Tạo và nhấp nháy bộ định tuyến biên cho bảng Bộ định tuyến biên sử dụng giao thức Thread của ESP.
- Quản lý các nút Thread theo cách thủ công bằng ESP Monitor và OpenThread CLI.
- Tạo một mạng Thread trên Bộ định tuyến biên theo giao thức Thread.
- Bảo mật quá trình thiết lập các thiết bị trên mạng Thread.
- Ping địa chỉ IPv6 giữa các nút Thread.
- Truyền thông báo giữa các nút Thread bằng UDP.
Bạn cần có
Phần cứng:
- 2 bảng ESP có các mô-đun IEEE 802.15.4.
- 1 bảng Bộ định tuyến biên sử dụng giao thức Thread ESP.
Phần mềm:
2. Bắt đầu
- Cài đặt ESP-IDF.
Vui lòng làm theo Hướng dẫn lập trình ESP-IDF để cài đặt môi trường phát triển phần mềm.
- Sao chép ESP Thread Border Router SDK.
ESP-THREAD-BR là SDK Bộ định tuyến biên sử dụng giao thức Thread chính thức của ESP. Nó hỗ trợ tất cả các tính năng mạng cơ bản để tạo Bộ định tuyến biên Thread và tích hợp các tính năng phong phú ở cấp độ sản phẩm để sản xuất nhanh.
$ cd <your-local-workspace> $ git clone --recursive https://github.com/espressif/esp-thread-br.git
3. Tạo và flash
Để tạo và flash tệp nhị phân ot-cli-ftd trên các bo mạch ESP có mô-đun IEEE 802.15.4, bạn có thể tham khảo ví dụ ot_cli của ESP-IDF để biết thêm thông tin chi tiết:
$ cd <your-idf-path>/examples/openthread/ot_cli $ idf.py set-target <your-board-type>
Bật tính năng kết hợp thông qua menuconfig:
$ idf.py menuconfig
Component config (Cấu hình thành phần) > OpenThread > Enable Joiner (Bật Joiner), sau đó tạo và flash.
$ idf.py -p <your-local-port> build flash monitor
Để tạo và flash tệp nhị phân ot-br trên Bo mạch bộ định tuyến biên ESP Thread, trước tiên, bạn cần tạo tệp nhị phân RCP. Bạn không cần phải flash rõ ràng tệp nhị phân RCP này vào thiết bị trên Bo mạch bộ định tuyến biên theo giao thức Thread của ESP. Nội dung này sẽ được đưa vào tệp nhị phân Border Router và được chuyển sang chip ESP32-H2 khi khởi động lần đầu (hoặc khi thay đổi chương trình cơ sở RCP). Bạn có thể tham khảo tài liệu về ESP Thread BR để biết thêm thông tin chi tiết:
$ cd <your-idf-path>/examples/openthread/ot_rcp $ idf.py set-target esp32h2 $ idf.py build $ cd <your-esp-thread-br-path>/examples/basic_thread_border_router $ idf.py set-target esp32s3
Bật tính năng uỷ viên thông qua menuconfig:
$ idf.py menuconfig
Cấu hình thành phần > OpenThread > Bật Commissioner, sau đó tạo và flash.
$ idf.py -p <your-local-port> build flash monitor
4. Tạo mạng Thread trên Bộ định tuyến biên sử dụng giao thức Thread
Giờ đây, bạn có thể tạo một mạng Thread bằng dòng lệnh OpenThread trên ESP Thread Border Router Board (BR Commissioner):
## BR Commissioner ## ---------------------- > dataset init new Done > dataset Active Timestamp: 1 Channel: 21 Channel Mask: 0x07fff800 Ext PAN ID: 151975d11bea97b5 Mesh Local Prefix: fd6a:b54b:d6a3:b05a::/64 Network Key: 731ab6a60a64a0a0b14b259b86b2be01 Network Name: OpenThread-1444 PAN ID: 0x1444 PSKc: 54e7f18d2575014da94db09df29c5df0 Security Policy: 672 onrc 0 Done
Xác nhận tập dữ liệu này là tập dữ liệu đang hoạt động:
> dataset commit active Done
Mở giao diện IPv6:
> ifconfig up I (59329) OPENTHREAD: Platform UDP bound to port 49153 Done I (59329) OT_STATE: netif up
Bắt đầu thao tác giao thức Thread:
> thread start I(61709) OPENTHREAD:[N] Mle-----------: Role disabled -> detached Done > I(62469) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition reattaching with Active Dataset I(69079) OPENTHREAD:[N] RouterTable---: Allocate router id 11 I(69079) OPENTHREAD:[N] Mle-----------: RLOC16 fffe -> 2c00 I(69089) OPENTHREAD:[N] Mle-----------: Role detached -> leader I(69089) OPENTHREAD:[N] Mle-----------: Partition ID 0x28b518c6 I (69099) OPENTHREAD: Platform UDP bound to port 49154
Sau một lát, hãy kiểm tra trạng thái thiết bị. Đó phải là Nhà lãnh đạo.
> state leader Done >
5. Tham gia mạng Thread thông qua networkkey
Trong lớp học lập trình này, 2 bảng ESP có các mô-đun IEEE 802.15.4 được chuẩn bị để tham gia mạng được tạo bởi BR. Trong phiên này, chúng ta sẽ thêm Board1 vào mạng.
Lấy networkkey từ BR:
## BR Commissioner ## ---------------------- > networkkey 731ab6a60a64a0a0b14b259b86b2be01 Done >
Đặt networkkey này thành một bảng ESP (Board1 Joiner) có các mô-đun IEEE 802.15.4:
## Board1 Joiner ## ---------------------- > dataset networkkey 731ab6a60a64a0a0b14b259b86b2be01 Done
Xác nhận tập dữ liệu này là tập dữ liệu đang hoạt động:
> dataset commit active Done
Mở giao diện IPv6:
> ifconfig up Done I (20308) OT_STATE: netif up
Bắt đầu thao tác giao thức Thread:
> thread start I(23058) OPENTHREAD:[N] Mle-----------: Role disabled -> detached Done > I(23408) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition reattaching with Active Dataset I(30028) OPENTHREAD:[N] Mle-----------: Attach attempt 1 unsuccessful, will try again in 0.288 seconds I(30328) OPENTHREAD:[N] Mle-----------: Attach attempt 2, AnyPartition I(33498) OPENTHREAD:[N] Mle-----------: Delay processing Announce - channel 21, panid 0x1444 I(33758) OPENTHREAD:[N] Mle-----------: Processing Announce - channel 21, panid 0x1444 I(33758) OPENTHREAD:[N] Mle-----------: Role detached -> disabled I(33758) OPENTHREAD:[N] Mle-----------: Role disabled -> detached I(34178) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition I(35068) OPENTHREAD:[N] Mle-----------: RLOC16 fffe -> 2c01 I(35068) OPENTHREAD:[N] Mle-----------: Role detached -> child
Sau một lát, hãy kiểm tra trạng thái thiết bị. Đó phải là Trẻ.
> state child Done
Đặt vai trò thành Router.
> state router Done I(51028) OPENTHREAD:[N] Mle-----------: RLOC16 2c01 -> 2800 I(51028) OPENTHREAD:[N] Mle-----------: Role child -> router I(51028) OPENTHREAD:[N] Mle-----------: Partition ID 0x28b518c6 >

6. Tham gia mạng Thread thông qua quy trình thiết lập an toàn
Trong phiên này, chúng ta sẽ thêm Board2 vào mạng thông qua quy trình thiết lập bảo mật:
Lấy PSKc và panid từ BR Commissioner:
## BR Commissioner ## ---------------------- > pskc 54e7f18d2575014da94db09df29c5df0 Done > panid 0x1444 Done
Định cấu hình thông tin mạng cho Board2:
## Board2 Joiner ## ---------------------- > dataset pskc 54e7f18d2575014da94db09df29c5df0 Done > dataset panid 0x1444 Done
Xác nhận tập dữ liệu này là tập dữ liệu đang hoạt động:
## Board2 Joiner ## ---------------------- > dataset commit active Done
Mở giao diện IPv6:
## Board2 Joiner ## ---------------------- > ifconfig up Done I (29146) OT_STATE: netif up
Lấy eui64 từ Board2:
## Board2 Joiner ## ---------------------- > eui64 4831b7fffec02be1 Done
Trên BR Commissioner, hãy khởi động commissioner và chỉ định eui64 của thiết bị có thể tham gia, cùng với Joiner Credential (Thông tin đăng nhập của thiết bị tham gia), ví dụ: J01NME. Thông tin đăng nhập của thiết bị kết nối là một chuỗi gồm các ký tự chữ và số viết hoa (0-9 và A-Y, không bao gồm I, O, Q và Z để dễ đọc), có độ dài từ 6 đến 32 ký tự.
## BR Commissioner ## ---------------------- > commissioner start Commissioner: petitioning Done Commissioner: active > commissioner joiner add 4831b7fffec02be1 J01NME Done
Chuyển sang Board2 Joiner. Bắt đầu vai trò người tham gia bằng Thông tin xác thực của người tham gia mà bạn vừa thiết lập trên BR Commissioner:
## Board2 Joiner ## ---------------------- > ifconfig up Done > joiner start J01NME Done
Trong vòng khoảng một phút, bạn sẽ nhận được thông báo xác nhận rằng quá trình xác thực đã thành công:
## Board2 Joiner ## ---------------------- > Join success
Sau đó, bạn có thể bắt đầu và tham gia mạng Thread do BR Commissioner tạo.
Bắt đầu thao tác giao thức Thread:
> thread start I(35727) OPENTHREAD:[N] Mle-----------: Role disabled -> detached Done > I(36197) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition reattaching with Active Dataset I(37007) OPENTHREAD:[N] Mle-----------: RLOC16 fffe -> 2801 I(37007) OPENTHREAD:[N] Mle-----------: Role detached -> child
Đặt vai trò thành Router.
> state router Done I(46057) OPENTHREAD:[N] Mle-----------: RLOC16 2801 -> 4400 I(46057) OPENTHREAD:[N] Mle-----------: Role child -> router I(46057) OPENTHREAD:[N] Mle-----------: Partition ID 0x28b518c6 >
Giờ đây, bạn sẽ có một mạng Thread với cấu trúc liên kết như minh hoạ dưới đây:

7. Ping địa chỉ IPv6 giữa các nút Thread
Bạn có thể dùng lệnh ping để giao tiếp giữa hai bảng bất kỳ. Dùng lệnh ipaddr để in địa chỉ IPv6 của từng bảng:
## BR Commissioner ## ---------------------- > ipaddr fd6a:b54b:d6a3:b05a:0:ff:fe00:fc00 # Leader Anycast Locator (ALOC) fd6a:b54b:d6a3:b05a:0:ff:fe00:2c00 # Routing Locator (RLOC) fd6a:b54b:d6a3:b05a:a8df:eb43:63d8:bda0 # Mesh-Local EID (ML-EID) fe80:0:0:0:687c:7248:cc14:9c4d # Link-Local Address (LLA) Done >
## Board1 Joiner ## ---------------------- > ipaddr fd6a:b54b:d6a3:b05a:0:ff:fe00:2800 # Routing Locator (RLOC) fd6a:b54b:d6a3:b05a:e461:db08:c833:1248 # Mesh-Local EID (ML-EID) fe80:0:0:0:18ac:df04:4671:6a45 # Link-Local Address (LLA) Done
## Board2 Joiner ## ---------------------- > ipaddr fd6a:b54b:d6a3:b05a:0:ff:fe00:4400 # Routing Locator (RLOC) fd6a:b54b:d6a3:b05a:d7dc:8e90:9bc9:ecbc # Mesh-Local EID (ML-EID) fe80:0:0:0:a8cc:1483:f696:91a2 # Link-Local Address (LLA) Done
Ví dụ: để ping Board2 MLE-ID từ BR Commissioner, bạn có thể chạy lệnh này trên BR Commissioner:
## BR Commissioner ## ---------------------- > ping fd6a:b54b:d6a3:b05a:d7dc:8e90:9bc9:ecbc 16 bytes from fd6a:b54b:d6a3:b05a:d7dc:8e90:9bc9:ecbc: icmp_seq=1 hlim=255 time=123ms 1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 123/123.0/123 ms. Done
8. Truyền thông báo giữa các nút Thread bằng UDP
Trong phiên này, bạn sẽ tìm hiểu cách gửi thông báo giữa hai thiết bị Thread. Ví dụ: mở udp và liên kết nó trên cổng 20617, đồng thời lắng nghe tất cả các địa chỉ trên BR:
## BR Commissioner ## ---------------------- > udp open Done > udp bind :: 20617 I (1298739) OPENTHREAD: Platform UDP bound to port 20617 Done
Sau đó, hãy gửi một thông báo từ Board1 đến địa chỉ và cổng BR MLE-ID 20617:
## Board1 Joiner ## ---------------------- > udp open Done > udp send fd6a:b54b:d6a3:b05a:a8df:eb43:63d8:bda0 20617 ESP
Bạn có thể thấy tin nhắn nhận được trên BR:
## BR Commissioner ## ---------------------- 3 bytes from fd6a:b54b:d6a3:b05a:e461:db08:c833:1248 49154 ESP
9. Xin chúc mừng!
Bạn đã tạo một mạng Thread thực bằng các bảng ESP!

Giờ thì bạn đã biết:
- Tạo và flash các tệp nhị phân OpenThread CLI vào các bảng ESP.
- Tạo một bộ định tuyến biên nhấp nháy cho bảng Bộ định tuyến biên sử dụng giao thức Thread ESP.
- Quản lý các nút Thread theo cách thủ công bằng ESP Monitor và OpenThread CLI.
- Tạo một mạng Thread trên Bộ định tuyến biên theo giao thức Thread.
- Bảo mật quá trình thiết lập các thiết bị trên mạng Thread.
- Ping địa chỉ IPv6 giữa các nút Thread.
- Truyền thông báo giữa các nút Thread bằng UDP.
Tài liệu đọc thêm
Hãy truy cập vào openthread.io và GitHub để xem nhiều tài nguyên về OpenThread, bao gồm:
- Nền tảng được hỗ trợ – khám phá tất cả nền tảng hỗ trợ OpenThread
- Tạo OpenThread – thông tin chi tiết hơn về cách tạo và định cấu hình OpenThread
- Thread Primer – bao gồm tất cả các khái niệm về Thread có trong Lớp học lập trình này
Tài liệu tham khảo: