Sử dụng Linker Script trong khai báo, cấu hình sử dụng bộ nhớ ngoài -VĐK STM32

Linker là một chương trình (giống như compiler, assembler,…) có tác dụng liên kết các file object (file *.o) và static library (*.a) thành một file binary duy nhất và có thể thực thi được. Linker Script là một file chứa các mã giúp cho Linker biết được vùng nào của các file đầu vào (object file, library file) phải được liên kết như thế nào để tạo file binary thực thi. Ví dụ,khi khai báo một vùng nhớ trong linker Script đại diện cho một vùng nhớ trên bộ nhớ; Tại mã chương trình ứng dụng, nếu một biến được khai báo với thuộc tính vùng đó thì Linker sẽ biết được cần phải sắp xếp biến vào vùng nhớ nào trong file đầu ra (.bin/.elf).
Bài viết này sẽ giúp các bạn hiểu về các mã trong linker script và có thể khai báo một vùng nhớ trong linker script.
Nội dung nên tham khảo trước khi đọc bài viết này: IC nhớ FLASH,SDRAM và mô hình bộ nhớ của vi điều khiển khi sử dụng bộ nhớ ngoài

1. Phân tích đoạn mã của Linker Script:

Dưới đây là ví dụ về cấu trúc một đoạn linker script của STM32:

 

Mã linker  Giải thích
ENTRY(Reset_Handler) Khai báo địa chỉ bắt đầu chương trình
_estack = ORIGIN(RAM) + LENGTH(RAM); Tính toán địa chỉ của stack (=địa chỉ cao nhất trong RAM)
_Min_Heap_Size = 0x800 ;
_Min_Stack_Size = 0x800 ;
Minimum stack/heap: Thường dùng để linker check lỗi, kiểm tra đảm bảo sau khi trừ hết các khoảng không gian cho .bss và .data thì vẫn còn chừng đó không gian cho stack và heap. – Có thể set về 0 và chương trình vẫn chạy bthg miễn RAM còn không gian trống.
MEMORY
{}
Khai báo các vùng không gian nhớ: RAM, FLASH, SDRAM,…
SECTIONS
{
Cấu hình các vùng dữ liệu vào các vùng nhớ tương ứng
  .isr_vector :
  {} >FLASH
Bảng các vector ngắt => Flash
  .text :
  {} >FLASH
Mã chương trình => Flash
  .rodata :
  {} >FLASH
 Chứa các hằng (constant) => Flash
  .ARM.extab : 
  {} >FLASH

  .ARM : 
  {} >FLASH

  .preinit_array :
  {} >FLASH

  .init_array :
  {} >FLASH

  .fini_array :
  {} >FLASH

 Chưa cần quan tâm
_sidata = LOADADDR(.data);  symbol _sidata được kí hiệu cho địa chỉ bắt đầu của vùng data
  .data :
  {} >RAM AT> FLASH

. = ALIGN(4);

Vùng chứa các biến được khởi tạo trong FLASH sẽ được load vào RAM khi chạy
  .bss :
  {} >RAM
Vùng chứa các biến khởi tạo bằng 0 => RAM
  ._user_heap_stack :
  {} >RAM
Kiểm tra không gian trống cho heap stack dựa vào các chỉ số _Min_Heap_Size/_Min_Stack_Size
  .ext1flash_section :
  {} > EXT1FLASH
Vùng nhớ flash ngoài => EXTI1FLASH
  .sdram_section 0xC0000000:
  {} >SDRAM
Vùng nhớ RAM ngoài => SDRAM

2.Khai báo một vùng nhớ trong linker script

Để khai báo một vùng nhớ trong linker script, ta viết đoạn mã như sau:

  • Trong vùng MEMORY
    • SDRAM: tên đại diện cho bộ nhớ cần khai báo ví dụ như SDRAM đại diện cho bộ nhớ RAM ngoài trong trường hợp này.
    • rw: Thể hiện các quyền hạn của vùng nhớ; r là đọc (read), w là ghi (write), x (execution) có nghĩa là có thể thực thi lệnh từ bộ nhớ. Ví dụ: xrw nghĩa là có thể đọc ghi và thực thi lệnh từ bộ nhớ đó ví dụ như SRAM nội.
    • ORIGIN: địa chỉ base của bộ nhớ. Ví dụ như RAM nội là 0x20000000, bộ nhớ Flash nội là 0x08000000, bộ nhớ SDRAM là 0xC0000000
    • LENGTH: không gian của bộ nhớ mà người dùng có thể sử dụng ví dụ 8M (bytes) như trường hợp trên.

 

  • Trong vùng “.sdram_section 0xC0000000”:
    • .sdram_section: Tên vùng nhớ khai báo. Người dùng có thể đặt bất kỳ tên nào họ muốn ví dụ như “.Daylavungnhomoi”.
    • 0xC0000000: Khai báo địa chỉ bắt đầu của vùng nhớ. Con số này có thể được thay đổi thành bất kì địa chỉ nào miễn sao giới hạn trong khoảng thấp nhất là 0xC0000000 và cao nhất 0xC07fffff đối với vùng nhớ SDRAM 8MB trên board STM32F7 DISCO
    • . = ALIGN(4): Khai báo về việc căn chỉnh sắp xếp bộ nhớ mà cụ thể ở đây là 4 byte; Việc hiệu chỉnh con số trong align sẽ ảnh hưởng đến tốc độ và dung lượng lưu trữ của vùng nhớ
    • *(.buffer): Tên các vùng nhớ dùng trong khai báo biến.
    • >SDRAM: Vùng nhớ này được đưa vào bộ nhớ SDRAM khai báo ở trên

Theo dõi phần tiếp theo: Cấu hình ngoại vi giao tiếp FMC để sử dụng SRAM ngoài với vi điều khiển STM32. 

Nhóm tác giả
Ng.Q.Phương, Ng.H.N.Thương, Ng.H.Phúc