Embedded Systems Training with Raspberry Pi RP2040: A Guideline

<rawat.s>
5 min readJun 1, 2021

--

โดยทั่วไป เราสามารถจำแนกระบบสมองกลฝังตัว (Embedded Systems) ได้หลายประเภท เช่น จำแนกตามประเภทของตัวประมวลผลหลัก เช่น ไมโครคอนโทรลเลอร์ (MCU) หรือ ชิปประเภท SoC ที่โปรแกรมได้ (เช่น ที่ใช้กับคอมพิวเตอร์บอร์ดเดี่ยว หรือ Single-Board Computers: SBCs) หรือประเภทที่มีความซับซ้อนอย่างเช่น Hybrid Platform (เช่น CPU+FPGA SoC) แตกต่างกันไปตามสถาปัตยกรรมของตัวประมวลผลภายใน ประเภทและขนาดของหน่วยความจำที่ใช้งานได้ เป็นต้น

ไมโครคอนโทรลเลอร์คงเป็นตัวเลือกแรกสำหรับการเรียนรู้ ลองมาดูหัวข้อหลักในการเรียนรู้เกี่ยวกับไมโครคอนโทรลเลอร์กันก่อน ยกตัวมาเป็นตัวอย่างดังนี้

  • [T1] สถาปัตยกรรรมและการจัดการภายใน (CPU Architecture & Organization) ของตัวประมวลผล (ซีพียู) และไมโครคอนโทรลเลอร์: ในส่วนนี้ก็จะเกี่ยวข้องกับการศึกษาการทำงานจากเอกสารของผู้ผลิต เช่น ชุดคำสั่ง (Instruction Set Architecture: ISA) ของ ARM Cortex-M Series (เรียกว่า ARM / Thumb Instruction Set) หรืออาจจะเป็นตระกูลอื่นที่ไม่ใช่ ARM
  • [T2] การเขียนโปรแกรมเช่น ในระดับล่างสุดโดยใช้ภาษา Assembly ที่เกี่ยวข้องกับการใช้ชุดคำสั่งของซีพียู: ถ้าศึกษาเกี่ยวกับชุดคำสั่งของซีพียู ก็มักจะเกี่ยวข้องกับการเขียนโปรแกรมโดยใช้ภาษา Assembly และเครื่องมือที่สำคัญก็คือ ตัวจำลองการทำงานของคำสั่งไปทีละคำสั่ง หรือเรียกว่า Instruction-Set Simulator(ISS)
  • [T3] การใช้ภาษาในระดับสูงขึ้นมา เช่น C/C++ และรวมไปถึงการเลือกใช้คอมไพล์เลอร์ และ Toolchain ต่าง ๆ ที่เกี่ยวข้องสำหรับภาษา C/C++ โดยทั่วไปก็มีซอฟต์แวร์ประเภท Open Source ให้ใช้งาน และ IDE ที่นิยมใช้งานกันก็คือ Eclipse IDE เช่น Eclipse Theia, VS Code, Arduino IDE Pro เป็นต้น หรือตัวเลือกอื่นอย่างเช่น JetBrains CLion IDE
  • [T4] การใช้ภาษาประเภท Scripting Languages สำหรับไมโครคอนโทรลเลอร์ก็ได้รับความนิยมมากขึ้น ยกตัวอย่างภาษาที่มีพื้นฐานมาจากภาษา Python (MicroPython / CircuitPython), JavaScript ซึ่งถือว่าเป็นภาษาที่ได้รับความนิยม และตัวเลือกอื่นก็มีอีกเช่น ภาษา Rust และ Golang (TinyGo) เป็นต้น
  • [T5] การใช้งานวงจรภายในชิปไมโครคอนโทรลเลอร์ที่ใช้งานร่วมกับ CPU Core หรือที่เรียกว่า On-Chip Peripherals เช่น GPIOs, Timers/Counters, UART, SPI, I2C เป็นต้น และเชื่อมต่อสื่อสารกับวงจรอิเล็กทรอนิกส์และโมดูลประเภทต่าง ๆ ภายนอก เช่น เซ็นเซอร์
  • [T6] การใช้ระบบปฏิบัติการเวลาจริง (Real-Time Operating System: RTOS) โดยทั่วไปก็เป็น RTOS ประเภท Open Source เช่น FreeRTOS หรือ Arm Mbed OS เป็นต้น
  • [T7] การพัฒนาแอคพลิเคชันที่มีความซับซ้อนโดยใช้ Software Tools / SDK, Middleware / Libraries ที่เกี่ยวข้อง เพื่อนำไปใช้งานในด้านต่าง ๆ เช่น IoT หรือด้านอื่น ๆ เพื่อวัตถุประสงค์ในการวิจัย สิ่งประดิษฐ์หรืออุปกรณ์ต้นแบบ หรืออาจไปถึงการนำไปใช้งานเชิงพาณิชย์หรือระดับอุตสาหกรรม

