Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.
Trang này được dịch bởi Cloud Translation API.
Switch to English

Xây dựng mạng Thread với bo mạch nRF52840 và OpenThread

26b7f4f6b3ea0700.png

OpenThread do Google phát hành là một triển khai mã nguồn mở của giao thức mạng Thread® . Google Nest đã phát hành OpenThread để cung cấp rộng rãi công nghệ được sử dụng trong các sản phẩm Nest cho các nhà phát triển nhằm đẩy nhanh quá trình phát triển các sản phẩm dành cho ngôi nhà kết nối.

Đặc tả Chủ đề xác định một giao thức truyền thông không dây đáng tin cậy, an toàn và công suất thấp dựa trên IPv6 cho các ứng dụng gia đình. OpenThread triển khai tất cả các lớp mạng Thread bao gồm IPv6, 6LoWPAN, IEEE 802.15.4 với bảo mật MAC, Thiết lập liên kết lưới và Định tuyến lưới.

Trong Codelab 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ạng Thread và truyền thông điệp giữa các nút.

4806d16a8c137c6d.jpeg

Những gì bạn sẽ học

  • Xây dựng và cài đặt mã nhị phân OpenThread CLI cho bảng nhà phát triển
  • Xây dựng RCP bao gồm một máy Linux và một bảng nhà phát triển
  • Giao tiếp với RCP bằng OpenThread Daemon và ot-ctl
  • Quản lý thủ công các nút Thread với Screen và OpenThread CLI
  • Vận hành an toàn các thiết bị vào mạng Chủ đề
  • Cách hoạt động của IPv6 multicast
  • Truyền thông điệp giữa các nút Chủ đề bằng UDP

Những gì bạn cần

Phần cứng:

  • 3 bo mạch nhà phát triển Nordic Semiconductor nRF52840
  • 3 cáp USB sang Micro-USB để kết nối bo mạch
  • Máy Linux có ít nhất 3 cổng USB

Phần mềm:

  • GNU Toolchain
  • Công cụ dòng lệnh Nordic nRF5x
  • Phần mềm Segger J-Link
  • OpenThread
  • Git

Trừ khi có lưu ý khác, nội dung của Codelab này được cấp phép theo Giấy phép Creative Commons Attribution 3.0 và các mẫu mã được cấp phép theo Giấy phép Apache 2.0 .

Mô phỏng OpenThread

Trước khi bắt đầu, bạn có thể muốn chạy qua OpenThread Simulation Codelab để làm quen với các khái niệm Thread cơ bản và OpenThread CLI.

Các thiết bị đầu cuối cổng nối tiếp

Bạn nên làm quen với cách kết nối với một cổng nối tiếp thông qua một thiết bị đầu cuối. Codelab này sử dụng Screen và cung cấp tổng quan về cách sử dụng, nhưng có thể sử dụng bất kỳ phần mềm đầu cuối nào khác.

Máy Linux

Codelab này được thiết kế để sử dụng máy Linux dựa trên i386 hoặc x86 để đóng vai trò là máy chủ của thiết bị luồng Radio Co-Processor (RCP) và để flash tất cả các bảng phát triển Thread. Tất cả các bước đã được thử nghiệm trên Ubuntu 14.04.5 LTS (Trusty Tahr).

Bo mạch Nordic Semiconductor nRF52840

Codelab này sử dụng ba bo mạch PDK nRF52840 .

a6693da3ce213856.png

Chúng tôi sử dụng SEGGER J-Link để lập trình các bo mạch nRF52840, có các mô-đun JTAG tích hợp. Cài đặt cái này trên máy Linux của bạn.

Tải xuống gói tài liệu và phần mềm J-Link

Tải xuống gói thích hợp cho máy của bạn và cài đặt nó ở vị trí thích hợp. Trên Linux, đây là /opt/SEGGER/JLink .

Cài đặt công cụ dòng lệnh nRF5x

Công cụ Dòng lệnh nRF5x cho phép bạn flash các mã nhị phân OpenThread vào bảng nRF52840. Cài đặt bản dựng nRF5x-Command-Line-Tools- <OS> thích hợp trên máy Linux của bạn.

Tải xuống công cụ dòng lệnh nRF5x

Đặt gói đã giải nén vào thư mục gốc ~/

Cài đặt chuỗi công cụ ARM GNU

ARM GNU Toolchain được sử dụng để xây dựng.

Tải xuống kho lưu trữ di động ARM GNU Toolchain

Chúng tôi khuyên bạn nên đặt tệp lưu trữ đã giải nén vào /opt/gnu-mcu-eclipse/arm-none-eabi-gcc/ trên máy Linux của bạn. Làm theo hướng dẫn trong tệp readme.txt của kho lưu trữ để biết hướng dẫn cài đặt.

Cài đặt màn hình (tùy chọn)

Màn hình là một công cụ đơn giản để truy cập các thiết bị được kết nối bằng cổng nối tiếp. Codelab này sử dụng Screen, nhưng bạn có thể sử dụng bất kỳ ứng dụng đầu cuối cổng nối tiếp nào mà bạn muốn.

$ sudo apt-get install screen

OpenThread

Sao chép và cài đặt OpenThread. Các lệnh bootstrap đảm bảo chuỗi công cụ được cài đặt và môi trường được định cấu hình đúng cách:

$ mkdir -p ~/src
$ cd ~/src
$ git clone --recursive https://github.com/openthread/openthread.git
$ cd openthread
$ ./script/bootstrap
$ ./bootstrap

Xây dựng OpenThread Daemon:

$ make -f src/posix/Makefile-posix DAEMON=1

Bây giờ bạn đã sẵn sàng xây dựng và cài đặt OpenThread vào các bo mạch nRF52840.

