2016-04-25 1 views
0

J'essaie d'accéder à un bloc IP personnalisé à partir de GNU Radio [ZedBoard] en utilisant/dev/mem. J'ai testé la routine d'écriture de code et fait une lecture itérative depuis/dev/mem depuis un fichier c local. Le code qui s'exécute directement à partir de la console définit correctement les registres et lit les valeurs correctes.Accéder à/dev/mem à partir de GNU Radio sur ZedBoard

J'ai créé un bloc radio GNU personnalisé à l'aide de ce code, mais lors de l'exécution du script grc flow python, je reçois l'erreur que/dev/mem n'était pas accessible. Je sais que ce n'est pas un moyen sûr d'interagir avec l'appareil et je travaille sur un pilote pour le remplacer. Actuellement, j'ai besoin de cela pour travailler sur les tests et le développement. Je suis allé jusqu'à changer les permissions pour/dev/mem en 777, j'ai ajouté mon utilisateur local (Linaro) au groupe kmem également. J'exécute aussi le fichier python pour le flowgraph en utilisant sudo.

Qu'est-ce que je néglige? Je vous remercie.

modifier: Ajout de l'erreur de sortie est: "Autorisation refusée" si elle est exécutée de sudo après chmod 777/dev/mem l'erreur est: "Opération non autorisée"

/* -*- 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

vous devriez ajouter l'erreur * verbatim * que vous obtenez. Assez sûr que ce n'est pas lié à GNU Radio lui-même. –

+0

Le programme affiche "Impossible d'ouvrir/dev/mem" correspondant à cette section de code. La raison pour laquelle je l'ai étiqueté comme un problème GNU Radio est que je ne rencontre ce problème que lorsque j'appelle le code intégré dans le bloc Radio. '/ * Ouvrir/dev/mem */ fd = open ("/dev/mem ", O_RDWR); if (fd <1) { printf ("Impossible d'ouvrir/dev/mem \ n"); return -1; } ' – gutelfuldead

+0

@ MarcusMüller IE si je cours [this] (http://pastebin.com/tpNjQzbK) Je n'ai pas de problèmes. C'est seulement quand je cours le même ensemble de code incorporé dans l'implémentation radio GNU. – gutelfuldead

Répondre

0

Deux choses:

Vous ouvrez et memmap le même fichier pour l'accès en lecture/écriture plusieurs fois, sans le fermer entre - c'est une recette pour le désastre. Peut-être que vous êtes à court de descripteurs de fichiers (il y a une limite à cela). En fait lire le errno (vous devrait faire !!) vous dirait la raison. Ensuite: Même ouverture et fermeture du fichier à plusieurs reprises est une mauvaise idée, la performance sage - juste ouvrir mmap une fois dans le constructeur. Il n'y a aucun avantage à le rouvrir constamment.

+0

Merci - J'ai mis à jour le code pour fermer fd chaque lecture/écriture ainsi que de faire toutes les lectures itératives dans une session de fichier ouvert. En ce qui concerne l'autre problème d'accès concerne la sortie que je reçois lors de l'exécution de cette GNU Radio est: 'Impossible d'ouvrir/dev/mem, Erreur: autorisation denied' Lorsqu'une autorisation est refusée la' strerror (errorno) ' – gutelfuldead

+0

Quand je chmod/dev/mem à 777 et relance le script je reçois l'erreur:" Opération non autorisée " – gutelfuldead