มาหัดเขียน UART handler บน ESP32 Arduino กันเถอะ !

โดยปกติเวลาเราใช้ HardwareSerial บน ESP32 Arduino เราจะเซ็ต UART Interrupt Handler เป็นของเราเองไม่ได้ ของเดิมที่มีมาให้คือ จะนำ byte ที่ได้รับเก็บเข้า ring buffer ก่อน แล้วจึงใช้คำสั่ง Serial.available() / Serial.read() ดึงค่าออกมาใช้ แน่นอนว่ามันต้องนำไปเขียนใน loop ซึ่งเป็น blocking function หากจะต้องมีการเช็ค header packet ที่ได้รับมาก่อนนำไปเก็บเข้า ring buffer หรืออื่นๆ …
วิธีการหนึ่งที่ทำได้ง่ายและเร็วหากต้องการเปลี่ยน Handler คือสั่ง disable interrupt handler เดิม แล้วยัด handler ใหม่เข้าไป ดังตัวอย่างฟังก์ชันต่อไปนี้
ในวิธีการที่ว่าไปก็ยังมีปัญหา หากใช้งานร่วมกับ peripherals อื่น ในบางครั้งทำให้ ESP ไม่สามารถที่จะ allocate handler ให้ได้ ทำให้เกิดอาการบอร์ดค้าง โดยไม่มี error ทำให้ trace หาสาเหตุไม่เจอ โดยตัวผู้เขียนเองได้ลองไล่ก็พบว่าเกิดจากการที่ เรา disable แล้ว enable ใหม่นี่แหล่ะ จึงเกิดเป็นไอเดียว่า ..
ทำไมเราไม่ยัด handler ของเราเองตั้งแต่ initialize UART ล่ะ.. ปล่อยให้ HardwareSerial ทำให้ มันไม่ได้ดั่งใจ !
วิธีการใหม่ที่คิดไว้ก็คือ inherit class HardwareSerial มาโมต่อ ให้ใส่ handler function ของเราได้ตั้งแต่สั่ง begin()
ระหว่างทำก็พบปัญหา ไม่ว่าจะการที่เราเขียน handler function ไว้คนละไฟล์กับ class ใหม่ที่ implement ทำให้ต้อง forward reference ตัว uart instance ไปให้ handler เราใช้ แล้วเจอปัญหาที่ว่าตัว struct ของ uart ที่เราใช้ดันเขียน definition ไว้ในไฟล์ esp32-hal-uart.c แทนที่จะเป็น header file พอ include .c เข้าไปใน main file ก็จะทำให้เกิด error: multiple definition พอ include แค่ .h มันก็หา definition ไม่เจอ error: invalid use of incomplete type สุดท้ายจึงต้องย้าย handler ไปไว้ใน class ใหม่ที่ทำด้วย และอื่นๆ ..
สุดท้ายเราก็จะได้ class ใหม่ หน้าตาประมาณนี้
สุดท้ายนี้มีไอเดียใหม่ว่า หากเราเขียน class โดยอิงเอาจาก esp-idf ทั้งหมดอาจจะยุ่งยากน้อยกว่านี้รึเปล่า …