Xây dựng và flash

Xây dựng ví dụ OpenThread nRF52840 với Joiner và chức năng USB gốc. Một thiết bị sử dụng vai trò Joiner để được xác thực một cách an toàn và được đưa vào mạng Thread. USB gốc cho phép sử dụng USB CDC ACM làm phương tiện truyền nối tiếp giữa nRF52840 và máy chủ.

Luôn luôn làm sạch repo của các bản dựng trước bằng cách chạy make clean .

$ cd ~/src/openthread
$ make -f examples/Makefile-nrf52840 clean
$ make -f examples/Makefile-nrf52840 JOINER=1 USB=1

Điều hướng đến thư mục có tệp nhị phân OpenThread RCP và chuyển đổi nó sang định dạng hex:

$ cd ~/src/openthread/output/nrf52840/bin
$ arm-none-eabi-objcopy -O ihex ot-rcp ot-rcp.hex

Gắn cáp USB vào cổng gỡ lỗi Micro-USB bên cạnh chân nguồn bên ngoài trên bo mạch nRF52840, sau đó cắm vào máy Linux. Đặt công tắc nguồn nRF trên bo mạch nRF52840 thành VDD . Khi được kết nối đúng cách, LED5 sẽ bật.

20a3b4b480356447.png

Nếu đây là bo mạch đầu tiên được gắn vào máy Linux, nó sẽ xuất hiện dưới dạng cổng nối tiếp /dev/ttyACM0 (tất cả các bo mạch ttyACM sử dụng ttyACM cho mã định danh cổng nối tiếp).

$ ls /dev/ttyACM*
/dev/ttyACM0

Lưu ý số sê-ri của bo mạch nRF52840 đang được sử dụng cho RCP:

c00d519ebec7e5f0.jpeg

Điều hướng đến vị trí của Công cụ dòng lệnh nRFx và flash tệp hex OpenThread RCP vào bảng nRF52840, sử dụng số sê-ri của bảng:

$ cd ~/nrfjprog/
$ ./nrfjprog -f nrf52 -s 683704924 --chiperase --program \
       ~/openthread/output/nrf52840/bin/ot-rcp.hex --reset

Kết quả sau được tạo khi thành công:

Parsing hex file.
Erasing user available code and UICR flash areas.
Applying system reset.
Checking that the area to write is not protected.
Programing device.
Applying system reset.
Run.

Gắn nhãn bảng là "RCP" để sau này bạn không nhầm lẫn giữa các vai trò của bảng.

Kết nối với USB gốc

Vì bản dựng OpenThread RCP cho phép sử dụng USB CDC ACM gốc làm phương tiện truyền nối tiếp, bạn phải sử dụng cổng USB nRF trên bo mạch nRF52840 để giao tiếp với máy chủ RCP (máy Linux).

Tháo đầu Micro-USB của cáp USB khỏi cổng gỡ lỗi của bo mạch nRF52840 đã flash, sau đó gắn lại vào cổng USB Micro-USB nRF bên cạnh nút ĐẶT LẠI . Đặt công tắc nguồn nRF thành USB .

46e7b670d2464842.png

Khởi động OpenThread Daemon

Trong thiết kế RCP, sử dụng OpenThread Daemon để giao tiếp và quản lý thiết bị Thread. Khởi động ot-daemon với cờ chi tiết -v để bạn có thể thấy đầu ra nhật ký và xác nhận rằng nó đang chạy:

$ cd ~/src/openthread
$ ./output/posix/bin/ot-daemon -v \
    'spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=115200'

Khi thành công, ot-daemon ở chế độ tiết sẽ tạo ra đầu ra tương tự như sau:

ot-daemon[228024]: Running OPENTHREAD/20191113-00831-gfb399104; POSIX; Jun  7 2020 18:05:15
ot-daemon[228024]: Thread version: 2
ot-daemon[228024]: RCP version: OPENTHREAD/20191113-00831-gfb399104; SIMULATION; Jun  7 2020 18:06:08

Để cửa sổ đầu cuối này mở để có thể xem các bản ghi từ ot-daemon .

Sử dụng ot-ctl để giao tiếp với nút RCP. ot-ctl sử dụng cùng một CLI với ứng dụng OpenThread CLI. Do đó, bạn có thể điều khiển các nút ot-daemon theo cách tương tự như các thiết bị Thread được mô phỏng khác.

Trong cửa sổ đầu cuối thứ hai, bắt đầu ot-ctl :

$ ./output/posix/bin/ot-ctl
>

Kiểm tra state của Node 2 (nút RCP) mà bạn đã bắt đầu với ot-daemon :

> state
disabled
Done

Hai nút luồng khác được sử dụng trong Codelab này là Thiết bị luồng đầy đủ (FTD) trên thiết kế Hệ thống trên chip (SoC) tiêu chuẩn. Họ không sử dụng wpantund và người dùng tự quản lý chúng bằng OpenThread CLI.

Một thiết bị có chức năng như Ủy viên, để xác thực và đưa các thiết bị vào mạng đó một cách an toàn. Thiết bị khác hoạt động như một Bộ kết hợp mà Ủy viên có thể xác thực vào mạng Chủ đề.

Xây dựng và flash

Xây dựng ví dụ OpenThread FTD cho nền tảng nRF52840, với vai trò Ủy viên và Người tham gia được bật:

$ cd ~/src/openthread
$ make -f examples/Makefile-nrf52840 clean
$ make -f examples/Makefile-nrf52840 COMMISSIONER=1 JOINER=1

Điều hướng đến thư mục có nhị phân CLI OpenThread Full Thread Device (FTD) và chuyển đổi nó sang định dạng hex:

