Thao tác với Flash trên STM32

Giới thiệu về Flash trên STM32

STM32 sử dụng mô-đun flash gồm: khối lưu trữ chính, khối thông tin và các thanh ghi giao tiếp bộ nhớ flash.

  • Khối lưu trữ chính: Lưu trữ mã và dữ liệu hằng số (dữ liệu kiểu const).
  • Khối thông tin: Chia thành hai phần:
    • Bộ nhớ hệ thống: Lưu trữ chương trình bootloader.
    • Chọn byte: Cấu hình bảo vệ đọc và viết.
  • Thanh ghi giao tiếp bộ nhớ flash: Điều khiển thao tác đọc/ghi của flash.

Lưu ý khi lập trình Flash

  • 1 từ = 32 bit, nửa từ = 16 bit, 1 byte = 8 bit.
  • 1 từ = 2 nửa từ = 4 byte.
  • Sau khi reset, FPEC module được khóa, cần gửi dãy key đến FLASH_KEYR để mở khóa trước khi viết vào FLASH_CR.
  • Mỗi lần lập trình phải viết 16 bit. Khi PG bit trong FLASH_CR là '1', việc viết một nửa từ sẽ khởi động quá trình lập trình.

Thực hiện xóa Flash

Xóa Flash có thể thực hiện theo từng trang hoặc toàn bộ:

  1. Kiểm tra LOCK trong FLASH_CR đã mở khóa hay chưa.
  2. Kiểm tra BSY bit trong FLASH_SR để đảm bảo không có thao tác đang diễn ra.
  3. Đặt PER bit trong FLASH_CR thành '1' để xóa trang.

Hàm xóa trang Flash

FLASH_Status eraseFlashPage(uint32_t pageAddr) {
  FLASH_Status status = FLASH_OK;
  if (!isValidAddress(pageAddr)) return FLASH_ERROR;
  // Đợi cho hoạt động cuối cùng hoàn tất
  status = waitForLastOperation(EraseTimeout);
  if (status == FLASH_OK) {
    enablePageErase();
    setFlashAddress(pageAddr);
    startEraseOperation();
    status = waitForLastOperation(EraseTimeout);
    disablePageErase();
  }
  return status;
}

Hàm xóa toàn bộ Flash

FLASH_Status eraseAllFlash() {
  FLASH_Status status = FLASH_OK;
  status = waitForLastOperation(EraseTimeout);
  if (status == FLASH_OK) {
    enableFullErase();
    startEraseOperation();
    status = waitForLastOperation(EraseTimeout);
    disableFullErase();
  }
  return status;
}

Thực hiện đọc dữ liệu từ Flash

uint16_t readHalfWord(uint32_t address) {
  return *(volatile uint16_t*)address;
}

Viết dữ liệu vào Flash

  1. Kiểm tra LOCK trong FLASH_CR đã mở khóa hay chưa.
  2. Kiểm tra BSY bit trong FLASH_SR để xác nhận không có thao tác lập trình đang diễn ra.
  3. Đặt PG bit trong FLASH_CR thành '1' và ghi nửa từ tại địa chỉ cụ thể.
  4. Đợi BSY bit trở về '0'.
  5. Đọc lại địa chỉ và kiểm tra dữ liệu.

Hàm viết nửa từ vào Flash

FLASH_Status writeHalfWord(uint32_t addr, uint16_t data) {
  FLASH_Status status = FLASH_OK;
  if (!isValidAddress(addr)) return FLASH_ERROR;
  status = waitForLastOperation(ProgramTimeout);
  if (status == FLASH_OK) {
    enableProgram();
    *(volatile uint16_t*)addr = data;
    status = waitForLastOperation(ProgramTimeout);
    disableProgram();
  }
  return status;
}

Trạng thái Flash

typedef enum {
  FLASH_BUSY,
  FLASH_ERROR_PG,
  FLASH_ERROR_WRP,
  FLASH_COMPLETE,
  FLASH_TIMEOUT
} FLASH_Status;

FLASH_Status getFlashStatus() {
  // Lấy trạng thái từ FLASH_SR
  return getStatusFromSR();
}

FLASH_Status waitForLastOperation(uint32_t timeout) {
  // Đợi thao tác cuối cùng hoàn tất
  return waitOperation(timeout);
}

Thanh ghi liên quan đến Flash

  • ACR: Kiểm soát truy cập bộ nhớ.
  • KEYR: Gửi khóa để mở khóa FPEC.
  • OPTKEYR: Thanh ghi khóa chọn byte.
  • SR: Trạng thái của Flash.
  • CR: Điều khiển các hoạt động trên Flash.
  • AR: Địa chỉ của Flash.
  • OBR: Chọn byte.
  • WRPR: Bảo vệ ghi.

Thẻ: STM32 Flash embedded systems Microcontroller Programming

Đăng vào ngày 15 tháng 6 lúc 01:02