2016-04-25 4 views
0

Ich versuche mit GNU Radio [ZedBoard] mit/dev/mem auf einen benutzerdefinierten IP-Block zuzugreifen. Ich testete das Schreiben der Code-Routine und das iterative Lesen von/dev/mem aus einer lokalen c-Datei. Der Code, der direkt von der Konsole ausgeführt wird, setzt die Register korrekt und liest die korrekten Werte zurück.Zugriff auf/dev/mem von GNU Radio auf ZedBoard

Ich habe einen benutzerdefinierten GNU Radio-Block mit diesem Code erstellt, aber beim Ausführen des GRC-Flow-Python-Skripts erhalte ich den Fehler, dass/dev/mem nicht erreichbar war.

Ich weiß, dass dies keine sichere Möglichkeit ist, mit dem Gerät zu interagieren und arbeite an einem Treiber, um dies zu ersetzen. Momentan brauche ich das zum Testen und Entwickeln. Ich bin so weit gegangen, die Berechtigungen für/dev/mem auf 777 zu ändern, und habe meinen lokalen Benutzer (Linaro) ebenfalls zur kmem-Gruppe hinzugefügt. Ich führe die Python-Datei für den Flussgraphen auch mit sudo aus.

Was übersehe ich? Vielen Dank.

bearbeiten: die Ausgabefehler Hinzufügen ist: "Zugriff verweigert", wenn nach chmod 777/dev von sudo ausführen/den Fehler mem ist: "Operation nicht erlaubt"

/* -*- c++ -*- */ 
/* 
* Copyright 1970 <+YOU OR YOUR COMPANY+>. 
* 
* This is free software; you can redistribute it and/or modify 
* it under the terms of the GNU General Public License as published by 
* the Free Software Foundation; either version 3, or (at your option) 
* any later version. 
* 
* This software is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
* GNU General Public License for more details. 
* 
* You should have received a copy of the GNU General Public License 
* along with this software; see the file COPYING. If not, write to 
* the Free Software Foundation, Inc., 51 Franklin Street, 
* Boston, MA 02110-1301, USA. 
*/ 

#ifdef HAVE_CONFIG_H 
#include "config.h" 
#endif 

#include <gnuradio/io_signature.h> 
#include "qpskModulator_impl.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/mman.h> 
#include <fcntl.h> 

#define READ 0 
#define WRITE 1 

#define SAMPLES 64 
#define INPUT_WIDTH 32 

int memmap_fpga(int direction, char * address, float value); 

namespace gr { 
    namespace fpga_accelerators { 

    qpskModulator::sptr 
    qpskModulator::make() 
    { 
     return gnuradio::get_initial_sptr 
     (new qpskModulator_impl()); 
    } 

    /* 
    * The private constructor 
    */ 
    qpskModulator_impl::qpskModulator_impl() 
     : gr::block("qpskModulator", 
       gr::io_signature::make(1, 1, sizeof(float)), 
       gr::io_signature::make(2, 2, sizeof(short))) 
    {} 

    /* 
    * Our virtual destructor. 
    */ 
    qpskModulator_impl::~qpskModulator_impl() 
    { 
    } 

    void 
    qpskModulator_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) 
    { 
     ninput_items_required[0] = noutput_items; 
     ninput_items_required[1] = noutput_items; 
    } 

    int 
    qpskModulator_impl::general_work (int noutput_items, 
         gr_vector_int &ninput_items, 
         gr_vector_const_void_star &input_items, 
         gr_vector_void_star &output_items) 
    { 
     const float *in = (const float *) input_items[0]; 
     short *out0 = (short *) output_items[0]; // I CHANNEL 
     short *out1 = (short *) output_items[1]; // Q CHANNEL 

     short data_valid; 
     const float BLANK = 0; 
     float GO = 1; 

    //int hwI_mod[SAMPLES*INPUT_WIDTH/2]; 
    //int hwQ_mod[SAMPLES*INPUT_WIDTH/2]; 
    int i; 

    char * DATA_IN_ADDR = "0x43c00004"; 
    char * GO_ADDR = "0x43c00000"; 
    char * DATA_OUT_ADDR = "0x43c00008"; 
    char * DATA_VALID_ADDR = "0x43c0000C"; 

    // transfer input array and size to FPGA 
    memmap_fpga(WRITE, DATA_IN_ADDR, *in); 
    memmap_fpga(WRITE, GO_ADDR, GO); // assert go 
    GO = 0; 
    memmap_fpga(WRITE, GO_ADDR, GO); // reset go value 

    data_valid = 0; 
    while (data_valid == 0) { 
     data_valid = memmap_fpga(READ, DATA_VALID_ADDR, BLANK); 
     } 

     // read the outputs back from the FPGA 
    unsigned temp_dataout; 
    unsigned y; 
    for (i=0; i < SAMPLES*INPUT_WIDTH/2 - 8; i++) 
    { 
    temp_dataout = memmap_fpga(READ, DATA_OUT_ADDR, BLANK); 
     out0[i] = temp_dataout & 0xfff; // I channel 
     y = out0[i] >> 11; 
     if (y == 1) 
      out0[i] = out0[i] - 4096; 
     out1[i] = (temp_dataout >> 12) & 0xfff; 
     y = out1[i] >> 11; 
     if (y == 1) 
      out1[i] = out1[i] - 4096; 
     //printf("%d: HW: I_mod = %d and Q_mod = %d\n", i, hwI_mod[i], hwQ_mod[i]); 
    } 

     // Do <+signal processing+> 
     // Tell runtime system how many input items we consumed on 
     // each input stream. 
     consume_each (noutput_items); 

     // Tell runtime system how many output items we produced. 
     return noutput_items; 
    } 

    } /* namespace fpga_accelerators */ 
} /* namespace gr */ 

