Cách lưu trữ các biến trong bộ nhớ FLASH


7

Tôi đang làm việc với một bảng liệt kê STM32 từ STMicro, bao gồm bộ xử lý ARM Cortex-M4. Tôi cần một LUT cho cosinus và xoang (các biến chỉ đọc). Tôi cần quản lý bộ nhớ RAM do đó tôi muốn lưu trữ LUT này trong bộ nhớ flash.

Đầu tiên: tốt hơn là tạo ra một tính toán nội suy của cosinus / xoang hoặc việc đọc FLASH là đủ nhanh?

Thứ hai, làm thế nào để đặt các biến trong bộ nhớ FLASH. ST cung cấp một số ví dụ, nhưng có lẽ, đối với vấn đề của tôi, tôi chỉ cần khai báo các biến LUT là const tĩnh và nó sẽ giống như mã?

Câu trả lời:


12

Câu trả lời ngắn gọn là khai báo biến của bạn bằng consttừ khóa. Nếu MCU của bạn thực sự ghi nhớ giá trị của constbiế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ỉ 0x08000000và 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ả .textcác phần (đó là cách trình biên dịch gọi phần mã) và .rodatacác phần (đó là cách trình biên dịch gọi constcác biến) sẽ được đặt trong phần flash.

Như đã đề xuất ở trên, .maptệ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.


4

Không, bạn không thể đặt các biến trong bộ nhớ chỉ đọc. Tuy nhiên, bạn có thể đặt các hằng số ở đó, đó là tất cả những gì bạn cần vì bạn đang hỏi về bảng tra cứu sin / cos. Những giá trị đó được cố định bằng toán học và không cần phải thay đổi nhanh chóng.

Chắc chắn tài liệu ngôn ngữ mô tả cách buộc một mảng các hằng số vào bộ nhớ chương trình. Điều này thường được thực hiện với một số từ khóa hoặc bằng cách chỉ định các thuộc tính cho phần liên kết hoặc có thể bằng thông tin bổ sung được truyền riêng cho liên kết.

Về cách thực hiện tra cứu sin và cos, hãy xem các câu trả lời trước:

https://electronics.stackexchange.com/a/60819/4512
https://electronics.stackexchange.com/a/16516/4512


Sử dụng từ khóa const với ngôn ngữ C dường như đưa dữ liệu vào bộ nhớ flash / chương trình. Làm cách nào để kiểm tra, với IDE (Tôi sử dụng CooCox với trình biên dịch gcc ARM GNU), nếu các biến này thực sự được ánh xạ vào bộ nhớ FLASH? Thks.
dùng2412542

@user: Có thể, mặc dù trên lý thuyết chỉ nói với trình biên dịch rằng bạn không có ý định sửa đổi giá trị. Không có cách nào để biết chắc chắn cho bất kỳ bộ công cụ trình biên dịch / liên kết nào. Bạn vẫn cần phải đọc thông tin, tất nhiên bạn nên làm theo. Hãy nhớ rằng OP không bao giờ nói anh ấy đang sử dụng ngôn ngữ nào.
Olin Lathrop

@ user2412542 Bạn có thể thêm tùy chọn vào lệnh gcc và để nó tạo tệp bản đồ bộ nhớ hoặc bạn có thể sử dụng lệnh objdump để xem những thứ khác nhau sẽ được đặt trong bộ nhớ.
Joe Hass

Trên nhiều trình biên dịch, các biến có constbộ sửa đổi sẽ được phân bổ trong phần liên kết riêng với các trình biên dịch không có; thông thường sẽ có một tùy chọn để buộc một số phần liên kết vào không gian mã và trong nhiều trường hợp, các phần lưu trữ constcác biến sẽ tự động được đặt ở đó. Tôi tin rằng các trình biên dịch ARM thường có hành vi mặc định như vậy, vì vậy một lệnh constsẽ đủ cho những gì bạn cần.
supercat

Bạn có thể sử dụng bộ nhớ FLASH để lưu trữ các biến. Không phải ra khỏi hộp mặc dù, có một số mã liên quan. Dưới đây là ví dụ điển hình, MCU khác nhau nhưng cùng họ Cortex. os.mbed.com/users/olympux/code/eeprom_flash
Barmaley

4

để có dữ liệu đưa vào flash khai báo nó là const

const unsign int lut [] = {0x1234, 0xab, 0xcd, 0xefa1123, 0x1122334, ...

tập lệnh liên kết của bạn có thể cần phải có một mục, tùy thuộc vào hương vị và tuổi của chuỗi công cụ của bạn, nó có thể đi vào .text hoặc .rodata hoặc khác tùy thuộc vào chuỗi công cụ của bạn. và sau đó bạn sẽ đặt phần đó trong flash.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.