Bỏ qua, đến nội dung chính
Nastrotek
Bài viếtFirmware

Ghi chú đầu tiên về firmware cho sản phẩm nhúng

Nguyên tắc ban đầu khi viết firmware cho một sản phẩm nhúng nhỏ: phạm vi, ranh giới module, logging, và xử lý lỗi mà không đoán mò.

Chia sẻ

LinkedInFacebookX
Opened Mochi prototype showing the ESP32 board, display wiring and 3D-printed enclosure

Bắt đầu từ vòng lặp chính, không phải từ mọi tính năng

Bản firmware đầu tiên cho một sản phẩm nhỏ không cần mọi tính năng chạy được. Nó chỉ cần một thứ: một vòng lặp chính chạy ổn định và không âm thầm dừng lại. Trước khi thêm phần đọc cảm biến, giao tiếp hay logic giao diện, mình muốn biết chắc board boot giống nhau mỗi lần, sống sót qua reset, và tiếp tục chạy mà không treo.

Nghe có vẻ hiển nhiên, nhưng rất dễ bỏ qua. Rất hấp dẫn khi viết ngay "tính năng thật" trước vì nó thú vị hơn. Cái giá phải trả xuất hiện sau đó, khi một lần treo máy hoặc một vòng lặp reset không có nguyên nhân rõ ràng vì quá nhiều thứ đã được thêm vào trước khi vòng lặp nền được kiểm chứng ổn định.

Module nên dễ tách riêng

Firmware cho một sản phẩm nhỏ thường chạm vào cảm biến, giao tiếp, thời gian và một dạng output nào đó. Nếu tất cả nằm trong một file với state dùng chung khắp nơi, một lỗi ở một chỗ sẽ khó tách khỏi phần còn lại.

Mình thường giữ một ranh giới đơn giản giữa ba loại code: code nói chuyện trực tiếp với phần cứng, code quyết định phải làm gì, và code báo cáo trạng thái. Không cần là một kiến trúc chính thức. Nó chỉ cần đủ rõ để khi có gì chạy sai, bạn biết nên bắt đầu tìm ở đâu — đọc cảm biến sai, quyết định sai, hoặc báo trạng thái sai là ba vấn đề khác nhau, và trộn chúng lại làm mỗi cái khó tìm hơn.

Logging quan trọng hơn vẻ ngoài

Một dòng log qua UART gần như không tốn gì để viết nhưng có thể tiết kiệm rất nhiều thời gian debug. Ở giai đoạn đầu, mình luôn muốn có tối thiểu một thông báo boot, một cách in ra trạng thái hiện tại, và một cách báo cáo giá trị bất thường thay vì âm thầm bỏ qua nó.

Lỗi cần tránh là chỉ thêm logging sau khi có gì đó hỏng. Lúc đó, lỗi có thể đã trở nên chập chờn hoặc biến mất. Logging có sẵn từ bản chạy được đầu tiên biến một lỗi bí ẩn thành một chuỗi sự kiện có thể đọc được, thường đủ để tìm nguyên nhân mà không cần mở thêm một phiên debug riêng.

Xử lý lỗi mà không đoán mò

Firmware nhúng nhỏ thường bỏ qua việc xử lý lỗi thật vì "chuyện đó không nên xảy ra." Một lần đọc cảm biến thất bại đôi khi. Một message đến bị lỗi định dạng. Một timer tràn sớm hơn dự kiến. Không cái nào phổ biến, nhưng tất cả đều xảy ra sớm muộn, và nếu không được xử lý, chúng có xu hướng tạo ra hành vi khó hiểu ở rất xa nguyên nhân thật.

Quy tắc mình dùng cho firmware giai đoạn đầu khá đơn giản: mọi giá trị đến từ bên ngoài code — cảm biến, đường giao tiếp, input người dùng — đều phải được kiểm tra trước khi tin dùng. Nếu không qua kiểm tra, firmware nên báo cáo thay vì âm thầm chạy tiếp với giá trị sai. Chỉ riêng thói quen này đã loại bỏ phần lớn những lỗi kỳ lạ chỉ xuất hiện sau nhiều giờ chạy.

Ghi chú cho lần làm firmware tiếp theo

Kỷ luật giống với ghi chú phần cứng cũng áp dụng ở đây: ghi lại vì sao chọn một giá trị, không chỉ giá trị đó là gì. Một timeout 200ms, một số lần retry là ba, một độ trễ debounce 20ms — không giá trị nào trong số này còn hiển nhiên vài tháng sau nếu thiếu lý do đi kèm.

Firmware cho một sản phẩm nhỏ không cần thanh lịch ngay ở bản đầu. Nó cần trung thực về việc đã xử lý gì và chưa xử lý gì, để bản tiếp theo có thể cải thiện dựa trên một nền đã biết rõ, thay vì đoán mò về hiện trạng.

Tài liệu tham khảo

Các nguồn dưới đây là tài liệu nền để kiểm tra lại thuật ngữ, thông số và khuyến nghị kỹ thuật trước khi áp dụng vào prototype thật.

Đọc thêm liên quan

Chia sẻ

LinkedInFacebookX

Tiếp tục khám phá

Đọc tiếp

Bài viết liên quan

Xem thêm trong Bài viết

Nastrotek sử dụng cookie để phân tích truy cập và cá nhân hóa quảng cáo, giúp hiểu cách website được sử dụng. Bạn có thể chấp nhận hoặc từ chối các cookie không thiết yếu.