Câu trả lời ngắn gọn là khai báo biến của bạn bằng const
từ khóa. Nếu MCU của bạn thực sự ghi nhớ giá trị của const
biến của bạn (tức là tính toán sin của bạn thực sự hoạt động), thì nó sẽ phải được lưu trữ trong bộ nhớ flash, nếu không nó sẽ bị mất trong lần khởi động lại đầu tiên sau khi lập trình.
Câu trả lời dài phải làm với tập lệnh liên kết. Các kịch bản này phụ thuộc vào MCU và cho người liên kết biết nơi để đặt cái gì. Thông thường, tập lệnh này được cung cấp bởi IDE, nhưng bạn có thể tự viết. Khi thiết lập STM32F4, tập lệnh liên kết của tôi bắt đầu bằng một câu lệnh như vậy:
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
Nó nói rằng đèn flash bắt đầu tại địa chỉ 0x08000000
và RAM tại địa chỉ 0x20000000
. Các địa chỉ này có thể được tìm thấy trong biểu dữ liệu nơi bản đồ bộ nhớ được mô tả. Phần còn lại của kịch bản có thể tham gia, nhưng đến một lúc nào đó, những dòng này sẽ xuất hiện:
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
Điều này nói rằng tất cả .text
các phần (đó là cách trình biên dịch gọi phần mã) và .rodata
các phần (đó là cách trình biên dịch gọi const
các biến) sẽ được đặt trong phần flash.
Như đã đề xuất ở trên, .map
tệp là cách chính mà bạn có thể kiểm tra xem trình liên kết đặt ở đâu. Bạn nói với trình liên kết để tạo nó bằng tùy chọn này:
arm-eabi-gcc -Wl,-Map=my_program.map ...
Bạn có thể tìm kiếm symbole của mình trong tệp bản đồ này, xem địa chỉ nào nó đã được lưu trữ và kiểm tra xem bản đồ bộ nhớ được chỉ định trong biểu dữ liệu MCU.