$ cd ~/src/openthread/output/nrf52840/bin
$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex

Gắn cáp USB vào cổng Micro-USB bên cạnh chân cắm nguồn bên ngoài trên bo mạch nRF52840, sau đó cắm vào máy Linux. Nếu RCP vẫn được gắn vào máy Linux, bảng mới này sẽ xuất hiện dưới dạng cổng nối tiếp /dev/ttyACM1 (tất cả các bảng ttyACM sử dụng ttyACM cho mã định danh cổng nối tiếp).

$ ls /dev/ttyACM*
/dev/ttyACM0  /dev/ttyACM1

Như trước đây, hãy lưu ý số sê-ri của bo mạch nRF52840 được sử dụng cho FTD:

c00d519ebec7e5f0.jpeg

Điều hướng đến vị trí của Công cụ dòng lệnh nRFx và flash tệp hex OpenThread CLI FTD vào bảng nRF52840, sử dụng số sê-ri của bảng:

$ cd ~/nrfjprog/
$ ./nrfjprog -f nrf52 -s 683704924 --chiperase --program \
       ~/openthread/output/nrf52840/bin/ot-cli-ftd.hex --reset

Dán nhãn bảng "Ủy viên."

Xác minh bản dựng

Xác minh bản dựng thành công bằng cách truy cập OpenThread CLI bằng GNU Screen từ cửa sổ đầu cuối. Các bo mạch nRF52840 sử dụng tốc độ truyền là 115200.

$ screen /dev/ttyACM1 115200

Trong cửa sổ mới, nhấn Return trên bàn phím một vài lần để hiển thị lời nhắc OpenThread CLI > . Mở giao diện IPv6 và kiểm tra các địa chỉ:

> ifconfig up
Done
> ipaddr
fe80:0:0:0:1cd6:87a9:cb9d:4b1d
Done

Sử dụng Ctrl + a → d để tách khỏi màn hình CLI của Ủy viên FTD và quay lại thiết bị đầu cuối Linux để bảng tiếp theo có thể được hiển thị. Để nhập lại CLI bất kỳ lúc nào, hãy sử dụng screen -r từ dòng lệnh. Để xem danh sách các màn hình có sẵn, hãy sử dụng screen -ls :

$ screen -ls
There is a screen on:
        74182.ttys000.mylinuxmachine        (Detached)
1 Socket in /tmp/uscreens/S-username.

Thiết lập FTD Joiner

Lặp lại quy trình trên để flash bo mạch nRF52840 thứ ba, sử dụng bản dựng ot-cli-ftd.hex .

Nếu hai nút khác được gắn vào máy Linux khi bảng thứ ba này được gắn, nó sẽ xuất hiện dưới dạng cổng nối tiếp /dev/ttyACM2 :

$ ls /dev/ttyACM*
/dev/ttyACM0  /dev/ttyACM1  /dev/ttyACM2

Gắn nhãn bảng là "Người tham gia".

Khi xác minh bằng Screen, thay vì tạo một phiên bản mới của Screen từ dòng lệnh, hãy gắn lại với phiên bản hiện có và tạo một cửa sổ mới bên trong nó (mà bạn đã sử dụng cho FTD Com Member):

$ screen -r

Tạo cửa sổ mới trong Screen bằng Ctrl + a → c **. ** Một dòng lệnh mới xuất hiện. Truy cập CLI OpenThread cho FTD Joiner:

$ screen /dev/ttyACM2 115200

Trong cửa sổ mới này, nhấn Return trên bàn phím một vài lần để hiển thị lời nhắc OpenThread CLI > . Mở giao diện IPv6 và kiểm tra các địa chỉ:

> ifconfig up
Done
> ipaddr
fe80:0:0:0:6c1e:87a2:df05:c240
Done

Bây giờ FTD Joiner CLI ở trong cùng một phiên bản của Screen với FTD Com ủy viên, bạn có thể chuyển đổi giữa chúng bằng cách sử dụng Ctrl + a → n .

Sử dụng Ctrl + a → d bất kỳ lúc nào để thoát khỏi Màn hình.

Về sau, bạn sẽ thường xuyên chuyển đổi giữa các thiết bị Thread, vì vậy hãy đảm bảo tất cả chúng đều hoạt động và dễ dàng truy cập. Cho đến nay, chúng tôi đã sử dụng Screen để truy cập hai FTD và công cụ này cũng cho phép chia đôi màn hình trên cùng một cửa sổ đầu cuối. Sử dụng điều này để xem cách một nút phản ứng với các lệnh được đưa ra trên nút khác.

Tốt nhất, bạn nên có sẵn bốn cửa sổ:

  1. dịch vụ ot-daemon / nhật ký
  2. RCP Joiner qua ot-ctl
  3. Ủy viên FTD thông qua OpenThread CLI
  4. FTD Joiner qua OpenThread CLI

Nếu bạn muốn sử dụng cấu hình hoặc công cụ thiết bị đầu cuối / cổng nối tiếp của riêng mình, vui lòng chuyển sang bước tiếp theo. Định cấu hình cửa sổ đầu cuối cho tất cả các thiết bị theo cách phù hợp nhất với bạn.

Sử dụng màn hình

Để dễ sử dụng, chỉ bắt đầu một phiên Màn hình. Bạn nên có một cái từ khi bạn thiết lập cả hai FTD.

Tất cả các lệnh trong Màn hình bắt đầu bằng Ctrl + a.

Các lệnh màn hình cơ bản:

Gắn lại với phiên Màn hình (từ dòng lệnh)

screen -r

Rời khỏi phiên Màn hình

Ctrl + a → d

Tạo cửa sổ mới trong phiên Màn hình

