2015-02-11 15 views
8

Bạn có ý tưởng cách khởi tạo mảng cấu trúc bắt đầu từ địa chỉ cụ thể trong bộ nhớ (không phải bộ nhớ DDR ảo). Tôi đang làm việc để thực hiện TxRx trên SoC (ARM-FPGA). Về cơ bản ARM (PS) và FPGA (PL) giao tiếp với nhau bằng cách sử dụng bộ nhớ RAM chia sẻ. Hiện tại tôi đang làm việc trên phía máy phát, vì vậy tôi cần phải liên tục tải các gói mà tôi nhận được từ lớp MAC vào bộ nhớ, sau đó Tx của tôi đọc dữ liệu và gửi nó trong không khí. Để đạt được điều này, tôi muốn thực hiện bộ đệm FIFO tròn trên (ARM), theo cách mà tôi có thể lưu trữ tối đa 6 gói vào bộ đệm và gửi từng gói một, trong cùng thời gian tải các gói khác trên các vị trí đã gửi gói. Bởi vì tôi cần phải sử dụng các địa chỉ bộ nhớ cụ thể mà tôi quan tâm là có thể khởi tạo mảng cấu trúc sẽ được lưu trữ trên các địa chỉ cụ thể trong bộ nhớ. Ví dụ tôi muốn mảng của tôi bắt đầu tại địa chỉ 0x400000 và kết thúc tại địa chỉ 0x400000 + MaximumNumberOfPackets x SizeOfPackets Tôi biết cách thực hiện nó cho một cấu trúc tức thời như sau: buffer_t * tmp = (struct buffer_t *) 234881024;Khởi tạo mảng bắt đầu từ địa chỉ cụ thể trong bộ nhớ - Lập trình C

Nhưng làm thế nào để làm điều đó cho mảng cấu trúc?

+0

biên dịch & OS của bạn (nếu có) là gì? –

+0

Xin chào, đó là trình biên dịch ARM gcc – elem

+0

Có thể trợ giúp: http://stackoverflow.com/questions/4067811/how-to-place-a-variable-at-a-given-absolute-address-in-memory-with- gcc –

Trả lời

5

Một con trỏ tới một cấu trúc đơn lẻ (hoặc int, float hoặc bất kỳ thứ gì khác) vốn là một con trỏ trỏ tới một mảng của chúng. Kiểu con trỏ cung cấp giá trị sizeof() cho một mục nhập mảng, và do đó cho phép số học con trỏ hoạt động.

Như vậy, cho một struct buffer bạn chỉ có thể làm

static struct buffer * const myFIFO = (struct buffer *) 0x40000 

và sau đó chỉ cần truy cập vào myFIFO như một mảng

for (size_t i = 0; i < maxPackets; ++i) 
{ 
    buffer[i].someField = initialValue1; 
    buffer[i].someOtherField = 42; 
} 

này hoạt động giống theo cách bạn mong đợi.

gì bạn không có thể làm (sử dụng tiêu chuẩn tinh khiết C) là khai báo một mảng tại một địa chỉ cụ thể như thế này:

struct buffer myFIFO[23] @ 0x400000; 

Tuy nhiên, trình biên dịch của bạn thể có phần mở rộng để cho phép nó. Nhiều trình biên dịch nhúng (sau khi tất cả, thường là cách chúng khai báo các thanh ghi thiết bị ánh xạ bộ nhớ), nhưng nó sẽ khác nhau đối với mọi nhà cung cấp trình biên dịch, và có thể cho mọi chip bởi vì nó là phần mở rộng của nhà cung cấp.

GCC không cho phép nó để xử lý AVR qua một thuộc tính, ví dụ

volatile int porta __attribute__((address (0x600))); 

Nhưng nó dường như không hỗ trợ nó cho một ARM.

+0

kdopen cảm ơn bạn đã trả lời tôi sẽ làm như vậy. Khởi tạo buffer_pool lúc bắt đầu và sau đó điền thông qua vòng lặp. – elem

2

chung @kdopen là đúng nhưng đối với cánh tay bạn nên tạo một mục trong NHỚ phần kịch bản mối liên kết đó cho thấy để Linker đâu là bộ nhớ của bạn:

MEMORY 
{ 
    ... 
    ExternalDDR (w) : ORIGIN = 0x400000, LENGTH = 4M 
} 

Và hơn, khi bạn đang khai báo biến chỉ cần sử dụng

__attribute__((section("ExternalDDR"))) 
+0

Gaskoin Tôi không có kinh nghiệm với các kịch bản liên kết, nhưng tôi sẽ cố gắng làm điều đó có vẻ thú vị. Tôi sẽ biết cách viết kịch bản liên kết. – elem

+0

Tôi không biết làm thế nào để bạn xây dựng mã của bạn vì vậy tôi không thể cung cấp cho bạn bất kỳ chi tiết. Nếu bạn có IDE chuyên dụng cho ARM của bạn có thể bạn có thể tìm thấy một cái gì đó trong cấu hình. Nếu bạn đang sử dụng gcc bạn nên có một nơi nào đó một tập tin với phần mở rộng ld -> đó là những gì bạn cần :) – Gaskoin

+0

Thưa tôi đang sử dụng Xilinx SDK, nó được dựa trên nhật thực. Tôi đã tìm ra cách để làm điều đó. Vì vậy, tôi có thể làm điều đó như thế này. Tôi thiết lập này vào kịch bản mối liên kết: NHỚ { ps7_ddr_0_S_AXI_BASEADDR: XỨ = 0x00100000, LENGTH = 0x1FF00000 ps7_ram_0_S_AXI_BASEADDR: XỨ = 0x00000000, LENGTH = 0x00030000 ps7_ram_1_S_AXI_BASEADDR: XỨ = 0xFFFF0000, LENGTH = 0x0000FE00 DAC_DMA (w): XỨ = 0xE000000, LENGTH = 64K } Và sau đó tôi đặt mã này thành mã tĩnh buffer_t __attribute __ ((phần ("DAC_DMA"))) buf_pool [6]; – elem

0

Tôi đã tìm được cách thực hiện. Vì vậy, tôi có thể làm điều đó như thế này.Tôi thiết lập này vào kịch bản mối liên kết:

MEMORY { 
     ps7_ddr_0_S_AXI_BASEADDR : ORIGIN = 0x00100000, LENGTH = 0x1FF00000   
     ps7_ram_0_S_AXI_BASEADDR : ORIGIN = 0x00000000, LENGTH = 0x00030000 
     ps7_ram_1_S_AXI_BASEADDR : ORIGIN = 0xFFFF0000, LENGTH = 0x0000FE00 
     DAC_DMA (w) : ORIGIN = 0xE000000, LENGTH = 64K 
     } 

.dacdma : { 
    __dacdma_start = .; 
    *(.data) 
    __dacdma_end = .; 
} > DAC_DMA 

Và sau đó tôi thiết lập này vào mã

static buffer_t __attribute__((section("DAC_DMA"))) buf_pool[6]; 
Các vấn đề liên quan