2015-02-11 15 views
8

Bellekte belirli adreslerden başlayan (sanal, fiziksel DDR bellek değil) yapı dizisinin nasıl başlatılacağı konusunda bir fikriniz var mı? SoC'de (ARM-FPGA) TxRx'in uygulanması üzerinde çalışıyorum. Temel olarak ARM (PS) ve FPGA (PL), paylaşılan RAM belleğini kullanarak birbirleriyle iletişim kurar. Şu anda verici tarafında çalışıyorum, bu yüzden MAC katmanından belleğe aldığım paketleri sürekli olarak yüklemem gerekiyor, sonra Tx veri okuyor ve havaya gönderiyor. Bunu başarmak için (ARM) tarafındaki dairesel FIFO arabelleğini uygulamak istiyorum. Bu sayede 6 pakete kadar arabellek depolayabiliyor ve tek tek gönderebiliyordum, aynı zamanda paketlerin bulunduğu yerlere diğer paketleri de yükleyebiliyordum. Belirli bellek adreslerini kullanmam gerektiğinden, ilgilenen belirli adreslerde belleğe kaydedilecek yapı dizisini başlatmak mümkün. Örneğin, dizimin 0x400000 adresinde başladığını ve 0x400000 + MaximumNumberOfPackets x SizeOfPackets adresinde bittiğini istiyorum. Bunun gibi bir yapı örneği için nasıl yapılacağını biliyorum: buffer_t * tmp = (struct buffer_t *) 234881024;Bellekte belirli bir adresten başlayan diziyi başlat - C programlama

Ancak bu yapı dizisi için nasıl yapılır?

+0

sizin derleyici ve İşletim Sistemi (eğer varsa) nedir içine bu ayarlayın: Ben bağlayıcı komut dosyası içine bu set? –

+0

Merhaba, bu ARM gcc derleyicisi – elem

+0

Might yardım: http://stackoverflow.com/questions/4067811/how-to-place-a-variable-at-a-given-absolute-address-in-memory-with- gcc –

cevap

5

tek yapı (veya int, yüzen veya başka bir şey) için bir işaretçi doğal olarak bunların bir dizi için bir işaretçidir. İşaretçi tipi, bir dizi girişi için sizeof() değerini sağlar ve böylece işaretçi aritmetiğinin çalışmasına izin verir.

Böylece, struct buffer sadece

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

yapmak ve daha sonra bunu bir dizide

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

Bu beklediğiniz sadece şekilde çalışır olarak myFIFO erişebilir verilen.

struct buffer myFIFO[23] @ 0x400000; 

Ancak, derleyici may buna izin uzantılarına sahip:

Eğer (saf standart C kullanılarak) yapamaz yapabilirsiniz? Bu gibi belirli bir adreste bir diziyi bildirmek olduğunu. Birçok gömülü derleyici (her şeyden önce, bellek eşlemeli aygıt kayıtlarını nasıl bildirdiklerini sık sık yapar), ancak her derleyici satıcısı için ve muhtemelen her çip için farklı olacaktır, çünkü bir satıcı uzantısıdır.

GCC örnek

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

, bir özelliğiyle AVR işlemciler için izin vermez Ama bir ARM için bunu destekleyecek gibi görünmüyor.

+0

kdopen Cevabınız için teşekkür ederim Bunu böyle yapacağım. Başlangıçta buffer_pool'u başlatın ve for döngüsünü doldurun. – elem

2

Genellikle sağ @kdopen ama hafıza nerede kol için size linker'a gösterir BELLEK bölümünde bağlayıcı komut bir giriş oluşturmak olmalıdır:

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

Ve değişkeni bildirmek zaman sadece

kullanmak, daha

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

Gaskoin Linker komut dosyaları ile deneyimli değilim, ama bunu yapmaya çalışacağım ilginç görünüyor. Linker betiklerinin nasıl yazılacağını öğreneceğim. – elem

+0

Kodunuzu nasıl oluşturursunuz bilmiyorum, böylece size herhangi bir ayrıntı veremiyorum. ARM'niz için özel IDE'niz varsa, konfigürasyonda bir şeyler bulabilirsiniz. Eğer gcc kullanıyorsanız ld uzantılı bir dosyaya sahip olmalısınız -> ihtiyacınız olan şey budur :) – Gaskoin

+0

Sevgili Xilinx SDK kullanıyorum, bu tutulmaya dayanıyor. Nasıl yapılacağını buldum. Bunu böyle yapabilir miyim? I bağlayıcı komut dosyası, bu set: BELLEK { ps7_ddr_0_S_AXI_BASEADDR: ORIGIN = 0x00100000, UZUNLUK = 0x1FF00000 ps7_ram_0_S_AXI_BASEADDR: ORIGIN = 0x00000000, UZUNLUK = 0x00030000 ps7_ram_1_S_AXI_BASEADDR: ORIGIN = 0xFFFF0000, UZUNLUK = 0x0000FE00 DAC_DMA (w): ORIGIN = 0xE000000, LENGTH = 64K } Ve sonra bunu kod içine koydum static buffer_t __attribute __ ((bölüm ("DAC_DMA"))) buf_pool [6]; – elem

0

Nasıl yapılacağını buldum. Bunu böyle yapabilir miyim?

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 

Sonra kod

static buffer_t __attribute__((section("DAC_DMA"))) buf_pool[6]; 
İlgili konular