Ctrl + a → c

Chuyển đổi giữa các cửa sổ trong cùng một phiên Màn hình

Ctrl + a → n (tiến) Ctrl + a → p (lùi)

Hủy cửa sổ hiện tại trong phiên Màn hình

Ctrl + a → k

Màn hình chia nhỏ

Với Screen, bạn có thể chia thiết bị đầu cuối thành nhiều cửa sổ:

f1cbf1258cf0a5a.png

Các lệnh trên screen được truy cập bằng cách sử dụng Ctrl + a. Mọi lệnh phải bắt đầu bằng tổ hợp phím truy cập này.

Nếu bạn đã theo dõi chính xác Codelab, bạn sẽ có hai cửa sổ (FTD Com Member, FTD Joiner) trên cùng một phiên bản Screen. Để phân chia màn hình giữa hai, trước tiên hãy nhập Phiên màn hình hiện có của bạn:

$ screen -r

Bạn nên sử dụng một trong các thiết bị FTD. Làm theo các bước sau trong Màn hình:

  1. Ctrl + a → S để chia cửa sổ theo chiều ngang
  2. Ctrl + a → Tab để di chuyển con trỏ đến cửa sổ trống mới
  3. Ctrl + a → n để chuyển cửa sổ mới đó sang cửa sổ tiếp theo
  4. Nếu nó giống với cửa sổ trên cùng, Ctrl + a → n lần nữa để xem thiết bị FTD khác

Bây giờ cả hai đều có thể nhìn thấy. Chuyển đổi giữa chúng bằng Ctrl + a → Tab . Bạn nên tắt từng cửa sổ bằng Ctrl + a → A để tránh nhầm lẫn.

Sử dụng nâng cao

Để tiếp tục chia màn hình thành các góc phần tư và xem nhật ký ot-daemonot-ctl RCP Joiner, các dịch vụ đó phải được khởi động trong cùng phiên bản Screen này. Để làm như vậy, hãy dừng ot-daemon và thoát ot-ctl , và khởi động lại chúng trong các cửa sổ Màn hình mới (Ctrl + a → c ).

Thiết lập này không bắt buộc và được để như một bài tập cho người dùng.

Tách và điều hướng giữa các cửa sổ bằng các lệnh sau:

Tạo cửa sổ mới

Ctrl + a → c

Chia cửa sổ theo chiều dọc

Ctrl + a →

Chia cửa sổ theo chiều ngang

Ctrl + a → S

Chuyển đến cửa sổ hiển thị tiếp theo

Ctrl + a → Tab

Chuyển cửa sổ được hiển thị về phía trước hoặc phía sau

Ctrl + a → n hoặc p

Đổi tên cửa sổ hiện tại

Ctrl + a → A

Rời khỏi Màn hình bất kỳ lúc nào bằng Ctrl + a → d và đính kèm lại bằng screen -r từ dòng lệnh.

Để biết thêm thông tin về Screen, hãy xem phần tham khảo nhanh GNU Screen .

Bây giờ bạn đã định cấu hình tất cả các cửa sổ và màn hình đầu cuối của mình, hãy tạo mạng Chủ đề của chúng tôi. Trên Ủy viên FTD , hãy tạo Tập dữ liệu hoạt động mới và cam kết tập dữ liệu đó là tập hoạt động. Tập dữ liệu hoạt động là cấu hình cho mạng Luồng mà bạn đang tạo.

## FTD Commissioner ##
----------------------

> dataset init new
Done
> dataset
Active Timestamp: 1
Channel: 11
Channel Mask: 07fff800
Ext PAN ID: c0de7ab5c0de7ab5
Mesh Local Prefix: fdc0:de7a:b5c0/64
Master Key: 1234c0de7ab51234c0de7ab51234c0de
Network Name: OpenThread-c0de
PAN ID: 0xc0de
PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4
Security Policy: 0, onrcb
Done

Ghi lại Khóa chính 1234c0de7ab51234c0de7ab51234c0de sẽ được sử dụng sau này.

Cam kết tập dữ liệu này là tập dữ liệu hoạt động:

> dataset commit active
Done

Mang lại giao diện IPv6:

> ifconfig up
Done

Bắt đầu hoạt động giao thức Chủ đề:

> thread start
Done

Sau một lúc, hãy kiểm tra trạng thái thiết bị. Nó phải là Người lãnh đạo. Cũng lấy RLOC16 để tham khảo trong tương lai.

## FTD Commissioner ##
----------------------

> state
leader
Done
> rloc16
0c00
Done

Kiểm tra địa chỉ IPv6 của thiết bị:

## FTD Commissioner ##
----------------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00        # Leader Anycast Locator (ALOC)
fdc0:de7a:b5c0:0:0:ff:fe00:c00         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:6394:5a75:a1ad:e5a    # Mesh-Local EID (ML-EID)
fe80:0:0:0:1cd6:87a9:cb9d:4b1d         # Link-Local Address (LLA)

Mạng "codelab" hiện được hiển thị khi được quét từ các thiết bị Thread khác.

Từ ot-ctl trên RCP Joiner :

## RCP Joiner ##
----------------

> scan
| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |
+---+------------------+------------------+------+------------------+----+-----+-----+
| 0 | OpenThread-c0de  | c0de7ab5c0de7ab5 | c0de | 1ed687a9cb9d4b1d | 11 | -36 | 232 |

Từ CLI OpenThread trên FTD Joiner :

## FTD Joiner ##
----------------

> scan
| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |
+---+------------------+------------------+------+------------------+----+-----+-----+
| 0 | OpenThread-c0de  | c0de7ab5c0de7ab5 | c0de | 1ed687a9cb9d4b1d | 11 | -38 | 229 |

