โฮสต์เว็บไซต์ด้วยบุหรี่ไฟฟ้าแบบใช้แล้วทิ้ง
(bogdanthegeek.github.io)- โปรเจกต์เชิงทดลองที่นำไมโครคอนโทรลเลอร์ ARM Cortex-M0+ สมรรถนะต่ำซึ่งฝังอยู่ในบุหรี่ไฟฟ้าแบบใช้แล้วทิ้งมารันเว็บเซิร์ฟเวอร์
- วิเคราะห์ชิป PY32F002B ของ PUYA ที่มี แฟลช 24KiB และ RAM 3KiB พร้อมสร้างการเชื่อมต่อเครือข่ายด้วยวิธี SLIP
- ใช้ Semihosting, โปรโตคอล SLIP และสแตก uIP TCP/IP เพื่อพอร์ตการสื่อสาร TCP/IP และความสามารถของ HTTP server ผ่าน virtual tty
- เดิมทีช้ามาก แต่หลังจาก ปรับแต่งบัฟเฟอร์ และปรับปรุงการประมวลผลข้อมูล ก็ทำให้การตอบสนองและความเร็วในการโหลดหน้าเพิ่มขึ้นอย่างมาก
- ทำให้สามารถรันโค้ดเซิร์ฟเวอร์แบบไดนามิกและให้บริการ API endpoint ได้ แม้อยู่ในสภาพแวดล้อมที่มีหน่วยความจำต่ำ
- มีการเผยแพร่โค้ดแล้ว และแม้จะโฮสต์ใช้งานจริงได้ แต่ก็ยังมีข้อจำกัดด้านทรัพยากรอย่างหน่วยความจำ
บทนำ
- ขอชี้แจงก่อนว่าบทความนี้ไม่ได้ให้บริการผ่านเว็บเซิร์ฟเวอร์ที่รันอยู่บนบุหรี่ไฟฟ้าแบบใช้แล้วทิ้งโดยตรง แต่ให้บริการเนื้อหาเดียวกันผ่านเซิร์ฟเวอร์แยกต่างหาก
- สามารถดูตัวอย่างการทำงานจริงได้ที่ http://ewaste.fka.wtf/
ที่มา
- ตลอดหลายปีที่ผ่านมา ผู้เขียนได้รวบรวมบุหรี่ไฟฟ้าแบบใช้แล้วทิ้งจากคนรู้จักเพื่อนำ แบตเตอรี่ มาใช้ซ้ำ
- ช่วงหลังเริ่มสนใจที่อุปกรณ์บุหรี่ไฟฟ้าแบบใช้แล้วทิ้งมีความก้าวหน้ามากขึ้นเรื่อย ๆ และเริ่มมาพร้อม USB-C และแบตเตอรี่แบบชาร์จซ้ำได้
- ระหว่างการแยกชิ้นส่วนได้พบไมโครคอนโทรลเลอร์ ARM Cortex-M0+ ที่มีแฟลชในตัว ชื่อ PUYA ซึ่งเป็นชิปที่รู้จักกันดีในฐานะไมโครคอนโทรลเลอร์ราคาประหยัด
- ผู้เขียนเก็บไมโครคอนโทรลเลอร์เหล่านี้มาจากหลายรุ่น และพบว่ามีการติดป้ายกำกับขาดีบักไว้ ทำให้ง่ายต่อการวิเคราะห์
ฮาร์ดแวร์ที่ใช้
- บนชิปมีสกรีนว่า
PUYA C642F15แต่คาดว่าแท้จริงแล้วอยู่ในตระกูล PY32F002B - สเปกหลัก:
- คอร์ 24MHz Cortex-M0+
- แฟลช 24KiB
- RAM 3KiB
- มีอุปกรณ์ต่อพ่วงหลายอย่าง แต่ไม่ได้ใช้งานในโปรเจกต์นี้
- แม้ประสิทธิภาพจะต่ำเมื่อเทียบกับสมาร์ตโฟนทั่วไป แต่ในสภาพแวดล้อมแบบฝังตัวก็ยังสร้างเว็บเซิร์ฟเวอร์แบบง่าย ๆ ได้เพียงพอ
การเชื่อมต่อเครือข่าย
- แม้ไม่ใช่แนวคิดใหม่ทั้งหมด แต่ผู้เขียนเกิดไอเดียในการรันเว็บเซิร์ฟเวอร์ระหว่างทดลองแนวคิด semihosting
- Semihosting คือวิธีจำลอง syscall บนระบบ ARM แบบฝังตัว
- เมื่อนำค่า/พอยน์เตอร์ใส่ไว้ในรีจิสเตอร์แล้วเรียก breakpoint ดีบักเกอร์จะตีความและจัดการการทำงานให้
- โดยทั่วไปใช้เพื่อส่งล็อก แต่ก็สามารถทำการสื่อสารข้อมูลแบบสองทางได้
- อุปกรณ์ USB serial รองรับโปรโตคอล SLIP(Serial Line Internet Protocol) จึงนำมาใช้เป็นอินเทอร์เฟซเครือข่าย
- บน Linux (และบางส่วนของ macOS) สามารถสร้างสภาพแวดล้อม เครือข่าย SLIP ผ่าน virtual tty ด้วย
slattachและsocatเป็นต้นpyocd gdb -S -O semihost_console_type=telnet -T $(PORT) $(PYOCDFLAGS) & socat PTY,link=$(TTY),raw,echo=0 TCP:localhost:$(PORT),nodelay & sudo slattach -L -p slip -s 115200 $(TTY) & sudo ip addr add 192.168.190.1 peer 192.168.190.2/24 dev sl0 sudo ip link set mtu 1500 up dev sl0 - เลือกใช้ uIP เป็นสแตก TCP/IP เพราะมีขนาดเล็กมาก ไม่ต้องใช้ RTOS และพอร์ตได้ง่าย
- จากตัวอย่างของ uIP ได้นำ HTTP server มาใช้ และพอร์ตโค้ด SLIP ให้เข้ากับวิธี semihosting จนสามารถเปิดใช้งานเว็บเซิร์ฟเวอร์ได้สำเร็จ
- เนื่องจากสถาปัตยกรรม ARM มีปัญหาเรื่องการจัดแนว 16 บิต จึงได้แก้ไขสคริปต์สร้าง filesystem และแปลงผลด้วย Perl
การปรับความเร็วให้เหมาะสม
- ในช่วงแรกมีความเร็วตอบสนองช้ามาก โดย ping 1.5 วินาที, packet loss 50% และโหลดหน้าเว็บนานเกิน 20 วินาที
- สาเหตุคือโอเวอร์เฮดที่สูงมากของการรับส่งข้อมูลแบบไบต์ต่อไบต์
- จึงใช้ RAM 3KiB อย่างเต็มที่ เพิ่ม ring buffer และปรับให้ฟังก์ชัน SLIP ป้อนข้อมูลเป็นชุด
- ฝั่งการเขียนก็แบ่งส่งเป็นแบตช์เช่นกัน เพื่อให้การส่งข้อมูลและการล้างสถานะทำได้รวดเร็ว
- หลังการปรับแต่งสามารถทำได้ถึง ping 20ms, ไม่สูญหาย, โหลดหน้า 160ms
- การใช้ RAM และแฟลชทั้งหมด:
- แฟลช: 5,116B จาก 24KB (20.82%)
- RAM: 1,380B จาก 3KB (44.92%)
- มีพื้นที่เพียงพอสำหรับให้บริการคอนเทนต์บล็อกทั้งหมดได้สบาย และยังสามารถรันโค้ด C ฝั่งเซิร์ฟเวอร์ได้อีกด้วย
ฟีเจอร์อื่น ๆ และบทสรุป
- ผู้เขียนได้สร้าง API endpoint เอง เพื่อส่งคืนจำนวนครั้งที่มีการร้องขอหน้าแรกและ unique ID ของไมโครคอนโทรลเลอร์
- นี่เป็นการทดลองที่สร้างได้ถึงเว็บเซิร์ฟเวอร์แบบไดนามิกและ API บนฮาร์ดแวร์สเปกต่ำสุดขั้วและหน่วยความจำระดับน้อยมาก
ยังไม่มีความคิดเห็น