Thông qua các giai đoạn của quá trình biên dịch, chương trình ứng dụng được người dùng phát triển trên ngôn ngữ bậc cao như C/C++ sẽ được chuyển thành ngôn ngữ máy để thiết bị nhúng có thể hiểu và thực thi được. Chương trình ứng dụng sẽ được truyền thành từng chuỗi byte sau khi nó được chuyển thành định dạng tập tin phổ biến như *.hex hoặc *.bin từ các ngôn ngữ lập trình thường sử dụng khi lập trình nhúng như C/C++. Chuỗi byte này có liên quan tới địa chỉ bộ nhớ của vi điều khiển. Có thể nạp hay thay đổi chương trình đang chạy trên thiết bị bằng cách cắm dây nạp trực tiếp từ máy tính xuống thiết bị thông qua các mạch nạp (programmer). Trong trường hợp các thiết bị nhúng hỗ trợ cập nhật chương trình từ xa thì tập tin chương trình từ máy chủ quản lý dữ liệu sẽ được tải xuống thiết bị nhúng thông qua môi trường Internet và được ghi vào bộ nhớ. Bài viết này sẽ phân tích định dạng của tập tin chương trình ở định dạng HEX và tập tin chương trình ở định dạng BIN. Việc hiểu được định dạng các tập tin giúp các bạn có thể triển khai các tính năng như cập nhật chương trình từ xa (FOTA) hoặc có thay đổi chương trình ứng dụng thông qua một chuẩn giao tiếp nào đó (In-Application Programming – IAP) như UART mà không cần sử dụng mạch nạp để ghi trực tiếp chương trình vào bộ nhớ.
Hình 1: Mô tả về quá trình biên dịch một chương trình nhúng
[HỌC ONLINE TẠI TAPIT: LẬP TRÌNH VI ĐIỀU KHIỂN STM32, VI XỬ LÝ ARM CORTEX – M]
Tập tin chương trình ở định dạng HEX: là một tập tin chứa nội dung chương trình cùng các thông tin chỉ dẫn với 6 loại HEX record khác nhau theo định dạng Intel HEX. Mỗi record sẽ bao gồm nhiều ký tự ASCII biểu diễn các giá trị theo mã hexadecimal. Mỗi hàng (record) sẽ thường sẽ có 6 trường (field), mỗi trường sẽ có nhiệm vụ riêng. Mỗi hàng có thể kết thúc bằng kí tự CR(0x13)/LF(0x0A)/NULL(0x00) [1].
Hình 2. Ví dụ về nội dung và cấu trúc tập tin HEX
Start code
- Số lượng kí tự: 1
- Dấu hai chấm ( : ) trong bảng ASCII.
Byte count
- Số lượng kí tự: 2
- Đại diện cho số lượng các byte sẽ xuất hiện trong Data field. Giá trị byte count có thể nằm trong khoảng từ 0 – 255 (0x00 – 0xFF). Thông thường byte count có giá trị 16 (0x10).
Address
- Số lượng kí tự: 4
- Với Data Record thì trường này cung cấp 16 bit địa chỉ bộ nhớ chương trình có trọng số thấp (0-15).
- Với các record khác thì nó sẽ có giá trị 0x0000.
Record type
- Số lượng kí tự: 2
- Dùng để xác định chức năng của record đó. Sẽ có 6 loại record tương ứng với 6 giá trị:
- Record type = 00 ⇒ Data Record: Record này sẽ chứa dữ liệu, chính là chương trình của chúng ta. Bên cạnh đó nó cũng sẽ cung cấp giá trị 16 bit địa chỉ bộ nhớ có trọng số thấp (bit 0-15) nơi lưu dữ liệu trong bộ nhớ chương trình của vi điều khiển.
- Record type = 01 ⇒End of File Record: Record này xuất hiện cuối cùng file chương trình nhằm thông báo kết thúc file.
- Record type = 02 ⇒Extended Segment Address Record: Record này để thay đổi bit 4-19 trong địa chỉ bộ nhớ lưu chương trình so với record đã cung cấp trước đó.
- Record type = 03 ⇒Start Segment Address Record.
- Record type = 04 ⇒ Extended Linear Address Record: Record này chứa thông tin bit 16-31 địa chỉ của bộ nhớ lưu chương trình.
- Record type = 05 ⇒Start Linear Address Record.
Data
- Số lượng kí tự: 2 x Byte count
- Thường sử dụng để biểu thi thông tin hoặc dữ liệu tùy thuộc vào từng loại record. Có một số record sẽ không có trường này.
Checksum
- Số lượng kí tự: 2
- Một giá trị được tính toán được sử dụng để xác nhận record không có lỗi.
- Trong quá trình FOTA, từ File Intel HEX chúng ta phải tách nội dung chương trình ra và lưu vào bộ nhớ flash của vi điều khiển theo các chỉ dẫn địa chỉ đi kèm trong tập tin.
Tập tin chương trình ở định dạng Intel BIN: Tập tin chương trình ở định dạng BIN là một tập tin chứa nội dung chương trình có đuôi “.bin”. Đây là một dạng tệp tin phi văn bản, được lưu trữ dưới định dạng mã nhị phân gồm các giá trị 0 và 1, dữ liệu trong tập tin chính là chương trình ứng dụng được lưu một cách liên tục theo địa chỉ bộ nhớ, không chia thành từng dòng, không chứa các ký tự kết thúc câu, kí tự xuống dòng, không chứa địa chỉ, các trường chỉ dẫn và không có giá trị checksum.
Hình 3. Ví dụ về nội dung và cấu trúc tập tin BIN
Có thể thấy tập tin chương trình ở định dạng BIN không có sẵn một giải pháp kiểm tra lỗi, độ toàn vẹn dữ liệu như giải pháp checksum của tập tin định dạng HEX nên trong các ứng dụng OTA hay IAP các bạn áp dụng các kỹ thuật như tính checksum (ví dụ CRC) hay Hash (ví dụ SHA256) để gửi kèm kết quả tính toán với tập tin định dạng BIN. Vi điều khiển sau khi nhận được tập tin sẽ tính toán và so sánh kiểm tra để xác nhận tính toàn vẹn của chương trình trước khi cho phép thực thi chương trình. Hiện nay CRC hay SHA256 được hỗ trợ bởi rất nhiều bởi phần cứng của vi điều khiển hoăc các thư viện thuật toán.
Tìm hiểu thêm:
[HỌC ONLINE TẠI TAPIT: LẬP TRÌNH VI ĐIỀU KHIỂN STM32, VI XỬ LÝ ARM CORTEX – M]
Xem thêm Tổng hợp các bài hướng dẫn Lập trình vi điều khiển STM32 tại đây.
Xem thêm Tổng hợp hướng dẫn Internet of Things với NodeMCU ESP8266 và ESP32 tại đây.
Tài liệu tham khảo:
[1] ARM, GENERAL: INTEL HEX FILE FORMAT, https://www.keil.com/
Thuong Nguyen
Chúc các bạn thành công!