Firmware update chỉ thực sự đáng tin khi hệ thống vẫn còn đường sống sau một lần update lỗi. Với microcontroller, đây là phần khó nhất của bootloader, vì tài nguyên ít nhưng yêu cầu fail-safe lại rất cao.
Bài này tập trung vào cách thiết kế firmware update fail-safe trên microcontroller, gồm các trạng thái image, cơ chế rollback, cách xử lý khi update bị gián đoạn và những quyết định quan trọng để tránh brick thiết bị.
Mục lục
Fail-safe update là gì
Fail-safe update là cách tổ chức update sao cho khi có lỗi trong lúc truyền, ghi flash memory, kiểm tra image hoặc boot thử application image mới, hệ thống vẫn còn ít nhất một đường để quay về trạng thái boot được.
Mục tiêu của fail-safe update không phải là làm cho update không bao giờ lỗi. Mục tiêu là khi update lỗi, thiết bị vẫn còn cách quay về trạng thái boot được.
Các tình huống thường làm update thất bại
Thiết kế fail-safe thường bắt đầu từ việc liệt kê rõ các kiểu lỗi có thể xảy ra.
- Update bị gián đoạn trong lúc đang ghi flash memory, do mất điện hoặc do lỗi ở đường truyền, tool update hay thành phần trung gian.
- Image mới nhận chưa đủ hoặc bị sai dữ liệu.
- Metadata bị cập nhật dở dang hoặc bị ghi trạng thái không nhất quán.
- Image mới ghi xong nhưng không boot được.
- Application boot được nhưng treo trước khi xác nhận thành công.
- Rollback logic bị thiếu hoặc sai trạng thái.
Những nền tảng thường dùng để đạt fail-safe
Bootloader thường dựa vào một trong các nền tảng sau để đạt fail-safe.
Single image với update mode hoặc flash loader
Ở kiểu này, trong flash memory chỉ có một application image để thiết bị boot và chạy bình thường.
Khi cần update, bootloader không boot vào application ngay mà chuyển sang update mode, hoặc gọi một flash loader để nhận firmware mới và ghi lại vùng application image.
Nếu update thất bại và application image không còn boot được, thiết bị vẫn còn chính update mode hoặc flash loader đó để nạp lại firmware. Đây là điểm tạo ra tính fail-safe của kiểu thiết kế này.
Nói ngắn gọn, kiểu này không giữ sẵn application image dự phòng. Nó giữ một cách để ghi lại application image khi có sự cố.
Ưu điểm
- Tiết kiệm flash hơn A/B.
- Dễ phù hợp với MCU nhỏ.
Nhược điểm
- Thời gian phục hồi thường chậm hơn vì phải nạp lại firmware từ ngoài.
- Vẫn có rủi ro cao hơn nếu application image bị ghi đè trực tiếp và update mode hoặc flash loader không đủ chắc.
Staging area với copy có kiểm soát
Cách này nhận application image mới vào vùng staging trước, kiểm tra xong rồi mới copy sang vùng chính theo quy trình có kiểm soát.
Ưu điểm
- An toàn hơn kiểu ghi đè trực tiếp.
- Không cần hai slot full image như A/B.
Nhược điểm
- Chậm hơn vì phải copy thêm một lần.
- Phải xử lý rất kỹ các điểm dừng giữa quá trình copy.
A/B image với rollback
Cách này giữ song song application image cũ và application image mới. Bootloader chỉ chuyển sang boot application image mới khi image đó đã được ghi xong và đạt điều kiện cần thiết.
Với A/B partition, việc ghi application image mới thậm chí có thể do application hiện tại thực hiện. Bootloader chủ yếu giữ vai trò quyết định slot nào sẽ được boot và khi nào cần rollback.
Ưu điểm
- Dễ làm rollback rõ ràng.
- Dễ giữ lại application image cũ cho tới khi application image mới được xác nhận.
- Rất hợp với yêu cầu fail-safe cao.
Nhược điểm
- Tốn flash hơn.
- Không phải MCU nào cũng phù hợp để boot từ nhiều offset khác nhau.
- Cần metadata và boot decision logic chặt chẽ.
Các trạng thái image thường dùng
Một update flow fail-safe thường không chỉ có khái niệm image hợp lệ hoặc không hợp lệ. Thay vào đó, bootloader theo dõi trạng thái của image qua metadata. Điểm quan trọng là phải xác định rõ software nào được phép ghi từng state và state đó được chuyển ở thời điểm nào.
- Invalid: Bootloader thường đặt state này từ đầu hoặc đặt lại state này ngay sau khi xóa vùng flash memory đích, để nếu update bị gián đoạn thì application image mới vẫn bị xem là không hợp lệ. Chỉ khi ghi xong và pass các kiểm tra kỹ thuật ban đầu thì state mới được chuyển tiếp.
- Pending: Bootloader ghi state này sau khi application image mới đã được ghi xong và pass các kiểm tra kỹ thuật ban đầu, để đánh dấu image đủ điều kiện boot thử.
- Confirmed: Application mới hoặc bootloader ghi state này sau khi application image mới đã boot ổn và đạt điều kiện xác nhận theo thiết kế.
- Rollback: Bootloader chuyển sang nhánh này khi application image mới boot thử thất bại, không được confirm đúng hạn hoặc hệ thống phát hiện cần quay về application image cũ.
Thiếu mô hình trạng thái rõ ràng, hoặc để bootloader và application cùng ghi state mà không có quy ước chặt, là lý do rất nhiều hệ rơi vào boot loop hoặc không rollback đúng lúc.
State transition là phần phải được thiết kế và review rất kỹ.
Một số hệ còn có thêm Virgin như một optional state. State này được dùng khi cần phân biệt thiết bị chưa từng được nạp application image, chưa qua bước provision ban đầu, hoặc vẫn đang ở trạng thái blank sau manufacturing. Trong nhiều thiết kế, Virgin không nhất thiết phải được lưu thành một cờ riêng mà có thể được suy ra từ flash còn trống, metadata chưa có magic number hoặc chưa có marker khởi tạo ban đầu.
Boot thử và xác nhận application image mới
Một flow fail-safe thường không xác nhận application image mới ngay sau khi ghi xong. Thay vào đó, bootloader đánh dấu image ở trạng thái pending, cho boot thử một lần, rồi chờ application xác nhận thành công.
Nếu application không xác nhận trong thời gian hoặc số lần boot cho phép, bootloader sẽ coi application image mới là thất bại và rollback về application image cũ hoặc vào update mode.
Xử lý update bị gián đoạn
Update bị gián đoạn là bài test khó nhất của update flow.
Nguyên nhân có thể là mất điện, lỗi đường truyền, tool update dừng giữa chừng hoặc gateway trung gian gặp sự cố.
Thiết kế fail-safe phải chỉ ra rõ sau mỗi điểm dừng, hệ thống sẽ nhìn metadata thế nào và quyết định boot ra sao khi chạy lại.
- Nếu update bị gián đoạn khi đang nhận image, bootloader phải biết image chưa hoàn chỉnh.
- Nếu update bị gián đoạn khi đang copy image, bootloader phải biết vùng nào còn dùng được.
- Nếu update bị gián đoạn sau khi đổi trạng thái metadata, bootloader phải đọc lại trạng thái theo cách nhất quán.
- Nếu update bị gián đoạn sau boot thử nhưng trước khi confirm, bootloader phải biết có nên rollback hay boot lại application image mới.
Đây là nơi metadata, counter và atomic update của các cờ trạng thái trở nên rất quan trọng. Nếu muốn đi xa hơn, có thể tách metadata thành phần dữ liệu chính và phần journal hoặc marker để giảm rủi ro trạng thái nửa vời khi update bị gián đoạn.
Metadata cho fail-safe cần gì
Metadata trong update fail-safe thường cần nhiều hơn CRC hoặc version.
- Version của image.
- Trạng thái pending, confirmed hoặc invalid.
- Slot active hiện tại.
- Boot counter hoặc retry counter.
- Cờ rollback nếu có.
- Thông tin kiểm tra image như CRC, checksum hoặc signature status.
Metadata phải được đặt ở vùng đủ an toàn và có chiến lược cập nhật nhất quán.
Nếu không, chính phần metadata sẽ trở thành điểm hỏng của toàn hệ thống.
Những lỗi thiết kế fail-safe thường gặp
Một số lỗi lặp đi lặp lại trong các hệ bootloader MCU gồm các điểm sau.
- Không xác định rõ thời điểm application image mới được coi là confirmed.
- Rollback logic không gắn chặt với boot counter hoặc trạng thái boot thử.
- Cập nhật metadata theo nhiều bước nhưng không có tính nhất quán khi mất điện.
- Không giữ lại đủ thông tin để recovery sau khi application mới boot lỗi.
- Giả định quá lạc quan rằng update sẽ không bị gián đoạn trong lúc truyền, ghi hoặc đổi state.
Cập nhật chính bootloader
Một trường hợp đặc biệt hơn nhiều là cập nhật chính bootloader.
Khi đó phần mềm đang nắm quyền điều khiển update lại chính là phần mềm sắp bị thay thế, nên rủi ro cao hơn hẳn so với update application.
Trong nhiều hệ, bootloader không được update theo cùng flow với application.
Thay vào đó, người ta tách thành nhiều stage, giữ một ROM boot code hoặc một boot manager tối thiểu không đổi, rồi chỉ update phần loader ở stage sau.
Nếu không có tầng bảo vệ như vậy, lỗi trong lúc cập nhật bootloader có thể làm thiết bị mất luôn cách update thông thường hoặc mất luôn đường cứu hộ.
Vì vậy, bootloader self-update thường cần chiến lược riêng, ví dụ dual-stage boot, bank swap, ROM fallback hoặc tool phục hồi ngoài hệ thống.
Kết luận
Firmware update fail-safe là phần làm nên độ tin cậy thật sự của bootloader. Nhận image và ghi application image mới chỉ là phần đầu. Phần quyết định nằm ở chỗ hệ thống xử lý update bị gián đoạn ra sao, theo dõi trạng thái image thế nào và rollback bằng cách nào khi application image mới không chạy được.








