Chuyển đến nội dung
AIOTAIOT
  • Trang chủ
  • Giới thiệu
  • Tin tức
  • Sản phẩm
  • Giải pháp
    • Chấm công bằng Face ID
    • Thiết bị đọc căn cước
    • IoT trong giáo dục
    • IoT trong quản lý năng lượng
    • IoT trong y tế
  • Đào tạo
    • Khóa đào tạo cơ bản
      • Hệ thống nhúng
      • LabVIEW FPGA
      • Phần cứng máy tính & Truyền thông công nghiệp
      • FPGA cơ bản
    • Khóa đào tạo nâng cao
      • LabVIEW FPGA High Performance
    • Tài liệu
  • PCCC
  • Liên hệ
  • icon
    097 186 8316    |    0839 799 889
Đào tạo, Hệ thống nhúng, Khóa đào tạo cơ bản

[Embedded Series – Bài 27] Chuyên Sâu Bootloader: Cơ Chế Khởi Động, Quản Lý Vector Table Và Kỹ Thuật Jump Firmware

Đã đăng trên 19/05/202628/04/2026 bởi ThaoNguyen
19
Th5

Trong lộ trình phát triển sản phẩm nhúng chuyên nghiệp, việc chỉ biết viết code ứng dụng (Application) là chưa đủ. Để thiết bị có khả năng tự cập nhật từ xa (FOTA), khôi phục cài đặt gốc (Factory Reset) hay bảo mật Firmware, chúng ta cần một chương trình đóng vai trò “người gác cổng” – đó chính là Bootloader. Bài viết này sẽ đi sâu vào cấu trúc phần cứng của nhân Cortex-M4 để giải mã cách Bootloader điều khiển quy trình khởi động của hệ thống.

🎯 Mục tiêu bài học chuyên sâu

  • Nắm vững khái niệm Bootloader và lộ trình thực thi Firmware (Current, FOTA, Factory).
  • Giải mã vai trò của thanh ghi SP (Stack Pointer) và PC (Program Counter) trong 4 byte đầu tiên của bộ nhớ.
  • Hiểu bản chất Vector Table và tại sao phải dời địa chỉ bảng Vector khi chạy Application.
  • Lập trình quy trình “De-initialization” để đưa MCU về trạng thái sạch trước khi nhảy.
  • Thực hành cấu hình Toolchain để nạp chồng nhiều chương trình vào Flash mà không bị xóa dữ liệu cũ.

1. Kiến trúc hệ thống: Bootloader vs Application

a) Bootloader là gì?

Bootloader là chương trình đầu tiên chạy khi Chip được cấp nguồn hoặc Reset. Nhiệm vụ của nó là kiểm tra các điều kiện phần cứng (ví dụ: nút bấm được giữ) hoặc phần mềm (ví dụ: cờ báo cập nhật trong Flash) để quyết định nhảy vào một trong các vùng nhớ:

  • Current Firmware: Bản ứng dụng hiện tại đang hoạt động.
  • FOTA Firmware: Bản cập nhật mới vừa được tải về vùng nhớ tạm.
  • Factory Firmware: Bản Firmware gốc an toàn do nhà sản xuất nạp sẵn.

b) Phân vùng bộ nhớ Flash

Bootloader và Application là hai dự án (Project) hoàn toàn riêng biệt, được biên dịch ra hai file nhị phân khác nhau và lưu trữ tại các vùng địa chỉ khác nhau trên Flash:

  • Bootloader: Bắt đầu tại 0x0800 0000 (Địa chỉ mặc định sau Reset).
  • Application: Bắt đầu tại một địa chỉ do người dùng chỉ định, ví dụ: 0x0800 4000 (Sector 1).

2. Cơ chế khởi động của nhân ARM Cortex-M

Khi CPU thoát khỏi trạng thái Reset, nó thực hiện các bước sau một cách tự động tại địa chỉ 0x0800 0000:

  1. Nạp MSP: Đọc 4 byte đầu tiên để lấy giá trị khởi tạo cho Main Stack Pointer.
  2. Nạp PC: Đọc 4 byte tiếp theo (địa chỉ +4) để lấy địa chỉ của Reset Handler.
  3. Thực thi: Nhảy đến địa chỉ Reset Handler để bắt đầu chạy code.