int memmap_fpga(int direction, char * address, float value){ 


    unsigned gpio_addr = strtoul(address, NULL, 0); 

    /* DEBUG INFO 
    printf("address: %08x\n",gpio_addr); 
    if (direction == IN) 
     printf("direction: IN\n"); 
    else 
     printf("direction: OUT\n"); 
    printf("value: %d\n",value); 
    */ 

    int fd; 
    unsigned page_addr, page_offset; 
    void *ptr; 
    unsigned page_size=sysconf(_SC_PAGESIZE); 
    short temp_value; 

     if (gpio_addr == 0) { 
      printf("GPIO physical address is required.\n"); 
      return -1; 
     } 

    /* Open /dev/mem file */ 
     fd = open ("/dev/mem", O_RDWR); 
     if (fd < 1) { 
      printf("Couldn't open /dev/mem\n"); 
      return -1; 
     } 


     /* mmap the device into memory */ 
     page_addr = (gpio_addr & (~(page_size-1))); 
     page_offset = gpio_addr - page_addr; 
     ptr = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, page_addr); 

     if (direction == READ) { 
     /* Read value from the device register */ 
      temp_value = *((unsigned *)(ptr + page_offset)); 
      //printf("gpio dev-mem test: input: %08x\n",temp_value); 
      munmap(ptr, page_size); 
      return(temp_value); 
     } else { 
     /* Write value to the device register */ 
      *((unsigned *)(ptr + page_offset)) = value; 
       munmap(ptr, page_size); 
      //printf("Wrote to register\n"); 
     } 


     munmap(ptr, page_size); 

return 0; 
} 
+0

sollten Sie den * verbatim * Fehler, den Sie bekommen, hinzufügen. Ziemlich sicher, dass dies nichts mit GNU Radio selbst zu tun hat. –

+0

Das Programm druckt "Konnte nicht öffnen/dev/mem" entsprechend diesem Codeabschnitt. Der Grund, warum ich es als GNU-Radio-Problem markiert habe, ist, dass ich nur auf dieses Problem stoße, wenn ich den im Radio-Block eingebetteten Code anrufe. '/ * Öffnen/dev/mem file */ fd = öffnen ("/dev/mem ", O_RDWR); if (fd <1) { printf ("Konnte nicht öffnen/dev/mem \ n"); Rückkehr -1; } ' – gutelfuldead

+0

@ MarcusMüller IE wenn ich [das] (http://pastebin.com/tpNjQzbK) ich habe keine Probleme. Es ist nur, wenn ich den gleichen Code Code innerhalb der GNU Radio-Implementierung ausgeführt habe. – gutelfuldead

Antwort

0

Zwei Dinge:

Sie öffnen und mem map die gleiche Datei für Lese-/Schreibzugriff mehrmals, ohne es zwischendurch zu schließen - das ist ein Rezept für ein Desaster. Vielleicht haben Sie gerade keine Dateideskriptoren mehr (da gibt es ein Limit). Eigentlich würde das Lesen der errno (Sie sollte tun, dass !!) würde Ihnen den Grund sagen.

Dann: gerade öffnen und Schließen Sie die Datei wiederholt ist eine schlechte Idee, Leistung weise nur öffnen und mmap es einmal im Konstruktor. Es gibt keinen Vorteil, es ständig wieder zu öffnen.

+0

Danke - Ich habe den Code aktualisiert, um fd jeden Lese-/Schreibvorgang sowie alle Lesevorgänge in einer Sitzung der Datei iterative öffnen. Was die anderen Zugriffsproblem die Ausgabe Ich bin immer besorgt, wenn dies von GNU Radio läuft: 'konnte nicht geöffnet werden/dev/mem, Fehler: Zugriff denied' Wo die Erlaubnis, die verweigert wird' strerror (errorno) ' – gutelfuldead

+0

Wenn ich chmod/dev/mem zu 777 und das Skript erneut ausführen, erhalte ich den Fehler:" Operation nicht erlaubt " – gutelfuldead