การใช้งาน Zephyr RTOS สำหรับ Raspberry Pi Pico (ตอนที่ 1)#
Keywords: Zephyr RTOS, Zephyr IDE, Extension Pack for VS Code IDE, Raspberry Pi Pico
▷ บอร์ด Raspberry Pico#
บอร์ดไมโครคอนโทรลเลอร์ของ Raspberry Pi มีหลายรุ่นในปัจจุบัน เช่น
- Raspberry Pi Pico (ใช้ชิป RP2040 SoC)
- Raspberry Pi Pico W (มีโมดูล CYW43439: WiFi / BLE)
- Raspberry Pi Pico 2 (ใช้ชิป RP2350 SoC)
- Raspberry Pi Pico 2 W (มีโมดูล CYW43439: WiFi / BLE)
ในขณะที่เขียนบทความนี้ Zephyr RTOS รองรับการใช้งานสำหรับบอร์ด Pico / Pico-W แต่ก็สามารถใช้กับบอร์ดไมโครคอนโทรลเลอร์ RP2040 ของบริษัทอื่นได้ เช่น Waveshare RP2040 Zero และ VCC-GND Studio YD_RP2040
รูป: รายการวงจรภายในของ RP2040 และการใช้งานได้กับ Zephyr RTOS
รูป: ตัวอย่างบอร์ด YD-RP2040 ที่ได้นำมาทดลองใช้งานแทน Pico ( Schematic .PDF | Schematic .JPG)
รูป: YD-RP2040 Pinout
▷ การเริ่มต้นสร้างโปรเจกต์ใหม่#
เริ่มต้นให้สร้างโปรเจกต์ใหม่ใน Zephyr Workspace
โดยเลือกวิธีสร้างจากโปรเจกต์ตัวอย่าง เช่น led_blinky
ในตัวอย่างนี้ได้ตั้งชื่อ led_blink_pico
สำหรับโปรเจกต์ใหม่
กดปุ่ม Ctrl+Shift+P
แล้วเลือก "Zephyr IDE: Create Project From Template"
เพื่อสร้างโปรเจกต์ใหม่จากตัวอย่าง basic\led_blinkly
และใช้ชื่อเป็น led_blink_pico
รูป: VS Code - Zephyr IDE ที่มีการติดตั้งซอฟต์แวร์และสร้าง Workspace ไว้แล้ว
รูป: การสร้างโปรเจกต์ใหม่ โดยเลือกจากตัวอย่างของ Zephyr SDK (เลือก basic\led_blinkly
)
ทำขั้นตอน "Add Build" ในโปรเจกต์ โดยเลือกใช้บอร์ดไมโครคอนโทรลเลอร์ Raspberry Pi Pico (RP2040)
รูป: การตั้งชื่อโปรเจกต์ใหม่
เมื่อสร้าง Build และเลือกบอร์ดไมโครคอนโทรลเลอร์ แล้วจึงทำขั้นตอน Build เพื่อคอมไพล์โค้ดในโปรเจกต์
รูป: การเลือกบอร์ด rpi_pico/rp2040
รูป: การทำขั้นตอน Build
เลือกวิธีการอัปโหลดไฟล์เฟิร์มแวร์ โดยตั้งค่า Runner ให้เป็นuf2
สำหรับบอร์ด Pico
แล้วทำขั้นตอน Flash
รูป: การทำขั้นตอน Flash
เมื่อถึงขั้นตอนนี้ แสดงว่า เราสามารถใช้ Zephyr IDE และเขียนโค้ดสำหรับบอร์ด Pico ได้สำเร็จแล้ว
▷ การส่งข้อความผ่านทาง USB-CDC#
ตัวอย่างโค้ดถัดไปสาธิตการส่งข้อความผ่านทางพอร์ต USB
ที่เกิดจากการใช้คำสั่ง printk()
โดยใช้ USB-CDC
File: main.c
#include <stdio.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/usb/usb_device.h>
#include <zephyr/drivers/uart.h>
// Check if the overlay exists for CDC UART console
BUILD_ASSERT(DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_console),
zephyr_cdc_acm_uart),
"Console device is not ACM CDC UART device");
#define SLEEP_TIME_MS (1000)
#define LED0_NODE DT_ALIAS(led0)
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
// Configure the console output (USB Serial).
const struct device *usb_dev = DEVICE_DT_GET(DT_NODELABEL(cdc_acm_uart0));
//const struct device *usb_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
void main(void) {
// Check if USB can be initialized.
if (usb_enable(NULL) != 0) {
return;
}
// Wait for a console connection, if the DTR flag was set to activate USB.
uint32_t dtr = 0;
while (!dtr) {
uart_line_ctrl_get(usb_dev, UART_LINE_CTRL_DTR, &dtr);
k_sleep(K_MSEC(100));
}
if (!gpio_is_ready_dt(&led)) {
return;
}
if (gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE) != 0) {
return;
}
bool led_state = true;
while (1) {
led_state = !led_state;
(void)gpio_pin_set_dt(&led, led_state);
printf("LED state: %s\n", led_state ? "ON" : "OFF");
k_msleep(SLEEP_TIME_MS);
}
}
การเปิดใช้งานวงจร USB-CDC (Communications Device Class) บนชิป RP2040
เพื่อใช้งาน UART-Serial / Console โดยใช้ Zephyr Device Driver ชื่อว่า zephyr,cdc-acm-uart
และกำหนดให้รองรับการใช้งาน zephyr,console
สำหรับคำสั่ง printk()
สามารถทำได้โดยการแก้ไขไฟล์ proj.conf
และ app.overlay
ตามตัวอย่างด้านล่างนี้
File: proj.conf
CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_UART_LINE_CTRL=y
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_PRODUCT="RPi Pico USB Serial Console"
CONFIG_USB_DEVICE_VID=0x2e8a
CONFIG_USB_DEVICE_PID=0x000a
CONFIG_USB_CDC_ACM=y
CONFIG_UART_CONSOLE=y
File: app.overlay
/ {
chosen {
zephyr,console = &cdc_acm_uart0;
};
aliases {
led0 = &led0;
sw0 = &button0;
};
buttons {
compatible = "gpio-keys";
button0: button_0 {
gpios = <&gpio0 24 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
label = "User button";
};
};
leds {
compatible = "gpio-leds";
led0: led_0 {
gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
label = "LED 0";
};
};
};
&zephyr_udc0 {
cdc_acm_uart0: cdc_acm_uart0 {
compatible = "zephyr,cdc-acm-uart";
label = "CDC_ACM_0";
};
};
รูป: ตัวอย่างการรับข้อความจากบอร์ด RP2040 ผ่านทาง USB-CDC
▷ การอ่านค่าจากปุ่มกดและใช้เป็นค่าเอาต์พุตสำหรับ LED#
ตัวอย่างโค้ดนี้สาธิตการอ่านค่าจากปุ่มกดด้วยวิธีวนซ้ำ (Polling Loop) โดยเลือกใช้ขา GPIO-24 ซึ่งทำงานแบบ Active-low ค่าอินพุตที่อ่านได้ในแต่ละครั้ง จะถูกนำไปใช้กำหนดสถานะของ LED ซึ่งตรงกับขา GPIO-25 (Active-High)
#include <stdio.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/usb/usb_device.h>
#include <zephyr/drivers/uart.h>
// Check if the overlay exists for CDC UART console
BUILD_ASSERT(DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_console),
zephyr_cdc_acm_uart),
"Console device is not ACM CDC UART device");
#define LED0_NODE DT_ALIAS(led0)
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
#define SW_NODE DT_ALIAS(sw0)
static const struct gpio_dt_spec sw = GPIO_DT_SPEC_GET(SW_NODE, gpios);
// Configure the console output (USB Serial).
const struct device *usb_dev = DEVICE_DT_GET(DT_NODELABEL(cdc_acm_uart0));
//const struct device *usb_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
void main(void) {
// Check if USB can be initialized.
if (usb_enable(NULL) != 0) {
return;
}
// Wait for a console connection, if the DTR flag was set to activate USB.
uint32_t dtr = 0;
while (!dtr) {
uart_line_ctrl_get(usb_dev, UART_LINE_CTRL_DTR, &dtr);
k_sleep(K_MSEC(100));
}
if (!gpio_is_ready_dt(&led)) {
return;
}
if (gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE) != 0) {
return;
}
if (!gpio_is_ready_dt(&sw)) {
printk("GPIO device is not ready: %s\n", sw.port->name);
return;
}
if (gpio_pin_configure_dt(&sw, GPIO_INPUT) != 0) {
printk("GPIO device config failed: %s\n", sw.port->name);
return;
}
(void)gpio_pin_set_dt(&led, 0); // Turn off the LED
k_msleep(10);
while (1) {
int value = gpio_pin_get_dt(&sw); // Read button input
if (value >= 0) {
(void)gpio_pin_set_dt(&led, value); // Update LED state
printf("LED state: %s\n", value ? "ON" : "OFF");
}
k_msleep(100);
}
}
▷ กล่าวสรุป#
บทความนี้ได้นำเสนอขั้นตอนการสร้างโปรเจกต์ใหม่ใน VS Code IDE + Zephyr IDE Extension (ทดลองกับระบบปฏิบัติการ Windows 11) ได้ทดลองเขียนโค้ดร่วมกับ Zephyr RTOS ในเบื้องต้น และมีตัวอย่างโค้ดที่สามารถนำไปทดลองใช้กับบอร์ดไมโครคอนโทรลเลอร์ RP2040
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Created: 2024-12-14 | Last Updated: 2024-12-15