Lưu ý: Mọi chương trình Application nằm ở các vùng nhớ khác (như 0x0800 4000) cũng phải tuân thủ đúng cấu trúc này ở 8 byte đầu tiên của nó.

3. Vector Table Relocation – “Dời đô” cho bảng ngắt

Bảng Vector chứa địa chỉ các hàm xử lý ngắt (Interrupt Handlers). Nếu bạn nhảy sang App ở địa chỉ 0x0800 4000 mà không dời bảng Vector, khi có ngắt xảy ra (ví dụ ngắt Timer), CPU vẫn sẽ tìm địa chỉ hàm xử lý ở vùng của Bootloader (địa chỉ 0x0800 0000), dẫn đến hệ thống bị treo hoặc thực thi sai.

Cách xử lý: Trong chương trình Application, chúng ta phải định nghĩa lại VECT_TAB_OFFSET trong file system_stm32f4xx.c:

/* Trong file system_stm32f4xx.c của dự án Application */
#define USER_VECT_TAB_ADDRESS 
#define VECT_TAB_OFFSET  0x00004000U // Khớp với địa chỉ nạp App

4. Lập trình Bootloader: Quy trình “Jump” an toàn

Để chương trình Application chạy ổn định sau khi nhảy từ Bootloader, chúng ta cần đưa vi điều khiển về trạng thái “như mới” bằng cách vô hiệu hóa các ngoại vi đã dùng ở Bootloader.

Bước 1: Vô hiệu hóa ngoại vi (De-init)

/* 1. Tắt Clock của các ngoại vi và Reset cấu hình RCC */
HAL_RCC_DeInit();

/* 2. Vô hiệu hóa Systick và các ngắt hệ thống */
HAL_DeInit();

/* 3. Tắt các Fault Handler để tránh lỗi nhảy bất ngờ */
SCB->SHCSR &= ~(SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk);

Bước 2: Thiết lập con trỏ và Nhảy (Jump)

Chúng ta cần trích xuất giá trị SP và địa chỉ Reset Handler từ vùng nhớ của Application.

#define APP_START_ADDRESS  0x08004000

void jump_to_app(void) {
    // Lấy giá trị Stack Pointer từ 4 byte đầu của App
    uint32_t msp_val = *(volatile uint32_t*)APP_START_ADDRESS;
    
    // Lấy địa chỉ Reset Handler từ 4 byte tiếp theo
    uint32_t jump_addr = *(volatile uint32_t*)(APP_START_ADDRESS + 4);
    
    // Định nghĩa con trỏ hàm trỏ tới địa chỉ Reset Handler
    void (*app_reset_handler)(void) = (void*)jump_addr;

    // Thiết lập MSP cho Application
    __set_MSP(msp_val);

    // Nhảy sang App
    app_reset_handler();
}

5. Cấu hình Toolchain: Nạp chồng Firmware

Mặc định khi nhấn “Download” trong Keil MDK, nó sẽ xóa toàn bộ Chip (Full Chip Erase). Điều này sẽ xóa mất chương trình Bootloader khi bạn nạp App. Bạn cần cấu hình lại:

  1. Vào Options for Target -> Debug -> Settings.
  2. Chọn tab Flash Download.
  3. Trong mục “Erase”, chọn “Erase Sectors” (chỉ xóa những vùng cần nạp) thay vì “Full Chip Erase”.

🚀 Bài tập thực hành

  1. Điều kiện Jump: Viết Bootloader sao cho: Nếu chân PA0 nối xuống GND khi khởi động thì nhảy vào App_1, nếu nối lên 3.3V thì nhảy vào App_2.
  2. Kiểm tra Flash: Trước khi thực hiện lệnh app_reset_handler(), hãy kiểm tra xem 4 byte đầu tiên của địa chỉ App có phải là một địa chỉ RAM hợp lệ không (thường bắt đầu bằng 0x2000...). Nếu không đúng, không thực hiện Jump để tránh HardFault.
