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

Peranut Pongpakatien
Nov 5 · 1 min read
HardwareSerial.Begin Function

โดยปกติเวลาเราใช้ 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 ใหม่เข้าไป ดังตัวอย่างฟังก์ชันต่อไปนี้

เป็นการนำเอาฟังก์ชัน uartDisableInterrupt และฟังก์ชัน uartEnableInterrupt จากไฟล์ esp32-hal-uart.c มารวมกันเพื่อสั่ง disable และ enable ใหม่เป็น handler จากที่รับ parameter มา (intr_handler_fn)

ในวิธีการที่ว่าไปก็ยังมีปัญหา หากใช้งานร่วมกับ 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 ใหม่ หน้าตาประมาณนี้

header file ของ class ใหม่ที่สร้าง โดยมี handler ที่เราเขียนเองระบุเป็น static type ไว้
cpp file ของ class ใหม่ที่สร้าง โดยมี handler ที่เราเขียนเช็ค header packet …

สุดท้ายนี้มีไอเดียใหม่ว่า หากเราเขียน class โดยอิงเอาจาก esp-idf ทั้งหมดอาจจะยุ่งยากน้อยกว่านี้รึเปล่า …

    Peranut Pongpakatien

    Written by

    Embedded Software Engineer | Product Developer @LogixEd

    Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
    Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
    Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade