🌱 Bootloader - Triển khai một chương trình Bootloader

🌱 Bootloader - Triển khai một chương trình Bootloader

    Phần quan trọng nhất của topic Bootloader, chúng ta đang thắc mắc chương trình Bootloader làm gì và code như thế nào? Bài viết này sẽ giới thiệu tổng quan về nội dung và cách triển khai của một chương trình Bootloader.

Chương trình Bootloader dùng để làm gì?

    Chương trình Boot ở đây thực chất là một chương trình Firmware được lưu trong bộ nhớ, độc lập với chương trình Application. Khi Vi điều khiển Reset, nó sẽ nhảy vào chương trình Boot này (thường nằm ở Sector 0 - Đối với Vi điều khiển lõi ARM Cortex M thì Bootloader sẽ cần đặt tại địa chỉ 0x0000.0000). Công việc của chương trình Boot sẽ bao gồm 2 chế độ chính:

  • APP_MODE: Chế độ mặc định của chương trình Bootloader, đảm bảo khi đã có Firmware, và không nhận được tín hiệu update Firmware mới, thì Bootloader sẽ ở APP_MODE và cho phép vi điều khiển nhảy lên thực hiện chương trình Application.
  • BOOT_MODE: Chế độ được thực hiện khi có tín hiệu update Firmware mới, thực hiện nhận data (Application Firmware mới) thông qua các giao thức truyền thông (ví dụ UART), kiểm tra và ghi Firmware mới vào bộ nhớ Flash.
Bootloader Firmware
Chương trình Bootloader

    Note: Đối với các vi điều khiển lõi ARM Cortex-M, người lập trình có thể thay đổi địa chỉ base của bảng Vector Table bằng cách sử dụng thanh ghi SCB_VTOR, và trong bài toàn này, cần gán địa chỉ base của Firmware vào thanh ghi SCB_VTOR.

Ví dụ các step chương trình Bootloader trên vi điều khiển STM32

Chẳng hạn: SCB➔VTOR = 0x0800.8000

Boot Flow
Sequence to Jump to Application Firmware
  • Sau khi Reset thì vi điều khiển nhảy đến Reset_Handler() mặc định ở địa chỉ 0x0800.0000 và nhảy đến hàm Main() của chương trình Boot.
  • Ở chương trình Boot này nó sẽ lấy địa chỉ của chương trình ứng dụng mà chúng ta muốn nhảy đến (chẳng hạn 0x0800.8000).
  • Gọi hàm Bootloader(), hàm này sẽ set thanh ghi SCB_VTOR theo địa chỉ Firmware muốn nhảy đến, SCB➔VTOR = 0x0800.8000.
  • Sau đó gọi hàm Software Reset (nhảy đến Reset_Handler()) là xong, Bây giờ Firmware mới ở địa chỉ 0x0800.8000 đã bắt đầu chạy và Vi xử lý đã nhận diện Reset_Handler() ở địa chỉ mới 0x0800.8004 nên dù có nhấn nút Reset thì nó vẫn chạy trong Application Code.

Triển khai hàm JumptoApplication()

    Đối với APP_MODE, vi điều khiển sẽ thực thi các lệnh để nhảy đến thực thi Application. Trước đó, nó cần thực hiện một số công việc để tránh lỗi (như mô tả trong hình dưới), và thay đổi thanh ghi VTOR đến địa chỉ base của Application Firmware.

  • Lấy địa chỉ của Firmware cần nhảy đến.
  • Dissable các ngắt của hệ thống và xóa các Ngắt đang chờ xử lý, nhằm tránh làm chương trình Boot bị gián đoạn.
  • Set MSP - Main Stack Pointer và thanh ghi SCB_VTOR với tác dụng đã nói ở trên.
  • Set PC - Program Counter trỏ đến Reset_Handler() của Firmware mới.
  • Gọi đến Reset_Handler() để Reset lại chương trình. Bây giờ, vi xử lý sẽ bắt đầu với Firmware mới.
    Phần set Main Stack Pointer, có thể thêm một số lệnh Barrier Instruction để đảm bảo nó thực hiện thành công.

    Chú ý: Trước khi nhảy đến Application, tùy vào yêu cầu của bài toán, bạn cần kiểm tra xem Application Firmware đã đầy đủ điều kiện để chạy chưa? Một số phương án phổ biến thường dùng như kiểm tra checksum, CRC, ...

Kết luận

    Trên đây là nhưng gì cơ bản nhất về một chương trình Bootloader trong một Vi điều khiển STM32. Các bạn có thể thiết kế thêm cho nó xử lý một số công việc khác ở phần trên trước khi gọi hàm Bootloader(), chẳng hạn như việc chờ một điều kiện nút bấm, hoặc dữ liệu tới để chọn Firmware thích hợp, hoặc đọc mật khẩu từ Flash, ....

    Nếu muốn chuyển đổi từ Firmware này sang Firmware khác trong quá trình chạy, thì trong chương trình ứng dụng của chúng ta cần phải có một số điều kiện để chuyển đổi, chẳng hạn như một ngắt UART, nhận lệnh cập nhật Firmware chẳng hạn.

>>>>>> Follow ngay <<<<<<<

Để nhận được những bài học miễn phí mới nhất nhé 😊

Chúc các bạn học tập tốt 😊

Nguyễn Văn Nghĩa

Mình là một người thích học hỏi và chia sẻ các kiến thức về Nhúng IOT.

Đăng nhận xét

Mới hơn Cũ hơn