ถ้าจะเลือกไมโครคอนโทรลเลอร์มาสักตัวเลือกหนึ่งที่มีขายในตลาด จะสามารถนำมาใช้ในการเรียนรู้ตามหัวข้อที่ได้ยกตัวอย่างได้หรือไม่ ?

เมื่อลองย้อนดูในอดีต จะเห็นว่า มีการใช้ไมโครคอนโทรลเลอร์ 8 บิต เช่น 8051, Microchip PIC, Atmel AVR เป็นต้น บางกรณีก็อาจมี 16 บิต บ้าง ต่อมาก็เริ่มมีการใช้งาน 32 บิต และโดยทั่วไปก็มีสถาปัตยกรรมแบบ RISC เช่น ตระกูล STM32 ของบริษัท STMicroelectronics และอีกหลายบริษัทที่เลือกใช้ซีพียูแบบ ARM Cortex-M Series

ถ้าจะเลือกใช้ชิป RP2040 จะมีแนวทางอย่างไรบ้าง ?

Raspberry Pi RP2040

​​

Raspberry Pi Trading Ltd. เปิดตัวชิป RP2040 SoC และบอร์ดไมโครคอนโทรลเลอร์ Pico ในวันที่ 21 มกราคม ค.ศ. 2021 ชิป RP2040 มีซีพียู ARM Cortex-M0+ ทำงานแบบสองแกน (Dual-Core) และการเขียนโปรแกรมก็เป็นไปตามชุดคำสั่งของ ARM Thumb-2 Instruction Set (ARMv6-M Architecture)

ในเชิงเปรียบเทียบ ไมโครคอนโทรลเลอร์ของบริษัทอื่นที่ใช้ (Single-Core) Cortex-M0+ (ตั้งแต่ประมาณปีค.ศ. 2012 เป็นต้นมา) เช่น

  • Atmel/Microchip: SAMD21
  • STMicroelectronics: STM32L0 Series
  • NXP/Freescale: LPC81xM, Kinetis KL0x
  • Cypress: PSoC 4 S-Series
  • Renesas Electronics: RE01

การศึกษาในหัวข้อ T1 ก็มีเอกสารอ้างอิงที่สำคัญ (ไฟล์ .pdf) และเกี่ยวข้องกับ RP2040 / ARM Cortex-M0+ ได้แก่