Nếu mạng "codelab" không xuất hiện trong danh sách, hãy thử quét lại.

Bạn có thể lưu ý rằng trong cả hai lần quét, mạng dường như không thể kết hợp được (cột J trên RCP Joiner và FTD Joiner). Điều này chỉ có nghĩa là cài đặt chủ đề không hoạt động trên mạng. Nó vẫn có thể được kết nối ngoài băng tần, bằng cách nhập thủ công khóa chính của mạng vào thiết bị kết nối.

Hãy thêm RCP Joiner vào mạng Thread mà chúng ta vừa tạo, sử dụng quy trình ngoài băng tần. Quét các mạng trên RCP Joiner :

## RCP Joiner ##
----------------

> scan
| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |
+---+------------------+------------------+------+------------------+----+-----+-----+
| 0 | OpenThread-c0de  | c0de7ab5c0de7ab5 | c0de | 1ed687a9cb9d4b1d | 11 | -38 | 229 |

Để tham gia, hãy đặt khóa chính của mạng (chúng tôi vừa nhận được từ ủy viên FTD) trên RCP Joiner trong tập dữ liệu hoạt động của nó.

## RCP Joiner ##
----------------

> dataset masterkey 1234c0de7ab51234c0de7ab51234c0de
Done
> dataset commit active
Done

Kiểm tra tập dữ liệu để đảm bảo rằng nó được đặt chính xác.

## RCP Joiner ##
----------------

> dataset
Master Key: 1234c0de7ab51234c0de7ab51234c0de

Đưa ra Chủ đề để RCP Joiner tham gia vào mạng "codelab". Chờ vài giây, kiểm tra trạng thái, RLOC16 và địa chỉ IPv6 của nó:

## RCP Joiner ##
----------------

> thread start
Done
> state
child
Done
> rloc16
0c01
Done
> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:0c01         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f    # Mesh-Local EID (ML-EID)
fe80:0:0:0:18e5:29b3:a638:943b          # Link-Local Address (LLA)
Done

Ghi lại Địa chỉ IPv6 Mesh-Local ( fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f tại đây), bạn sẽ sử dụng nó sau.

Trở lại với FTD Com Commission , hãy kiểm tra bộ định tuyến và bảng con để xác nhận cả hai thiết bị đều thuộc cùng một mạng. Sử dụng RLOC16 để xác định RCP Joiner.

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  35 | 1ed687a9cb9d4b1d |

Done
> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|VER| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+---+------------------+
|   1 | 0x0c01 |        240 |         25 |     3 |   89 |1|1|1|  2| 1ae529b3a638943b |
Done

Ping địa chỉ mesh-local của RCP Joiner (địa chỉ Mesh-Local thu được từ đầu ra ipaddr của RCP Joiner) để xác minh kết nối:

## FTD Commissioner ##
----------------------

> ping fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f
> 8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=1 hlim=64 time=40ms

Bây giờ chúng ta có một mạng Thread bao gồm hai nút, được minh họa bằng sơ đồ cấu trúc liên kết này:

otcodelab_top01C_2nodes.png

Sơ đồ cấu trúc liên kết

Khi bạn làm việc với phần còn lại của Codelab, chúng tôi sẽ hiển thị một sơ đồ cấu trúc liên kết Thread mới bất cứ khi nào trạng thái của mạng thay đổi. Vai trò nút được biểu thị như sau:

b75a527be4563215.png

Bộ định tuyến luôn là hình ngũ giác và Thiết bị cuối luôn là hình tròn. Các số trên mỗi nút đại diện cho ID bộ định tuyến hoặc ID con được hiển thị trong đầu ra CLI, tùy thuộc vào vai trò và trạng thái hiện tại của mỗi nút tại thời điểm đó.

Bây giờ hãy thêm thiết bị Thread thứ ba vào mạng "codelab". Lần này, chúng tôi sẽ sử dụng quy trình vận hành trong băng an toàn hơn. Trên FTD Joiner , hãy quét mạng:

## FTD Joiner ##
----------------

> scan
| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |
+---+------------------+------------------+------+------------------+----+-----+-----+
| 0 | OpenThread-c0de  | c0de7ab5c0de7ab5 | c0de | f65ae2853ff0c4e4 | 11 | -36 |  57 |

Một 0 trong cột J cho biết rằng Kiểm tra Chủ đề không hoạt động trên thiết bị.

Hãy nói rõ khi vận hành trên thiết bị tiếp theo này và chỉ cho phép FTD Joiner tham gia. Vẫn trên FTD Joiner, hãy lấy eui64 , để Ủy viên FTD có thể xác định nó:

## FTD Joiner ##
----------------

> eui64
2f57d222545271f1
Done

Trên Ủy viên FTD , bắt đầu ủy viên và chỉ định eui64 của thiết bị có thể tham gia, cùng với Thông tin đăng nhập của Người tham gia. Joiner Credential là một cụm mật khẩu dành riêng cho thiết bị.

## FTD Commissioner ##
----------------------

> commissioner start
Done
> commissioner joiner add 2f57d222545271f1 J01NME
Done

Chuyển sang Trình kết hợp FTD và quét lại:

## FTD Joiner ##
----------------

> scan
| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |
+---+------------------+------------------+------+------------------+----+-----+-----+
| 1 | OpenThread-c0de  | c0de7ab5c0de7ab5 | c0de | 1ed687a9cb9d4b1d | 11 | -45 | 196 |

Như được chỉ ra bởi 1 trong cột J, Kiểm tra luồng hiện đang hoạt động trên mạng. Bắt đầu vai trò người tham gia với Thông tin đăng nhập của Người tham gia mà bạn vừa thiết lập trên Ủy viên FTD:

