Tôi đang làm việc trên một dự án ARM7TDMI bằng GCC 4.3 và tôi đang nói với trình biên dịch để sử dụng các cuộc gọi dài trong một số trường hợp nhất định.long_calls giữa các phần RAM và ROM trên ARM kim loại trần với gcc
Quá trình xây dựng chạy arm-eabi-gcc
để tạo định vị các file đối tượng ELF cho mỗi tập tin nguồn .c (CFLAGS phù hợp nhất bao gồm -Os -ffunction-sections -fdata-sections -mthumb -mthumb-interwork
), sau đó liên kết tất cả chúng thành một thực thi ELF (hầu hết LDFLAGS liên quan bao gồm -Wl,--gc-sections -Wl,-static -Wl,-n -nostdlib
, và một kịch bản tùy chỉnh mối liên kết) . Sau đó, tập tin ELF được chuyển đổi thành một tập tin thực thi thô với arm-eabi-objcopy -O binary
, và một bộ tải khởi động tùy chỉnh sao chép nó từ ROM sang RAM (một SRAM duy nhất với cả mã và dữ liệu) khi khởi động. Vì vậy, tất cả mọi thứ sau đó thực hiện từ RAM, .rodata
là hiện diện trong RAM, và mọi thứ tiến hành nhanh chóng, hoàn toàn bỏ qua ROM sau khi khởi động.
Tôi đang cố gắng thay đổi điều đó, sao cho một số phần dữ liệu RO nhất định và văn bản của các hàm chọn có thể chỉ hoạt động trong ROM và được truy cập trong thời gian chạy khi cần thiết. Tôi đã sửa đổi kịch bản trình liên kết để biết về hai phần mới ".flashdata"
và ".flashtext"
, cả hai phần này phải được đặt ở một địa chỉ cố định trong ROM. Tôi cũng đã rải __attribute__((__section__(".flashdata")))
và __attribute__((__section__(".flashtext"),__long_call__))
trên toàn bộ mã C khi thích hợp và tôi đã tái hoạt hóa quy trình xây dựng để hiện tượng objcopy cũ thêm -R .flashdata -R .flashtext
và tôi thực hiện một objcopy thứ hai với -j
cho từng phần đó, sau đó tôi kết hợp hai tệp đầu ra sao cho bộ nạp khởi động có thể làm điều đúng và các phần ROM xuất hiện ở vị trí được ánh xạ bộ nhớ mong muốn.
này tất cả hoạt động tốt - Tôi có thể printf dây gắn thẻ vào phần .flashdata
, và tôi có thể gọi một hàm .flashtext
từ mã chạy trên RAM (mà biết sử dụng một cuộc gọi dài do đặc tính __long_call__
bên cạnh thuộc tính __section__(".flashtext")
). Chức năng dựa trên ROM đó có thể gọi ngắn gọn các chức năng dựa trên ROM khác, và nó có thể quay trở lại với trình gọi dựa trên RAM của nó.
Sự cố xảy ra khi cố gắng gọi từ một chức năng dựa trên ROM thành một bộ nhớ dựa trên RAM, đó cũng phải là một cuộc gọi dài. Tôi không muốn sử dụng các cuộc gọi dài ở khắp mọi nơi, vì vậy tôi không muốn -mlong_calls trong CFLAGS của tôi. Nếu tôi nhóm tất cả các chức năng để sống trong ROM thành một đơn rom.c
, tôi có thể tạo một tệp với -mlong-calls
và mọi thứ hoạt động. Tuy nhiên, tôi mạnh mẽ muốn tránh điều đó, và giữ cho các chức năng được nhóm lại theo mục đích, chỉ cần gắn thẻ một vài ở đây và ở đó khi thích hợp để chạy từ ROM.
Ngẫu nhiên, điều này không đủ theo gcc 3.4. Sử dụng -mlong-calls
có trình biên dịch suy nghĩ đúng, nhưng nó không thể đi qua vì nó chỉ sẵn sàng thực hiện các bước nhảy dài với những người trợ giúp _call_via_rX
... tất cả đều sống trong RAM và chỉ có thể truy cập thông qua một cuộc gọi dài. This was fixed in the linker in gcc 4.0, but not backported to anything in the 3.x tree.
Vì vậy, thật tuyệt vời mà bây giờ tôi có thể gọi lại vào RAM vì tôi đang sử dụng gcc 4.3. Sẽ tốt hơn nếu tôi bằng cách nào đó có thể gắn thẻ mã trong các hàm dựa trên ROM để buộc nó sử dụng các cuộc gọi dài. Có một #pragma long_calls
, nhưng nó chỉ ảnh hưởng đến các khai báo, vì vậy tôi có thể sử dụng nó thay vì __attribute__((__long_call__))
. Thật đáng buồn là không có sức ép buộc trình biên dịch sử dụng các cuộc gọi dài cho tất cả các cuộc gọi chức năng gặp phải trong khi nó có hiệu lực.
Về mặt tổ chức, đơn giản là không phải là điều đúng đắn để nhóm tất cả mã chạy chậm thành một tệp, ngoài ngữ cảnh và tách biệt với mã khác trong danh mục chung của nó. Vui lòng cho tôi biết có một tùy chọn mà tôi chưa xem xét. Tại sao không phải là phần chức năng hoặc chỉ thực tế là mã ở các phần khác nhau (.text
so với .flashtext
) tự động khắc phục sự cố của tôi?
Nhân tiện, lỗi ra khỏi trình liên kết khi nó chỉ ra rằng trình biên dịch đã sử dụng một cuộc gọi ngắn mà không để lại đủ không gian để quản lý việc di chuyển là: relocation truncated to fit: R_ARM_THM_CALL against symbol
foo 'được xác định trong phần .text.foo objs/foo.o (and the section
.text.foo is used instead of
.tiếp theo because of
-chức năng-phần` trong CFLAGS).