ข้อสังเกต: ความแตกต่างระหว่าง Arm Cortex-M0 และ M0+ เช่น

  • Number of Pipeline Stages: 2 สำหรับ Cortex-M0+ และ 3 สำหรับ Cortex-M0
  • Memory Protection Unit (MPU): yes/optional (M0+), no (M0)
  • CoreMark / MHz: เป็นการเปรียบเทียบประสิทธิภาพด้วย CoreMark Benchmarking [https://www.eembc.org/coremark/] และโดยทั่วไป จะได้ค่าสำหรับ Cortex-M0+ สูงกว่า M0 และโค้ด CoreMark สำหรับ RP2040 ก็สามารถดูได้จาก [https://github.com/protik09/CoreMark-RP2040]

การเลือกใช้บอร์ดไมโครคอนโทรลเลอร์ที่ใช้ชิป RP2040 ก็มีอยู่หลายตัวเลือก ราคาแตกต่างกันไป ตัวอย่างบริษัทที่ออกแบบและผลิตบอร์ดได้แก่ [อ้างอิง: https://en.wikipedia.org/wiki/RP2040]

  • Raspberry Pi: Raspberry Pi Pico
  • Arduino: Arduino Nano RP2040 Connect (with Wi-Fi/BLE onboard)
  • Sparkfun: Pro Micro RP2040, Thing Plus RP2040, MicroMod RP2040
  • Adafruit: Feather RP2040, ItsyBitsy RP2040, QT Py RP2040
  • Pimoroni: Tiny 2040
  • Seeedstudio: Wio RP2040 (with Wi-Fi onboard)

แต่บอร์ด Raspberry Pi คงเป็นบอร์ดที่มีราคาถูกที่สุด เมื่อเปรียบเทียบกับบอร์ดอื่นที่มีวงจรต่าง ๆ เพิ่มเติมไว้บนบอร์ด ทำให้มีราคาสูงขึ้น

สำหรับหัวข้อ T2 และ T3: การเขียนโค้ด Assembly และ C/C++ สำหรับ RP2040 ก็สามารถใช้ Pico C/C++ SDK (Software Development Kit) และ Toolchain ต่าง ๆ ที่เป็น Open Source ได้ แต่เป็นการใช้งานในรูปแบบของ CLI (Command line interface) ที่ใช้คำสั่งอย่างเช่น CMake แต่ก็สามารถใช้ร่วมกับ Microsoft Visual Studio Code ได้เช่นกัน

ถ้าจะใช้งานให้ง่ายกว่านั้น ก็สามารถใช้ Arduino IDE และเขียนโค้ดโดยใช้ Arduino API โดยติดตั้ง Arduino Mbed Core for RP2040 [https://github.com/arduino/ArduinoCore-mbed]

ถ้าจะฝึกเขียนโค้ด C หรือ Assembly (อาจจะใช้แบบ Inline Assembly ในโค้ดภาษา C ก็ได้) ถ้ามีซอฟต์แวร์ที่จำลองการทำงานของโปรแกรมได้ เช่น แปลงโค้ดให้เป็น .hex แล้วจำลองการทำงาน และดูค่าต่าง ๆ ของรีจิสเตอร์ภายในได้ ก็จะเป็นประโยชน์สำหรับการดีบัก (Debug)

การใช้ ISS ทำให้ผู้ใช้สามารถมองเห็นการทำคำสั่งและการเปลี่ยนแปลงสถานะภายในของซีพียูได้ เช่น รีจิสเตอร์ต่าง ๆ ดังนั้นจึงต้องมีซอฟต์แวร์ที่ใช้ในการจำลองการทำงานในลักษณะนี้ได้ ยกตัวอย่าง

  • ถ้าใช้ Arduino-AVR ก็มีตัวเลือกเช่น Microchip Studio IDE หรือ
  • ถ้าใช้ ARM Cortex-M Series ก็สามารถใช้ ARM-Keil MDK / uVision IDE (MDK-Lite Edition) เป็นต้น

แต่ทั้งสองซอฟต์แวร์นี้ จะใช้ได้เฉพาะระบบปฏิบัติการ Windows เท่านั้น (อาจมองว่าเป็นข้อจำกัดในการใช้งาน) และสำหรับ RP2040 ก็ยังไม่มีซอฟต์แวร์ที่สนับสนุนการดีบักดังกล่าว (ในขณะที่เขียนบทความนี้)

แต่ถ้าเป็นตัวจำลองการทำงาน และเหมาะสำหรับผู้เริ่มต้นที่ยังไม่มีบอร์ดหรือฮาร์ดแวร์ ก็พอจะมีตัวอย่างเช่น Wokwi for RP2040 และใช้ภาษา JavaScript / Nodejs สามารถนำมาสร้างเป็น Web-based Emulator สำหรับรันโค้ด .hex ของ RP2040

รูป: การจำลองการทำงานโค้ด RP2040 (Arduino Sketch) + LCD1602 โดยใช้ Wokwi Simulator
รูป: การจำลองการทำงานโค้ด RP2040 (Arduino Sketch) + 7-segment display
รูป: การจำลองการทำงานโค้ด RP2040 (Arduino Sketch) โดยใช้คำสั่งของ Pico SDK (C API)

แม้ว่าจะจำลองการทำงานของซีพียูได้ (Single-Core Only) เวอร์ชันล่าสุดรองรับการใช้งาน Peripherals ได้เฉพาะ GPIO, Timer, UART เท่านั้น แต่ก็สามารถดูค่ารีจิสเตอร์ต่าง ๆ ของซีพียูได้ในหน้า Console ของ Chrome เมื่อจำลองการทำงานของโค้ด และจะต้องใช้คำสั่ง __asm("bkpt #42") ซึ่งเป็นคำสั่งประเภท Software Breakpoint เพื่อให้ Wokwi Simulator อ่านและแสดงค่ารีจิสเตอร์ของซีพียูในขณะนั้น (CPU Register Dump: R0-R12, SP, LR, PC, APSR) เป็นข้อความในหน้าต่าง Console

ในเบื้องต้นผู้ใช้สามารถเลือกโมดูลภายนอกที่นำมาต่อกับบอร์ด Pico ได้ เช่น LED + Resistor, LCD1602, Buzzer, HC-SR04 (Ultrasonic), Membrane Keypad เป็นต้น (แต่ถ้าใช้ Wokwi กับบอร์ด Arduino-AVR ก็จะมีตัวเลือกมากกว่า ดูรายการอุปกรณ์ที่ใช้ได้จาก [https://docs.wokwi.com/])

หัวข้อ T4: การใช้งาน Scripting Languages ที่ใช้ได้กับ RP2040 ถ้าเป็นภาษา Python ก็มี MicroPython [https://micropython.org/] และ CircuitPython https://circuitpython.org/] หรือถ้าจะลองภาษา Rust ก็ได้เช่นกัน [https://crates.io/crates/rp2040]​, [https://github.com/rp-rs]

หัวข้อ T5: การใช้งาน Peripherals ต่าง ๆ นอกเหนือจากวงจรพื้นฐาน เช่น GPIO, ADC, Timer, PWM, UART, I2C, SPI, WDT, RTC เหมือนที่มีในไมโครคอนโทรลเลอร์ทั่ว ๆ ไป และก็สามารถเขียนโค้ดแบบ Bare-Metal C Programming โดยการเข้าถึงรีจิสเตอร์ด้วยพอยน์เตอร์ หรือจะใช้ฟังก์ชันจากไลบรารีของ Pico SDK เป็นต้น

นอกจากวงจรพื้นฐาน ก็มีวงจรในระดับ Advanced อย่างเช่น USB, DMA Controller, Programmable I/O (PIO) for Realtime I/O และ IOPORT/SIO spin lock / FIFO (สำหรับ Dual-core Programming) ให้ศึกษาและลองใช้งาน

หัวข้อ T6: ถ้าต้องการเขียนโค้ดโดยใช้ RTOS สำหรับ RP2040 ก็ทำได้เช่นกัน เช่น FreeRTOS และ ARM Mbed OS

ในหัวข้อ T7 ถ้าต้องการนำ RP2040 ไปใช้งานที่มีการเชื่อมต่อผ่านเครือข่าย เช่น สำหรับงาน IoT ก็มีแนวทางดังนี้

  • ใช้โมดูล Ethernet อย่างเช่น Wiznet W5500 (Ethernet MAC+PHY) เชื่อมต่อผ่านทาง SPI + GPIO มีตัวอย่างเช่น [https://github.com/bjnhur/pico-W5500/]
  • ใช้โมดูล LAN8720 เชื่อมต่อโดยใช้วงจร PIO ภายใน RP2040 ให้สื่อสารด้วยสัญญาณตามรูปแบบที่เรียกว่า RMII ไปยังวงจรภายนอกที่ทำหน้าที่เป็น Ethernet PHY มีตัวอย่างเช่น [https://www.raspberrypi.org/blog/how-to-add-ethernet-to-raspberry-pi-pico/], [https://github.com/sandeepmistry/pico-rmii-ethernet]
  • ใช้โมดูล ESP8266 / ESP-01 หรือโมดูล ESP32 เช่น Ai-Thinker BW18 ทำหน้าที่เป็น Wi-Fi to Serial สำหรับย่านความถี่ 2.4GHz IEEE 802.11 b/g/n โดยใช้ชุดคำสั่ง AT Commands ที่กำหนดโดยบริษัท Espressif [https://github.com/espressif/esp-at]
  • ใช้โมดูล ESP32 เป็น Wi-Fi/BLE ESP32 coprocessor เชื่อมต่อผ่าน SPI + GPIO เช่น โมดูล AirLift Breakout Board ของบริษัท Adafruit [https://www.adafruit.com/product/4201] ซึ่งคล้ายกับการทำงานของโมดูล u-Blox WiFi/BLE NINA-W102
  • ใช้ USB ของ RP2040 เชื่อมต่อกับ Host Computer ในรูปแบบที่เรียกว่า “Ethernet over USB” มีตัวอย่างการใช้งาน เช่น [https://github.com/maxnet/pico-webserver]
  • ใช้โมดูล LoRa Radio เช่น RFM95W Breakout (based on Semtech SX1276 chip) มีตัวอย่างการใช้งาน เช่น [https://www.raspberrypi.org/blog/how-to-add-lorawan-to-raspberry-pi-pico/]

Raspberry Pi-based Platform for Embedded Systems Development


ถ้าเลือกใช้ฮาร์ดแวร์ของ Raspberry Pi สำหรับเรียนรู้การพัฒนาด้าน Embedded Systems ก็มีหัวข้อเพิ่มเติมดังนี้

  • การใช้บอร์ด Raspberry Pi เช่น RPi 4 Model B เป็นคอมพิวเตอร์หรือแพลตฟอร์มในการพัฒนา เช่น การใช้ซอฟต์แวร์ Arduino IDE [อ่านบทความที่เกี่ยวข้อง] หรือ Arduino CLI หรือ VS Code เป็นต้น
  • การติดตั้ง Toolchains และซอฟต์แวร์ต่าง ๆ เช่น Pico SDK, GNU Arm Embedded GCC, CMake, VS Code, Arduino IDE, …
  • การใช้ซอฟต์แวร์ Open Source สำหรับ Flashing / Debugging: OpenOCD, GDB (the GNU Debugger) ดูตัวอย่างเช่น
  • การใช้ขา GPIO ของ Raspberry Pi เป็น JTAG/SWD Programmer และใช้งานร่วมกับโปรแกรม OpenOCD สำหรับการดีบักการทำงานของไมโครคอนโทรลเลอร์ เช่น RP2040 ดูตัวอย่างเช่น
    [https://www.electronicshub.org/programming-raspberry-pi-pico-with-swd/],
    [https://lupyuen.github.io/articles/openocd-on-raspberry-pi-better-with-swd-on-spi]
  • การใช้ Cortex M0+ หนึ่งแกนรันโค้ดสำหรับ RP2040 และใช้อีกหนึ่งแกนสำหรับทำหน้าที่เป็น CMSIS-DAP Debugger ในชิปเดียวกัน
    [https://github.com/majbthrd/pico-debug]
รูป: SWD Port Wiring (Source: “Getting started with Raspberry Pi Pico”)
รูป: การใช้บอร์ด Raspberry Pi เป็นอุปกรณ์เพื่อโปรแกรมไฟล์ .hex ไปยังบอร์ด Pico

สรุป: เราได้เห็นตัวอย่างหัวข้อและแนวทางการนำ RP2040 มาใช้เป็นอุปกรณ์ในการเรียนรู้ระบบสมองกลฝังตัว แม้ว่า RP2040 อาจจะไม่ใช่ตัวเลือกที่ดีที่สุด แต่ไม่ว่าเราจะเลือกใช้อะไรเพื่อการฝึกปฏิบัติ (อาจจะเป็น AVR, STM32, ESP8266/ESP32) แต่อย่างน้อยเราก็มีประเด็นหรือหัวข้อ Checklist ในการพิจารณา มีข้อดีหรือข้อเสีย ทำได้หรือทำไม่ได้ หรือมีข้อจำกัดอย่างไรบ้าง เหมาะกับกลุ่มเป้าหมาย (กลุ่มผู้เรียน) หรือไม่ เป็นต้น

--

--