## FTD Joiner ##
----------------

> ifconfig up
Done
> joiner start J01NME
Done

Trong vòng một phút hoặc lâu hơn, bạn sẽ nhận được thông báo xác thực thành công:

## FTD Joiner ##
----------------

>
Join success

Mang Chủ đề lên để FTD Joiner tham gia mạng "codelab" và ngay lập tức kiểm tra trạng thái và RLOC16:

## FTD Joiner ##
----------------

> thread start
Done
> state
child
Done
> rloc16
0c02
Done

Kiểm tra địa chỉ IPv6 của thiết bị. Chú ý rằng không có ALOC. Đó là bởi vì thiết bị này không phải là Thiết bị dẫn đầu, cũng như không giữ vai trò dành riêng cho Anycast yêu cầu ALOC.

## FTD Joiner ##
----------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:c02         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd    # Mesh-Local EID (ML-EID)
fe80:0:0:0:e4cd:d2d9:3249:a243         # Link-Local Address (LLA)

Chuyển ngay sang FTD Com Member và kiểm tra bộ định tuyến và bảng con để xác nhận rằng ba thiết bị tồn tại trong mạng "codelab":

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         25 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
|   2 | 0x0c02 |        240 |         15 |     3 |   44 |1|1|1|1| e6cdd2d93249a243 |
Done

Dựa trên RLOC16, FTD Joiner đã gắn vào mạng như một Thiết bị cuối (con). Đây là cấu trúc liên kết được cập nhật của chúng tôi:

otcodelab_top01C_ed01.png

Thiết bị luồng trong Codelab này là một loại Thiết bị luồng đầy đủ (FTD) cụ thể được gọi là Thiết bị cuối đủ điều kiện của Bộ định tuyến (REED). Điều này có nghĩa là chúng có thể hoạt động như một Bộ định tuyến hoặc Thiết bị cuối và có thể tự quảng bá từ Thiết bị cuối thành Bộ định tuyến.

Luồng có thể hỗ trợ tối đa 32 Bộ định tuyến, nhưng cố gắng giữ số Bộ định tuyến nằm trong khoảng từ 16 đến 23. Nếu một REED được gắn dưới dạng Thiết bị cuối (con) và số Bộ định tuyến dưới 16, sau một khoảng thời gian ngẫu nhiên trong vòng hai phút tự động quảng bá chính nó thành một Bộ định tuyến.

Nếu bạn có hai phần tử con trong mạng Thread của mình sau khi thêm FTD Joiner, hãy đợi ít nhất hai phút, sau đó kiểm tra lại bộ định tuyến và bảng con trên FTD Com Member :

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       63 |         0 |     3 |      3 |   1 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         61 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
Done

FTD Joiner (Extended MAC = e6cdd2d93249a243 ) đã tự thăng cấp thành Bộ định tuyến. Lưu ý rằng RLOC16 khác ( b800 thay vì 0c02 ). Đó là bởi vì RLOC16 dựa trên ID Bộ định tuyến và ID Con của một thiết bị. Khi nó chuyển từ Thiết bị cuối sang Bộ định tuyến, các giá trị ID Bộ định tuyến và ID Con của nó sẽ thay đổi, và RLOC16 cũng vậy.

otcodelab_top01C.png

Xác nhận trạng thái mới và RLOC16 trên FTD Joiner :

## FTD Joiner ##
----------------

> state
router
Done
> rloc16
b800
Done

Hạ cấp FTD Joiner

Bạn có thể kiểm tra hành vi này bằng cách hạ cấp thủ công FTD Joiner từ Bộ định tuyến trở lại Thiết bị cuối. Thay đổi trạng thái thành con và kiểm tra RLOC16:

## FTD Joiner ##
----------------

> state child
Done
> rloc16
0c03
Done

otcodelab_top01C_ed02.png

Trở lại với Ủy viên FTD , FTD Joiner bây giờ sẽ xuất hiện trong bảng con (ID = 3). Nó thậm chí có thể ở cả hai khi nó chuyển tiếp:

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       63 |         0 |     3 |      3 |   1 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         61 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
|   3 | 0x0c03 |        240 |         16 |     3 |   94 |1|1|1|1| e6cdd2d93249a243 |
Done

Sau một thời gian, nó sẽ chuyển trở lại một Bộ định tuyến có RLOC là b800 .

otcodelab_top01C.png

Xóa nhóm trưởng

Người đứng đầu được tự bầu trong tất cả các Bộ định tuyến luồng. Điều này có nghĩa là nếu Người lãnh đạo hiện tại bị xóa khỏi mạng Chủ đề, một trong những Bộ định tuyến khác sẽ trở thành Người lãnh đạo mới.

Trên Ủy viên FTD , hãy tắt Chủ đề để xóa nó khỏi mạng Chủ đề:

## FTD Commissioner ##
----------------------

> thread stop
Done
> ifconfig down
Done

Trong vòng hai phút, FTD Joiner trở thành người lãnh đạo Thread mới. Kiểm tra trạng thái và địa chỉ IPv6 của FTD Joiner để xác minh:

## FTD Joiner ##
----------------

> state
leader
Done
> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00       # Now it has the Leader ALOC!
fdc0:de7a:b5c0:0:0:ff:fe00:b800
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd
fe80:0:0:0:e4cd:d2d9:3249:a243
Done

otcodelab_top02C_01.png

Kiểm tra bảng con. Lưu ý rằng có một RLOC16 mới. Đây là Bộ kết hợp RCP, như được chỉ ra bởi ID và MAC mở rộng của nó. Để giữ mạng Thread với nhau, nó đã chuyển các Bộ định tuyến mẹ, từ Ủy viên FTD sang Bộ kết hợp FTD. Điều này dẫn đến một RLOC16 mới cho RCP Joiner (vì Router ID của nó đã thay đổi, từ 3 thành 46).

