Title Image

Blog Logo

Bootloader 7. Chương trình Bootloader

🌱 Bootloader 7. Chương trình Bootloader

    Phần quan trọng nhất của topic này, chúng ta đang thắc mắc chương trình Bootloader làm gì và code như thế nào? Trong topic này mình sẽ giới thiệu về phần này!

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

    Chương trình Boot ở đây thực chất là một hàm/chương trình được lưu trong bộ nhớ. Khi Vi điều khiển Reset, nó sẽ nhảy vào chương trình Boot này (nằm ở Sector 0), thực hiện một số công việc nhanh chóng và lựa chọn việc nhảy vào Firmware Ứng dụng nào trong bộ nhớ để bắt đầu thực hiện.

    Ở đây mình có câu hỏi: "Khi Boot xong, giả sử chuyển từ Firmware 1 sang Firmware 2 chẳng hạn, thì khi mình reset Vi điều khiển, nó sẽ bắt đầu lại với chương trình nào? Bắt đầu với Firmware 1, Firmware 2, hay là chương trình Boot???"

    Hãy trả lời điều đó bằng những gì mình mong muốn. Mình muốn chuyển từ Firmware 1 update lên Firmware 2, vậy điều mình muốn là sau khi reset, nó vẫn sẽ phải chạy Firmware 2! Vậy làm như thế nào?

    👉 Có thể thấy việc chương trình sau khi Reset sẽ nhảy vào Reset_Handler(), mà Reset_Handler() nằm trên Vector Table

  • Khi chúng ta nạp code, chẳng hạn Firmware 2 nạp vào địa chỉ 0x0800.8000 thì MSP của Firmware 2 sẽ ở địa chỉ này 0x0800.8000, còn Vector Table sẽ nằm ở địa chỉ tiếp theo 0x0800.8004. 
  • Vi xử lý xác định Bảng Vector Table bằng thanh ghi SCB_VTOR (Xem tài liệu Core).  

    Vậy khá đơn giản rồi, chúng ta chỉ việc gán giá trị tương ứng vào thanh ghi SCB_VTOR với địa chỉ base của Firmware là xong.

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

    👉 Vậy mình để xuất một phương án cho chương trình Boot như sau (mình nói một phương án vì có rất nhiều cách khác nhau mà mọi người thường làm để đạt được mục đích này, ở đây là một cách đơn giản nhất):

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 Reset mềm (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. 

    👉 Cụ thể về hàm Bootloader()

    Như trên đã nói hàm Bootloader() sẽ thay đổi thanh ghi SCB_VTOR và nhảy đến Firmware mới, ở đây, cụ thể nó sẽ làm những công việc sau:

Boot

    Cụ thể về quy trình và Code hàm Bootloader() mình để ở trên hình luôn:

  • 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.

    👉 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 😊

                                        

Đăng nhận xét

0 Nhận xét