Producer-Consumer pattern trong hệ thống logging embedded

Giải thích mô hình producer-consumer khi CPU ghi log vào buffer và DMA/UART truyền dữ liệu ở background.

3 phút đọc
Firmware Architecture cover

Ghi chú nhanh

Producer-Consumer là mô hình tách bên tạo dữ liệu và bên tiêu thụ dữ liệu.

Trong UART logger:

Producer = CPU / task / ISR ghi log
Buffer   = Ring Buffer trong RAM
Consumer = UART TX DMA truyền log ra ngoài

Mô hình này nghe có vẻ sách vở, nhưng trong firmware nó xuất hiện rất nhiều: UART, USB, audio, sensor stream, flash log, network packet… Nói hơi vui: cứ nơi nào có một bên “đẻ dữ liệu” nhanh hơn bên kia xử lý, bạn sẽ gặp producer-consumer.

Vì sao logging cần mô hình này?

CPU có thể tạo log rất nhanh. Một task chỉ cần vài micro giây để format và ghi dữ liệu vào RAM.

UART thì chậm hơn nhiều. Ở 115200 bps, một dòng log vài chục ký tự có thể mất vài mili giây để truyền vật lý.

Nếu bắt CPU chờ UART gửi xong từng dòng, debug log sẽ bắt đầu ảnh hưởng tới timing của firmware. Khi đó log không còn là công cụ quan sát nữa, mà trở thành một phần của bug.

Ví dụ tư duy thiết kế

Thay vì để producer gọi thẳng UART:

Task A -> UART
Task B -> UART
ISR    -> UART

Ta gom log vào một buffer chung:

Task A ----Task B -----+--> Ring Buffer --> UART DMA
ISR    ----/

Lợi ích là các producer chỉ cần ghi nhanh vào RAM rồi quay lại việc chính. Consumer sẽ truyền dữ liệu ra ngoài theo tốc độ mà UART chịu được.

Câu hỏi quan trọng: buffer đầy thì sao?

Producer-consumer không làm UART nhanh hơn. Nó chỉ giúp firmware không bị block ngay lập tức.

Nếu log đến nhanh hơn UART truyền trong thời gian dài, buffer chắc chắn sẽ đầy. Khi đó phải có policy rõ ràng:

PolicyÝ nghĩaKhi nào dùng
Drop new byte/messageBỏ log mới khi buffer đầyƯu tiên giữ log cũ
Drop old dataGhi đè log cũƯu tiên xem trạng thái mới nhất
Block producerChờ còn chỗ trốngKhông phù hợp ISR/real-time critical
Count dropped logsGhi lại số log bị mấtRất nên có khi debug nghiêm túc

Một logger tốt không nhất thiết phải giữ mọi byte log. Nhưng nó nên nói thật rằng đã mất bao nhiêu log.

Cách tự hỏi khi đọc source

  • Ai là producer?
  • Ai là consumer?
  • Buffer nằm ở đâu?
  • Producer có thể chạy trong ISR không?
  • Consumer được kích hoạt bằng polling, interrupt, DMA callback hay task?
  • Khi buffer đầy thì policy là gì?

Cách nhớ

Producer nhanh thì ghi vào RAM.
Consumer chậm thì xử lý nền.
Buffer là vùng đệm giữa hai tốc độ khác nhau.

Bài liên quan nên đọc tiếp

Thấy nội dung này hữu ích?

Lưu lại hoặc chia sẻ cho người cũng đang học firmware, BIOS/UEFI và embedded systems.

Nội dung liên quan

Một số bài viết, ghi chú hoặc project có liên quan đến nội dung bạn vừa đọc.

Biến note thành bài viết hoàn chỉnh

Notes là nơi ghi nhanh khái niệm.