## FTD Joiner ##
----------------

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0xb801 |        240 |         27 |     3 |  145 |1|1|1|1| 1ae529b3a638943b |
Done

Bạn có thể phải đợi vài phút để RCP Joiner gắn vào FTD Joiner khi còn nhỏ. Kiểm tra trạng thái và RLOC16 để xác nhận rằng:

## RCP Joiner ##
--------------

> state
child
> rloc16
b801

Gắn lại Ủy viên FTD

Một mạng Thread với hai nút không thú vị lắm. Hãy đưa Ủy viên FTD trở lại trực tuyến.

Trên Ủy viên FTD , khởi động lại Chủ đề:

## FTD Commissioner ##
----------------------

> ifconfig up
Done
> thread start
Done

Trong vòng hai phút, nó sẽ tự động gắn lại với mạng "codelab" dưới dạng Thiết bị cuối, và sau đó tự quảng bá thành Bộ định tuyến.

## FTD Commissioner ##
----------------------

> state
router
Done

Kiểm tra bộ định tuyến và bảng con trên FTD Joiner để xác minh:

## FTD Joiner ##
----------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |       63 |         0 |     3 |      3 |   0 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       46 |         0 |     0 |      0 |  15 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0xb801 |        240 |        184 |     3 |  145 |1|1|1|1| 1ae529b3a638943b |
Done

otcodelab_top02C_02.png

Mạng Thread của chúng tôi lại bao gồm ba nút.

Quản lý mạng Thread với nhiều thiết bị trên các cửa sổ màn hình hoặc thiết bị đầu cuối khác nhau có thể phức tạp. Sử dụng các mẹo này để "đặt lại" trạng thái mạng hoặc không gian làm việc của bạn nếu bạn gặp sự cố.

Màn

Nếu bạn từng bị lạc trong cấu hình của mình (quá nhiều Cửa sổ màn hình hoặc Màn hình trong Màn hình), hãy tiếp tục tắt Cửa sổ màn hình bằng Ctrl + a → k cho đến khi không tồn tại và screen -ls trên dòng lệnh xuất ra No Sockets found . Sau đó tạo lại các cửa sổ Màn hình cho từng thiết bị. Trạng thái thiết bị được giữ lại ngay cả khi Màn hình bị tắt.

Các nút chủ đề

Nếu cấu trúc liên kết mạng Thread không như được mô tả trong Codelab này hoặc các nút ngắt kết nối vì lý do nào đó (có thể do máy Linux cấp nguồn cho chúng đã chuyển sang chế độ ngủ), tốt nhất là gỡ Thread xuống, xóa thông tin đăng nhập mạng và bắt đầu lại từ Tạo bước Mạng luồng.

Để đặt lại FTD:

## FTD Commissioner or FTD Joiner ##
------------------------------------

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

RCP có thể được đặt lại theo cách tương tự qua ot-ctl :

## RCP Joiner ##
----------------

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

Multicast được sử dụng để truyền thông tin tới một nhóm thiết bị cùng một lúc. Trong mạng Thread, các địa chỉ cụ thể được dành riêng để sử dụng đa hướng với các nhóm thiết bị khác nhau, tùy thuộc vào phạm vi.

Địa chỉ IPv6

Phạm vi

Đã giao cho

ff02::1

Liên kết cục bộ

Tất cả FTD và MED

ff02::2

Liên kết cục bộ

Tất cả FTD và Bộ định tuyến biên giới

ff03::1

Mesh-Local

Tất cả FTD và MED

ff03::2

Mesh-Local

Tất cả FTD và Bộ định tuyến biên giới

Vì chúng ta không sử dụng Bộ định tuyến biên giới trong Codelab này, chúng ta hãy tập trung vào hai địa chỉ multicast FTD và MED.

Phạm vi Liên kết-Cục bộ bao gồm tất cả các giao diện Chủ đề có thể truy cập được bằng một đường truyền vô tuyến duy nhất hoặc một "bước nhảy". Cấu trúc liên kết mạng quy định thiết bị nào phản hồi một ping tới địa chỉ multicast ff02::1 .

Ping ff02::1 từ Ủy viên FTD :

## FTD Commissioner ##
----------------------

> ping ff02::1
> 8 bytes from fe80:0:0:0:e4cd:d2d9:3249:a243: icmp_seq=2 hlim=64 time=9ms

Có hai thiết bị khác trong mạng (FTD Joiner và RCP Joiner), nhưng Ủy viên FTD chỉ nhận được một phản hồi, từ Địa chỉ liên kết cục bộ (LLA) của FTD Joiner. Điều này có nghĩa là FTD Joiner là thiết bị duy nhất mà Ủy viên FTD có thể tiếp cận với một bước nhảy.

otcodelab_top02C_02_LL.png

Bây giờ ping ff02::1 từ FTD Joiner :

## FTD Joiner ##
----------------

> ping ff02::1
> 8 bytes from fe80:0:0:0:1cd6:87a9:cb9d:4b1d: icmp_seq=1 hlim=64 time=11ms
8 bytes from fe80:0:0:0:18e5:29b3:a638:943b: icmp_seq=1 hlim=64 time=24ms

Hai phản hồi! Kiểm tra địa chỉ IPv6 cho các thiết bị khác, chúng ta có thể thấy địa chỉ đầu tiên (kết thúc bằng 4b1d ) là LLA của Ủy viên FTD và địa chỉ thứ hai (kết thúc bằng 943b ) là LLA của RCP Joiner.