📝 Tóm tắt: Bootloader là chương trình “nền tảng” giúp quản lý vòng đời của thiết bị. Hiểu rõ cơ chế nạp MSP, PC và cách dời bảng Vector ngắt (VTOR) là chìa khóa để triển khai thành công các hệ thống nhúng có khả năng cập nhật linh hoạt và bền bỉ.

“Lập trình viên viết ứng dụng, nhưng Kỹ sư hệ thống làm chủ quy trình vận hành của ứng dụng đó.”

Gợi ý bài tiếp theo: Tổng Ôn Kiến Thức Hệ Thống Nhúng & STM32 (Phần 1).

 

Mục nhập này đã được đăng trong Đào tạo, Hệ thống nhúng, Khóa đào tạo cơ bản và được gắn thẻ Embedded Systems.
ThaoNguyen

[Embedded Series – Bài 26] Làm Chủ Giao Tiếp Bộ Nhớ Flash Trên Vi Điều Khiển STM32F407

Để lại một bình luận Hủy

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Bài viết mới
  • [Embedded Series – Bài 27] Chuyên Sâu Bootloader: Cơ Chế Khởi Động, Quản Lý Vector Table Và Kỹ Thuật Jump Firmware
  • [Embedded Series – Bài 26] Làm Chủ Giao Tiếp Bộ Nhớ Flash Trên Vi Điều Khiển STM32F407
  • [Embedded Series – Bài 25] Lập Trình FreeRTOS Trên STM32: Từ Ngắt, Queue Đến Quản Lý Tài Nguyên
  • [Embedded Series – Bài 24] Hệ Điều Hành Thời Gian Thực (RTOS): Giải Pháp Đa Tác Vụ Chuyên Nghiệp
  • [Embedded Series – Bài 23] Thực Hành Lập Trình SPI Với DAC MCP4922 Và I2C Với EEPROM AT24C32
Danh mục
  • Đào tạo
  • FPGA cơ bản
  • Giải pháp
  • Hệ thống nhúng
  • IoT trong giáo dục
  • IoT trong y tế
  • Khóa đào tạo cơ bản
  • Khóa đào tạo nâng cao
  • LabVIEW FPGA
  • LabVIEW FPGA High Performance
  • Phần cứng máy tính & Truyền thông công nghiệp
  • Sản xuất công nghiệp
  • Thiết bị dịch vụ thông minh
  • Thiết bị đọc căn cước
  • Tin tức

CÔNG TY CỔ PHẦN HỆ THỐNG AIOT

VPGD: Số A21-TT9 Đường Foresa 1 KĐT Xuân Phương, Phường Xuân Phương, Hà Nội.

Địa chỉ kinh doanh: Đường Phú Diễn, Tổ dân phố 18, phường Phú Diễn, Thành phố Hà Nội, Việt Nam

Hotline/Zalo: 097 186 8316 | 0839 799 889

Email: aiot@aiots.vn

VỀ CHÚNG TÔI

Giới thiệu

Sản phẩm

Giải pháp

Đào tạo

Tin tức

QUY ĐỊNH & CHÍNH SÁCH

Chính sách thanh toán

Chính sách vận chuyển

Chính sách bảo hành

Chính sách đổi trả

Chính sách bảo mật

ĐỊA CHỈ VĂN PHÒNG GIAO DỊCH

Copyright 2024 © Bản quyền thuộc về AIOT. Thiết kế bởi Jamina JSC
  • Trang chủ
  • Giới thiệu
  • Tin tức
  • Sản phẩm
  • Giải pháp
    • Chấm công bằng Face ID
    • Thiết bị đọc căn cước
    • IoT trong giáo dục
    • IoT trong quản lý năng lượng
    • IoT trong y tế
  • Đào tạo
    • Khóa đào tạo cơ bản
      • Hệ thống nhúng
      • LabVIEW FPGA
      • Phần cứng máy tính & Truyền thông công nghiệp
      • FPGA cơ bản
    • Khóa đào tạo nâng cao
      • LabVIEW FPGA High Performance
    • Tài liệu
  • PCCC
  • Liên hệ
Zalo
Phone

Đăng nhập

Quên mật khẩu?