บทความนี้อธิบายขั้นตอนการติดตั้งซอฟต์แวร์ต่าง ๆ ที่จำเป็นสำหรับการเขียนโค้ดภาษา C/C++ เพื่อใช้งาน Zephyr RTOS สำหรับบอร์ดไมโครคอนโทรลเลอร์ โดยใช้เครื่องคอมพิวเตอร์ที่ทำงานด้วยระบบปฏิบัติการ Windows 10 (64 บิต)
Zephyr RTOS
Zephyr (เซฟ-เฟอะ) เป็นชื่อโปรเจกต์ของซอฟต์แวร์ประเภท Open Source และมีเป้าหมายที่จะพัฒนาระบบปฏิบัติการเวลาจริง หรือ “เรียลไทม์-โอเอส” (Real-Time Operating System: RTOS) เพื่อนำไปใช้กับระบบคอมพิวเตอร์ฝัวตัวที่เหมาะสำหรับงานด้าน IoT (Internet of Things)
โครงการนี้ได้มีการเปิดตัวครั้งแรกในปีค.ศ. 2016 และในปัจจุบันโปรเจกต์นี้ก็ได้รับการสนับสนุนโดย Linux Foundation และมีหลายบริษัทเข้าร่วมสนับสนุนเป็นสมาชิก (Project Members)
Zephyr นอกจากส่วนที่เป็น Real-Time Kernel ยังมีซอฟต์แวร์ส่วนอื่นอีก เช่น Drivers / Device Trees, Board Support Package (BSP), Flash File System และ Network Protocol Stacks (BLE, OpenThread, …)
Zephyr สามารถนำไปใช้งานกับบอร์ดไมโครคอนโทรลเลอร์ได้หลายตระกูล เช่น ARM Cortex-M Series, RISC-V หรือแม้กระทั่ง Xtensa (ESP32) [สามารถดูรายชื่อทั้งหมดได้จาก Zephyr Supported Boards]
เครื่องมือที่เป็นซอฟต์แวร์สำหรับการใช้งาน Zephyr นั้น สามารถเลือกใช้ได้ทั้งระบบปฏิบัติการ Linux, Mac OS X และ Windows
เครื่องมือที่จำเป็นสำหรับการอัปโหลดไฟล์ .hex ไปยังบอร์ดไมโครคอนโทรลเลอร์ ก็อาจจะแตกต่างกันได้ เช่น อุปกรณ์ ST-Link V2 Programmer สำหรับชิป STM32 และตัวเลือกอื่น เช่น ใช้ J-Link Programmer (SWD) หรือ JTAG Programmer หรือ UFU-Bootloader ผ่าน USB เป็นต้น
Features of Zephyr
- Highly configurable and modular
- Supports cooperative and preemptive threading
- Memory and resources are typically statically allocated, benefiting long-running systems
- An integrated device driver interface
- Memory protection via stack overflow protection, kernel object and device driver permission tracking, and thread isolation
- Bluetooth Low Energy (BLE 4.2, 5.0) support, with both controller and host, BLE Mesh
- 802.15.4 OpenThread compliant
- A native, fully featured and optimized networking stack
- Supports a range of subsystems, including USB, file system, logging, DFU
ขั้นตอนการดำเนินการ
- ดาวน์โหลดและติดตั้งโปรแกรมต่อไปนี้ สำหรับระบบปฏิบัติการ Windows 10 (ถ้ายังไม่เคยได้ติดตั้งใช้งาน)
- Python 3 for Windows
- Git for Windows
- CMake for Windows
- Ninja for Windows
- CCache (Compiler Cache) for Windows
- GNU ARM Embedded toolchain for Windows
- ESP-IDF Installer for Windows
- OpenOCD for Windows
2. เปิดใช้งาน Git Bash แล้วติดตั้ง Python Tool ที่มีชื่อว่า west
3. สร้างโปรเจกต์ใหม่สำหรับ Zephyr RTOS โดยใช้คำสั่ง west init
และ west update
4. ติดตั้ง Python Packages ที่จำเป็นสำหรับ Zephyr Build Tools
5. ทำขั้นตอน Build ตัวอย่างโค้ด เช่น sample/basic/blinky
สำหรับบอร์ดไมโครคอนโทรลเลอร์ที่เป็นเป้าหมาย
6. ทำขั้นตอน Upload หรือ Flash ไฟล์ที่ได้จากขั้นตอน Build ไปยังบอร์ดไมโครคอนโทรลเลอร์ โดยใช้คำสั่ง west flash
การทดสอบความพร้อมในการใช้คำสั่งต่าง ๆ สำหรับ Zephyr
เริ่มต้นด้วยการเรียกใช้ Git Bash และจะต้องลองตรวจสอบดูก่อนว่า สามารถเรียกใช้คำสั่งที่จำเป็นจาก Git Bash ได้หรือไม่ สังเกตว่า การใช้คำสั่งจะเหมือนในกรณีของ Linux เช่น Ubuntu
คำสั่งหรือโปรแกรมใดที่จำเป็นต้องใช้ และยังไม่ได้อยู่ในรายการของตัวแปร PATH (เป็นชื่อ Environment Variable ในส่วนของ System Properties ของระบบ Windows) เราก็สามารถกำหนดเพิ่มได้ เพียงแต่ต้องทราบก่อนว่า ได้ติดตั้งโปรแกรมเหล่านั้นไว้ที่ใดในระบบของเรา
ตัวอย่างการทำคำสั่ง เพื่อเพิ่มไดเรกทอรีสำหรับการค้นหาคำสั่งเมื่อเรียกใช้
$ export PATH="/c/Program Files/Python37/:/c/Program Files/Python37/Scripts:$PATH"$ export PATH="/c/Program Files/Git/bin:/c/Program Files/CMake/bin:$PATH"$ export PATH="/C/Tools/OpenOCD/bin:$PATH"
คำสั่งในลักษณะนี้ จะระบุ Path เพื่อใช้คำสั่ง เช่น python.exe และ cmake.exe เป็นต้น
ลองเรียกใช้คำสั่ง ตรวจสอบเวอร์ชัน และระบุไดเรกทอรีที่เกี่ยวข้อง (พร้อมตัวอย่างเอาต์พุตที่ได้)
$ which python
/c/Program Files/Python37/python$ python -V
Python 3.7.4$ which git
/c/Program Files/Git/cmd/git$ git --version
git version 2.25.1.windows.1$ which cmake
/c/Program Files/CMake/bin/cmake$ cmake --version | head -1
cmake version 3.17.0-rc3$ which ninja
/c/Program Files/CMake/bin/ninja$ ninja --version | head -1
1.10.0$ which ccache
/c/Program Files/CMake/bin/ccache$ ccache --version | head -1
ccache version 3.7.4
เนื่องจากเราเลือกใช้ GNU ARM Embedded Toolchain (เลือกใช้เวอร์ชัน 7 2017-q4-major) และ OpenOCD (เวอร์ชัน 0.10.0) ดังนั้นจึงต้องกำหนดชื่อตัวแปรต่อไปนี้ เพื่อนำไปใช้กับ Zephyr
$ export ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb$ export GNUARMEMB_TOOLCHAIN_PATH="/c/Tools/GNU_ARM_Embedded/7_2017-q4-major"$ export PATH="/C/Tools/OpenOCD/bin:$PATH"$ export OPENOCD_DEFAULT_PATH="/C/Tools/OpenOCD/share/openocd/scripts"
ถัดไป ให้ติดตั้ง Python package ที่มีชื่อว่า west
ดังนี้ (เวอร์ชันที่ใช้คือ v.0.7.2)
$ pip3 install -U --user west$ west --version
West version: v0.7.2
จากนั้นจึงสร้างไดเรกทอรีใหม่สำหรับโปรเจกต์แรก ในตัวอย่างนี้คือ Zephyr/zephyr_demo
และทำคำสั่งเพื่อดาวน์โหลดและอัปเดตไฟล์ต่าง ๆ จาก Github Repositories (อาจใช้เวลานาน และขึ้ออยู่กับความเร็วของอินเทอร์เน็ต)
$ mkdir Zephyr && cd Zephyr$ west init zephyr_demo$ cd ./zephyr_demo && west update
หลังจากทำคำสั่งดังกล่าวแล้ว โครงสร้างของไฟล์ในไดเรกทอรี จะเป็นดังนี้
.
├── bootloader
│ └── mcuboot
├── modules
│ ├── bsim_hw_models
│ ├── crypto
│ ├── debug
│ ├── fs
│ ├── hal
│ └── lib
├── tools
│ ├── ci-tools
│ ├── edtt
│ └── net-tools
└── zephyr
├── arch
├── boards
├── cmake
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CODEOWNERS
├── CONTRIBUTING.rst
├── doc
├── drivers
├── dts
├── ext
├── include
├── Kconfig
├── Kconfig.zephyr
├── kernel
├── lib
├── LICENSE
├── Makefile
├── misc
├── modules
├── README.rst
├── samples
├── scripts
├── soc
├── subsys
├── tests
├── VERSION
├── version.h.in
├── west.yml
├── zephyr-env.cmd
└── zephyr-env.sh
จากนั้นทำคำสั่งเพื่อติดตั้ง Python Packages ตาม Requirements ของโปรเจกต์
$ pip install --user -r ./zephyr/scripts/requirements.txt
ถัดไปก็มาลองทำขั้นตอน Build จากโค้ดตัวอย่างในโปรเจกต์ samples/basic/blinky
และเลือกใช้บอร์ด NUCLEO L476RG
$ cd ./zephyr
$ source zephyr-env.sh
$ west build -p auto -b nucleo_l476rg samples/basic/blinky
เมื่อทำขั้นตอนได้สำเร็จแล้ว จึงทำขั้นตอนการอัปโหลดไฟล์ .hex ไปยังบอร์ดทดลอง โดยทำคำสั่งดังนี้
ข้อสังเกต: บอร์ด ST NUCLEO ของบริษัท STMicroelectronics นั้นมีวงจร ST-Link V2 รวมไว้บนบอร์ดแล้วเพื่อใช้สำหรับการอัปโหลดและดีบักโปรแกรมในฮาร์ดแวร์ได้ ดังนั้นเราสามารถใช้โปรแกรม OpenOCD สำหรับวัตถุประสงค์ดังกล่าว
$ west flash --runner openocd
เมื่อทำได้สำเร็จ เราจะเห็น LED บนบอร์ดไมโครโทรลเลอร์กระพริบทุก ๆ 1 วินาที
ลองมาแก้ไขโค้ด samples/basic/blinky/src/main.c
เช่น เปลี่ยนความเร็วในการกระพริบ LED โดยเลือกใช้ค่าตัวเลขอื่นที่ไม่ใช่ 1000 สำหรับ SLEEP_TIME_MS
#define SLEEP_TIME_MS 1000
แล้วทำขั้นตอน Build & Flash อีกรอบ
ลองใช้งานร้วมกับ VSCode IDE
เราสามารถใช้ VSCode เป็น IDE ในการเขียนโค้ดภาษา C/C++ สำหรับ Zephyr Project ได้ โดยใช้งานร่วมกับ Git Bash ใน Terminal ของ VSCode ตามรูปตัวอย่างนี้ และให้สร้างไดเรกทอรี .vscode
เป็นส่วนหนึ่งของโปรเจกต์ ซึ่งภายในจะต้องสร้างไฟล์ เช่น c_cpp_properties.json
, settings.json
, launch.json
และ tasks.json
เป็นต้น (โดยส่วนตัว จะใช้วิธีทำคำสั่งแบบ Command Line โดยใช้ Git Bash Terminal ภายใน VSCode)
ทดลองกับบอร์ด ESP32 (Xtensa)
ถ้าจะลองเปลี่ยนมาใช้บอร์ด ESP32 แทน ST NUCLEO ดูบ้าง ก่อนอื่นจะต้องมีการติดตั้ง ESP-IDF (Espressif IoT Development Framework) Tools โดยใช้ไฟล์ ESP-IDF Installer for Windows ตามที่อยู่นี้
https://dl.espressif.com/dl/esp-idf-tools-setup-2.3.exe
และจะต้องกำหนดตัวแปรสำหรับระบบในลักษณะนี้ (อาจแตกต่างกันไป ขึ้นอยู่กับการเลือกไดเรกทอรีสำหรับการติดตั้งโปรแกรม)
$ export "ESP_IDF_PATH=/C/Users/$USERNAME/esp-idf"
$ export "IDF_TOOLS_PATH=/C/Tools/espressif"$ export ZEPHYR_TOOLCHAIN_VARIANT="espressif"
$ export ESPRESSIF_TOOLCHAIN_PATH="/C/Tools/espressif/tools/xtensa-esp32-elf/esp-2019r2-8.2.0/xtensa-esp32-elf"
ติดตั้ง Python tool ชื่อ esptool
แล้ว เสียบบอร์ด ESP32 เข้ากับพอร์ต USB ของคอมพิวเตอร์ แล้วทำคำสั่งตรวจสอบหาพอร์ต
$ pip install --user esptool -U
เมื่อทำคำสั่งต่อไปนี้ และพบว่า สามารถเชื่อมต่อกับบอร์ด ESP32 ได้ จะปรากฎข้อความในลักษณะนี้ (หมายเลขพอร์ตที่พบคือ COM21 ในกรณีตัวอย่างนี้)
$ esptool chip_id
esptool.py v2.8
Found 2 serial ports
Serial port COM21
Connecting........__
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, Coding Scheme None
Crystal is 40MHz
MAC: 24:0a:c4:xx:xx:xx
Uploading stub...
Running stub...
Stub running...
Warning: ESP32 has no Chip ID. Reading MAC instead.
MAC: 24:0a:c4:xx:xx:xx
Hard resetting via RTS pin...
ขั้นตอนถัดไป ให้แก้ไขไฟล์และบันทึกลงไฟล์ boards/xtensa/esp32/esp32.dts
ซึ่งจะใช้กับ Device Tree (.dts) สำหรับบอร์ด ESP32 ที่ใช้ซีพียู Xtensa ดังนี้ เพื่อกำหนดขาสำหรับ On-board LED (GPIO-2)
/*
* Copyright (c) 2019 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
/dts-v1/;#include <espressif/esp32.dtsi>/ {
model = "esp32";
compatible = "espressif,esp32"; leds {
compatible = "gpio-leds";
blue_led: led {
gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
label = "Status Led";
};
};
aliases {
uart-0 = &uart0;
i2c-0 = &i2c0;
led0 = &blue_led;
};chosen {
zephyr,sram = &sram0;
zephyr,console = &uart0;
zephyr,shell-uart = &uart0;
};
};&cpu0 {
clock-frequency = <40000000>;
};&cpu1 {
clock-frequency = <40000000>;
};&uart0 {
status = "okay";
current-speed = <115200>;
tx-pin = <1>;
rx-pin = <3>;
rts-pin = <22>;
cts-pin = <19>;
};&uart1 {
current-speed = <115200>;
tx-pin = <10>;
rx-pin = <9>;
rts-pin = <11>;
cts-pin = <6>;
hw-flow-control;
};&uart2 {
current-speed = <115200>;
tx-pin = <17>;
rx-pin = <16>;
rts-pin = <7>;
cts-pin = <8>;
hw-flow-control;
};&i2c0 {
status = "okay";
clock-frequency = <I2C_BITRATE_FAST>;
sda-pin = <21>;
scl-pin = <22>;
};&i2c1 {
clock-frequency = <I2C_BITRATE_FAST>;
sda-pin = <18>;
scl-pin = <5>;
};&trng0 {
status = "okay";
};
จากนั้นก็ทำขั้นตอน Build และ Flash (ผ่าน USB-to-Serial) ตามลำดับ
$ rm -fr build .cache$ west build -p auto -b esp32 samples/basic/blinky$ west flash --esp-device COM21
ถ้าทำได้สำเร็จ จะเห็นว่า LED สีน้ำเงินบนบอร์ด ESP32 จะกระพริบ
โดยสรุป เราสามารถติดตั้งและใช้งาน Software Tools ต่าง ๆ ที่จำเป็นในการเขียนโปรแกรมภาษา C และใช้ Zephyr RTOS กับบอร์ดไมโครคอนโทรลเลอร์ที่ได้เลือกมากเป็นตัวอย่างคือ ST NUCLEO L476RG และ ESP32 แม้ว่าจะเป็นการลองแค่ตัวอย่างง่าย ๆ (LED กระพริบ) แต่ก็ถือว่า เป็นก้าวแรกที่เราจะได้เรียนรู้ Zephyr ในลำดับถัดไป