Đối với các ứng dụng nhúng, nó thường là cần thiết để truy cập các vị trí bộ nhớ cố định cho các thanh ghi ngoại vi. Cách chuẩn mà tôi đã tìm thấy để làm điều này là một cái gì đó như sau:Biến địa chỉ cố định trong C
// access register 'foo_reg', which is located at address 0x100
#define foo_reg *(int *)0x100
foo_reg = 1; // write to foo_reg
int x = foo_reg; // read from foo_reg
tôi hiểu làm thế nào mà làm việc, nhưng những gì tôi không hiểu là như thế nào không gian cho foo_reg được phân bổ (tức là những gì giữ cho mối liên kết từ đặt một biến khác ở 0x100?). Không gian có thể được đặt trước ở cấp độ C hay không phải có tùy chọn trình liên kết chỉ định rằng không có gì được đặt ở 0x100. Tôi đang sử dụng các công cụ GNU (gcc, ld, v.v.), do đó, tôi chủ yếu quan tâm đến các chi tiết cụ thể của bộ công cụ đó vào lúc này.
Một số thông tin thêm về kiến trúc của tôi để làm rõ câu hỏi:
giao diện của tôi xử lý để một FPGA thông qua một tập các thanh ghi ánh xạ vào không gian dữ liệu thường xuyên (nơi biến sống) của bộ xử lý. Vì vậy, tôi cần phải trỏ đến những thanh ghi và chặn không gian địa chỉ liên quan. Trong quá khứ, tôi đã sử dụng một trình biên dịch có phần mở rộng để định vị các biến từ mã C. Tôi sẽ nhóm các thanh ghi vào một cấu trúc, sau đó đặt cấu trúc tại vị trí thích hợp:
typedef struct
{
BYTE reg1;
BYTE reg2;
...
} Registers;
Registers regs _at_ 0x100;
regs.reg1 = 0;
Thực tế việc tạo cấu trúc 'Đăng ký' bảo toàn không gian trong trình biên dịch/mắt của người liên kết.
Bây giờ, bằng cách sử dụng các công cụ GNU, tôi rõ ràng không có số ở số. Sử dụng phương pháp con trỏ:
#define reg1 *(BYTE*)0x100;
#define reg2 *(BYTE*)0x101;
reg1 = 0
// or
#define regs *(Registers*)0x100
regs->reg1 = 0;
Đây là ứng dụng đơn giản không có hệ điều hành và không có quản lý bộ nhớ nâng cao. Về cơ bản:
void main()
{
while(1){
do_stuff();
}
}
Trên thực tế, trình liên kết thực hiện, thông qua tập lệnh trình liên kết xác định vùng bộ nhớ có sẵn để sử dụng. Nó định nghĩa (ví dụ) các vùng .text và .bss cho dữ liệu không đổi và dữ liệu biến động (RAM), tương ứng. – strager
thực sự :) có nghĩa là để nói mà không làm bất cứ điều gì, không có cơ hội cho nó để biết về điều đó :) –
Liệu 'defsym' thực sự phân bổ bất cứ điều gì ở tất cả tại một địa chỉ nhất định? AFAIK về cơ bản nó là một trình liên kết tương đương '# define', bạn thậm chí không thể xác định kích thước của đối tượng với nó, và nó sẽ không ngăn chặn mối liên kết đặt một biến khác tại cùng một địa chỉ. –