otcodelab_top02C_02_LL02.png

Điều này có nghĩa là FTD Joiner được kết nối trực tiếp với cả FTD Com Member và RCP Joiner, điều này xác nhận cấu trúc liên kết của chúng tôi.

Mesh-Local

Phạm vi Mesh-Local bao gồm tất cả các giao diện Thread có thể truy cập được trong cùng một mạng Thread. Hãy xem các phản hồi cho một ping đến địa chỉ multicast ff03::1 .

Ping ff03::1 từ Ủy viên FTD :

## FTD Commissioner ##
----------------------

> ping ff03::1
> 8 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:b800: icmp_seq=3 hlim=64 time=9ms
8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=3 hlim=64 time=68ms

Lần này, Ủy viên FTD đã nhận được hai phản hồi, một từ Bộ định vị Định tuyến của Bộ điều phối FTD (RLOC, kết thúc bằng b800 ) và một từ b800 lưới Địa phương của RCP (ML-EID, kết thúc bằng d55f ). Đó là bởi vì phạm vi mesh-local bao gồm toàn bộ mạng Thread. Bất kể thiết bị ở đâu trong mạng, thiết bị đó sẽ được đăng ký với địa chỉ ff03::1 .

otcodelab_top02C_02_ML.png

Ping ff03::1 từ FTD Joiner để xác nhận cùng một hành vi:

## FTD Joiner ##
----------------

> ping ff03::1
> 8 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:c00: icmp_seq=2 hlim=64 time=11ms
8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=2 hlim=64 time=23ms

otcodelab_top02C_02_LL02.png

Lưu ý thời gian phản hồi cho RCP Joiner ở cả hai đầu ra ping. Người tham gia RCP mất nhiều thời gian hơn để đạt được Ủy viên FTD (68ms) so với thời gian đạt được Người tham gia FTD (23ms). Đó là bởi vì nó phải thực hiện hai bước nhảy để đạt được Ủy viên FTD, so với một bước cho Người tham gia FTD.

Bạn cũng có thể nhận thấy rằng ping đa hướng cục bộ lưới chỉ phản hồi với RLOC cho hai FTD - không phải RCP Joiner. Điều này là do FTD là Bộ định tuyến trong mạng, trong khi RCP là Thiết bị cuối.

Kiểm tra trạng thái của RCP Joiner để xác nhận:

## RCP Joiner ##
----------------

> state
child

Một trong những dịch vụ ứng dụng mà OpenThread cung cấp là User Datagram Protocol (UDP), một giao thức Lớp truyền tải. Một ứng dụng được xây dựng trên OpenThread có thể sử dụng UDP API để truyền thông báo giữa các nút trong mạng Luồng hoặc đến các thiết bị khác trong mạng bên ngoài (như internet, nếu mạng Luồng có Bộ định tuyến biên giới).

Các ổ cắm UDP được tiếp xúc thông qua OpenThread CLI. Hãy sử dụng nó để chuyển các thông điệp giữa hai FTD.

Nhận địa chỉ Mesh-Local EID cho FTD Joiner . Chúng tôi đang sử dụng địa chỉ này vì nó có thể truy cập được từ bất kỳ đâu trong mạng Thread.

## FTD Joiner ##
----------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00        # Leader Anycast Locator (ALOC)
fdc0:de7a:b5c0:0:0:ff:fe00:b800        # Routing Locator (RLOC)
fe80:0:0:0:e4cd:d2d9:3249:a243         # Link-Local Address (LLA)
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd    # Mesh-Local EID (ML-EID)
Done

Khởi động UDP và liên kết nó với một ổ cắm cho bất kỳ địa chỉ IPv6 nào:

## FTD Joiner ##
----------------

> udp open
Done
> udp bind :: 1212

Chuyển sang FTD Com Member , khởi động UDP và kết nối với ổ cắm bạn đã thiết lập trên FTD Joiner, sử dụng ML-EID của nó:

## FTD Commissioner ##
----------------------

> udp open
Done
> udp connect fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd 1212
Done

Kết nối UDP phải hoạt động giữa hai nút. Gửi tin nhắn từ Ủy viên FTD:

## FTD Commissioner ##
----------------------

> udp send hellothere
Done

Trên FTD Joiner , thông báo UDP đã được nhận!

## FTD Joiner ##
----------------

> 10 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:c00 49153 hellothere

Bạn đã tạo một mạng Chủ đề vật lý!

b915c433e7027cc7.png

Bây giờ bạn biết:

  • sự khác biệt giữa các loại thiết bị Thread, vai trò và phạm vi
  • cách thiết bị Thread quản lý trạng thái của chúng trong mạng
  • cách chuyển các thông điệp đơn giản giữa các nút bằng UDP

Bước tiếp theo

Xây dựng Codelab này, hãy thử các bài tập sau:

  • Đảo ngược bảng FTD Joiner dưới dạng MTD bằng cách sử dụng nhị phân ot-cli-mtd và quan sát rằng nó không bao giờ tự nâng cấp lên Bộ định tuyến hoặc cố gắng trở thành Người dẫn đầu
  • Thêm nhiều thiết bị hơn (thử một nền tảng khác!) Vào mạng và phác thảo cấu trúc liên kết bằng cách sử dụng bộ định tuyến và bảng con, cùng với ping đến địa chỉ multicast
  • Sử dụng pyspinel để kiểm soát NCP
  • Chuyển đổi NCP thành Bộ định tuyến biên giới bằng Bộ định tuyến biên giới OpenThread và kết nối mạng Chủ đề của bạn với internet

đọc thêm

Kiểm tra openthread.ioGitHub để biết nhiều tài nguyên OpenThread, bao gồm:

Tài liệu tham khảo: